File: websocket-api.cpp

package info (click to toggle)
obs-advanced-scene-switcher 1.32.8-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 43,492 kB
  • sloc: xml: 297,593; cpp: 147,875; python: 387; sh: 280; ansic: 170; makefile: 33
file content (128 lines) | stat: -rw-r--r-- 3,423 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "websocket-api.hpp"
#include "obs-websocket-api.h"
#include "plugin-state-helpers.hpp"

// Must be after "obs-websocket-api.h" to avoid logging function conflict
#include "log-helper.hpp"

#include <mutex>

namespace advss {

static std::vector<std::function<void(obs_data_t *, obs_data_t *)>> callbacks;

static constexpr char VendorName[] = "AdvancedSceneSwitcher";
static constexpr char VendorRequestStart[] = "AdvancedSceneSwitcherStart";
static constexpr char VendorRequestStop[] = "AdvancedSceneSwitcherStop";
static constexpr char VendorRequestStatus[] = "IsAdvancedSceneSwitcherRunning";
static obs_websocket_vendor vendor;

static void registerWebsocketVendor();

static bool setup();
static bool setupDone = setup();

bool setup()
{
	AddPluginPostLoadStep(registerWebsocketVendor);
	AddStartStep([]() {
		SendWebsocketVendorEvent("AdvancedSceneSwitcherStarted",
					 nullptr);
	});
	AddStopStep([]() {
		SendWebsocketVendorEvent("AdvancedSceneSwitcherStopped",
					 nullptr);
	});
	return true;
}

static void
registerWebsocketVendorRequest(const char *requestName,
			       obs_websocket_request_callback_function callback)
{
	if (!obs_websocket_vendor_register_request(vendor, requestName,
						   callback, NULL)) {
		blog(LOG_ERROR,
		     "Failed to register \"%s\" request with obs-websocket.",
		     requestName);
	}
}

static void registerWebsocketVendor()
{
	vendor = obs_websocket_register_vendor(VendorName);
	if (!vendor) {
		blog(LOG_ERROR,
		     "Vendor registration failed! (obs-websocket should have logged something if installed properly.)");
		return;
	}

	auto api_version = obs_websocket_get_api_version();
	if (api_version == 0) {
		blog(LOG_ERROR,
		     "Unable to fetch obs-websocket plugin API version.");
		return;
	} else if (api_version == 1) {
		blog(LOG_WARNING,
		     "Unsupported obs-websocket plugin API version for calling requests.");
		return;
	}

	registerWebsocketVendorRequest(VendorRequestStart,
				       [](obs_data_t *, obs_data_t *, void *) {
					       StartPlugin();
				       });
	registerWebsocketVendorRequest(VendorRequestStop,
				       [](obs_data_t *, obs_data_t *, void *) {
					       StopPlugin();
				       });
	registerWebsocketVendorRequest(
		VendorRequestStatus,
		[](obs_data_t *, obs_data_t *response, void *) {
			obs_data_set_bool(response, "isRunning",
					  PluginIsRunning());
		});
}

const char *GetWebsocketVendorName()
{
	return VendorName;
}

void RegisterWebsocketRequest(
	const std::string &name,
	const std::function<void(obs_data_t *, obs_data_t *)> &callback)
{
	static std::mutex m;
	std::lock_guard<std::mutex> lock(m);

	callbacks.emplace_back(callback);
	int index = callbacks.size() - 1;
	auto handleRequest = [](obs_data *requestData, obs_data *other,
				void *cbPtr) {
		auto cb = *(static_cast<
			    std::function<void(obs_data *, obs_data *)> *>(
			cbPtr));
		cb(requestData, other);
	};

	AddPluginPostLoadStep([name, handleRequest, index]() {
		if (!obs_websocket_vendor_register_request(
			    vendor, name.c_str(), handleRequest,
			    &callbacks.at(index))) {
			blog(LOG_ERROR,
			     "Failed to register \"%s\" request with obs-websocket.",
			     name.c_str());
		}
	});
}

void SendWebsocketVendorEvent(const std::string &eventName, obs_data_t *data)
{
	if (OBSIsShuttingDown()) {
		return;
	}
	obs_websocket_vendor_emit_event(vendor, eventName.c_str(), data);
}

} // namespace advss