WebSocketApi: Finish implementations

This commit is contained in:
tt2468 2021-12-14 18:22:52 -08:00
parent 539ee3f28f
commit 5f261de143
6 changed files with 108 additions and 8 deletions

View File

@ -55,7 +55,7 @@ enum WebSocketApi::RequestReturnCode WebSocketApi::PerformVendorRequest(std::str
std::shared_lock l(_mutex);
if (_vendors.count(vendorName) == 0)
return WEBSOCKET_API_REQUEST_RETURN_CODE_NO_VENDOR;
return RequestReturnCode::NoVendor;
auto v = _vendors[vendorName];
@ -64,7 +64,7 @@ enum WebSocketApi::RequestReturnCode WebSocketApi::PerformVendorRequest(std::str
std::shared_lock v_l(v->_mutex);
if (v->_requests.count(requestType) == 0)
return WEBSOCKET_API_REQUEST_RETURN_CODE_NO_VENDOR_REQUEST;
return RequestReturnCode::NoVendorRequest;
auto cb = v->_requests[requestType];
@ -72,7 +72,7 @@ enum WebSocketApi::RequestReturnCode WebSocketApi::PerformVendorRequest(std::str
cb.callback(requestData, responseData, cb.priv_data);
return WEBSOCKET_API_REQUEST_RETURN_CODE_NORMAL;
return RequestReturnCode::Normal;
}
void WebSocketApi::get_ph_cb(void *priv_data, calldata_t *cd)

View File

@ -12,9 +12,9 @@
class WebSocketApi {
public:
enum RequestReturnCode {
WEBSOCKET_API_REQUEST_RETURN_CODE_NORMAL,
WEBSOCKET_API_REQUEST_RETURN_CODE_NO_VENDOR,
WEBSOCKET_API_REQUEST_RETURN_CODE_NO_VENDOR_REQUEST,
Normal,
NoVendor,
NoVendorRequest,
};
typedef std::function<void(std::string, std::string, obs_data_t*)> EventCallback;

View File

@ -138,7 +138,7 @@ void WebSocketApiEventCallback(std::string vendorName, std::string eventType, ob
broadcastEventData["eventType"] = eventType;
broadcastEventData["eventData"] = eventData;
_webSocketServer->BroadcastEvent(EventSubscription::ExternalPlugins, "ExternalPluginEvent", broadcastEventData);
_webSocketServer->BroadcastEvent(EventSubscription::ExternalPlugins, "VendorEvent", broadcastEventData);
}
void ___source_dummy_addref(obs_source_t*) {}
@ -151,3 +151,40 @@ void ___output_dummy_addref(obs_output_t*) {}
void ___data_item_dummy_addref(obs_data_item_t*) {}
void ___data_item_release(obs_data_item_t* dataItem){ obs_data_item_release(&dataItem); }
void ___properties_dummy_addref(obs_properties_t*) {}
#define PLUGIN_API_TEST
#ifdef PLUGIN_API_TEST
static void test_vendor_request_cb(obs_data_t *requestData, obs_data_t *responseData, void *priv_data)
{
blog(LOG_INFO, "[test_vendor_request_cb] Request called!");
blog(LOG_INFO, "[test_vendor_request_cb] Request data: %s", obs_data_get_json(requestData));
// Set an item to the response data
obs_data_set_string(responseData, "test", "pp");
// Emit an event with the request data as the event data
obs_websocket_vendor_emit_event(priv_data, "TestEvent", requestData);
}
void obs_module_post_load()
{
blog(LOG_INFO, "[obs_module_post_load] Post load started.");
auto vendor = obs_websocket_register_vendor("obs-websocket-test");
if (!vendor) {
blog(LOG_WARNING, "[obs_module_post_load] Failed to create vendor!");
return;
}
if (!obs_websocket_vendor_register_request(vendor, "TestRequest", test_vendor_request_cb, vendor)) {
blog(LOG_WARNING, "[obs_module_post_load] Failed to register vendor request!");
return;
}
blog(LOG_INFO, "[obs_module_post_load] Post load completed.");
}
#endif

View File

@ -25,6 +25,7 @@ const std::map<std::string, RequestMethodHandler> RequestHandler::_handlerMap
{"GetVersion", &RequestHandler::GetVersion},
{"GetStats", &RequestHandler::GetStats},
{"BroadcastCustomEvent", &RequestHandler::BroadcastCustomEvent},
{"CallVendorRequest", &RequestHandler::CallVendorRequest},
{"GetHotkeyList", &RequestHandler::GetHotkeyList},
{"TriggerHotkeyByName", &RequestHandler::TriggerHotkeyByName},
{"TriggerHotkeyByKeySequence", &RequestHandler::TriggerHotkeyByKeySequence},

View File

@ -47,6 +47,7 @@ class RequestHandler {
RequestResult GetVersion(const Request&);
RequestResult GetStats(const Request&);
RequestResult BroadcastCustomEvent(const Request&);
RequestResult CallVendorRequest(const Request&);
RequestResult GetHotkeyList(const Request&);
RequestResult TriggerHotkeyByName(const Request&);
RequestResult TriggerHotkeyByKeySequence(const Request&);

View File

@ -22,6 +22,7 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include "RequestHandler.h"
#include "../websocketserver/WebSocketServer.h"
#include "../eventhandler/types/EventSubscription.h"
#include "../WebSocketApi.h"
#include "../obs-websocket.h"
@ -111,13 +112,73 @@ RequestResult RequestHandler::BroadcastCustomEvent(const Request& request)
auto webSocketServer = GetWebSocketServer();
if (!webSocketServer)
return RequestResult::Error(RequestStatus::RequestProcessingFailed, "Unable to send event.");
return RequestResult::Error(RequestStatus::RequestProcessingFailed, "Unable to send event due to internal error.");
webSocketServer->BroadcastEvent(EventSubscription::General, "CustomEvent", request.RequestData["eventData"]);
return RequestResult::Success();
}
/**
* Call a request registered to a vendor.
*
* A vendor is a unique name registered by a third-party plugin or script, which allows for custom requests and events to be added to obs-websocket.
* If a plugin or script implements vendor requests or events, documentation is expected to be provided with them.
*
* @requestField vendorName | String | Name of the vendor to use
* @requestField requestType | String | The request type to call
* @requestField ?requestData | Object | Object containing appropriate request data | {}
*
* @responseField responseData | Object | Object containing appropriate response data. May be null if vendor request does not implement responses
*
* @requestType CallVendorRequest
* @complexity 3
* @rpcVersion -1
* @initialVersion 5.0.0
* @category general
* @api requests
*/
RequestResult RequestHandler::CallVendorRequest(const Request& request)
{
RequestStatus::RequestStatus statusCode;
std::string comment;
if (!request.ValidateString("vendorName", statusCode, comment) || !request.ValidateString("requestType", statusCode, comment))
return RequestResult::Error(statusCode, comment);
std::string vendorName = request.RequestData["vendorName"];
std::string requestType = request.RequestData["requestType"];
OBSDataAutoRelease requestData = obs_data_create();
if (request.Contains("requestData")) {
if (!request.ValidateOptionalObject("requestData", statusCode, comment))
return RequestResult::Error(statusCode, comment);
requestData = Utils::Json::JsonToObsData(request.RequestData["requestData"]);
}
OBSDataAutoRelease obsResponseData = obs_data_create();
auto webSocketApi = GetWebSocketApi();
if (!webSocketApi)
return RequestResult::Error(RequestStatus::RequestProcessingFailed, "Unable to call request due to internal error.");
auto ret = webSocketApi->PerformVendorRequest(vendorName, requestType, requestData, obsResponseData);
switch (ret) {
default:
case WebSocketApi::RequestReturnCode::Normal:
break;
case WebSocketApi::RequestReturnCode::NoVendor:
return RequestResult::Error(RequestStatus::ResourceNotFound, "No vendor was found by that name.");
case WebSocketApi::RequestReturnCode::NoVendorRequest:
return RequestResult::Error(RequestStatus::ResourceNotFound, "No request was found by that name.");
}
json responseData;
responseData["responseData"] = Utils::Json::ObsDataToJson(obsResponseData);
return RequestResult::Success(responseData);
}
/**
* Gets an array of all hotkey names in OBS
*