From 45cbf0abd289294315a484ef85f2fe5d70e6fd63 Mon Sep 17 00:00:00 2001 From: Keaton Sentak <54916859+ksentak@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:08:52 -0400 Subject: [PATCH] feat: Cpp global subscriber type (#218) * feat: Global subscribe for cpp * feat: Add global subscriber templates for cpp --- .../templates/declarations-override/event.h | 4 ++ languages/cpp/templates/declarations/event.h | 4 ++ languages/cpp/templates/methods/event.cpp | 38 +++++++++++++++++++ src/macrofier/engine.mjs | 21 ++++++++++ 4 files changed, 67 insertions(+) diff --git a/languages/cpp/templates/declarations-override/event.h b/languages/cpp/templates/declarations-override/event.h index 25fd5887..63654969 100644 --- a/languages/cpp/templates/declarations-override/event.h +++ b/languages/cpp/templates/declarations-override/event.h @@ -2,3 +2,7 @@ // method result properties : ${method.result.properties} void subscribe( ${event.signature.params}${if.event.params}, ${end.if.event.params}I${info.Title}::I${method.Name}Notification& notification, Firebolt::Error *err = nullptr ) override; void unsubscribe( I${info.Title}::I${method.Name}Notification& notification, Firebolt::Error *err = nullptr ) override; +${if.globalsubscriber} + void globalSubscribe( I${info.Title}::I${method.Name}Notification& notification, Firebolt::Error *err = nullptr ) override; + void globalUnsubscribe( I${info.Title}::I${method.Name}Notification& notification, Firebolt::Error *err = nullptr ) override; +${end.if.globalsubscriber} \ No newline at end of file diff --git a/languages/cpp/templates/declarations/event.h b/languages/cpp/templates/declarations/event.h index 29803793..711ecf55 100644 --- a/languages/cpp/templates/declarations/event.h +++ b/languages/cpp/templates/declarations/event.h @@ -6,3 +6,7 @@ // method result properties : ${method.result.properties} virtual void subscribe( ${event.signature.params}${if.event.params}, ${end.if.event.params}I${method.Name}Notification& notification, Firebolt::Error *err = nullptr ) = 0; virtual void unsubscribe( I${method.Name}Notification& notification, Firebolt::Error *err = nullptr ) = 0; +${if.globalsubscriber} + virtual void globalSubscribe( I${method.Name}Notification& notification, Firebolt::Error *err = nullptr ) = 0; + virtual void globalUnsubscribe( I${method.Name}Notification& notification, Firebolt::Error *err = nullptr ) = 0; +${end.if.globalsubscriber} \ No newline at end of file diff --git a/languages/cpp/templates/methods/event.cpp b/languages/cpp/templates/methods/event.cpp index ec3ba93f..8f21e9d7 100644 --- a/languages/cpp/templates/methods/event.cpp +++ b/languages/cpp/templates/methods/event.cpp @@ -35,3 +35,41 @@ *err = status; } } + +${if.globalsubscriber} + static void ${method.name}GlobalCallback( void* notification, const void* userData, void* jsonResponse) + { +${event.callback.serialization} + ASSERT(proxyResponse.IsValid() == true); + + if (proxyResponse.IsValid() == true) { +${event.callback.initialization} + +${event.callback.instantiation} + proxyResponse.Release(); + + I${info.Title}::I${method.Name}Notification& notifier = *(reinterpret_cast(notification)); + notifier.${method.rpc.name}(${event.callback.response.instantiation}); + } + } + void ${info.Title}Impl::globalSubscribe( I${info.Title}::I${method.Name}Notification& notification, Firebolt::Error *err ) + { + const string eventName = _T("${info.title.lowercase}.${method.rpc.name}"); + Firebolt::Error status = Firebolt::Error::None; + + JsonObject jsonParameters; + status = FireboltSDK::Event::Instance().Subscribe<${event.result.json.type}>(eventName, jsonParameters, ${method.name}GlobalCallback, reinterpret_cast(¬ification), nullptr); + + if (err != nullptr) { + *err = status; + } + } + void ${info.Title}Impl::globalUnsubscribe( I${info.Title}::I${method.Name}Notification& notification, Firebolt::Error *err ) + { + Firebolt::Error status = FireboltSDK::Event::Instance().Unsubscribe(_T("${info.title.lowercase}.${method.rpc.name}"), reinterpret_cast(¬ification)); + + if (err != nullptr) { + *err = status; + } + } +${end.if.globalsubscriber} diff --git a/src/macrofier/engine.mjs b/src/macrofier/engine.mjs index 8ae9b67c..b23f5d05 100644 --- a/src/macrofier/engine.mjs +++ b/src/macrofier/engine.mjs @@ -269,6 +269,10 @@ const eventHasOptionalParam = (event) => { return event.params.length && event.params.find(param => !(param.required && param.required === true)) } +const isGlobalSubscriber = (method) => { + return method.tags && method.tags.some(tag => tag['x-subscriber-type'] === 'global'); +} + const isOptionalParam = (param) => { return (!(param.required && param.required === true)) } @@ -347,6 +351,12 @@ const deprecatedOrEmptyArray = compose( getMethods ) +const getGlobalSubscribers = compose( + option([]), + map(filter(isGlobalSubscriber)), + getMethods +) + const props = compose( option([]), map(filter(m => isPropertyMethod(m))), @@ -1299,7 +1309,17 @@ function insertMethodMacros(template, methodObj, json, templates, type = '', exa const result = JSON.parse(JSON.stringify(methodObj.result)) const event = isEventMethod(methodObj) ? JSON.parse(JSON.stringify(methodObj)) : '' + // Keep track of any global subscribers to insert into templates + const globalSubscribersArr = getGlobalSubscribers(json); + let isGlobalSubscriberEvent = false + if (event) { + isGlobalSubscriberEvent = globalSubscribersArr.some(subscriber => { + const strippedEventName = event.name.replace(/^on/, '').replace(/Changed$/, '').toLowerCase(); + const subscriberName = subscriber.name.toLowerCase(); + return subscriberName && strippedEventName === subscriberName; + }) + result.schema = JSON.parse(JSON.stringify(getPayloadFromEvent(methodObj))) event.result.schema = getPayloadFromEvent(event) event.params = event.params.filter(p => p.name !== 'listen') @@ -1440,6 +1460,7 @@ function insertMethodMacros(template, methodObj, json, templates, type = '', exa .replace(/\$\{event\.params\}/g, eventParams) .replace(/\$\{event\.params\.table\.rows\}/g, eventParamsRows) .replace(/\$\{if\.event\.params\}(.*?)\$\{end\.if\.event\.params\}/gms, event && event.params.length ? '$1' : '') + .replace(/\$\{if\.globalsubscriber\}(.*?)\$\{end\.if\.globalsubscriber\}/gms, (isGlobalSubscriberEvent) ? '$1' : '') .replace(/\$\{if\.event\.callback\.params\}(.*?)\$\{end\.if\.event\.callback\.params\}/gms, event && eventHasOptionalParam(event) ? '$1' : '') .replace(/\$\{event\.signature\.params\}/g, event ? types.getMethodSignatureParams(event, json, { destination: state.destination, section: state.section }) : '') .replace(/\$\{event\.signature\.callback\.params\}/g, event ? types.getMethodSignatureParams(event, json, { destination: state.destination, section: state.section, callback: true }) : '')