mirror of
https://github.com/Palakis/obs-websocket.git
synced 2024-08-30 18:12:16 +00:00
base, lib: Add ability to call obs-websocket requests via plugin API
**Increments Plugin API Version** Adds functions: - `obs_websocket_get_api_version()` - Gets the current obs-websocket plugin API version - `obs_websocket_call_request()` - Calls an obs-websocket request via the plugin API Adds structs: - `obs_websocket_request_response`
This commit is contained in:
parent
3303acfcca
commit
d85c86e3a0
@ -1,7 +1,7 @@
|
||||
/*
|
||||
obs-websocket
|
||||
Copyright (C) 2016-2021 Stephane Lepin <stephane.lepin@gmail.com>
|
||||
Copyright (C) 2020-2021 Kyle Manning <tt2468@gmail.com>
|
||||
Copyright (C) 2020-2022 Kyle Manning <tt2468@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -22,7 +22,7 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
|
||||
#include <obs.h>
|
||||
|
||||
#define OBS_WEBSOCKET_API_VERSION 1
|
||||
#define OBS_WEBSOCKET_API_VERSION 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -31,12 +31,22 @@ extern "C" {
|
||||
typedef void* obs_websocket_vendor;
|
||||
typedef void (*obs_websocket_request_callback_function)(obs_data_t*, obs_data_t*, void*);
|
||||
|
||||
struct obs_websocket_request_response {
|
||||
uint status_code;
|
||||
char *comment;
|
||||
char *response_data; // JSON string, because obs_data_t* only supports array<object>, so conversions would break API.
|
||||
};
|
||||
|
||||
/* ==================== INTERNAL DEFINITIONS ==================== */
|
||||
|
||||
struct obs_websocket_request_callback {
|
||||
obs_websocket_request_callback_function callback;
|
||||
void *priv_data;
|
||||
};
|
||||
|
||||
inline proc_handler_t *ph;
|
||||
inline proc_handler_t *_ph;
|
||||
|
||||
/* ==================== INTERNAL API FUNCTIONS ==================== */
|
||||
|
||||
static inline proc_handler_t *obs_websocket_get_ph(void)
|
||||
{
|
||||
@ -52,30 +62,98 @@ static inline proc_handler_t *obs_websocket_get_ph(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool obs_websocket_run_simple_proc(obs_websocket_vendor vendor, const char *proc_name, calldata_t *cd)
|
||||
static inline bool obs_websocket_ensure_ph(void)
|
||||
{
|
||||
if (!ph || !vendor || !proc_name || !strlen(proc_name) || !cd)
|
||||
if (!_ph)
|
||||
_ph = obs_websocket_get_ph();
|
||||
return _ph != NULL;
|
||||
}
|
||||
|
||||
static inline bool obs_websocket_vendor_run_simple_proc(obs_websocket_vendor vendor, const char *proc_name, calldata_t *cd)
|
||||
{
|
||||
if (!obs_websocket_ensure_ph())
|
||||
return false;
|
||||
|
||||
if (!vendor || !proc_name || !strlen(proc_name) || !cd)
|
||||
return false;
|
||||
|
||||
calldata_set_ptr(cd, "vendor", vendor);
|
||||
|
||||
proc_handler_call(ph, proc_name, cd);
|
||||
proc_handler_call(_ph, proc_name, cd);
|
||||
return calldata_bool(cd, "success");
|
||||
}
|
||||
|
||||
// ALWAYS CALL VIA `obs_module_post_load()` CALLBACK!
|
||||
/* ==================== GENERAL API FUNCTIONS ==================== */
|
||||
|
||||
// Gets the API version built with the obs-websocket plugin
|
||||
static inline uint obs_websocket_get_api_version(void)
|
||||
{
|
||||
if (!obs_websocket_ensure_ph())
|
||||
return 0;
|
||||
|
||||
calldata_t cd = {0};
|
||||
|
||||
if (!proc_handler_call(_ph, "get_api_version", &cd))
|
||||
return 1; // API v1 does not include get_api_version
|
||||
|
||||
uint ret = calldata_int(&cd, "version");
|
||||
|
||||
calldata_free(&cd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Calls an obs-websocket request. Free response with `obs_websocket_request_response_free()`
|
||||
static inline obs_websocket_request_response *obs_websocket_call_request(const char *request_type, obs_data_t *request_data = NULL)
|
||||
{
|
||||
if (!obs_websocket_ensure_ph())
|
||||
return NULL;
|
||||
|
||||
const char *request_data_string = NULL;
|
||||
if (request_data)
|
||||
request_data_string = obs_data_get_json(request_data);
|
||||
|
||||
calldata_t cd = {0};
|
||||
|
||||
calldata_set_string(&cd, "request_type", request_type);
|
||||
calldata_set_string(&cd, "request_data", request_data_string);
|
||||
|
||||
proc_handler_call(_ph, "call_request", &cd);
|
||||
|
||||
auto ret = (struct obs_websocket_request_response*)calldata_ptr(&cd, "response");
|
||||
|
||||
calldata_free(&cd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Free a request response object returned by `obs_websocket_call_request()`
|
||||
static inline void obs_websocket_request_response_free(struct obs_websocket_request_response *response)
|
||||
{
|
||||
if (!response)
|
||||
return;
|
||||
|
||||
if (response->comment)
|
||||
bfree(response->comment);
|
||||
if (response->response_data)
|
||||
bfree(response->response_data);
|
||||
bfree(response);
|
||||
}
|
||||
|
||||
/* ==================== VENDOR API FUNCTIONS ==================== */
|
||||
|
||||
// ALWAYS CALL ONLY VIA `obs_module_post_load()` CALLBACK!
|
||||
// Registers a new "vendor" (Example: obs-ndi)
|
||||
static inline obs_websocket_vendor obs_websocket_register_vendor(const char *vendor_name)
|
||||
{
|
||||
ph = obs_websocket_get_ph();
|
||||
if (!ph)
|
||||
if (!obs_websocket_ensure_ph())
|
||||
return NULL;
|
||||
|
||||
calldata_t cd = {0};
|
||||
|
||||
calldata_set_string(&cd, "name", vendor_name);
|
||||
|
||||
proc_handler_call(ph, "vendor_register", &cd);
|
||||
proc_handler_call(_ph, "vendor_register", &cd);
|
||||
obs_websocket_vendor ret = calldata_ptr(&cd, "vendor");
|
||||
calldata_free(&cd);
|
||||
|
||||
@ -94,7 +172,7 @@ static inline bool obs_websocket_vendor_register_request(obs_websocket_vendor ve
|
||||
calldata_set_string(&cd, "type", request_type);
|
||||
calldata_set_ptr(&cd, "callback", &cb);
|
||||
|
||||
bool success = obs_websocket_run_simple_proc(vendor, "vendor_request_register", &cd);
|
||||
bool success = obs_websocket_vendor_run_simple_proc(vendor, "vendor_request_register", &cd);
|
||||
calldata_free(&cd);
|
||||
|
||||
return success;
|
||||
@ -107,7 +185,7 @@ static inline bool obs_websocket_vendor_unregister_request(obs_websocket_vendor
|
||||
|
||||
calldata_set_string(&cd, "type", request_type);
|
||||
|
||||
bool success = obs_websocket_run_simple_proc(vendor, "vendor_request_unregister", &cd);
|
||||
bool success = obs_websocket_vendor_run_simple_proc(vendor, "vendor_request_unregister", &cd);
|
||||
calldata_free(&cd);
|
||||
|
||||
return success;
|
||||
@ -122,12 +200,14 @@ static inline bool obs_websocket_vendor_emit_event(obs_websocket_vendor vendor,
|
||||
calldata_set_string(&cd, "type", event_name);
|
||||
calldata_set_ptr(&cd, "data", (void*)event_data);
|
||||
|
||||
bool success = obs_websocket_run_simple_proc(vendor, "vendor_event_emit", &cd);
|
||||
bool success = obs_websocket_vendor_run_simple_proc(vendor, "vendor_event_emit", &cd);
|
||||
calldata_free(&cd);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/* ==================== END API FUNCTIONS ==================== */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "WebSocketApi.h"
|
||||
#include "requesthandler/RequestHandler.h"
|
||||
#include "obs-websocket.h"
|
||||
#include "utils/Json.h"
|
||||
|
||||
#define RETURN_STATUS(status) { calldata_set_bool(cd, "success", status); return; }
|
||||
#define RETURN_SUCCESS() RETURN_STATUS(true);
|
||||
@ -22,6 +24,8 @@ WebSocketApi::WebSocketApi()
|
||||
|
||||
_procHandler = proc_handler_create();
|
||||
|
||||
proc_handler_add(_procHandler, "bool get_api_version(out int version)", &get_api_version, nullptr);
|
||||
proc_handler_add(_procHandler, "bool call_request(in string request_type, in string request_data, out ptr response)", &call_request, nullptr);
|
||||
proc_handler_add(_procHandler, "bool vendor_register(in string name, out ptr vendor)", &vendor_register_cb, this);
|
||||
proc_handler_add(_procHandler, "bool vendor_request_register(in ptr vendor, in string type, in ptr callback)", &vendor_request_register_cb, this);
|
||||
proc_handler_add(_procHandler, "bool vendor_request_unregister(in ptr vendor, in string type)", &vendor_request_unregister_cb, this);
|
||||
@ -88,6 +92,48 @@ void WebSocketApi::get_ph_cb(void *priv_data, calldata_t *cd)
|
||||
RETURN_SUCCESS();
|
||||
}
|
||||
|
||||
void WebSocketApi::get_api_version(void *, calldata_t *cd)
|
||||
{
|
||||
calldata_set_int(cd, "version", OBS_WEBSOCKET_API_VERSION);
|
||||
|
||||
RETURN_SUCCESS();
|
||||
}
|
||||
|
||||
void WebSocketApi::call_request(void *, calldata_t *cd)
|
||||
{
|
||||
const char *request_type = calldata_string(cd, "request_type");
|
||||
const char *request_data = calldata_string(cd, "request_data");
|
||||
|
||||
if (!request_type)
|
||||
RETURN_FAILURE();
|
||||
|
||||
auto response = static_cast<obs_websocket_request_response*>(bzalloc(sizeof(struct obs_websocket_request_response)));
|
||||
if (!response)
|
||||
RETURN_FAILURE();
|
||||
|
||||
json requestData;
|
||||
if (request_data)
|
||||
requestData = json::parse(request_data);
|
||||
|
||||
RequestHandler requestHandler;
|
||||
Request request(request_type, requestData);
|
||||
RequestResult requestResult = requestHandler.ProcessRequest(request);
|
||||
|
||||
response->status_code = (uint)requestResult.StatusCode;
|
||||
if (!requestResult.Comment.empty())
|
||||
response->comment = bstrdup(requestResult.Comment.c_str());
|
||||
if (requestResult.ResponseData.is_object()) {
|
||||
std::string responseData = requestResult.ResponseData.dump();
|
||||
response->response_data = bstrdup(responseData.c_str());
|
||||
}
|
||||
|
||||
calldata_set_ptr(cd, "response", response);
|
||||
|
||||
blog_debug("[WebSocketApi::call_request] Request %s called, response status code is %u", request_type, response->status_code);
|
||||
|
||||
RETURN_SUCCESS();
|
||||
}
|
||||
|
||||
void WebSocketApi::vendor_register_cb(void *priv_data, calldata_t *cd)
|
||||
{
|
||||
auto c = static_cast<WebSocketApi*>(priv_data);
|
||||
|
@ -33,6 +33,8 @@ class WebSocketApi {
|
||||
enum RequestReturnCode PerformVendorRequest(std::string vendorName, std::string requestName, obs_data_t *requestData, obs_data_t *responseData);
|
||||
|
||||
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);
|
||||
static void vendor_register_cb(void *priv_data, calldata_t *cd);
|
||||
static void vendor_request_register_cb(void *priv_data, calldata_t *cd);
|
||||
static void vendor_request_unregister_cb(void *priv_data, calldata_t *cd);
|
||||
|
Loading…
x
Reference in New Issue
Block a user