From 179e197bd5827b920418052c9eff6f5b7d0826d8 Mon Sep 17 00:00:00 2001 From: tt2468 Date: Tue, 23 Apr 2024 00:24:55 -0700 Subject: [PATCH] base: Many random fixups preparing for WebSocketApi event callbacks --- src/WebSocketApi.cpp | 12 ++++--- src/WebSocketApi.h | 23 +++++++++----- src/eventhandler/EventHandler.cpp | 4 +-- src/eventhandler/EventHandler.h | 14 +++++---- src/obs-websocket.cpp | 42 ++++++++++++++++--------- src/websocketserver/WebSocketServer.cpp | 5 --- src/websocketserver/WebSocketServer.h | 13 +++----- 7 files changed, 66 insertions(+), 47 deletions(-) diff --git a/src/WebSocketApi.cpp b/src/WebSocketApi.cpp index 15c27150..6939fb98 100644 --- a/src/WebSocketApi.cpp +++ b/src/WebSocketApi.cpp @@ -18,7 +18,6 @@ with this program. If not, see #include "WebSocketApi.h" #include "requesthandler/RequestHandler.h" -#include "obs-websocket.h" #include "utils/Json.h" #define RETURN_STATUS(status) \ @@ -79,9 +78,12 @@ WebSocketApi::~WebSocketApi() blog_debug("[WebSocketApi::~WebSocketApi] Finished."); } -void WebSocketApi::SetEventCallback(EventCallback cb) +void WebSocketApi::BroadcastEvent(uint64_t requiredIntent, const std::string &eventType, const json &eventData, uint8_t rpcVersion) { - _eventCallback = cb; + UNUSED_PARAMETER(requiredIntent); + UNUSED_PARAMETER(eventType); + UNUSED_PARAMETER(eventData); + UNUSED_PARAMETER(rpcVersion); } enum WebSocketApi::RequestReturnCode WebSocketApi::PerformVendorRequest(std::string vendorName, std::string requestType, @@ -289,10 +291,10 @@ void WebSocketApi::vendor_event_emit_cb(void *priv_data, calldata_t *cd) auto eventData = static_cast(voidEventData); - if (!c->_eventCallback) + if (!c->_vendorEventCallback) RETURN_FAILURE(); - c->_eventCallback(v->_name, eventType, eventData); + c->_vendorEventCallback(v->_name, eventType, eventData); RETURN_SUCCESS(); } diff --git a/src/WebSocketApi.h b/src/WebSocketApi.h index 35d9ecd5..1c88502c 100644 --- a/src/WebSocketApi.h +++ b/src/WebSocketApi.h @@ -23,9 +23,13 @@ with this program. If not, see #include #include #include +#include #include #include +#include "utils/Json.h" +#include "plugin-macros.generated.h" + class WebSocketApi { public: enum RequestReturnCode { @@ -34,8 +38,6 @@ public: NoVendorRequest, }; - typedef std::function EventCallback; - struct Vendor { std::shared_mutex _mutex; std::string _name; @@ -44,12 +46,17 @@ public: WebSocketApi(); ~WebSocketApi(); - - void SetEventCallback(EventCallback cb); - + void BroadcastEvent(uint64_t requiredIntent, const std::string &eventType, const json &eventData = nullptr, + uint8_t rpcVersion = 0); + void SetObsReady(bool ready) { _obsReady = ready; } enum RequestReturnCode PerformVendorRequest(std::string vendorName, std::string requestName, obs_data_t *requestData, obs_data_t *responseData); + // Callback for when a vendor emits an event + typedef std::function VendorEventCallback; + inline void SetVendorEventCallback(VendorEventCallback cb) { _vendorEventCallback = cb; } + +private: static void get_ph_cb(void *priv_data, calldata_t *cd); static void get_api_version(void *, calldata_t *cd); static void call_request(void *, calldata_t *cd); @@ -58,9 +65,11 @@ public: static void vendor_request_unregister_cb(void *priv_data, calldata_t *cd); static void vendor_event_emit_cb(void *priv_data, calldata_t *cd); -private: std::shared_mutex _mutex; - EventCallback _eventCallback; proc_handler_t *_procHandler; std::map _vendors; + + std::atomic _obsReady = false; + + VendorEventCallback _vendorEventCallback; }; diff --git a/src/eventhandler/EventHandler.cpp b/src/eventhandler/EventHandler.cpp index 874878a5..cf862b62 100644 --- a/src/eventhandler/EventHandler.cpp +++ b/src/eventhandler/EventHandler.cpp @@ -110,10 +110,10 @@ void EventHandler::ProcessSubscriptionChange(bool type, uint64_t eventSubscripti // Function required in order to use default arguments void EventHandler::BroadcastEvent(uint64_t requiredIntent, std::string eventType, json eventData, uint8_t rpcVersion) { - if (!_broadcastCallback) + if (!_eventCallback) return; - _broadcastCallback(requiredIntent, eventType, eventData, rpcVersion); + _eventCallback(requiredIntent, eventType, eventData, rpcVersion); } // Connect source signals for Inputs, Scenes, and Transitions. Filters are automatically connected. diff --git a/src/eventhandler/EventHandler.h b/src/eventhandler/EventHandler.h index 163879e1..e9094428 100644 --- a/src/eventhandler/EventHandler.h +++ b/src/eventhandler/EventHandler.h @@ -34,17 +34,19 @@ public: EventHandler(); ~EventHandler(); - typedef std::function - BroadcastCallback; // uint64_t requiredIntent, std::string eventType, json eventData, uint8_t rpcVersion - inline void SetBroadcastCallback(BroadcastCallback cb) { _broadcastCallback = cb; } + void ProcessSubscriptionChange(bool type, uint64_t eventSubscriptions); + // Callback when an event fires + typedef std::function + EventCallback; // uint64_t requiredIntent, std::string eventType, json eventData, uint8_t rpcVersion + inline void SetEventCallback(EventCallback cb) { _eventCallback = cb; } + + // Callback when OBS becomes ready or non-ready typedef std::function ObsReadyCallback; // bool ready inline void SetObsReadyCallback(ObsReadyCallback cb) { _obsReadyCallback = cb; } - void ProcessSubscriptionChange(bool type, uint64_t eventSubscriptions); - private: - BroadcastCallback _broadcastCallback; + EventCallback _eventCallback; ObsReadyCallback _obsReadyCallback; std::atomic _obsReady = false; diff --git a/src/obs-websocket.cpp b/src/obs-websocket.cpp index e399abc4..629890e3 100644 --- a/src/obs-websocket.cpp +++ b/src/obs-websocket.cpp @@ -48,7 +48,9 @@ WebSocketApiPtr _webSocketApi; WebSocketServerPtr _webSocketServer; SettingsDialog *_settingsDialog = nullptr; -void WebSocketApiEventCallback(std::string vendorName, std::string eventType, obs_data_t *obsEventData); +void OnWebSocketApiVendorEvent(std::string vendorName, std::string eventType, obs_data_t *obsEventData); +void OnEvent(uint64_t requiredIntent, std::string eventType, json eventData, uint8_t rpcVersion); +void OnObsReady(bool ready); bool obs_module_load(void) { @@ -73,19 +75,15 @@ bool obs_module_load(void) // Initialize the event handler _eventHandler = std::make_shared(); + _eventHandler->SetEventCallback(OnEvent); + _eventHandler->SetObsReadyCallback(OnObsReady); // Initialize the plugin/script API _webSocketApi = std::make_shared(); - _webSocketApi->SetEventCallback(WebSocketApiEventCallback); + _webSocketApi->SetVendorEventCallback(OnWebSocketApiVendorEvent); // Initialize the WebSocket server _webSocketServer = std::make_shared(); - - // Attach event handlers between WebSocket server and event handler - _eventHandler->SetBroadcastCallback(std::bind(&WebSocketServer::BroadcastEvent, _webSocketServer.get(), - std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, - std::placeholders::_4)); - _eventHandler->SetObsReadyCallback(std::bind(&WebSocketServer::SetObsReady, _webSocketServer.get(), std::placeholders::_1)); _webSocketServer->SetClientSubscriptionCallback(std::bind(&EventHandler::ProcessSubscriptionChange, _eventHandler.get(), std::placeholders::_1, std::placeholders::_2)); @@ -131,18 +129,16 @@ void obs_module_unload(void) _webSocketServer->Stop(); } - // Disconnect event handler from WebSocket server - _eventHandler->SetObsReadyCallback(nullptr); - _eventHandler->SetBroadcastCallback(nullptr); - _webSocketServer->SetClientSubscriptionCallback(nullptr); - // Release the WebSocket server + _webSocketServer->SetClientSubscriptionCallback(nullptr); _webSocketServer = nullptr; // Release the plugin/script api _webSocketApi = nullptr; // Release the event handler + _eventHandler->SetObsReadyCallback(nullptr); + _eventHandler->SetEventCallback(nullptr); _eventHandler = nullptr; // Release the config manager @@ -202,7 +198,7 @@ bool IsDebugEnabled() * @api events * @category general */ -void WebSocketApiEventCallback(std::string vendorName, std::string eventType, obs_data_t *obsEventData) +void OnWebSocketApiVendorEvent(std::string vendorName, std::string eventType, obs_data_t *obsEventData) { json eventData = Utils::Json::ObsDataToJson(obsEventData); @@ -214,6 +210,24 @@ void WebSocketApiEventCallback(std::string vendorName, std::string eventType, ob _webSocketServer->BroadcastEvent(EventSubscription::Vendors, "VendorEvent", broadcastEventData); } +// Sent from: EventHandler +void OnEvent(uint64_t requiredIntent, std::string eventType, json eventData, uint8_t rpcVersion) +{ + if (_webSocketServer) + _webSocketServer->BroadcastEvent(requiredIntent, eventType, eventData, rpcVersion); + if (_webSocketApi) + _webSocketApi->BroadcastEvent(requiredIntent, eventType, eventData, rpcVersion); +} + +// Sent from: EventHandler +void OnObsReady(bool ready) +{ + if (_webSocketServer) + _webSocketServer->SetObsReady(ready); + if (_webSocketApi) + _webSocketApi->SetObsReady(ready); +} + #ifdef PLUGIN_TESTS static void test_vendor_request_cb(obs_data_t *requestData, obs_data_t *responseData, void *priv_data) diff --git a/src/websocketserver/WebSocketServer.cpp b/src/websocketserver/WebSocketServer.cpp index ee9334fa..bd1bc3c6 100644 --- a/src/websocketserver/WebSocketServer.cpp +++ b/src/websocketserver/WebSocketServer.cpp @@ -201,11 +201,6 @@ std::vector WebSocketServer::GetWebSocke return webSocketSessions; } -void WebSocketServer::SetObsReady(bool ready) -{ - _obsReady = ready; -} - bool WebSocketServer::onValidate(websocketpp::connection_hdl hdl) { auto conn = _server.get_con_from_hdl(hdl); diff --git a/src/websocketserver/WebSocketServer.h b/src/websocketserver/WebSocketServer.h index 091a4fbe..6bb406b5 100644 --- a/src/websocketserver/WebSocketServer.h +++ b/src/websocketserver/WebSocketServer.h @@ -30,8 +30,8 @@ with this program. If not, see #include "rpc/WebSocketSession.h" #include "types/WebSocketCloseCode.h" #include "types/WebSocketOpCode.h" -#include "../utils/Json.h" #include "../requesthandler/rpc/Request.h" +#include "../utils/Json.h" #include "plugin-macros.generated.h" class WebSocketServer : QObject { @@ -57,18 +57,15 @@ public: void InvalidateSession(websocketpp::connection_hdl hdl); void BroadcastEvent(uint64_t requiredIntent, const std::string &eventType, const json &eventData = nullptr, uint8_t rpcVersion = 0); - void SetObsReady(bool ready); + inline void SetObsReady(bool ready) { _obsReady = ready; } + inline bool IsListening() { return _server.is_listening(); } + std::vector GetWebSocketSessions(); + inline QThreadPool *GetThreadPool() { return &_threadPool; } // Callback for when a client subscribes or unsubscribes. `true` for sub, `false` for unsub typedef std::function ClientSubscriptionCallback; // bool type, uint64_t eventSubscriptions inline void SetClientSubscriptionCallback(ClientSubscriptionCallback cb) { _clientSubscriptionCallback = cb; } - inline bool IsListening() { return _server.is_listening(); } - - std::vector GetWebSocketSessions(); - - inline QThreadPool *GetThreadPool() { return &_threadPool; } - signals: void ClientConnected(WebSocketSessionState state); void ClientDisconnected(WebSocketSessionState state, uint16_t closeCode);