mirror of
https://github.com/Palakis/obs-websocket.git
synced 2024-08-30 18:12:16 +00:00
base: Many random fixups preparing for WebSocketApi event callbacks
This commit is contained in:
parent
5fc39ef054
commit
179e197bd5
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user