#if !defined(LIBREMIDI_HEADER_ONLY) #include #endif #include #include namespace libremidi { LIBREMIDI_INLINE auto make_observer(auto base_conf, std::any api_conf) { std::unique_ptr ptr; auto from_api = [&](T& /*backend*/) mutable { if (auto conf = std::any_cast(&api_conf)) { ptr = libremidi::make(std::move(base_conf), std::move(*conf)); return true; } return false; }; std::apply([&](auto&&... b) { (from_api(b) || ...); }, midi1::available_backends); std::apply([&](auto&&... b) { (from_api(b) || ...); }, midi2::available_backends); return ptr; } LIBREMIDI_INLINE observer::observer(const observer_configuration& base_conf) noexcept { for (const auto& api : available_apis()) { try { impl_ = make_observer(base_conf, observer_configuration_for(api)); } catch (const std::exception& e) { } if (impl_) return; } if (!impl_) impl_ = std::make_unique(observer_configuration{}, dummy_configuration{}); } LIBREMIDI_INLINE observer::observer(observer_configuration base_conf, std::any api_conf) : impl_{make_observer(base_conf, api_conf)} { if (!impl_) throw midi_exception("Could not open observer for the given API"); } LIBREMIDI_INLINE observer::observer(observer&& other) noexcept : impl_{std::move(other.impl_)} { other.impl_ = std::make_unique( observer_configuration{}, dummy_configuration{}); } LIBREMIDI_INLINE observer& observer::operator=(observer&& other) noexcept { this->impl_ = std::move(other.impl_); other.impl_ = std::make_unique( observer_configuration{}, dummy_configuration{}); return *this; } LIBREMIDI_INLINE observer::~observer() = default; LIBREMIDI_INLINE libremidi::API observer::get_current_api() const noexcept { return impl_->get_current_api(); } LIBREMIDI_INLINE std::vector observer::get_input_ports() const noexcept { return impl_->get_input_ports(); } LIBREMIDI_INLINE std::vector observer::get_output_ports() const noexcept { return impl_->get_output_ports(); } }