From d570a53484b76385accac22eaed5391668ddf2bc Mon Sep 17 00:00:00 2001 From: "Kandasamy, Divya" Date: Fri, 5 Jul 2024 17:59:10 -0400 Subject: [PATCH 1/9] fix: Addded prioritize fix: addded prioritize --- languages/cpp/src/shared/src/Event/Event.cpp | 126 +++++++++++-------- languages/cpp/src/shared/src/Event/Event.h | 29 +++-- package.json | 2 +- src/macrofier/engine.mjs | 9 +- src/macrofier/index.mjs | 8 +- src/shared/template.mjs | 1 + src/validate/index.mjs | 1 + 7 files changed, 111 insertions(+), 65 deletions(-) diff --git a/languages/cpp/src/shared/src/Event/Event.cpp b/languages/cpp/src/shared/src/Event/Event.cpp index 5d739d70..79dc25c8 100644 --- a/languages/cpp/src/shared/src/Event/Event.cpp +++ b/languages/cpp/src/shared/src/Event/Event.cpp @@ -22,7 +22,8 @@ namespace FireboltSDK { Event* Event::_singleton = nullptr; Event::Event() - : _eventMap() + : _internalEventMap() + , _externalEventMap() , _adminLock() , _transport(nullptr) { @@ -91,73 +92,98 @@ namespace FireboltSDK { Firebolt::Error Event::Dispatch(const string& eventName, const WPEFramework::Core::ProxyType& jsonResponse) /* override */ { string response = jsonResponse->Result.Value(); - _adminLock.Lock(); - EventMap::iterator eventIndex = _eventMap.find(eventName); - if (eventIndex != _eventMap.end()) { - CallbackMap::iterator callbackIndex = eventIndex->second.begin(); - while(callbackIndex != eventIndex->second.end()) { - State state; - if (callbackIndex->second.state != State::REVOKED) { - callbackIndex->second.state = State::EXECUTING; - } - state = callbackIndex->second.state; - _adminLock.Unlock(); - if (state == State::EXECUTING) { - callbackIndex->second.lambda(callbackIndex->first, callbackIndex->second.userdata, (jsonResponse->Result.Value())); - } - _adminLock.Lock(); - if (callbackIndex->second.state == State::REVOKED) { - callbackIndex = eventIndex->second.erase(callbackIndex); - if (eventIndex->second.size() == 0) { - _eventMap.erase(eventIndex); + + + // Combine both _internalEventMap and _externalEventMap into a single loop + for (auto& eventMap : {_internalEventMap, _externalEventMap}) { + _adminLock.Lock(); + EventMap::iterator eventIndex = eventMap.find(eventName); + if (eventIndex != eventMap.end()) { + CallbackMap& callbacks = eventIndex->second; + for (CallbackMap::iterator callbackIndex = callbacks.begin(); callbackIndex != callbacks.end();) { + State state; + if (callbackIndex->second.state != State::REVOKED) { + callbackIndex->second.state = State::EXECUTING; + } + state = callbackIndex->second.state; + _adminLock.Unlock(); + if (state == State::EXECUTING) { + callbackIndex->second.lambda(callbackIndex->first, callbackIndex->second.userdata, response); + } + _adminLock.Lock(); + if (callbackIndex->second.state == State::REVOKED) { + callbackIndex = callbacks.erase(callbackIndex); + if (callbacks.empty()) { + eventMap.erase(eventIndex); // Erase from the correct eventMap + break; // No need to continue iterating if map is empty + } + } else { + callbackIndex->second.state = State::IDLE; + ++callbackIndex; } - } else { - callbackIndex->second.state = State::IDLE; - callbackIndex++; } } + _adminLock.Unlock(); } - _adminLock.Unlock(); - - return Firebolt::Error::None;; + return Firebolt::Error::None; } - Firebolt::Error Event::Revoke(const string& eventName, void* usercb) - { - Firebolt::Error status = Firebolt::Error::None; - _adminLock.Lock(); - EventMap::iterator eventIndex = _eventMap.begin(); - if (eventIndex != _eventMap.end()) { + + Firebolt::Error Event::Revoke(const string& eventName, void* usercb) +{ + Firebolt::Error status = Firebolt::Error::None; + + // Combine both _internalEventMap and _externalEventMap into a single loop + for (auto& eventMap : {_internalEventMap, _externalEventMap}) { + _adminLock.Lock(); // Lock inside the loop + + // Find the eventIndex for eventName in the current eventMap + EventMap::iterator eventIndex = eventMap.find(eventName); + if (eventIndex != eventMap.end()) { + // Find the callbackIndex for usercb in the current CallbackMap CallbackMap::iterator callbackIndex = eventIndex->second.find(usercb); - if (callbackIndex->second.state != State::EXECUTING) { - if (callbackIndex != eventIndex->second.end()) { + if (callbackIndex != eventIndex->second.end()) { + // Check if callback is not executing, then erase it + if (callbackIndex->second.state != State::EXECUTING) { eventIndex->second.erase(callbackIndex); + } else { + // Mark the callback as revoked + callbackIndex->second.state = State::REVOKED; + } + + // Check if the CallbackMap is empty after potential erasure + if (eventIndex->second.empty()) { + eventMap.erase(eventIndex); + } else { + // Set status to General error if CallbackMap is not empty + status = Firebolt::Error::General; } - } else { - callbackIndex->second.state = State::REVOKED; - } - if (eventIndex->second.size() == 0) { - _eventMap.erase(eventIndex); - } else { - status = Firebolt::Error::General; } } - _adminLock.Unlock(); - return status; + _adminLock.Unlock(); // Unlock after processing each eventMap } - void Event::Clear() - { - EventMap::iterator eventIndex = _eventMap.begin(); - while (eventIndex != _eventMap.end()) { + return status; +} + + void Event::Clear() +{ + // Clear both _internalEventMap and _externalEventMap + for (auto& eventMap : {_internalEventMap, _externalEventMap}) { + _adminLock.Lock(); // Lock before clearing + + EventMap::iterator eventIndex = eventMap.begin(); + while (eventIndex != eventMap.end()) { CallbackMap::iterator callbackIndex = eventIndex->second.begin(); while (callbackIndex != eventIndex->second.end()) { - callbackIndex = eventIndex->second.erase(callbackIndex); + callbackIndex = eventIndex->second.erase(callbackIndex); } - eventIndex = _eventMap.erase(eventIndex); + eventIndex = eventMap.erase(eventIndex); } - _adminLock.Unlock(); + + _adminLock.Unlock(); // Unlock after clearing } +} } diff --git a/languages/cpp/src/shared/src/Event/Event.h b/languages/cpp/src/shared/src/Event/Event.h index 7299fde0..6cd877c4 100644 --- a/languages/cpp/src/shared/src/Event/Event.h +++ b/languages/cpp/src/shared/src/Event/Event.h @@ -80,12 +80,15 @@ namespace FireboltSDK { } template - Firebolt::Error Subscribe(const string& eventName, JsonObject& jsonParameters, const CALLBACK& callback, void* usercb, const void* userdata) + Firebolt::Error Subscribe(const string& eventName, JsonObject& jsonParameters, const CALLBACK& callback, void* usercb, const void* userdata, bool prioritize = false) { Firebolt::Error status = Firebolt::Error::General; if (_transport != nullptr) { - - status = Assign(eventName, callback, usercb, userdata); + if (prioritize) { + status = Assign(_internalEventMap, eventName, callback, usercb, userdata); + } else { + status = Assign(_externalEventMap, eventName, callback, usercb, userdata); + } if (status == Firebolt::Error::None) { Response response; @@ -108,11 +111,20 @@ namespace FireboltSDK { return status; } + int32_t Prioritize(const string& eventName, const CALLBACK& callback, void* usercb, const void* userdata) + { + int32_t status = FireboltSDKErrorNone; + JsonObject jsonParameters; + // Assuming prioritized events also need subscription via transport + status = Subscribe(eventName, jsonParameters, callback, usercb, userdata, true); + return status; + } + Firebolt::Error Unsubscribe(const string& eventName, void* usercb); private: template - Firebolt::Error Assign(const string& eventName, const CALLBACK& callback, void* usercb, const void* userdata) + Firebolt::Error Assign(EventMap& eventMap, const string& eventName, const CALLBACK& callback, void* usercb, const void* userdata) { Firebolt::Error status = Firebolt::Error::General; std::function actualCallback = callback; @@ -127,8 +139,8 @@ namespace FireboltSDK { CallbackData callbackData = {implementation, userdata, State::IDLE}; _adminLock.Lock(); - EventMap::iterator eventIndex = _eventMap.find(eventName); - if (eventIndex != _eventMap.end()) { + EventMap::iterator eventIndex = eventMap.find(eventName); + if (eventIndex != eventMap.end()) { CallbackMap::iterator callbackIndex = eventIndex->second.find(usercb); if (callbackIndex == eventIndex->second.end()) { eventIndex->second.emplace(std::piecewise_construct, std::forward_as_tuple(usercb), std::forward_as_tuple(callbackData)); @@ -138,7 +150,7 @@ namespace FireboltSDK { CallbackMap callbackMap; callbackMap.emplace(std::piecewise_construct, std::forward_as_tuple(usercb), std::forward_as_tuple(callbackData)); - _eventMap.emplace(std::piecewise_construct, std::forward_as_tuple(eventName), std::forward_as_tuple(callbackMap)); + eventMap.emplace(std::piecewise_construct, std::forward_as_tuple(eventName), std::forward_as_tuple(callbackMap)); status = Firebolt::Error::None; } @@ -154,7 +166,8 @@ namespace FireboltSDK { Firebolt::Error Dispatch(const string& eventName, const WPEFramework::Core::ProxyType& jsonResponse) override; private: - EventMap _eventMap; + EventMap _internalEventMap; + EventMap _externalEventMap; WPEFramework::Core::CriticalSection _adminLock; Transport* _transport; diff --git a/package.json b/package.json index 6ae1731a..be798cea 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "scripts": { "prepack": "npm run prepare:setup && npm run dist", "prepare:setup": "npx mkdirp ./dist/docs ./build/docs/markdown ./build/docs/wiki ./build/sdk/javascript/src", - "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config=jest.config.json --detectOpenHandles", + "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config=jest.config.json --detectOpenHandles --collectCoverage --runInBand --forceExit", "build": "npm run validate && npm run build:docs && npm run build:sdk", "validate": "node ./src/cli.mjs validate --input ./test/openrpc --schemas test/schemas --transformations && npm run build:openrpc && node ./src/cli.mjs validate --input ./build/sdk-open-rpc.json", "build:openrpc": "node ./src/cli.mjs openrpc --input ./test --template ./src/openrpc-template.json --output ./build/sdk-open-rpc.json --schemas test/schemas", diff --git a/src/macrofier/engine.mjs b/src/macrofier/engine.mjs index 9a7823fc..2aab2728 100644 --- a/src/macrofier/engine.mjs +++ b/src/macrofier/engine.mjs @@ -363,7 +363,7 @@ const makeProviderMethod = x => x.name["onRequest".length].toLowerCase() + x.nam //import { default as platform } from '../Platform/defaults' const generateAggregateMacros = (openrpc, modules, templates, library) => Object.values(modules) .reduce((acc, module) => { - + console.log("Inside generate Aggregated macros") let template = getTemplate('/codeblocks/export', templates) if (template) { acc.exports += insertMacros(template + '\n', generateMacros(module, templates)) @@ -378,7 +378,7 @@ const generateAggregateMacros = (openrpc, modules, templates, library) => Object if (template) { acc.mockObjects += insertMacros(template + '\n', generateMacros(module, templates)) } - + console.log('****Return ACC'+JSON.stringify(acc)) return acc }, { exports: '', @@ -405,6 +405,7 @@ const promoteSchema = (location, property, title, document, destinationPath) => location[property] = { $ref: `${destinationPath}/${title}` } + console.log('***** Destinationin the promoteSchema',JSON.stringify(promoteSchema)) } // only consider sub-objects and sub enums to be sub-schemas @@ -596,12 +597,14 @@ const clearMacros = (fContents = '') => { } const insertAggregateMacros = (fContents = '', aggregateMacros = {}) => { + console.log('**FCONTENT in the BEGINNING'+JSON.stringify(fContents)) + console.log('**aggregateMacros in the BEGINNING'+JSON.stringify(aggregateMacros)) fContents = fContents.replace(/[ \t]*\/\* \$\{EXPORTS\} \*\/[ \t]*\n/, aggregateMacros.exports) fContents = fContents.replace(/[ \t]*\/\* \$\{MOCK_IMPORTS\} \*\/[ \t]*\n/, aggregateMacros.mockImports) fContents = fContents.replace(/[ \t]*\/\* \$\{MOCK_OBJECTS\} \*\/[ \t]*\n/, aggregateMacros.mockObjects) fContents = fContents.replace(/\$\{readable\}/g, aggregateMacros.version.readable) fContents = fContents.replace(/\$\{package.name\}/g, aggregateMacros.library) - + console.log('****Inside insertAggregateMacros and displaying its contents'+JSON.stringify(Contents)) return fContents } diff --git a/src/macrofier/index.mjs b/src/macrofier/index.mjs index 298241f6..8782bc50 100644 --- a/src/macrofier/index.mjs +++ b/src/macrofier/index.mjs @@ -154,6 +154,7 @@ const macrofy = async ( else { modules = moduleList.map(name => getModule(name, openrpc, copySchemasIntoModules, extractSubSchemas)) } + console.log('****Modules is the',JSON.stringify(modules)) const aggregateMacros = engine.generateAggregateMacros(openrpc, modules.concat(staticModules), templates, libraryName) @@ -163,6 +164,7 @@ const macrofy = async ( let primaryOutput = [] Object.keys(templates).forEach(file => { + console.log("****TemplateFile"+JSON.stringify(file)) if (file.startsWith(path.sep + outputDirectory + path.sep) || outputDirectory === '') { // Note: '/foo/bar/file.js'.split('/') => ['', 'foo', 'bar', 'file.js'] so we need to drop one more that you might suspect, hence slice(2) below... const dirsToDrop = outputDirectory === '' ? 1 : 2 @@ -191,19 +193,19 @@ const macrofy = async ( let append = false modules.forEach(module => { - + console.log('First module to gernerate Macros'+JSON.stringify(module)) // Pick the index and defaults templates for each module. templatesPerModule.forEach(t => { + console.log("****Template per module"+JSON.stringify(t)) const macros = engine.generateMacros(module, templates, exampleTemplates, {hideExcluded: hideExcluded, copySchemasIntoModules: copySchemasIntoModules, createPolymorphicMethods: createPolymorphicMethods, destination: t, type: 'methods'}) let content = getTemplateForModule(module.info.title, t, templates) - // NOTE: whichever insert is called first also needs to be called again last, so each phase can insert recursive macros from the other content = engine.insertAggregateMacros(content, aggregateMacros) content = engine.insertMacros(content, macros) content = engine.insertAggregateMacros(content, aggregateMacros) const location = createModuleDirectories ? path.join(output, module.info.title, t) : path.join(output, t.replace(/module/, module.info.title.toLowerCase()).replace(/index/, module.info.title)) - + console.log('******Location'+JSON.stringify(location)) outputFiles[location] = content logSuccess(`Generated macros for module ${path.relative(output, location)}`) }) diff --git a/src/shared/template.mjs b/src/shared/template.mjs index 9f3d899d..cc4c8c38 100644 --- a/src/shared/template.mjs +++ b/src/shared/template.mjs @@ -24,6 +24,7 @@ const getTemplateForMethod = (method, suffix, templates) => { } const getTemplateForModule = (module, file, templates) => { + console.log("***Module in get getTemplateForModule"+JSON.stringify(getTemplateForModule)) return getTemplate(module, file, templates) || getTemplate('/modules/', file, templates) } diff --git a/src/validate/index.mjs b/src/validate/index.mjs index ca7d0712..77fe3929 100644 --- a/src/validate/index.mjs +++ b/src/validate/index.mjs @@ -273,6 +273,7 @@ const run = async ({ const examples = ajv.compile(exampleSpec) try { + console.log("*****************Inside Validate*************") const openrpcResult = validate(json, {}, ajv, openrpc) const fireboltResult = validate(json, {}, ajv, firebolt) const exampleResult = validate(json, {}, ajv, examples) From 8fe305b9d7e61e4d4f19b662949e685c9d5e97ee Mon Sep 17 00:00:00 2001 From: "Kandasamy, Divya" Date: Mon, 8 Jul 2024 17:17:14 -0400 Subject: [PATCH 2/9] fix: Added vector in the event map --- languages/cpp/src/shared/src/Event/Event.cpp | 108 ++++++++++--------- languages/cpp/src/shared/src/Event/Event.h | 5 +- 2 files changed, 59 insertions(+), 54 deletions(-) diff --git a/languages/cpp/src/shared/src/Event/Event.cpp b/languages/cpp/src/shared/src/Event/Event.cpp index 79dc25c8..9a5918be 100644 --- a/languages/cpp/src/shared/src/Event/Event.cpp +++ b/languages/cpp/src/shared/src/Event/Event.cpp @@ -22,7 +22,7 @@ namespace FireboltSDK { Event* Event::_singleton = nullptr; Event::Event() - : _internalEventMap() + : _internalEventMap() , _externalEventMap() , _adminLock() , _transport(nullptr) @@ -89,16 +89,16 @@ namespace FireboltSDK { return result; } - Firebolt::Error Event::Dispatch(const string& eventName, const WPEFramework::Core::ProxyType& jsonResponse) /* override */ + Firebolt::Error Event::Dispatch(const string& eventName, const WPEFramework::Core::ProxyType& jsonResponse) /* override */ { string response = jsonResponse->Result.Value(); - + std::vector eventMaps = {&_internalEventMap, &_externalEventMap}; // Combine both _internalEventMap and _externalEventMap into a single loop - for (auto& eventMap : {_internalEventMap, _externalEventMap}) { + for (auto eventMap : eventMaps) { _adminLock.Lock(); - EventMap::iterator eventIndex = eventMap.find(eventName); - if (eventIndex != eventMap.end()) { + EventMap::iterator eventIndex = eventMap->find(eventName); + if (eventIndex != eventMap->end()) { CallbackMap& callbacks = eventIndex->second; for (CallbackMap::iterator callbackIndex = callbacks.begin(); callbackIndex != callbacks.end();) { State state; @@ -114,7 +114,7 @@ namespace FireboltSDK { if (callbackIndex->second.state == State::REVOKED) { callbackIndex = callbacks.erase(callbackIndex); if (callbacks.empty()) { - eventMap.erase(eventIndex); // Erase from the correct eventMap + eventMap->erase(eventIndex); // Erase from the correct eventMap break; // No need to continue iterating if map is empty } } else { @@ -129,61 +129,65 @@ namespace FireboltSDK { } - Firebolt::Error Event::Revoke(const string& eventName, void* usercb) -{ - Firebolt::Error status = Firebolt::Error::None; - - // Combine both _internalEventMap and _externalEventMap into a single loop - for (auto& eventMap : {_internalEventMap, _externalEventMap}) { - _adminLock.Lock(); // Lock inside the loop - - // Find the eventIndex for eventName in the current eventMap - EventMap::iterator eventIndex = eventMap.find(eventName); - if (eventIndex != eventMap.end()) { - // Find the callbackIndex for usercb in the current CallbackMap - CallbackMap::iterator callbackIndex = eventIndex->second.find(usercb); - if (callbackIndex != eventIndex->second.end()) { - // Check if callback is not executing, then erase it - if (callbackIndex->second.state != State::EXECUTING) { - eventIndex->second.erase(callbackIndex); - } else { - // Mark the callback as revoked - callbackIndex->second.state = State::REVOKED; - } + Firebolt::Error Event::Revoke(const string& eventName, void* usercb) + { + Firebolt::Error status = Firebolt::Error::None; - // Check if the CallbackMap is empty after potential erasure - if (eventIndex->second.empty()) { - eventMap.erase(eventIndex); - } else { - // Set status to General error if CallbackMap is not empty - status = Firebolt::Error::General; + // Combine both _internalEventMap and _externalEventMap into a single loop + std::vector eventMaps = {&_internalEventMap, &_externalEventMap}; + + for (auto eventMap : eventMaps) { + _adminLock.Lock(); // Lock inside the loop + + // Find the eventIndex for eventName in the current eventMap + EventMap::iterator eventIndex = eventMap->find(eventName); + if (eventIndex != eventMap->end()) { + // Find the callbackIndex for usercb in the current CallbackMap + CallbackMap::iterator callbackIndex = eventIndex->second.find(usercb); + if (callbackIndex != eventIndex->second.end()) { + // Check if callback is not executing, then erase it + if (callbackIndex->second.state != State::EXECUTING) { + eventIndex->second.erase(callbackIndex); + } else { + // Mark the callback as revoked + callbackIndex->second.state = State::REVOKED; + } + + // Check if the CallbackMap is empty after potential erasure + if (eventIndex->second.empty()) { + eventMap->erase(eventIndex); + } else { + // Set status to General error if CallbackMap is not empty + status = Firebolt::Error::General; + } } } + + _adminLock.Unlock(); // Unlock after processing each eventMap } - _adminLock.Unlock(); // Unlock after processing each eventMap + return status; } - return status; -} + void Event::Clear() + { + // Clear both _internalEventMap and _externalEventMap + std::vector eventMaps = {&_internalEventMap, &_externalEventMap}; + + for (auto eventMap : eventMaps) { + _adminLock.Lock(); // Lock before clearing - void Event::Clear() -{ - // Clear both _internalEventMap and _externalEventMap - for (auto& eventMap : {_internalEventMap, _externalEventMap}) { - _adminLock.Lock(); // Lock before clearing - - EventMap::iterator eventIndex = eventMap.begin(); - while (eventIndex != eventMap.end()) { - CallbackMap::iterator callbackIndex = eventIndex->second.begin(); - while (callbackIndex != eventIndex->second.end()) { - callbackIndex = eventIndex->second.erase(callbackIndex); + EventMap::iterator eventIndex = eventMap->begin(); + while (eventIndex != eventMap->end()) { + CallbackMap::iterator callbackIndex = eventIndex->second.begin(); + while (callbackIndex != eventIndex->second.end()) { + callbackIndex = eventIndex->second.erase(callbackIndex); + } + eventIndex = eventMap->erase(eventIndex); } - eventIndex = eventMap.erase(eventIndex); - } - _adminLock.Unlock(); // Unlock after clearing + _adminLock.Unlock(); // Unlock after clearing + } } -} } diff --git a/languages/cpp/src/shared/src/Event/Event.h b/languages/cpp/src/shared/src/Event/Event.h index 6cd877c4..a5b2ffa3 100644 --- a/languages/cpp/src/shared/src/Event/Event.h +++ b/languages/cpp/src/shared/src/Event/Event.h @@ -111,9 +111,10 @@ namespace FireboltSDK { return status; } - int32_t Prioritize(const string& eventName, const CALLBACK& callback, void* usercb, const void* userdata) + template + Firebolt::Error Prioritize(const string& eventName, const CALLBACK& callback, void* usercb, const void* userdata) { - int32_t status = FireboltSDKErrorNone; + Firebolt::Error status = Firebolt::Error::General; JsonObject jsonParameters; // Assuming prioritized events also need subscription via transport status = Subscribe(eventName, jsonParameters, callback, usercb, userdata, true); From f23c80ff590b6cf0a2945d5635e2c9315343d6ab Mon Sep 17 00:00:00 2001 From: "Kandasamy, Divya" Date: Wed, 10 Jul 2024 11:56:40 -0400 Subject: [PATCH 3/9] fix: Prioritize signatures Prioritize signatures --- languages/cpp/src/shared/src/Event/Event.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/languages/cpp/src/shared/src/Event/Event.h b/languages/cpp/src/shared/src/Event/Event.h index a5b2ffa3..0811bde5 100644 --- a/languages/cpp/src/shared/src/Event/Event.h +++ b/languages/cpp/src/shared/src/Event/Event.h @@ -88,7 +88,7 @@ namespace FireboltSDK { status = Assign(_internalEventMap, eventName, callback, usercb, userdata); } else { status = Assign(_externalEventMap, eventName, callback, usercb, userdata); - } + } if (status == Firebolt::Error::None) { Response response; @@ -112,15 +112,16 @@ namespace FireboltSDK { } template - Firebolt::Error Prioritize(const string& eventName, const CALLBACK& callback, void* usercb, const void* userdata) + Firebolt::Error Prioritize(const string& eventName,JsonObject& jsonParameters, const CALLBACK& callback, void* usercb, const void* userdata) { + std::cout << "Inside Prioritize" << std::endl; Firebolt::Error status = Firebolt::Error::General; - JsonObject jsonParameters; // Assuming prioritized events also need subscription via transport status = Subscribe(eventName, jsonParameters, callback, usercb, userdata, true); return status; } + Firebolt::Error Unsubscribe(const string& eventName, void* usercb); private: @@ -128,13 +129,13 @@ namespace FireboltSDK { Firebolt::Error Assign(EventMap& eventMap, const string& eventName, const CALLBACK& callback, void* usercb, const void* userdata) { Firebolt::Error status = Firebolt::Error::General; - std::function actualCallback = callback; - DispatchFunction implementation = [actualCallback](void* usercb, const void* userdata, const string& parameters) -> Firebolt::Error { + //std::function actualCallback = callback; + DispatchFunction implementation = [callback](void* usercb, const void* userdata, const string& parameters) -> Firebolt::Error { WPEFramework::Core::ProxyType* inbound = new WPEFramework::Core::ProxyType(); *inbound = WPEFramework::Core::ProxyType::Create(); (*inbound)->FromString(parameters); - actualCallback(usercb, userdata, static_cast(inbound)); + callback(usercb, userdata, static_cast(inbound)); return (Firebolt::Error::None); }; CallbackData callbackData = {implementation, userdata, State::IDLE}; @@ -166,7 +167,7 @@ namespace FireboltSDK { Firebolt::Error ValidateResponse(const WPEFramework::Core::ProxyType& jsonResponse, bool& enabled) override; Firebolt::Error Dispatch(const string& eventName, const WPEFramework::Core::ProxyType& jsonResponse) override; - private: + private: EventMap _internalEventMap; EventMap _externalEventMap; WPEFramework::Core::CriticalSection _adminLock; @@ -175,3 +176,4 @@ namespace FireboltSDK { static Event* _singleton; }; } + From 253fc7e9786e5df9a4401708296e204c87566b1e Mon Sep 17 00:00:00 2001 From: "Kandasamy, Divya" Date: Thu, 18 Jul 2024 12:22:42 -0400 Subject: [PATCH 4/9] fix: Updated event.h to priortize internal events Updated event.h to priortize internal events --- languages/cpp/src/shared/src/Event/Event.cpp | 6 +++--- languages/cpp/src/shared/src/Event/Event.h | 15 +++++++-------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/languages/cpp/src/shared/src/Event/Event.cpp b/languages/cpp/src/shared/src/Event/Event.cpp index 9a5918be..3ee54683 100644 --- a/languages/cpp/src/shared/src/Event/Event.cpp +++ b/languages/cpp/src/shared/src/Event/Event.cpp @@ -88,8 +88,8 @@ namespace FireboltSDK { } return result; } - - Firebolt::Error Event::Dispatch(const string& eventName, const WPEFramework::Core::ProxyType& jsonResponse) /* override */ + + Firebolt::Error Event::Dispatch(const string& eventName, const WPEFramework::Core::ProxyType& jsonResponse) /* override */ { string response = jsonResponse->Result.Value(); std::vector eventMaps = {&_internalEventMap, &_externalEventMap}; @@ -190,4 +190,4 @@ namespace FireboltSDK { } } -} +} \ No newline at end of file diff --git a/languages/cpp/src/shared/src/Event/Event.h b/languages/cpp/src/shared/src/Event/Event.h index 0811bde5..0a3f760d 100644 --- a/languages/cpp/src/shared/src/Event/Event.h +++ b/languages/cpp/src/shared/src/Event/Event.h @@ -111,10 +111,10 @@ namespace FireboltSDK { return status; } + // To prioritize internal and external events and its corresponding callbacks template Firebolt::Error Prioritize(const string& eventName,JsonObject& jsonParameters, const CALLBACK& callback, void* usercb, const void* userdata) { - std::cout << "Inside Prioritize" << std::endl; Firebolt::Error status = Firebolt::Error::General; // Assuming prioritized events also need subscription via transport status = Subscribe(eventName, jsonParameters, callback, usercb, userdata, true); @@ -129,22 +129,22 @@ namespace FireboltSDK { Firebolt::Error Assign(EventMap& eventMap, const string& eventName, const CALLBACK& callback, void* usercb, const void* userdata) { Firebolt::Error status = Firebolt::Error::General; - //std::function actualCallback = callback; - DispatchFunction implementation = [callback](void* usercb, const void* userdata, const string& parameters) -> Firebolt::Error { - + std::function actualCallback = callback; + DispatchFunction implementation = [actualCallback](void* usercb, const void* userdata, const string& parameters) -> Firebolt::Error { WPEFramework::Core::ProxyType* inbound = new WPEFramework::Core::ProxyType(); *inbound = WPEFramework::Core::ProxyType::Create(); (*inbound)->FromString(parameters); - callback(usercb, userdata, static_cast(inbound)); + actualCallback(usercb, userdata, static_cast(inbound)); return (Firebolt::Error::None); }; CallbackData callbackData = {implementation, userdata, State::IDLE}; - _adminLock.Lock(); EventMap::iterator eventIndex = eventMap.find(eventName); if (eventIndex != eventMap.end()) { CallbackMap::iterator callbackIndex = eventIndex->second.find(usercb); + if (callbackIndex == eventIndex->second.end()) { + std::cout << "Registering new callback for event: " << eventName << std::endl; eventIndex->second.emplace(std::piecewise_construct, std::forward_as_tuple(usercb), std::forward_as_tuple(callbackData)); status = Firebolt::Error::None; } @@ -175,5 +175,4 @@ namespace FireboltSDK { static Event* _singleton; }; -} - +} \ No newline at end of file From e4a93d82f357c5c98fe576a3b6edadb56ffcd6a8 Mon Sep 17 00:00:00 2001 From: "Kandasamy, Divya" Date: Thu, 18 Jul 2024 12:31:55 -0400 Subject: [PATCH 5/9] fix: Removed logs --- src/macrofier/engine.mjs | 6 ------ src/macrofier/index.mjs | 6 ------ src/shared/template.mjs | 1 - src/validate/index.mjs | 1 - 4 files changed, 14 deletions(-) diff --git a/src/macrofier/engine.mjs b/src/macrofier/engine.mjs index 2aab2728..0246cdaf 100644 --- a/src/macrofier/engine.mjs +++ b/src/macrofier/engine.mjs @@ -363,7 +363,6 @@ const makeProviderMethod = x => x.name["onRequest".length].toLowerCase() + x.nam //import { default as platform } from '../Platform/defaults' const generateAggregateMacros = (openrpc, modules, templates, library) => Object.values(modules) .reduce((acc, module) => { - console.log("Inside generate Aggregated macros") let template = getTemplate('/codeblocks/export', templates) if (template) { acc.exports += insertMacros(template + '\n', generateMacros(module, templates)) @@ -378,7 +377,6 @@ const generateAggregateMacros = (openrpc, modules, templates, library) => Object if (template) { acc.mockObjects += insertMacros(template + '\n', generateMacros(module, templates)) } - console.log('****Return ACC'+JSON.stringify(acc)) return acc }, { exports: '', @@ -405,7 +403,6 @@ const promoteSchema = (location, property, title, document, destinationPath) => location[property] = { $ref: `${destinationPath}/${title}` } - console.log('***** Destinationin the promoteSchema',JSON.stringify(promoteSchema)) } // only consider sub-objects and sub enums to be sub-schemas @@ -597,14 +594,11 @@ const clearMacros = (fContents = '') => { } const insertAggregateMacros = (fContents = '', aggregateMacros = {}) => { - console.log('**FCONTENT in the BEGINNING'+JSON.stringify(fContents)) - console.log('**aggregateMacros in the BEGINNING'+JSON.stringify(aggregateMacros)) fContents = fContents.replace(/[ \t]*\/\* \$\{EXPORTS\} \*\/[ \t]*\n/, aggregateMacros.exports) fContents = fContents.replace(/[ \t]*\/\* \$\{MOCK_IMPORTS\} \*\/[ \t]*\n/, aggregateMacros.mockImports) fContents = fContents.replace(/[ \t]*\/\* \$\{MOCK_OBJECTS\} \*\/[ \t]*\n/, aggregateMacros.mockObjects) fContents = fContents.replace(/\$\{readable\}/g, aggregateMacros.version.readable) fContents = fContents.replace(/\$\{package.name\}/g, aggregateMacros.library) - console.log('****Inside insertAggregateMacros and displaying its contents'+JSON.stringify(Contents)) return fContents } diff --git a/src/macrofier/index.mjs b/src/macrofier/index.mjs index 8782bc50..4982205b 100644 --- a/src/macrofier/index.mjs +++ b/src/macrofier/index.mjs @@ -154,8 +154,6 @@ const macrofy = async ( else { modules = moduleList.map(name => getModule(name, openrpc, copySchemasIntoModules, extractSubSchemas)) } - console.log('****Modules is the',JSON.stringify(modules)) - const aggregateMacros = engine.generateAggregateMacros(openrpc, modules.concat(staticModules), templates, libraryName) const outputFiles = Object.fromEntries(Object.entries(await readFiles( staticCodeList, staticContent)) @@ -164,7 +162,6 @@ const macrofy = async ( let primaryOutput = [] Object.keys(templates).forEach(file => { - console.log("****TemplateFile"+JSON.stringify(file)) if (file.startsWith(path.sep + outputDirectory + path.sep) || outputDirectory === '') { // Note: '/foo/bar/file.js'.split('/') => ['', 'foo', 'bar', 'file.js'] so we need to drop one more that you might suspect, hence slice(2) below... const dirsToDrop = outputDirectory === '' ? 1 : 2 @@ -193,10 +190,8 @@ const macrofy = async ( let append = false modules.forEach(module => { - console.log('First module to gernerate Macros'+JSON.stringify(module)) // Pick the index and defaults templates for each module. templatesPerModule.forEach(t => { - console.log("****Template per module"+JSON.stringify(t)) const macros = engine.generateMacros(module, templates, exampleTemplates, {hideExcluded: hideExcluded, copySchemasIntoModules: copySchemasIntoModules, createPolymorphicMethods: createPolymorphicMethods, destination: t, type: 'methods'}) let content = getTemplateForModule(module.info.title, t, templates) // NOTE: whichever insert is called first also needs to be called again last, so each phase can insert recursive macros from the other @@ -205,7 +200,6 @@ const macrofy = async ( content = engine.insertAggregateMacros(content, aggregateMacros) const location = createModuleDirectories ? path.join(output, module.info.title, t) : path.join(output, t.replace(/module/, module.info.title.toLowerCase()).replace(/index/, module.info.title)) - console.log('******Location'+JSON.stringify(location)) outputFiles[location] = content logSuccess(`Generated macros for module ${path.relative(output, location)}`) }) diff --git a/src/shared/template.mjs b/src/shared/template.mjs index cc4c8c38..9f3d899d 100644 --- a/src/shared/template.mjs +++ b/src/shared/template.mjs @@ -24,7 +24,6 @@ const getTemplateForMethod = (method, suffix, templates) => { } const getTemplateForModule = (module, file, templates) => { - console.log("***Module in get getTemplateForModule"+JSON.stringify(getTemplateForModule)) return getTemplate(module, file, templates) || getTemplate('/modules/', file, templates) } diff --git a/src/validate/index.mjs b/src/validate/index.mjs index 77fe3929..ca7d0712 100644 --- a/src/validate/index.mjs +++ b/src/validate/index.mjs @@ -273,7 +273,6 @@ const run = async ({ const examples = ajv.compile(exampleSpec) try { - console.log("*****************Inside Validate*************") const openrpcResult = validate(json, {}, ajv, openrpc) const fireboltResult = validate(json, {}, ajv, firebolt) const exampleResult = validate(json, {}, ajv, examples) From c7f034ed3255d91ed0ee3691c2f50e3a6f834447 Mon Sep 17 00:00:00 2001 From: "Kandasamy, Divya" Date: Thu, 18 Jul 2024 12:35:11 -0400 Subject: [PATCH 6/9] fix: Removed logs --- src/macrofier/engine.mjs | 3 +++ src/macrofier/index.mjs | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/macrofier/engine.mjs b/src/macrofier/engine.mjs index 0246cdaf..fc0b437a 100644 --- a/src/macrofier/engine.mjs +++ b/src/macrofier/engine.mjs @@ -363,6 +363,7 @@ const makeProviderMethod = x => x.name["onRequest".length].toLowerCase() + x.nam //import { default as platform } from '../Platform/defaults' const generateAggregateMacros = (openrpc, modules, templates, library) => Object.values(modules) .reduce((acc, module) => { + let template = getTemplate('/codeblocks/export', templates) if (template) { acc.exports += insertMacros(template + '\n', generateMacros(module, templates)) @@ -377,6 +378,7 @@ const generateAggregateMacros = (openrpc, modules, templates, library) => Object if (template) { acc.mockObjects += insertMacros(template + '\n', generateMacros(module, templates)) } + return acc }, { exports: '', @@ -599,6 +601,7 @@ const insertAggregateMacros = (fContents = '', aggregateMacros = {}) => { fContents = fContents.replace(/[ \t]*\/\* \$\{MOCK_OBJECTS\} \*\/[ \t]*\n/, aggregateMacros.mockObjects) fContents = fContents.replace(/\$\{readable\}/g, aggregateMacros.version.readable) fContents = fContents.replace(/\$\{package.name\}/g, aggregateMacros.library) + return fContents } diff --git a/src/macrofier/index.mjs b/src/macrofier/index.mjs index 4982205b..9ff30291 100644 --- a/src/macrofier/index.mjs +++ b/src/macrofier/index.mjs @@ -154,6 +154,7 @@ const macrofy = async ( else { modules = moduleList.map(name => getModule(name, openrpc, copySchemasIntoModules, extractSubSchemas)) } + const aggregateMacros = engine.generateAggregateMacros(openrpc, modules.concat(staticModules), templates, libraryName) const outputFiles = Object.fromEntries(Object.entries(await readFiles( staticCodeList, staticContent)) @@ -190,16 +191,19 @@ const macrofy = async ( let append = false modules.forEach(module => { + // Pick the index and defaults templates for each module. templatesPerModule.forEach(t => { const macros = engine.generateMacros(module, templates, exampleTemplates, {hideExcluded: hideExcluded, copySchemasIntoModules: copySchemasIntoModules, createPolymorphicMethods: createPolymorphicMethods, destination: t, type: 'methods'}) let content = getTemplateForModule(module.info.title, t, templates) + // NOTE: whichever insert is called first also needs to be called again last, so each phase can insert recursive macros from the other content = engine.insertAggregateMacros(content, aggregateMacros) content = engine.insertMacros(content, macros) content = engine.insertAggregateMacros(content, aggregateMacros) const location = createModuleDirectories ? path.join(output, module.info.title, t) : path.join(output, t.replace(/module/, module.info.title.toLowerCase()).replace(/index/, module.info.title)) + outputFiles[location] = content logSuccess(`Generated macros for module ${path.relative(output, location)}`) }) From 40d3d7de8e583b5bde4fb47d1930b6ac0c357ca6 Mon Sep 17 00:00:00 2001 From: "Kandasamy, Divya" Date: Thu, 18 Jul 2024 12:36:52 -0400 Subject: [PATCH 7/9] fix: Revoked Package.json changes --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index be798cea..6ae1731a 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "scripts": { "prepack": "npm run prepare:setup && npm run dist", "prepare:setup": "npx mkdirp ./dist/docs ./build/docs/markdown ./build/docs/wiki ./build/sdk/javascript/src", - "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config=jest.config.json --detectOpenHandles --collectCoverage --runInBand --forceExit", + "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config=jest.config.json --detectOpenHandles", "build": "npm run validate && npm run build:docs && npm run build:sdk", "validate": "node ./src/cli.mjs validate --input ./test/openrpc --schemas test/schemas --transformations && npm run build:openrpc && node ./src/cli.mjs validate --input ./build/sdk-open-rpc.json", "build:openrpc": "node ./src/cli.mjs openrpc --input ./test --template ./src/openrpc-template.json --output ./build/sdk-open-rpc.json --schemas test/schemas", From 07998a08c0dc57d2bb1266f8e7d8ea9e0ccb444a Mon Sep 17 00:00:00 2001 From: "Kandasamy, Divya" Date: Tue, 23 Jul 2024 09:46:44 -0400 Subject: [PATCH 8/9] fix: Created internal and external eventMap in Transport.h Created internal and external eventMap in Transport.h --- languages/cpp/src/shared/src/Event/Event.h | 20 +++--- .../cpp/src/shared/src/Transport/Transport.h | 63 ++++++++++++++----- 2 files changed, 56 insertions(+), 27 deletions(-) diff --git a/languages/cpp/src/shared/src/Event/Event.h b/languages/cpp/src/shared/src/Event/Event.h index 0a3f760d..6e599716 100644 --- a/languages/cpp/src/shared/src/Event/Event.h +++ b/languages/cpp/src/shared/src/Event/Event.h @@ -83,32 +83,29 @@ namespace FireboltSDK { Firebolt::Error Subscribe(const string& eventName, JsonObject& jsonParameters, const CALLBACK& callback, void* usercb, const void* userdata, bool prioritize = false) { Firebolt::Error status = Firebolt::Error::General; + if (_transport != nullptr) { - if (prioritize) { - status = Assign(_internalEventMap, eventName, callback, usercb, userdata); - } else { - status = Assign(_externalEventMap, eventName, callback, usercb, userdata); - } + EventMap& eventMap = prioritize ? _internalEventMap : _externalEventMap; + + status = Assign(eventMap, eventName, callback, usercb, userdata); + if (status == Firebolt::Error::None) { Response response; - WPEFramework::Core::JSON::Variant Listen = true; jsonParameters.Set(_T("listen"), Listen); string parameters; jsonParameters.ToString(parameters); - status = _transport->Subscribe(eventName, parameters, response); + status = _transport->Subscribe(eventName, parameters, response, prioritize); if (status != Firebolt::Error::None) { Revoke(eventName, usercb); - } else if ((response.Listening.IsSet() == true) && - (response.Listening.Value() == true)) { + } else if (response.Listening.IsSet() && response.Listening.Value()) { status = Firebolt::Error::None; } } } - - return status; + return status; } // To prioritize internal and external events and its corresponding callbacks @@ -128,6 +125,7 @@ namespace FireboltSDK { template Firebolt::Error Assign(EventMap& eventMap, const string& eventName, const CALLBACK& callback, void* usercb, const void* userdata) { + Firebolt::Error status = Firebolt::Error::General; std::function actualCallback = callback; DispatchFunction implementation = [actualCallback](void* usercb, const void* userdata, const string& parameters) -> Firebolt::Error { diff --git a/languages/cpp/src/shared/src/Transport/Transport.h b/languages/cpp/src/shared/src/Transport/Transport.h index 0caa7603..16205745 100644 --- a/languages/cpp/src/shared/src/Transport/Transport.h +++ b/languages/cpp/src/shared/src/Transport/Transport.h @@ -565,7 +565,13 @@ namespace FireboltSDK { void Revoke(const string& eventName) { _adminLock.Lock(); - _eventMap.erase(eventName); + + // Remove from internal event map + _internalEventMap.erase(eventName); + + // Remove from external event map + _externalEventMap.erase(eventName); + _adminLock.Unlock(); } @@ -640,22 +646,31 @@ namespace FireboltSDK { } template - Firebolt::Error Subscribe(const string& eventName, const string& parameters, RESPONSE& response) + + Firebolt::Error Subscribe(const string& eventName, const string& parameters, RESPONSE& response, bool updateInternal = false) { Entry slot; uint32_t id = _channel->Sequence(); Firebolt::Error result = Send(eventName, parameters, id); + if (result == Firebolt::Error::None) { _adminLock.Lock(); - _eventMap.emplace(std::piecewise_construct, - std::forward_as_tuple(eventName), - std::forward_as_tuple(~0)); + + // Choose the map based on updateInternal flag + EventMap& eventMap = updateInternal ? _internalEventMap : _externalEventMap; + + // Add to the selected event map + eventMap.emplace(std::piecewise_construct, + std::forward_as_tuple(eventName), + std::forward_as_tuple(id)); + _adminLock.Unlock(); - result = WaitForEventResponse(id, eventName, response, _waitTime); + result = WaitForEventResponse(id, eventName, response, _waitTime, eventMap); + } - return (result); + return result; } Firebolt::Error Unsubscribe(const string& eventName, const string& parameters) @@ -692,18 +707,34 @@ namespace FireboltSDK { private: friend Channel; + inline bool IsEvent(const uint32_t id, string& eventName) { _adminLock.Lock(); - for (auto& event : _eventMap) { - if (event.second == id) { - eventName = event.first; - break; + + bool eventExist = false; + + // List of maps to search + std::vector maps = {&_internalEventMap, &_externalEventMap}; + + // Loop through each map + for (const auto* map : maps) { + for (const auto& event : *map) { + if (event.second == id) { + eventName = event.first; + eventExist = true; + break; // Break the inner loop + } + } + if (eventExist) { + break; // Break the outer loop } } + _adminLock.Unlock(); - return (eventName.empty() != true); + return eventExist; } + uint64_t Timed() { uint64_t result = ~0; @@ -802,8 +833,7 @@ namespace FireboltSDK { return (result); } - - + template Firebolt::Error Send(const string& method, const PARAMETERS& parameters, const uint32_t& id) { @@ -844,7 +874,7 @@ namespace FireboltSDK { static constexpr uint32_t WAITSLOT_TIME = 100; template - Firebolt::Error WaitForEventResponse(const uint32_t& id, const string& eventName, RESPONSE& response, const uint32_t waitTime) + Firebolt::Error WaitForEventResponse(const uint32_t& id, const string& eventName, RESPONSE& response, const uint32_t waitTime, EventMap& _eventMap) { Firebolt::Error result = Firebolt::Error::Timedout; _adminLock.Lock(); @@ -973,7 +1003,8 @@ namespace FireboltSDK { WPEFramework::Core::ProxyType _channel; IEventHandler* _eventHandler; PendingMap _pendingQueue; - EventMap _eventMap; + EventMap _internalEventMap; + EventMap _externalEventMap; uint64_t _scheduledTime; uint32_t _waitTime; Listener _listener; From b4b494e49f17b32e1b0534d654e18703aa9f223b Mon Sep 17 00:00:00 2001 From: "Kandasamy, Divya" Date: Wed, 24 Jul 2024 19:00:11 -0400 Subject: [PATCH 9/9] fix: Added comments Added comments --- languages/cpp/src/shared/src/Event/Event.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/languages/cpp/src/shared/src/Event/Event.cpp b/languages/cpp/src/shared/src/Event/Event.cpp index 3ee54683..6f771462 100644 --- a/languages/cpp/src/shared/src/Event/Event.cpp +++ b/languages/cpp/src/shared/src/Event/Event.cpp @@ -89,7 +89,12 @@ namespace FireboltSDK { return result; } - Firebolt::Error Event::Dispatch(const string& eventName, const WPEFramework::Core::ProxyType& jsonResponse) /* override */ + + /* This function combines both internal and external event maps, and iterates over them to find the specified event. + If the event is found, it iterates over its associated callbacks, updating their states and executing them if applicable. + Callbacks in the REVOKED state are removed. + */ + Firebolt::Error Event::Dispatch(const string& eventName, const WPEFramework::Core::ProxyType& jsonResponse) /* override */ { string response = jsonResponse->Result.Value(); std::vector eventMaps = {&_internalEventMap, &_externalEventMap};