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 "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<obs_data_t *>(voidEventData);
if (!c->_eventCallback)
if (!c->_vendorEventCallback)
RETURN_FAILURE();
c->_eventCallback(v->_name, eventType, eventData);
c->_vendorEventCallback(v->_name, eventType, eventData);
RETURN_SUCCESS();
}

View File

@ -23,9 +23,13 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include <map>
#include <mutex>
#include <shared_mutex>
#include <atomic>
#include <obs.h>
#include <obs-websocket-api.h>
#include "utils/Json.h"
#include "plugin-macros.generated.h"
class WebSocketApi {
public:
enum RequestReturnCode {
@ -34,8 +38,6 @@ public:
NoVendorRequest,
};
typedef std::function<void(std::string, std::string, obs_data_t *)> 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<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_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<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
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.

View File

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

View File

@ -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>();
_eventHandler->SetEventCallback(OnEvent);
_eventHandler->SetObsReadyCallback(OnObsReady);
// Initialize the plugin/script API
_webSocketApi = std::make_shared<WebSocketApi>();
_webSocketApi->SetEventCallback(WebSocketApiEventCallback);
_webSocketApi->SetVendorEventCallback(OnWebSocketApiVendorEvent);
// Initialize the WebSocket server
_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(),
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)

View File

@ -201,11 +201,6 @@ std::vector<WebSocketServer::WebSocketSessionState> 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);

View File

@ -30,8 +30,8 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#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<WebSocketSessionState> GetWebSocketSessions();
inline QThreadPool *GetThreadPool() { return &_threadPool; }
// 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
inline void SetClientSubscriptionCallback(ClientSubscriptionCallback cb) { _clientSubscriptionCallback = cb; }
inline bool IsListening() { return _server.is_listening(); }
std::vector<WebSocketSessionState> GetWebSocketSessions();
inline QThreadPool *GetThreadPool() { return &_threadPool; }
signals:
void ClientConnected(WebSocketSessionState state);
void ClientDisconnected(WebSocketSessionState state, uint16_t closeCode);