base: Many random fixups preparing for WebSocketApi event callbacks

This commit is contained in:
tt2468 2024-04-23 00:24:55 -07:00
parent 5fc39ef054
commit 179e197bd5
7 changed files with 66 additions and 47 deletions

View File

@ -18,7 +18,6 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include "WebSocketApi.h" #include "WebSocketApi.h"
#include "requesthandler/RequestHandler.h" #include "requesthandler/RequestHandler.h"
#include "obs-websocket.h"
#include "utils/Json.h" #include "utils/Json.h"
#define RETURN_STATUS(status) \ #define RETURN_STATUS(status) \
@ -79,9 +78,12 @@ WebSocketApi::~WebSocketApi()
blog_debug("[WebSocketApi::~WebSocketApi] Finished."); 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, 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<obs_data_t *>(voidEventData); auto eventData = static_cast<obs_data_t *>(voidEventData);
if (!c->_eventCallback) if (!c->_vendorEventCallback)
RETURN_FAILURE(); RETURN_FAILURE();
c->_eventCallback(v->_name, eventType, eventData); c->_vendorEventCallback(v->_name, eventType, eventData);
RETURN_SUCCESS(); RETURN_SUCCESS();
} }

View File

@ -23,9 +23,13 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include <map> #include <map>
#include <mutex> #include <mutex>
#include <shared_mutex> #include <shared_mutex>
#include <atomic>
#include <obs.h> #include <obs.h>
#include <obs-websocket-api.h> #include <obs-websocket-api.h>
#include "utils/Json.h"
#include "plugin-macros.generated.h"
class WebSocketApi { class WebSocketApi {
public: public:
enum RequestReturnCode { enum RequestReturnCode {
@ -34,8 +38,6 @@ public:
NoVendorRequest, NoVendorRequest,
}; };
typedef std::function<void(std::string, std::string, obs_data_t *)> EventCallback;
struct Vendor { struct Vendor {
std::shared_mutex _mutex; std::shared_mutex _mutex;
std::string _name; std::string _name;
@ -44,12 +46,17 @@ public:
WebSocketApi(); WebSocketApi();
~WebSocketApi(); ~WebSocketApi();
void BroadcastEvent(uint64_t requiredIntent, const std::string &eventType, const json &eventData = nullptr,
void SetEventCallback(EventCallback cb); uint8_t rpcVersion = 0);
void SetObsReady(bool ready) { _obsReady = ready; }
enum RequestReturnCode PerformVendorRequest(std::string vendorName, std::string requestName, obs_data_t *requestData, enum RequestReturnCode PerformVendorRequest(std::string vendorName, std::string requestName, obs_data_t *requestData,
obs_data_t *responseData); obs_data_t *responseData);
// Callback for when a vendor emits an event
typedef std::function<void(std::string, std::string, obs_data_t *)> VendorEventCallback;
inline void SetVendorEventCallback(VendorEventCallback cb) { _vendorEventCallback = cb; }
private:
static void get_ph_cb(void *priv_data, calldata_t *cd); static void get_ph_cb(void *priv_data, calldata_t *cd);
static void get_api_version(void *, calldata_t *cd); static void get_api_version(void *, calldata_t *cd);
static void call_request(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_request_unregister_cb(void *priv_data, calldata_t *cd);
static void vendor_event_emit_cb(void *priv_data, calldata_t *cd); static void vendor_event_emit_cb(void *priv_data, calldata_t *cd);
private:
std::shared_mutex _mutex; std::shared_mutex _mutex;
EventCallback _eventCallback;
proc_handler_t *_procHandler; proc_handler_t *_procHandler;
std::map<std::string, Vendor *> _vendors; std::map<std::string, Vendor *> _vendors;
std::atomic<bool> _obsReady = false;
VendorEventCallback _vendorEventCallback;
}; };

View File

@ -110,10 +110,10 @@ void EventHandler::ProcessSubscriptionChange(bool type, uint64_t eventSubscripti
// Function required in order to use default arguments // Function required in order to use default arguments
void EventHandler::BroadcastEvent(uint64_t requiredIntent, std::string eventType, json eventData, uint8_t rpcVersion) void EventHandler::BroadcastEvent(uint64_t requiredIntent, std::string eventType, json eventData, uint8_t rpcVersion)
{ {
if (!_broadcastCallback) if (!_eventCallback)
return; return;
_broadcastCallback(requiredIntent, eventType, eventData, rpcVersion); _eventCallback(requiredIntent, eventType, eventData, rpcVersion);
} }
// Connect source signals for Inputs, Scenes, and Transitions. Filters are automatically connected. // Connect source signals for Inputs, Scenes, and Transitions. Filters are automatically connected.

View File

@ -34,17 +34,19 @@ public:
EventHandler(); EventHandler();
~EventHandler(); ~EventHandler();
typedef std::function<void(uint64_t, std::string, json, uint8_t)> void ProcessSubscriptionChange(bool type, uint64_t eventSubscriptions);
BroadcastCallback; // uint64_t requiredIntent, std::string eventType, json eventData, uint8_t rpcVersion
inline void SetBroadcastCallback(BroadcastCallback cb) { _broadcastCallback = cb; }
// Callback when an event fires
typedef std::function<void(uint64_t, std::string, json, uint8_t)>
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<void(bool)> ObsReadyCallback; // bool ready typedef std::function<void(bool)> ObsReadyCallback; // bool ready
inline void SetObsReadyCallback(ObsReadyCallback cb) { _obsReadyCallback = cb; } inline void SetObsReadyCallback(ObsReadyCallback cb) { _obsReadyCallback = cb; }
void ProcessSubscriptionChange(bool type, uint64_t eventSubscriptions);
private: private:
BroadcastCallback _broadcastCallback; EventCallback _eventCallback;
ObsReadyCallback _obsReadyCallback; ObsReadyCallback _obsReadyCallback;
std::atomic<bool> _obsReady = false; std::atomic<bool> _obsReady = false;

View File

@ -48,7 +48,9 @@ WebSocketApiPtr _webSocketApi;
WebSocketServerPtr _webSocketServer; WebSocketServerPtr _webSocketServer;
SettingsDialog *_settingsDialog = nullptr; 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) bool obs_module_load(void)
{ {
@ -73,19 +75,15 @@ bool obs_module_load(void)
// Initialize the event handler // Initialize the event handler
_eventHandler = std::make_shared<EventHandler>(); _eventHandler = std::make_shared<EventHandler>();
_eventHandler->SetEventCallback(OnEvent);
_eventHandler->SetObsReadyCallback(OnObsReady);
// Initialize the plugin/script API // Initialize the plugin/script API
_webSocketApi = std::make_shared<WebSocketApi>(); _webSocketApi = std::make_shared<WebSocketApi>();
_webSocketApi->SetEventCallback(WebSocketApiEventCallback); _webSocketApi->SetVendorEventCallback(OnWebSocketApiVendorEvent);
// Initialize the WebSocket server // Initialize the WebSocket server
_webSocketServer = std::make_shared<WebSocketServer>(); _webSocketServer = std::make_shared<WebSocketServer>();
// 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(), _webSocketServer->SetClientSubscriptionCallback(std::bind(&EventHandler::ProcessSubscriptionChange, _eventHandler.get(),
std::placeholders::_1, std::placeholders::_2)); std::placeholders::_1, std::placeholders::_2));
@ -131,18 +129,16 @@ void obs_module_unload(void)
_webSocketServer->Stop(); _webSocketServer->Stop();
} }
// Disconnect event handler from WebSocket server
_eventHandler->SetObsReadyCallback(nullptr);
_eventHandler->SetBroadcastCallback(nullptr);
_webSocketServer->SetClientSubscriptionCallback(nullptr);
// Release the WebSocket server // Release the WebSocket server
_webSocketServer->SetClientSubscriptionCallback(nullptr);
_webSocketServer = nullptr; _webSocketServer = nullptr;
// Release the plugin/script api // Release the plugin/script api
_webSocketApi = nullptr; _webSocketApi = nullptr;
// Release the event handler // Release the event handler
_eventHandler->SetObsReadyCallback(nullptr);
_eventHandler->SetEventCallback(nullptr);
_eventHandler = nullptr; _eventHandler = nullptr;
// Release the config manager // Release the config manager
@ -202,7 +198,7 @@ bool IsDebugEnabled()
* @api events * @api events
* @category general * @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); 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); _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 #ifdef PLUGIN_TESTS
static void test_vendor_request_cb(obs_data_t *requestData, obs_data_t *responseData, void *priv_data) static void test_vendor_request_cb(obs_data_t *requestData, obs_data_t *responseData, void *priv_data)

View File

@ -201,11 +201,6 @@ std::vector<WebSocketServer::WebSocketSessionState> WebSocketServer::GetWebSocke
return webSocketSessions; return webSocketSessions;
} }
void WebSocketServer::SetObsReady(bool ready)
{
_obsReady = ready;
}
bool WebSocketServer::onValidate(websocketpp::connection_hdl hdl) bool WebSocketServer::onValidate(websocketpp::connection_hdl hdl)
{ {
auto conn = _server.get_con_from_hdl(hdl); auto conn = _server.get_con_from_hdl(hdl);

View File

@ -30,8 +30,8 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include "rpc/WebSocketSession.h" #include "rpc/WebSocketSession.h"
#include "types/WebSocketCloseCode.h" #include "types/WebSocketCloseCode.h"
#include "types/WebSocketOpCode.h" #include "types/WebSocketOpCode.h"
#include "../utils/Json.h"
#include "../requesthandler/rpc/Request.h" #include "../requesthandler/rpc/Request.h"
#include "../utils/Json.h"
#include "plugin-macros.generated.h" #include "plugin-macros.generated.h"
class WebSocketServer : QObject { class WebSocketServer : QObject {
@ -57,18 +57,15 @@ public:
void InvalidateSession(websocketpp::connection_hdl hdl); void InvalidateSession(websocketpp::connection_hdl hdl);
void BroadcastEvent(uint64_t requiredIntent, const std::string &eventType, const json &eventData = nullptr, void BroadcastEvent(uint64_t requiredIntent, const std::string &eventType, const json &eventData = nullptr,
uint8_t rpcVersion = 0); uint8_t rpcVersion = 0);
void SetObsReady(bool ready); inline void SetObsReady(bool ready) { _obsReady = ready; }
inline bool IsListening() { return _server.is_listening(); }
std::vector<WebSocketSessionState> GetWebSocketSessions();
inline QThreadPool *GetThreadPool() { return &_threadPool; }
// Callback for when a client subscribes or unsubscribes. `true` for sub, `false` for unsub // Callback for when a client subscribes or unsubscribes. `true` for sub, `false` for unsub
typedef std::function<void(bool, uint64_t)> ClientSubscriptionCallback; // bool type, uint64_t eventSubscriptions typedef std::function<void(bool, uint64_t)> ClientSubscriptionCallback; // bool type, uint64_t eventSubscriptions
inline void SetClientSubscriptionCallback(ClientSubscriptionCallback cb) { _clientSubscriptionCallback = cb; } inline void SetClientSubscriptionCallback(ClientSubscriptionCallback cb) { _clientSubscriptionCallback = cb; }
inline bool IsListening() { return _server.is_listening(); }
std::vector<WebSocketSessionState> GetWebSocketSessions();
inline QThreadPool *GetThreadPool() { return &_threadPool; }
signals: signals:
void ClientConnected(WebSocketSessionState state); void ClientConnected(WebSocketSessionState state);
void ClientDisconnected(WebSocketSessionState state, uint16_t closeCode); void ClientDisconnected(WebSocketSessionState state, uint16_t closeCode);