From: APTX Date: Sun, 20 Feb 2022 07:05:03 +0000 (+0900) Subject: Introduce EventHandler X-Git-Url: https://gitweb.aptx.org/?a=commitdiff_plain;h=0f5903f8672af87979c8dc62b7263084a561d0d9;p=aniplayer.git Introduce EventHandler --- diff --git a/backendplugins/backend_mpv/backendmpv.cpp b/backendplugins/backend_mpv/backendmpv.cpp index 6df7807..40a3c6e 100644 --- a/backendplugins/backend_mpv/backendmpv.cpp +++ b/backendplugins/backend_mpv/backendmpv.cpp @@ -34,6 +34,7 @@ MpvInstance::MpvInstance(PlayerPluginInterface *playerInterface, : QObject{parent}, m_player{playerInterface}, m_handle{ mpv::Handle::create()} { qCDebug(mpvBackend) << "Initialize"; + m_eventHandler = std::make_unique>(this); qCDebug(mpvBackend()).nospace() << "Client API version: " << (mpv_client_api_version() >> 16) << '.' @@ -107,6 +108,13 @@ MpvInstance::MpvInstance(PlayerPluginInterface *playerInterface, maxVolume /= 100.0; m_player->playbackMaxVolumeChanged(maxVolume); } + m_eventHandler->subscribe(mpv::event::LogMessage, &MpvInstance::onLogMessage); + m_eventHandler->subscribe(mpv::event::PropertyChange, + &MpvInstance::onPropertyChange); + m_eventHandler->subscribe(mpv::event::FileLoaded, &MpvInstance::onFileLoaded); + m_eventHandler->subscribe(mpv::event::EndFile, &MpvInstance::onEndFile); + m_eventHandler->subscribe(mpv::event::AudioReconfig, + &MpvInstance::onAudioReconfig); } MpvInstance::~MpvInstance() { @@ -259,32 +267,7 @@ void MpvInstance::processMpvEvents() { qCDebug(mpvVerboseBackend).nospace() << "Event " << mpv_event_name(event->event_id) << '(' << event->event_id << "), error: " << event->error; - switch (event->event_id) { - case MPV_EVENT_PROPERTY_CHANGE: { - Q_CHECK_PTR(event->data); - auto property = static_cast(event->data); - Q_CHECK_PTR(property); - onPropertyChange(property); - } break; - case MPV_EVENT_LOG_MESSAGE: { - Q_CHECK_PTR(event->data); - auto log = static_cast(event->data); - Q_CHECK_PTR(log); - onLogMessage(log); - } break; - case MPV_EVENT_FILE_LOADED: { - onFileLoaded(); - } break; - case MPV_EVENT_END_FILE: { - Q_CHECK_PTR(event->data); - auto endFile = static_cast(event->data); - onEndFile(endFile); - } break; - case MPV_EVENT_AUDIO_RECONFIG: { - onAudioReconfig(); - } break; - default:; - } + m_eventHandler->handleEvent(event); } while (event->event_id != MPV_EVENT_NONE); } diff --git a/backendplugins/backend_mpv/backendmpv.h b/backendplugins/backend_mpv/backendmpv.h index 88924f1..69013d3 100644 --- a/backendplugins/backend_mpv/backendmpv.h +++ b/backendplugins/backend_mpv/backendmpv.h @@ -13,6 +13,11 @@ struct mpv_event_property; struct mpv_event_log_message; struct mpv_event_end_file; +namespace mpv { +template +class EventHandler; +} + class BACKEND_MPVSHARED_EXPORT BackendMpv : public QObject, public BackendPluginBase { Q_OBJECT @@ -63,6 +68,7 @@ private: int readTrackIndex(struct mpv_event_property *); + std::unique_ptr> m_eventHandler; PlayerPluginInterface *m_player = nullptr; mpv::Handle m_handle; Volume m_volumeToSet = -1; diff --git a/backendplugins/backend_mpv/mpvhelper.h b/backendplugins/backend_mpv/mpvhelper.h index d0612cb..375ab82 100644 --- a/backendplugins/backend_mpv/mpvhelper.h +++ b/backendplugins/backend_mpv/mpvhelper.h @@ -9,6 +9,7 @@ #include #include +#include #include @@ -49,6 +50,7 @@ template struct Event { using type = DataType; + using type_ptr = type *; const mpv_event_id id; constexpr explicit Event(mpv_event_id id) : id{id} {} }; @@ -232,6 +234,70 @@ int SetProperty(const Handle &handle, const Property &property, return detail::WriteFormat(handle, format, property.name, value); } +template +class EventHandler { + struct Callback + { + virtual ~Callback() = default; + virtual void run(Class *, mpv_event *) const = 0; + }; + template + struct EventCallback : public Callback + { + const Event m_event; + CallbackType m_callback; + + EventCallback(Event event, CallbackType callback) + : m_event{event}, m_callback{callback} {} + + void run(Class *obj, mpv_event *event) const override { + assert(event->event_id == m_event.id); + if constexpr (IsVoid) { + (obj->*m_callback)(); + } else { + assert(event->data != nullptr); + auto data = static_cast(event->data); + (obj->*m_callback)(data); + } + } + }; + + Class *const m_obj; + + std::unordered_map> m_eventHandlers; + +public: + explicit EventHandler(Class *obj) : m_obj{obj} {} + + template + std::enable_if_t, bool> + subscribe(Event event, void (Class::*handler)(typename Event::type_ptr)) { + auto pair = m_eventHandlers.emplace(std::make_pair( + event.id, + std::make_unique>( + event, handler))); + return !pair.second; + } + + template + bool subscribe(Event event, void (Class::*handler)()) { + auto pair = m_eventHandlers.emplace(std::make_pair( + event.id, + std::make_unique>( + event, handler))); + return !pair.second; + } + + void handleEvent(mpv_event *event) { + assert(event != nullptr); + const auto it = m_eventHandlers.find(event->event_id); + if (it == std::end(m_eventHandlers)) { + return; + } + it->second->run(m_obj, event); + } +}; + } // namespace mpv #endif // MPVHELPER_H