websocket api path

lets vendors register to get callback notifications when other vendors emit broadcasts
 avatar
unknown
c_cpp
2 years ago
3.2 kB
6
Indexable
void WebSocketApi::vendor_event_emit_cb(void *priv_data, calldata_t *cd)
{
	auto c = static_cast<WebSocketApi *>(priv_data);

	Vendor *v = get_vendor(cd);
	if (!v)
		RETURN_FAILURE();

	const char *eventType;
	if (!calldata_get_string(cd, "type", &eventType) || strlen(eventType) == 0) {
		blog(LOG_WARNING, "[WebSocketApi::vendor_event_emit_cb] [vendorName: %s] Failed due to missing `type` string.",
		     v->_name.c_str());
		RETURN_FAILURE();
	}

	void *voidEventData;
	if (!calldata_get_ptr(cd, "data", &voidEventData)) {
		blog(LOG_WARNING, "[WebSocketApi::vendor_event_emit_cb] [vendorName: %s] Failed due to missing `data` pointer.",
		     v->_name.c_str());
		RETURN_FAILURE();
	}

	auto eventData = static_cast<obs_data_t *>(voidEventData);

	if (!c->_eventCallback)
		RETURN_FAILURE();

	c->_eventCallback(v->_name, eventType, eventData);

	// ATTN: jr adding code to let vendors receive events emited by other vendors
	c->jrSendVendorEmitToOtherVendors(v, eventType, eventData);

	RETURN_SUCCESS();
}




// ATTN: JR - my new function that allows vendors to get emit broadcast notifications from other vendors
// to get these, the vendor should register a request "ReceiveVendorBroadcastEvent"
// that request will be triggered when other vendors emit a broadcast
//
void WebSocketApi::jrSendVendorEmitToOtherVendors(Vendor *senderV, const char *eventType, obs_data_t * eventData) {
	// iterate through all vendors (other than *v) and if they have a registered request called "ReceiveVendorBroadcastEvent" then send them the event data
	char requestType[] = "ReceiveVendorBroadcastEvent";

	// create response data which we discard at the end
	obs_data_t *obsResponseData = NULL;
	obs_data_t *wrappedEventData = NULL;

	for (auto vpair : _vendors) {
		auto v = vpair.second;

		if (v == senderV) {
			// never send to yourself
			continue;
		}

		// ok does this vendor have a registered calledback for request for broardcast emits
		if (v->_requests.count(requestType) == 0) {
			// no such request registered for this consumer vendor
			continue;
		}

		// yes they want to receive other vendor emits!
		std::shared_lock v_l(v->_mutex);
		auto cb = v->_requests[requestType];
		v_l.unlock();

		// build it if first call
		if (obsResponseData == NULL) {
			// we defer doing this until we have our first receipient that wants to hear from us, since most of the time we might not
			obsResponseData = obs_data_create();
			// we wrap the data just as it would be received in an obs websocket client, with vendorName and eventType in outer data, and inner object named eventData
			wrappedEventData = obs_data_create();
			obs_data_set_string(wrappedEventData,"vendorName",senderV->_name.c_str());
			obs_data_set_string(wrappedEventData,"eventType",eventType);
			obs_data_set_obj(wrappedEventData,"eventData",eventData);
		}
		// call the vendor's request to send them the broardcast
		cb.callback(wrappedEventData, obsResponseData, cb.priv_data);
	}

	if (wrappedEventData != NULL) {
		obs_data_release(wrappedEventData);
	}
	if (obsResponseData != NULL) {
		obs_data_release(obsResponseData);
	}

}