diff --git a/languages/cpp/src/shared/include/error.h b/languages/cpp/src/shared/include/error.h index 07d6268a..b02859b3 100644 --- a/languages/cpp/src/shared/include/error.h +++ b/languages/cpp/src/shared/include/error.h @@ -16,26 +16,24 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef FIREBOLT_ERROR_H -#define FIREBOLT_ERROR_H +#pragma once -#ifdef __cplusplus -extern "C" { -#endif +namespace Firebolt { -typedef enum FireboltSDKError { - FireboltSDKErrorNone = 0, - FireboltSDKErrorGeneral = 1, - FireboltSDKErrorUnavailable = 2, - FireboltSDKErrorTimedout = 3, - FireboltSDKErrorNotSubscribed = 4, - FireboltSDKErrorUnknown = 5, - FireboltSDKErrorInUse = 6, - FireboltSDKErrorNotSupported = 7 -} FireboltSDKError_t; + enum class Error : int32_t { + None = 0, + General = 1, + Timedout = 2, + NotConnected = 3, + AlreadyConnected = 4, + //AuthenticationError, ? + InvalidRequest = -32600, + MethodNotFound = -32601, + InvalidParams = -32602, + CapabilityNotAvaialbale = -50300, + CapabilityNotSupported = -50100, + CapabilityGet = -50200, + CapabilityNotPermitted = -40300, + }; -#ifdef __cplusplus } -#endif - -#endif // FIREBOLT_ERROR_H diff --git a/languages/cpp/src/shared/include/types.h b/languages/cpp/src/shared/include/types.h index 8333f0eb..841bda7a 100644 --- a/languages/cpp/src/shared/include/types.h +++ b/languages/cpp/src/shared/include/types.h @@ -16,22 +16,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef FIREBOLT_TYPES_H -#define FIREBOLT_TYPES_H +#pragma once #include #include +#include +#include +#include +#include -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct Firebolt_String_s* Firebolt_String_t; -const char* Firebolt_String(Firebolt_String_t handle); -void Firebolt_String_Release(Firebolt_String_t handle); - -#ifdef __cplusplus -} -#endif - -#endif // FIREBOLT_TYPES_H diff --git a/languages/cpp/src/shared/src/Accessor/Accessor.cpp b/languages/cpp/src/shared/src/Accessor/Accessor.cpp index 6d4aceae..e34630ed 100644 --- a/languages/cpp/src/shared/src/Accessor/Accessor.cpp +++ b/languages/cpp/src/shared/src/Accessor/Accessor.cpp @@ -27,15 +27,13 @@ namespace FireboltSDK { , _transport(nullptr) , _config() { + ASSERT(_singleton == nullptr); _singleton = this; _config.FromString(configLine); Logger::SetLogLevel(WPEFramework::Core::EnumerateType(_config.LogLevel.Value().c_str()).Value()); FIREBOLT_LOG_INFO(Logger::Category::OpenRPC, Logger::Module(), "Url = %s", _config.WsUrl.Value().c_str()); - CreateTransport(_config.WsUrl.Value().c_str(), _config.WaitTime.Value()); - CreateEventHandler(); - _workerPool = WPEFramework::Core::ProxyType::Create(_config.WorkerPool.ThreadCount.Value(), _config.WorkerPool.StackSize.Value(), _config.WorkerPool.QueueSize.Value()); WPEFramework::Core::WorkerPool::Assign(&(*_workerPool)); _workerPool->Run(); @@ -43,23 +41,23 @@ namespace FireboltSDK { Accessor::~Accessor() { - DestroyTransport(); - DestroyEventHandler(); WPEFramework::Core::IWorkerPool::Assign(nullptr); _workerPool->Stop(); + + ASSERT(_singleton != nullptr); _singleton = nullptr; } - int32_t Accessor::CreateEventHandler() + Firebolt::Error Accessor::CreateEventHandler() { Event::Instance().Configure(_transport); - return FireboltSDKErrorNone; + return Firebolt::Error::None; } - int32_t Accessor::DestroyEventHandler() + Firebolt::Error Accessor::DestroyEventHandler() { Event::Dispose(); - return FireboltSDKErrorNone; + return Firebolt::Error::None; } Event& Accessor::GetEventManager() @@ -67,29 +65,25 @@ namespace FireboltSDK { return Event::Instance(); } - int32_t Accessor::CreateTransport(const string& url, const uint32_t waitTime = DefaultWaitTime) + Firebolt::Error Accessor::CreateTransport(const string& url, const Transport::Listener& listener, const uint32_t waitTime = DefaultWaitTime) { if (_transport != nullptr) { delete _transport; } - _transport = new Transport(static_cast(url), waitTime); - if (WaitForLinkReady(_transport, waitTime) != FireboltSDKErrorNone) { - delete _transport; - _transport = nullptr; - } + _transport = new Transport(static_cast(url), waitTime, listener); ASSERT(_transport != nullptr); - return ((_transport != nullptr) ? FireboltSDKErrorNone : FireboltSDKErrorUnavailable); + return ((_transport != nullptr) ? Firebolt::Error::None : Firebolt::Error::Timedout); } - int32_t Accessor::DestroyTransport() + Firebolt::Error Accessor::DestroyTransport() { if (_transport != nullptr) { delete _transport; _transport = nullptr; } - return FireboltSDKErrorNone; + return Firebolt::Error::None; } Transport* Accessor::GetTransport() @@ -98,20 +92,4 @@ namespace FireboltSDK { return _transport; } - int32_t Accessor::WaitForLinkReady(Transport* transport, const uint32_t waitTime = DefaultWaitTime) { - uint32_t waiting = (waitTime == WPEFramework::Core::infinite ? WPEFramework::Core::infinite : waitTime); - static constexpr uint32_t SLEEPSLOT_TIME = 100; - - // Right, a wait till connection is closed is requested.. - while ((waiting > 0) && (transport->IsOpen() == false)) { - - uint32_t sleepSlot = (waiting > SLEEPSLOT_TIME ? SLEEPSLOT_TIME : waiting); - - // Right, lets sleep in slices of 100 ms - SleepMs(sleepSlot); - - waiting -= (waiting == WPEFramework::Core::infinite ? 0 : sleepSlot); - } - return (((waiting == 0) || (transport->IsOpen() == true)) ? FireboltSDKErrorNone : FireboltSDKErrorTimedout); - } } diff --git a/languages/cpp/src/shared/src/Accessor/Accessor.h b/languages/cpp/src/shared/src/Accessor/Accessor.h index e247df98..29dd7dda 100644 --- a/languages/cpp/src/shared/src/Accessor/Accessor.h +++ b/languages/cpp/src/shared/src/Accessor/Accessor.h @@ -103,15 +103,34 @@ namespace FireboltSDK { delete _singleton; } } + + Firebolt::Error Connect(const Transport::Listener& listener) + { + Firebolt::Error status = CreateTransport(_config.WsUrl.Value().c_str(), listener, _config.WaitTime.Value()); + if (status == Firebolt::Error::None) { + status = CreateEventHandler(); + } + return status; + } + + Firebolt::Error Disconnect() + { + Firebolt::Error status = Firebolt::Error::None; + status = DestroyTransport(); + if (status == Firebolt::Error::None) { + status = DestroyEventHandler(); + } + return status; + } + Event& GetEventManager(); Transport* GetTransport(); private: - int32_t CreateEventHandler(); - int32_t DestroyEventHandler(); - int32_t CreateTransport(const string& url, const uint32_t waitTime); - int32_t DestroyTransport(); - int32_t WaitForLinkReady(Transport* transport, const uint32_t waitTime); + Firebolt::Error CreateEventHandler(); + Firebolt::Error DestroyEventHandler(); + Firebolt::Error CreateTransport(const string& url, const Transport::Listener& listener, const uint32_t waitTime); + Firebolt::Error DestroyTransport(); private: WPEFramework::Core::ProxyType _workerPool; diff --git a/languages/cpp/src/shared/src/CMakeLists.txt b/languages/cpp/src/shared/src/CMakeLists.txt index ecaf4efb..960af8de 100644 --- a/languages/cpp/src/shared/src/CMakeLists.txt +++ b/languages/cpp/src/shared/src/CMakeLists.txt @@ -45,7 +45,7 @@ target_include_directories(${TARGET} ) set_target_properties(${TARGET} PROPERTIES - CXX_STANDARD 11 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE LINK_WHAT_YOU_USE TRUE diff --git a/languages/cpp/src/shared/src/Event/Event.cpp b/languages/cpp/src/shared/src/Event/Event.cpp index c1fdff6f..2438e3c4 100644 --- a/languages/cpp/src/shared/src/Event/Event.cpp +++ b/languages/cpp/src/shared/src/Event/Event.cpp @@ -60,33 +60,35 @@ namespace FireboltSDK { _transport->SetEventHandler(this); } - int32_t Event::Unsubscribe(const string& eventName, void* usercb) + Firebolt::Error Event::Unsubscribe(const string& eventName, void* usercb) { - int32_t status = Revoke(eventName, usercb); + Firebolt::Error status = Revoke(eventName, usercb); - if (status == FireboltSDKErrorNone) { + if (status == Firebolt::Error::None) { if (_transport != nullptr) { const string parameters("{\"listen\":false}"); status = _transport->Unsubscribe(eventName, parameters); } + } else { + status = Firebolt::Error::None; } - return ((status == FireboltSDKErrorInUse) ? FireboltSDKErrorNone: status); + return status; } - int32_t Event::ValidateResponse(const WPEFramework::Core::ProxyType& jsonResponse, bool& enabled) /* override */ + Firebolt::Error Event::ValidateResponse(const WPEFramework::Core::ProxyType& jsonResponse, bool& enabled) /* override */ { - int32_t result = FireboltSDKErrorGeneral; + Firebolt::Error result = Firebolt::Error::General; Response response; _transport->FromMessage((WPEFramework::Core::JSON::IElement*)&response, *jsonResponse); if (response.Listening.IsSet() == true) { - result = FireboltSDKErrorNone; + result = Firebolt::Error::None; enabled = response.Listening.Value(); } return result; } - int32_t 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(); _adminLock.Lock(); @@ -117,12 +119,12 @@ namespace FireboltSDK { } _adminLock.Unlock(); - return FireboltSDKErrorNone;; + return Firebolt::Error::None;; } - int32_t Event::Revoke(const string& eventName, void* usercb) + Firebolt::Error Event::Revoke(const string& eventName, void* usercb) { - int32_t status = FireboltSDKErrorNone; + Firebolt::Error status = Firebolt::Error::None; _adminLock.Lock(); EventMap::iterator eventIndex = _eventMap.find(eventName); if (eventIndex != _eventMap.end()) { @@ -137,7 +139,7 @@ namespace FireboltSDK { if (eventIndex->second.size() == 0) { _eventMap.erase(eventIndex); } else { - status = FireboltSDKErrorInUse; + status = Firebolt::Error::General; } } _adminLock.Unlock(); diff --git a/languages/cpp/src/shared/src/Event/Event.h b/languages/cpp/src/shared/src/Event/Event.h index dd65cb53..cf2fdced 100644 --- a/languages/cpp/src/shared/src/Event/Event.h +++ b/languages/cpp/src/shared/src/Event/Event.h @@ -26,7 +26,7 @@ namespace FireboltSDK { class Event : public IEventHandler { public: - typedef std::function DispatchFunction; + typedef std::function DispatchFunction; private: enum State : uint8_t { IDLE, @@ -73,20 +73,20 @@ namespace FireboltSDK { public: template - int32_t Subscribe(const string& eventName, const CALLBACK& callback, void* usercb, const void* userdata) + Firebolt::Error Subscribe(const string& eventName, const CALLBACK& callback, void* usercb, const void* userdata) { JsonObject jsonParameters; return Subscribe(eventName, jsonParameters, callback, usercb, userdata); } template - int32_t 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) { - int32_t status = FireboltSDKErrorUnavailable; + Firebolt::Error status = Firebolt::Error::General; if (_transport != nullptr) { status = Assign(eventName, callback, usercb, userdata); - if (status == FireboltSDKErrorNone) { + if (status == Firebolt::Error::None) { Response response; WPEFramework::Core::JSON::Variant Listen = true; @@ -96,13 +96,11 @@ namespace FireboltSDK { status = _transport->Subscribe(eventName, parameters, response); - if (status != FireboltSDKErrorNone) { + if (status != Firebolt::Error::None) { Revoke(eventName, usercb); } else if ((response.Listening.IsSet() == true) && (response.Listening.Value() == true)) { - status = FireboltSDKErrorNone; - } else { - status = FireboltSDKErrorNotSubscribed; + status = Firebolt::Error::None; } } } @@ -110,21 +108,21 @@ namespace FireboltSDK { return status; } - int32_t Unsubscribe(const string& eventName, void* usercb); + Firebolt::Error Unsubscribe(const string& eventName, void* usercb); private: template - int32_t Assign(const string& eventName, const CALLBACK& callback, void* usercb, const void* userdata) + Firebolt::Error Assign(const string& eventName, const CALLBACK& callback, void* usercb, const void* userdata) { - int32_t status = FireboltSDKErrorNone; + Firebolt::Error status = Firebolt::Error::General; std::function actualCallback = callback; - DispatchFunction implementation = [actualCallback](void* usercb, const void* userdata, const string& parameters) -> int32_t { + 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); actualCallback(usercb, userdata, static_cast(inbound)); - return (FireboltSDKErrorNone); + return (Firebolt::Error::None); }; CallbackData callbackData = {implementation, userdata, State::IDLE}; @@ -134,26 +132,25 @@ namespace FireboltSDK { 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)); - } else { - // Already registered, no need to register again; - status = FireboltSDKErrorInUse; + status = Firebolt::Error::None; } } else { 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)); + status = Firebolt::Error::None; } _adminLock.Unlock(); return status; } - int32_t Revoke(const string& eventName, void* usercb); + Firebolt::Error Revoke(const string& eventName, void* usercb); private: - int32_t ValidateResponse(const WPEFramework::Core::ProxyType& jsonResponse, bool& enabled) override; - int32_t Dispatch(const string& eventName, const WPEFramework::Core::ProxyType& jsonResponse) override; + Firebolt::Error ValidateResponse(const WPEFramework::Core::ProxyType& jsonResponse, bool& enabled) override; + Firebolt::Error Dispatch(const string& eventName, const WPEFramework::Core::ProxyType& jsonResponse) override; private: EventMap _eventMap; diff --git a/languages/cpp/src/shared/test/OpenRPCCTests.h b/languages/cpp/src/shared/src/IModule.h similarity index 56% rename from languages/cpp/src/shared/test/OpenRPCCTests.h rename to languages/cpp/src/shared/src/IModule.h index 936a1ff9..1349e78a 100644 --- a/languages/cpp/src/shared/test/OpenRPCCTests.h +++ b/languages/cpp/src/shared/src/IModule.h @@ -16,28 +16,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef OPENRPC_C_TESTS_H -#define OPENRPC_C_TESTS_H +#pragma once -#include "TestUtils.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void test_firebolt_create_instance(); -void test_firebolt_dispose_instance(); - -int32_t test_firebolt_main(); -int32_t test_properties_get_device_id(); -int32_t test_properties_set(); -int32_t test_eventregister(); -int32_t test_eventregister_with_same_callback(); -int32_t test_eventregister_by_providing_callback(); -int32_t test_string_set_get_value(); - -#ifdef __cplusplus +namespace Firebolt { + struct IModule { + virtual ~IModule() = default; + }; } -#endif - -#endif // OPENRPC_C_TESTS_H diff --git a/languages/cpp/src/shared/src/Logger/Logger.cpp b/languages/cpp/src/shared/src/Logger/Logger.cpp index 44ebaba8..c66c6b68 100644 --- a/languages/cpp/src/shared/src/Logger/Logger.cpp +++ b/languages/cpp/src/shared/src/Logger/Logger.cpp @@ -35,7 +35,7 @@ ENUM_CONVERSION_BEGIN(FireboltSDK::Logger::Category) { FireboltSDK::Logger::Category::OpenRPC, _TXT("FireboltSDK::OpenRPC") }, { FireboltSDK::Logger::Category::Core, _TXT("FireboltSDK::Core") }, - { FireboltSDK::Logger::Category::Management, _TXT("FireboltSDK::Management") }, + { FireboltSDK::Logger::Category::Manage, _TXT("FireboltSDK::Manage") }, { FireboltSDK::Logger::Category::Discovery, _TXT("FireboltSDK::Discovery") }, ENUM_CONVERSION_END(FireboltSDK::Logger::Category) @@ -45,13 +45,13 @@ ENUM_CONVERSION_END(FireboltSDK::Logger::Category) namespace FireboltSDK { /* static */ Logger::LogLevel Logger::_logLevel = Logger::LogLevel::Error; - int32_t Logger::SetLogLevel(Logger::LogLevel logLevel) + Firebolt::Error Logger::SetLogLevel(Logger::LogLevel logLevel) { ASSERT(logLevel < Logger::LogLevel::MaxLevel); - int32_t status = FireboltSDKErrorNotSupported; + Firebolt::Error status = Firebolt::Error::General; if (logLevel < Logger::LogLevel::MaxLevel) { _logLevel = logLevel; - status = FireboltSDKErrorNone; + status = Firebolt::Error::None; } return status; } diff --git a/languages/cpp/src/shared/src/Logger/Logger.h b/languages/cpp/src/shared/src/Logger/Logger.h index b8e42031..ffe5a455 100644 --- a/languages/cpp/src/shared/src/Logger/Logger.h +++ b/languages/cpp/src/shared/src/Logger/Logger.h @@ -38,7 +38,7 @@ namespace FireboltSDK { enum class Category : uint8_t { OpenRPC, Core, - Management, + Manage, Discovery }; @@ -49,7 +49,7 @@ namespace FireboltSDK { ~Logger() = default; public: - static int32_t SetLogLevel(LogLevel logLevel); + static Firebolt::Error SetLogLevel(LogLevel logLevel); static void Log(LogLevel logLevel, Category category, const std::string& module, const std::string file, const std::string function, const uint16_t line, const std::string& format, ...); public: diff --git a/languages/cpp/src/shared/src/Properties/Properties.h b/languages/cpp/src/shared/src/Properties/Properties.h index eaf6c1a4..52051397 100644 --- a/languages/cpp/src/shared/src/Properties/Properties.h +++ b/languages/cpp/src/shared/src/Properties/Properties.h @@ -33,15 +33,15 @@ namespace FireboltSDK { public: template - static int32_t Get(const string& propertyName, WPEFramework::Core::ProxyType& response) + static Firebolt::Error Get(const string& propertyName, WPEFramework::Core::ProxyType& response) { - int32_t status = FireboltSDKErrorUnavailable; + Firebolt::Error status = Firebolt::Error::General; Transport* transport = Accessor::Instance().GetTransport(); if (transport != nullptr) { JsonObject parameters; RESPONSETYPE responseType; status = transport->Invoke(propertyName, parameters, responseType); - if (status == FireboltSDKErrorNone) { + if (status == Firebolt::Error::None) { ASSERT(response.IsValid() == false); if (response.IsValid() == true) { response.Release(); @@ -57,14 +57,14 @@ namespace FireboltSDK { } template - static int32_t Get(const string& propertyName, const PARAMETERS& parameters, WPEFramework::Core::ProxyType& response) + static Firebolt::Error Get(const string& propertyName, const PARAMETERS& parameters, WPEFramework::Core::ProxyType& response) { - int32_t status = FireboltSDKErrorUnavailable; + Firebolt::Error status = Firebolt::Error::General; Transport* transport = Accessor::Instance().GetTransport(); if (transport != nullptr) { RESPONSETYPE responseType; status = transport->Invoke(propertyName, parameters, responseType); - if (status == FireboltSDKErrorNone) { + if (status == Firebolt::Error::None) { ASSERT(response.IsValid() == false); if (response.IsValid() == true) { response.Release(); @@ -81,9 +81,9 @@ namespace FireboltSDK { template - static int32_t Get(const string& propertyName, RESPONSETYPE& response) + static Firebolt::Error Get(const string& propertyName, RESPONSETYPE& response) { - int32_t status = FireboltSDKErrorUnavailable; + Firebolt::Error status = Firebolt::Error::General; Transport* transport = Accessor::Instance().GetTransport(); if (transport != nullptr) { JsonObject parameters; @@ -96,9 +96,9 @@ namespace FireboltSDK { } template - static int32_t Get(const string& propertyName, const PARAMETERS& parameters, RESPONSETYPE& response) + static Firebolt::Error Get(const string& propertyName, const PARAMETERS& parameters, RESPONSETYPE& response) { - int32_t status = FireboltSDKErrorUnavailable; + Firebolt::Error status = Firebolt::Error::General; Transport* transport = Accessor::Instance().GetTransport(); if (transport != nullptr) { status = transport->Invoke(propertyName, parameters, response); @@ -110,9 +110,9 @@ namespace FireboltSDK { } template - static int32_t Set(const string& propertyName, const PARAMETERS& parameters) + static Firebolt::Error Set(const string& propertyName, const PARAMETERS& parameters) { - int32_t status = FireboltSDKErrorUnavailable; + Firebolt::Error status = Firebolt::Error::General; Transport* transport = Accessor::Instance().GetTransport(); if (transport != nullptr) { JsonObject responseType; @@ -125,12 +125,12 @@ namespace FireboltSDK { } template - static int32_t Subscribe(const string& propertyName, JsonObject& paramsters, const CALLBACK& callback, void* usercb, const void* userdata) + static Firebolt::Error Subscribe(const string& propertyName, JsonObject& paramsters, const CALLBACK& callback, void* usercb, const void* userdata) { return Event::Instance().Subscribe(EventName(propertyName), paramsters, callback, usercb, userdata); } - static int32_t Unsubscribe(const string& propertyName, void* usercb) + static Firebolt::Error Unsubscribe(const string& propertyName, void* usercb) { return Event::Instance().Unsubscribe(EventName(propertyName), usercb); } diff --git a/languages/cpp/src/shared/src/Transport/Transport.h b/languages/cpp/src/shared/src/Transport/Transport.h index 6b80cd25..87632dc1 100644 --- a/languages/cpp/src/shared/src/Transport/Transport.h +++ b/languages/cpp/src/shared/src/Transport/Transport.h @@ -441,8 +441,8 @@ namespace FireboltSDK { class IEventHandler { public: - virtual int32_t ValidateResponse(const WPEFramework::Core::ProxyType& jsonResponse, bool& enabled) = 0; - virtual int32_t Dispatch(const string& eventName, const WPEFramework::Core::ProxyType& jsonResponse) = 0; + virtual Firebolt::Error ValidateResponse(const WPEFramework::Core::ProxyType& jsonResponse, bool& enabled) = 0; + virtual Firebolt::Error Dispatch(const string& eventName, const WPEFramework::Core::ProxyType& jsonResponse) = 0; virtual ~IEventHandler() = default; }; @@ -455,20 +455,20 @@ namespace FireboltSDK { using EventMap = std::map; typedef std::function& jsonResponse, bool& enabled)> EventResponseValidatioionFunction; - class Job : public WPEFramework::Core::IDispatch { + class CommunicationJob : public WPEFramework::Core::IDispatch { protected: - Job(const WPEFramework::Core::ProxyType& inbound, class Transport* parent) + CommunicationJob(const WPEFramework::Core::ProxyType& inbound, class Transport* parent) : _inbound(inbound) , _parent(parent) { } public: - Job() = delete; - Job(const Job&) = delete; - Job& operator=(const Job&) = delete; + CommunicationJob() = delete; + CommunicationJob(const CommunicationJob&) = delete; + CommunicationJob& operator=(const CommunicationJob&) = delete; - ~Job() = default; + ~CommunicationJob() = default; public: static WPEFramework::Core::ProxyType Create(const WPEFramework::Core::ProxyType& inbound, class Transport* parent); @@ -483,6 +483,36 @@ namespace FireboltSDK { class Transport* _parent; }; + class ConnectionJob : public WPEFramework::Core::IDispatch { + protected: + ConnectionJob(class Transport* parent) + : _parent(parent) + { + } + + public: + ConnectionJob() = delete; + ConnectionJob(const ConnectionJob&) = delete; + ConnectionJob& operator=(const ConnectionJob&) = delete; + + ~ConnectionJob() = default; + + public: + static WPEFramework::Core::ProxyType Create(class Transport* parent); + + void Dispatch() override + { + if (Firebolt::Error::None != _parent->WaitForLinkReady()) { + _parent->NotifyStatus(Firebolt::Error::Timedout); + } + } + + private: + const WPEFramework::Core::ProxyType _inbound; + class Transport* _parent; + }; + + protected: static constexpr uint32_t DefaultWaitTime = 10000; @@ -492,11 +522,15 @@ namespace FireboltSDK { private: static constexpr const TCHAR* PathPrefix = _T("/"); + + public: + typedef std::function Listener; + public: Transport() = delete; Transport(const Transport&) = delete; Transport& operator=(Transport&) = delete; - Transport(const WPEFramework::Core::URL& url, const uint32_t waitTime) + Transport(const WPEFramework::Core::URL& url, const uint32_t waitTime, const Listener listener) : _adminLock() , _connectId(WPEFramework::Core::NodeId(url.Host().Value().c_str(), url.Port().Value())) , _channel(Channel::Instance(_connectId, ((url.Path().Value().rfind(PathPrefix, 0) == 0) ? url.Path().Value() : string(PathPrefix + url.Path().Value())), url.Query().Value(), true)) @@ -504,8 +538,12 @@ namespace FireboltSDK { , _pendingQueue() , _scheduledTime(0) , _waitTime(waitTime) + , _listener(listener) + , _status(Firebolt::Error::NotConnected) { _channel->Register(*this); + WPEFramework::Core::ProxyType job = WPEFramework::Core::ProxyType(WPEFramework::Core::ProxyType::Create(this)); + WPEFramework::Core::IWorkerPool::Instance().Submit(job); } virtual ~Transport() @@ -536,25 +574,25 @@ namespace FireboltSDK { } template - int32_t Invoke(const string& method, const PARAMETERS& parameters, RESPONSE& response) + Firebolt::Error Invoke(const string& method, const PARAMETERS& parameters, RESPONSE& response) { Entry slot; uint32_t id = _channel->Sequence(); - int32_t result = Send(method, parameters, id); - if (result == WPEFramework::Core::ERROR_NONE) { + Firebolt::Error result = Send(method, parameters, id); + if (result == Firebolt::Error::None) { result = WaitForResponse(id, response, _waitTime); } - return (FireboltErrorValue(result)); + return (result); } template - int32_t Subscribe(const string& eventName, const string& parameters, RESPONSE& response) + Firebolt::Error Subscribe(const string& eventName, const string& parameters, RESPONSE& response) { Entry slot; uint32_t id = _channel->Sequence(); - int32_t result = Send(eventName, parameters, id); - if (result == WPEFramework::Core::ERROR_NONE) { + Firebolt::Error result = Send(eventName, parameters, id); + if (result == Firebolt::Error::None) { _adminLock.Lock(); _eventMap.emplace(std::piecewise_construct, std::forward_as_tuple(eventName), @@ -564,17 +602,39 @@ namespace FireboltSDK { result = WaitForEventResponse(id, eventName, response, _waitTime); } - return (FireboltErrorValue(result)); + return (result); } - int32_t Unsubscribe(const string& eventName, const string& parameters) + Firebolt::Error Unsubscribe(const string& eventName, const string& parameters) { Revoke(eventName); Entry slot; uint32_t id = _channel->Sequence(); - int32_t result = Send(eventName, parameters, id); - return (FireboltErrorValue(result)); + return Send(eventName, parameters, id); + } + + void NotifyStatus(Firebolt::Error status) + { + _listener(false, status); + } + + Firebolt::Error WaitForLinkReady() + { + uint32_t waiting = _waitTime; + static constexpr uint32_t SLEEPSLOT_TIME = 100; + + // Right, a wait till connection is closed is requested.. + while ((waiting > 0) && (IsOpen() == false) && (_status == Firebolt::Error::NotConnected)) { + + uint32_t sleepSlot = (waiting > SLEEPSLOT_TIME ? SLEEPSLOT_TIME : waiting); + + // Right, lets sleep in slices of 100 ms + SleepMs(sleepSlot); + + waiting -= (waiting == WPEFramework::Core::infinite ? 0 : sleepSlot); + } + return (((waiting == 0) || (IsOpen() == true)) ? Firebolt::Error::None : Firebolt::Error::Timedout); } private: @@ -619,7 +679,8 @@ namespace FireboltSDK { virtual void Opened() { - // Nice to know :-) + _status = Firebolt::Error::None; + _listener(true, _status); } void Closed() @@ -635,12 +696,13 @@ namespace FireboltSDK { } _adminLock.Unlock(); + _listener(false, _status); } int32_t Submit(const WPEFramework::Core::ProxyType& inbound) { int32_t result = WPEFramework::Core::ERROR_UNAVAILABLE; - WPEFramework::Core::ProxyType job = WPEFramework::Core::ProxyType(WPEFramework::Core::ProxyType::Create(inbound, this)); + WPEFramework::Core::ProxyType job = WPEFramework::Core::ProxyType(WPEFramework::Core::ProxyType::Create(inbound, this)); WPEFramework::Core::IWorkerPool::Instance().Submit(job); return result; } @@ -684,7 +746,7 @@ namespace FireboltSDK { template - int32_t Send(const string& method, const PARAMETERS& parameters, const uint32_t& id) + Firebolt::Error Send(const string& method, const PARAMETERS& parameters, const uint32_t& id) { int32_t result = WPEFramework::Core::ERROR_UNAVAILABLE; @@ -718,11 +780,11 @@ namespace FireboltSDK { result = WPEFramework::Core::ERROR_NONE; } } - return result; + return FireboltErrorValue(result); } template - int32_t WaitForResponse(const uint32_t& id, RESPONSE& response, const uint32_t waitTime) + Firebolt::Error WaitForResponse(const uint32_t& id, RESPONSE& response, const uint32_t waitTime) { int32_t result = WPEFramework::Core::ERROR_TIMEDOUT; _adminLock.Lock(); @@ -753,14 +815,14 @@ namespace FireboltSDK { _adminLock.Lock(); _pendingQueue.erase(id); _adminLock.Unlock(); - return result; + return FireboltErrorValue(result); } static constexpr uint32_t WAITSLOT_TIME = 100; template - int32_t 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) { - int32_t result = WPEFramework::Core::ERROR_TIMEDOUT; + Firebolt::Error result = Firebolt::Error::Timedout; _adminLock.Lock(); typename PendingMap::iterator index = _pendingQueue.find(id); Entry& slot(index->second); @@ -776,14 +838,13 @@ namespace FireboltSDK { // that closed? if (jsonResponse.IsValid() == true) { if (jsonResponse->Error.IsSet() == true) { - result = jsonResponse->Error.Code.Value(); + result = FireboltErrorValue(jsonResponse->Error.Code.Value()); } else { if ((jsonResponse->Result.IsSet() == true) && (jsonResponse->Result.Value().empty() == false)) { - result = WPEFramework::Core::ERROR_NONE; bool enabled; result = _eventHandler->ValidateResponse(jsonResponse, enabled); - if (result == WPEFramework::Core::ERROR_NONE) { + if (result == Firebolt::Error::None) { FromMessage((INTERFACE*)&response, *jsonResponse); if (enabled) { _adminLock.Lock(); @@ -798,10 +859,10 @@ namespace FireboltSDK { } } } else { - result = WPEFramework::Core::ERROR_TIMEDOUT; + result = Firebolt::Error::Timedout; } waiting -= (waiting == WPEFramework::Core::infinite ? 0 : waitSlot); - } while ((result != WPEFramework::Core::ERROR_NONE) && (waiting > 0 )); + } while ((result != Firebolt::Error::None) && (waiting > 0 )); _adminLock.Lock(); _pendingQueue.erase(id); _adminLock.Unlock(); @@ -860,22 +921,20 @@ namespace FireboltSDK { return; } - int32_t FireboltErrorValue(const uint32_t error) + Firebolt::Error FireboltErrorValue(const uint32_t error) { - int32_t fireboltError = error; + Firebolt::Error fireboltError = static_cast(error); switch (error) { case WPEFramework::Core::ERROR_NONE: - fireboltError = FireboltSDKErrorNone; + fireboltError = Firebolt::Error::None; break; case WPEFramework::Core::ERROR_GENERAL: - fireboltError = FireboltSDKErrorGeneral; - break; case WPEFramework::Core::ERROR_UNAVAILABLE: - fireboltError = FireboltSDKErrorUnavailable; + fireboltError = Firebolt::Error::General; break; case WPEFramework::Core::ERROR_TIMEDOUT: - fireboltError = FireboltSDKErrorTimedout; + fireboltError = Firebolt::Error::Timedout; break; default: break; @@ -893,5 +952,7 @@ namespace FireboltSDK { EventMap _eventMap; uint64_t _scheduledTime; uint32_t _waitTime; + Listener _listener; + Firebolt::Error _status; }; } diff --git a/languages/cpp/src/shared/src/TypesPriv.h b/languages/cpp/src/shared/src/TypesPriv.h index 6e365ec7..224f0552 100644 --- a/languages/cpp/src/shared/src/TypesPriv.h +++ b/languages/cpp/src/shared/src/TypesPriv.h @@ -41,6 +41,12 @@ class String : public WPEFramework::Core::JSON::String { _value = RHS; return (*this); } + String& operator=(const string RHS) + { + Base::operator = (RHS); + _value = RHS; + return (*this); + } public: const string& Value() const diff --git a/languages/cpp/src/shared/test/CMakeLists.txt b/languages/cpp/src/shared/test/CMakeLists.txt index 21ee1f55..012f1a6d 100644 --- a/languages/cpp/src/shared/test/CMakeLists.txt +++ b/languages/cpp/src/shared/test/CMakeLists.txt @@ -63,7 +63,7 @@ set(TESTAPP "FireboltSDKTestApp") message("Setup ${TESTAPP}") -add_executable(${TESTAPP} Main.c) +add_executable(${TESTAPP} Main.cpp) target_link_libraries(${TESTAPP} PRIVATE diff --git a/languages/cpp/src/shared/test/Main.c b/languages/cpp/src/shared/test/Main.c deleted file mode 100644 index 6161792e..00000000 --- a/languages/cpp/src/shared/test/Main.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2023 Comcast Cable Communications Management, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "OpenRPCCTests.h" - -int __cnt = 0; -int __pass = 0; - -int TotalTests = 0; -int TotalTestsPassed = 0; - -int main() -{ - test_firebolt_create_instance(); - test_firebolt_main(); - - // Calling C function sequences - printf("%s:%s:%d Calling C function tests\n", __FILE__, __func__, __LINE__); - EXECUTE("test_properties_get_device_id", test_properties_get_device_id); - EXECUTE("test_properties_set", test_properties_set); - EXECUTE("test_eventregister_by_providing_callback", test_eventregister_by_providing_callback); - EXECUTE("test_eventregister", test_eventregister); - EXECUTE("test_eventregister_with_same_callback", test_eventregister_with_same_callback); - EXECUTE("test_string_set_get_value", test_string_set_get_value); - - test_firebolt_dispose_instance(); - - printf("TOTAL: %i tests; %i PASSED, %i FAILED\n", TotalTests, TotalTestsPassed, (TotalTests - TotalTestsPassed)); -} - diff --git a/languages/cpp/src/shared/test/OpenRPCTests.cpp b/languages/cpp/src/shared/test/OpenRPCTests.cpp index 03fd2645..8fc4f4fb 100644 --- a/languages/cpp/src/shared/test/OpenRPCTests.cpp +++ b/languages/cpp/src/shared/test/OpenRPCTests.cpp @@ -18,7 +18,6 @@ #include "Module.h" #include "OpenRPCTests.h" -#include "OpenRPCCTests.h" namespace WPEFramework { @@ -80,14 +79,14 @@ namespace FireboltSDK { } } - /* static */ int32_t Tests::GetDeviceId() + /* static */ Firebolt::Error Tests::GetDeviceId() { const string method = _T("device.id"); WPEFramework::Core::ProxyType response; - int32_t status = FireboltSDK::Properties::Get(method, response); + Firebolt::Error status = FireboltSDK::Properties::Get(method, response); - EXPECT_EQ(status, FireboltSDKErrorNone); - if (status == FireboltSDKErrorNone) { + EXPECT_EQ(status, Firebolt::Error::None); + if (status == Firebolt::Error::None) { FIREBOLT_LOG_INFO(Logger::Category::OpenRPC, Logger::Module(), "DeviceId : %s", response->Value().c_str()); } else { FIREBOLT_LOG_ERROR(Logger::Category::OpenRPC, Logger::Module(), "Get %s status = %d\n", method.c_str(), status); @@ -96,14 +95,14 @@ namespace FireboltSDK { return status; } - /*static */ int32_t Tests::GetDeviceVersion() + /*static */ Firebolt::Error Tests::GetDeviceVersion() { const string method = _T("device.version"); WPEFramework::Core::ProxyType response; - int32_t status = FireboltSDK::Properties::Get(method, response); + Firebolt::Error status = FireboltSDK::Properties::Get(method, response); - EXPECT_EQ(status, FireboltSDKErrorNone); - if (status == FireboltSDKErrorNone) { + EXPECT_EQ(status, Firebolt::Error::None); + if (status == Firebolt::Error::None) { FIREBOLT_LOG_INFO(Logger::Category::OpenRPC, Logger::Module(), "DeviceVersion"); PrintJsonObject(response->Variants()); } else { @@ -113,43 +112,43 @@ namespace FireboltSDK { return status; } - /* static */ int32_t Tests::GetUnKnownMethod() + /* static */ Firebolt::Error Tests::GetUnKnownMethod() { const string method = _T("get.unknownMethod"); WPEFramework::Core::ProxyType response; - int32_t status = FireboltSDK::Properties::Get(method, response); + Firebolt::Error status = FireboltSDK::Properties::Get(method, response); - EXPECT_NE(status, FireboltSDKErrorNone); - if (status != FireboltSDKErrorNone) { + EXPECT_NE(status, Firebolt::Error::None); + if (status != Firebolt::Error::None) { FIREBOLT_LOG_ERROR(Logger::Category::OpenRPC, Logger::Module(), "Get %s status = %d\n", method.c_str(), status); } return status; } - /* static */ int32_t Tests::SetLifeCycleClose() + /* static */ Firebolt::Error Tests::SetLifeCycleClose() { const string method = _T("lifecycle.close"); JsonObject parameters; parameters["reason"] = "remoteButton"; - int32_t status = FireboltSDK::Properties::Set(method, parameters); + Firebolt::Error status = FireboltSDK::Properties::Set(method, parameters); - EXPECT_EQ(status, FireboltSDKErrorNone); - if (status != FireboltSDKErrorNone) { + EXPECT_EQ(status, Firebolt::Error::None); + if (status != Firebolt::Error::None) { FIREBOLT_LOG_ERROR(Logger::Category::OpenRPC, Logger::Module(), "Set %s status = %d\n", method.c_str(), status); } return status; } - /* static */ int32_t Tests::SetUnKnownMethod() + /* static */ Firebolt::Error Tests::SetUnKnownMethod() { const string method = _T("set.unknownMethod"); JsonObject parameters; - int32_t status = FireboltSDK::Properties::Set(method, parameters); + Firebolt::Error status = FireboltSDK::Properties::Set(method, parameters); - EXPECT_NE(status, FireboltSDKErrorNone); - if (status != FireboltSDKErrorNone) { + EXPECT_NE(status, Firebolt::Error::None); + if (status != Firebolt::Error::None) { FIREBOLT_LOG_ERROR(Logger::Category::OpenRPC, Logger::Module(), "Set %s status = %d", method.c_str(), status); } @@ -167,7 +166,7 @@ namespace FireboltSDK { jsonResponse.Release(); } - /* static */ int32_t Tests::SubscribeEvent() + /* static */ Firebolt::Error Tests::SubscribeEvent() { FireboltSDK::Tests::EventControl* eventControl = new FireboltSDK::Tests::EventControl("EventControl"); const string eventName = _T("device.Name"); @@ -176,10 +175,10 @@ namespace FireboltSDK { eventControl->ResetEvent(); JsonObject jsonParameters; - int32_t status = Properties::Subscribe(eventName, jsonParameters, deviceNameChangeCallback,reinterpret_cast(NotifyEvent), userdata); + Firebolt::Error status = Properties::Subscribe(eventName, jsonParameters, deviceNameChangeCallback,reinterpret_cast(NotifyEvent), userdata); - EXPECT_EQ(status, FireboltSDKErrorNone); - if (status != FireboltSDKErrorNone) { + EXPECT_EQ(status, Firebolt::Error::None); + if (status != Firebolt::Error::None) { FIREBOLT_LOG_ERROR(Logger::Category::OpenRPC, Logger::Module(), "Set %s status = %d", eventName.c_str(), status); } else { @@ -189,13 +188,13 @@ namespace FireboltSDK { eventControl->WaitForEvent(WPEFramework::Core::infinite); } - EXPECT_EQ(Properties::Unsubscribe(eventName, reinterpret_cast(NotifyEvent)), FireboltSDKErrorNone); + EXPECT_EQ(Properties::Unsubscribe(eventName, reinterpret_cast(NotifyEvent)), Firebolt::Error::None); delete eventControl; return status; } - /* static */ int32_t Tests::SubscribeEventwithSameCallback() + /* static */ Firebolt::Error Tests::SubscribeEventwithSameCallback() { FireboltSDK::Tests::EventControl* eventControl = new FireboltSDK::Tests::EventControl("EventControl"); const string eventName = _T("device.Name"); @@ -204,10 +203,10 @@ namespace FireboltSDK { eventControl->ResetEvent(); JsonObject jsonParameters; - int32_t status = Properties::Subscribe(eventName, jsonParameters, deviceNameChangeCallback,reinterpret_cast(NotifyEvent), userdata); + Firebolt::Error status = Properties::Subscribe(eventName, jsonParameters, deviceNameChangeCallback,reinterpret_cast(NotifyEvent), userdata); - EXPECT_EQ(status, FireboltSDKErrorNone); - if (status != FireboltSDKErrorNone) { + EXPECT_EQ(status, Firebolt::Error::None); + if (status != Firebolt::Error::None) { FIREBOLT_LOG_ERROR(Logger::Category::OpenRPC, Logger::Module(), "Set %s status = %d", eventName.c_str(), status); } else { @@ -215,15 +214,15 @@ namespace FireboltSDK { "%s Yes registered successfully", __func__); status = Properties::Subscribe(eventName, jsonParameters, deviceNameChangeCallback, reinterpret_cast(NotifyEvent), userdata); - EXPECT_EQ(status, FireboltSDKErrorInUse); - if (status == FireboltSDKErrorInUse) { + EXPECT_EQ(status, Firebolt::Error::General); + if (status == Firebolt::Error::General) { FIREBOLT_LOG_INFO(Logger::Category::OpenRPC, Logger::Module(), "%s Yes this device.name event is already registered with same callback", __func__); } - status = ((status == FireboltSDKErrorInUse) ? FireboltSDKErrorNone : status); + status = ((status == Firebolt::Error::General) ? Firebolt::Error::None : status); } - EXPECT_EQ(Properties::Unsubscribe(eventName, reinterpret_cast(NotifyEvent)), FireboltSDKErrorNone); + EXPECT_EQ(Properties::Unsubscribe(eventName, reinterpret_cast(NotifyEvent)), Firebolt::Error::None); delete eventControl; return status; @@ -250,7 +249,7 @@ namespace FireboltSDK { } template - /* static */ int32_t Tests::SubscribeEventForC(const string& eventName, JsonObject& jsonParameters, CALLBACK& callbackFunc, void* usercb, const void* userdata) + /* static */ Firebolt::Error Tests::SubscribeEventForC(const string& eventName, JsonObject& jsonParameters, CALLBACK& callbackFunc, void* usercb, const void* userdata) { return Properties::Subscribe(eventName, jsonParameters, callbackFunc, usercb, userdata); } @@ -268,7 +267,7 @@ namespace FireboltSDK { jsonResponse.Release(); } - /* static */ int32_t Tests::SubscribeEventWithMultipleCallback() + /* static */ Firebolt::Error Tests::SubscribeEventWithMultipleCallback() { FireboltSDK::Tests::EventControl* eventControl1 = new FireboltSDK::Tests::EventControl("EventControl1"); const string eventName = _T("device.Name"); @@ -277,10 +276,10 @@ namespace FireboltSDK { eventControl1->ResetEvent(); JsonObject jsonParameters; - int32_t status = Properties::Subscribe(eventName, jsonParameters, deviceNameChangeMultipleCallback, reinterpret_cast(NotifyEvent1), userdata); + Firebolt::Error status = Properties::Subscribe(eventName, jsonParameters, deviceNameChangeMultipleCallback, reinterpret_cast(NotifyEvent1), userdata); - EXPECT_EQ(status, FireboltSDKErrorNone); - if (status != FireboltSDKErrorNone) { + EXPECT_EQ(status, Firebolt::Error::None); + if (status != Firebolt::Error::None) { FIREBOLT_LOG_ERROR(Logger::Category::OpenRPC, Logger::Module(), "Set %s status = %d", eventName.c_str(), status); } else { @@ -288,19 +287,19 @@ namespace FireboltSDK { "%s Yes registered successfully, Waiting for event...", __func__); } - if (status == FireboltSDKErrorNone) { + if (status == Firebolt::Error::None) { FireboltSDK::Tests::EventControl* eventControl2 = new FireboltSDK::Tests::EventControl("EventControl2"); userdata = static_cast(eventControl2); status = Properties::Subscribe(eventName, jsonParameters, deviceNameChangeMultipleCallback, reinterpret_cast(NotifyEvent2), userdata); - EXPECT_EQ(status, FireboltSDKErrorNone); - if (status != FireboltSDKErrorNone) { + EXPECT_EQ(status, Firebolt::Error::None); + if (status != Firebolt::Error::None) { FIREBOLT_LOG_ERROR(Logger::Category::OpenRPC, Logger::Module(), "Set %s status = %d", eventName.c_str(), status); } else { status = Properties::Subscribe(eventName, jsonParameters, deviceNameChangeMultipleCallback, reinterpret_cast(NotifyEvent2), userdata); - EXPECT_EQ(status, FireboltSDKErrorInUse); - status = ((status == FireboltSDKErrorInUse) ? FireboltSDKErrorNone : status); + EXPECT_EQ(status, Firebolt::Error::General); + status = ((status == Firebolt::Error::General) ? Firebolt::Error::None : status); FIREBOLT_LOG_INFO(Logger::Category::OpenRPC, Logger::Module(), "%s Yes registered second callback also successfully, waiting for events...\n", __func__); @@ -308,197 +307,13 @@ namespace FireboltSDK { eventControl1->WaitForEvent(WPEFramework::Core::infinite); eventControl2->WaitForEvent(WPEFramework::Core::infinite); } - EXPECT_EQ(Properties::Unsubscribe(eventName, reinterpret_cast(NotifyEvent2)), FireboltSDKErrorNone); + EXPECT_EQ(Properties::Unsubscribe(eventName, reinterpret_cast(NotifyEvent2)), Firebolt::Error::None); delete eventControl2; } - EXPECT_EQ(Properties::Unsubscribe(eventName, reinterpret_cast(NotifyEvent1)), FireboltSDKErrorNone); + EXPECT_EQ(Properties::Unsubscribe(eventName, reinterpret_cast(NotifyEvent1)), Firebolt::Error::None); delete eventControl1; return status; } } - -#ifdef __cplusplus -extern "C" { -#endif - -void test_firebolt_create_instance() -{ - const std::string config = _T("{\ - \"waitTime\": 1000,\ - \"logLevel\": \"Info\",\ - \"workerPool\":{\ - \"queueSize\": 8,\ - \"threadCount\": 3\ - },\ - \"wsUrl\": \"ws://127.0.0.1:9998\"\ -}"); - FireboltSDK::Accessor::Instance(config); -} - -void test_firebolt_dispose_instance() -{ - FireboltSDK::Accessor::Dispose(); -} - -int32_t test_firebolt_main() -{ - return FireboltSDK::Tests::Main(); -} - -int32_t test_properties_get_device_id() -{ - const string method = _T("device.id"); - WPEFramework::Core::ProxyType response; - int32_t status = FireboltSDK::Properties::Get(method, response); - - EXPECT_EQ(status, FireboltSDKErrorNone); - if (status == FireboltSDKErrorNone) { - FIREBOLT_LOG_INFO(FireboltSDK::Logger::Category::OpenRPC, "ctest", - "DeviceId : %s", response->Value().c_str()); - } else { - FIREBOLT_LOG_ERROR(FireboltSDK::Logger::Category::OpenRPC, "ctest", - "Get %s status = %d", method.c_str(), status); - } - - return status; -} - -int32_t test_properties_set() -{ - const string method = _T("lifecycle.close"); - JsonObject parameters; - parameters["reason"] = "remoteButton"; - int32_t status = FireboltSDK::Properties::Set(method, parameters); - - EXPECT_EQ(status, FireboltSDKErrorNone); - if (status != FireboltSDKErrorNone) { - FIREBOLT_LOG_ERROR(FireboltSDK::Logger::Category::OpenRPC, "ctest", - "Set %s status = %d", method.c_str(), status); - } - - return status; -} - -static void deviceNameChangeCallbackForC(void* userCB, const void* userData, void* response) -{ - WPEFramework::Core::ProxyType& jsonResponse = *(reinterpret_cast*>(response)); - FIREBOLT_LOG_INFO(FireboltSDK::Logger::Category::OpenRPC, "ctest", - "Received a new event--->: %s", jsonResponse->Value().c_str()); - - FireboltSDK::Tests::EventControl* eventControl = reinterpret_cast(const_cast(userData)); - eventControl->NotifyEvent(); - jsonResponse.Release(); -} - -int32_t test_eventregister() -{ - FireboltSDK::Tests::EventControl* eventControl = new FireboltSDK::Tests::EventControl(); - const string eventName = _T("device.Name"); - const void* userdata = static_cast(eventControl); - - eventControl->ResetEvent(); - - JsonObject jsonParameters; - int32_t status = FireboltSDK::Properties::Subscribe(eventName, jsonParameters, deviceNameChangeCallbackForC, reinterpret_cast(NotifyEvent), userdata); - - EXPECT_EQ(status, FireboltSDKErrorNone); - if (status != FireboltSDKErrorNone) { - FIREBOLT_LOG_ERROR(FireboltSDK::Logger::Category::OpenRPC, "ctest", - "%s Set %s status = %d", __func__, eventName.c_str(), status); - } else { - FIREBOLT_LOG_INFO(FireboltSDK::Logger::Category::OpenRPC, "ctest", - "%s Yes registered successfully, Waiting for event...", __func__); - eventControl->WaitForEvent(WPEFramework::Core::infinite); - } - - delete eventControl; - EXPECT_EQ(FireboltSDK::Properties::Unsubscribe(eventName, reinterpret_cast(NotifyEvent)), FireboltSDKErrorNone); - - return status; -} - -int32_t test_eventregister_with_same_callback() -{ - FireboltSDK::Tests::EventControl* eventControl = new FireboltSDK::Tests::EventControl(); - const string eventName = _T("device.Name"); - const void* userdata = static_cast(eventControl); - - eventControl->ResetEvent(); - - JsonObject jsonParameters; - int32_t status = FireboltSDK::Properties::Subscribe(eventName, jsonParameters, deviceNameChangeCallbackForC, reinterpret_cast(NotifyEvent), userdata); - - EXPECT_EQ(status, FireboltSDKErrorNone); - if (status != FireboltSDKErrorNone) { - FIREBOLT_LOG_ERROR(FireboltSDK::Logger::Category::OpenRPC, "ctest", - "%s Set %s status = %d", __func__, eventName.c_str(), status); - } else { - FIREBOLT_LOG_INFO(FireboltSDK::Logger::Category::OpenRPC, "ctest", - "%s Yes registered successfully", __func__); - - status = FireboltSDK::Properties::Subscribe(eventName, jsonParameters, deviceNameChangeCallbackForC, reinterpret_cast(NotifyEvent), userdata); - EXPECT_EQ(status, FireboltSDKErrorInUse); - if (status == FireboltSDKErrorInUse) { - FIREBOLT_LOG_INFO(FireboltSDK::Logger::Category::OpenRPC, "ctest", - "%s Yes this device.name event is already registered with same callback", __func__); - } - status = ((status == FireboltSDKErrorInUse) ? FireboltSDKErrorNone : status); - } - - delete eventControl; - EXPECT_EQ(FireboltSDK::Properties::Unsubscribe(eventName, reinterpret_cast(NotifyEvent)), FireboltSDKErrorNone); - - return status; -} -int32_t test_eventregister_by_providing_callback() -{ - FireboltSDK::Tests::EventControl* eventControl = new FireboltSDK::Tests::EventControl(); - - const string eventName = _T("device.Name"); - const void* userdata = static_cast(eventControl); - - eventControl->ResetEvent(); - - JsonObject jsonParameters; - int32_t status = FireboltSDK::Tests::SubscribeEventForC(eventName, jsonParameters, deviceNameChangeCallbackForC, reinterpret_cast(NotifyEvent), userdata); - - EXPECT_EQ(status, FireboltSDKErrorNone); - if (status != FireboltSDKErrorNone) { - FIREBOLT_LOG_ERROR(FireboltSDK::Logger::Category::OpenRPC, "ctest", - "%s Set %s status = %d", __func__, eventName.c_str(), status); - } else { - FIREBOLT_LOG_INFO(FireboltSDK::Logger::Category::OpenRPC, "ctest", - "%s Yes registered successfully, Waiting for event...", __func__); - eventControl->WaitForEvent(WPEFramework::Core::infinite); - } - - delete eventControl; - EXPECT_EQ(FireboltSDK::Properties::Unsubscribe(eventName, reinterpret_cast(NotifyEvent)), FireboltSDKErrorNone); - return status; -} - -#include "TypesPriv.h" -int32_t test_string_set_get_value() -{ - int32_t status = FireboltSDKErrorNone; - FireboltSDK::JSON::String* str = new FireboltSDK::JSON::String(); - WPEFramework::Core::JSON::String wpeJsonStr("TestString"); - Firebolt_String_t handle = reinterpret_cast(str); - - const char* value = Firebolt_String(handle); - EXPECT_EQ(strncmp(value, str->Value().c_str(), str->Value().length()), 0); - FIREBOLT_LOG_INFO(FireboltSDK::Logger::Category::OpenRPC, "ctest", - " ---> type name = %s %s", str->Value().c_str(), value); - - WPEFramework::Core::JSON::EnumType<::TestEnum> testEnum = Test4; - FIREBOLT_LOG_INFO(FireboltSDK::Logger::Category::OpenRPC, "ctest", - " EnumTest = %d %s", testEnum.Value(), testEnum.Data()); - Firebolt_String_Release(handle); - return status; -} - -#ifdef __cplusplus -} -#endif diff --git a/languages/cpp/src/shared/test/OpenRPCTests.h b/languages/cpp/src/shared/test/OpenRPCTests.h index 8eb7fd30..9c84bcf4 100644 --- a/languages/cpp/src/shared/test/OpenRPCTests.h +++ b/languages/cpp/src/shared/test/OpenRPCTests.h @@ -29,7 +29,7 @@ typedef enum { } TestEnum; namespace FireboltSDK { - typedef int32_t (*Func)(); + typedef Firebolt::Error (*Func)(); class Tests { public: @@ -94,19 +94,19 @@ namespace FireboltSDK { return 0; } - static int32_t GetDeviceId(); - static int32_t GetDeviceVersion(); - static int32_t GetUnKnownMethod(); + static Firebolt::Error GetDeviceId(); + static Firebolt::Error GetDeviceVersion(); + static Firebolt::Error GetUnKnownMethod(); - static int32_t SetLifeCycleClose(); - static int32_t SetUnKnownMethod(); + static Firebolt::Error SetLifeCycleClose(); + static Firebolt::Error SetUnKnownMethod(); - static int32_t SubscribeEvent(); - static int32_t SubscribeEventwithSameCallback(); - static int32_t SubscribeEventWithMultipleCallback(); + static Firebolt::Error SubscribeEvent(); + static Firebolt::Error SubscribeEventwithSameCallback(); + static Firebolt::Error SubscribeEventWithMultipleCallback(); template - static int32_t SubscribeEventForC(const string& eventName, JsonObject& jsonParameters, CALLBACK& callbackFunc, void* usercb, const void* userdata); + static Firebolt::Error SubscribeEventForC(const string& eventName, JsonObject& jsonParameters, CALLBACK& callbackFunc, void* usercb, const void* userdata); protected: static void PrintJsonObject(const JsonObject::Iterator& iterator); diff --git a/languages/cpp/templates/codeblocks/setter.c b/languages/cpp/templates/codeblocks/setter.c index c66068bc..ffe24fc6 100644 --- a/languages/cpp/templates/codeblocks/setter.c +++ b/languages/cpp/templates/codeblocks/setter.c @@ -1,7 +1,16 @@ -/* ${method.rpc.name} - ${method.description} */ -int32_t ${method.Name}( ${method.signature.params} ) -{ - const string method = _T("${info.title.lowercase}.${method.rpc.name}"); + + /* ${method.rpc.name} - ${method.description} */ + void ${method.Name}( ${method.signature.params}${if.params}, ${end.if.params}Firebolt::Error *err = nullptr ) + { + const string method = _T("${info.title.lowercase}.${method.rpc.name}"); + + JsonObject jsonParameters; ${if.params}${method.params.serialization}${end.if.params} - return FireboltSDK::Properties::Set(method, jsonParameters); -} + + Firebolt::Error status = FireboltSDK::Properties::Set(method, jsonParameters); + if (err != nullptr) { + *err = status; + } + + return; + } \ No newline at end of file diff --git a/languages/cpp/templates/declarations/default.c b/languages/cpp/templates/declarations/default.c index 2c19a1ef..e69de29b 100644 --- a/languages/cpp/templates/declarations/default.c +++ b/languages/cpp/templates/declarations/default.c @@ -1,6 +0,0 @@ - /* - ${method.name} - ${method.description} - ${method.params.annotations}${if.deprecated} * @deprecated ${method.deprecation}${end.if.deprecated} - */ - virtual int32_t ${method.Name}( ${method.signature.params}${if.result}${if.params}, ${end.if.params}${method.result.type}& ${method.result.name}${end.if.result} ) = 0; \ No newline at end of file diff --git a/languages/cpp/templates/declarations/event.c b/languages/cpp/templates/declarations/event.c index d2df4f12..8939efc8 100644 --- a/languages/cpp/templates/declarations/event.c +++ b/languages/cpp/templates/declarations/event.c @@ -1,8 +1,8 @@ /* ${method.name} - ${method.description} */ struct I${method.Name}Notification { - virtual void ${method.Name} ( ${event.signature.callback.params}${if.event.params}, ${end.if.event.params}${method.result.properties} ) = 0; + virtual void ${method.Name}( ${event.signature.callback.params}${if.event.params}, ${end.if.event.params}${event.result.type} ) = 0; }; // signature callback params: ${event.signature.callback.params} // method result properties : ${method.result.properties} - virtual int32_t subscribe ( ${event.signature.params}${if.event.params}, ${end.if.event.params}I${method.Name}Notification& notification ) = 0; - virtual int32_t unsubscribe ( I${method.Name}Notification& notification ) = 0; \ No newline at end of file + 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; diff --git a/languages/cpp/templates/declarations/polymorphic-pull-event.c b/languages/cpp/templates/declarations/polymorphic-pull-event.c index 178678ad..e69de29b 100644 --- a/languages/cpp/templates/declarations/polymorphic-pull-event.c +++ b/languages/cpp/templates/declarations/polymorphic-pull-event.c @@ -1,8 +0,0 @@ - /* ${method.name} - ${method.description} */ - struct I{method.Name}Notification { - virtual void ${method.Name} ( ${method.pulls.param.type}& value ) = 0; - }; - - virtual int32_t subscribe ( I{method.Name}Notification& notification ) = 0; - virtual int32_t unsubscribe ( I{method.Name}Notification& notification ) = 0; - diff --git a/languages/cpp/templates/declarations/polymorphic-pull.c b/languages/cpp/templates/declarations/polymorphic-pull.c index 6588a635..e69de29b 100644 --- a/languages/cpp/templates/declarations/polymorphic-pull.c +++ b/languages/cpp/templates/declarations/polymorphic-pull.c @@ -1,2 +0,0 @@ - /* ${method.name} - ${method.description} */ - virtual int32_t ${method.Name}( ${method.signature.params} ) = 0; diff --git a/languages/cpp/templates/declarations/polymorphic-reducer.c b/languages/cpp/templates/declarations/polymorphic-reducer.c index a6f50d1b..e69de29b 100644 --- a/languages/cpp/templates/declarations/polymorphic-reducer.c +++ b/languages/cpp/templates/declarations/polymorphic-reducer.c @@ -1,5 +0,0 @@ - /* - * ${method.summary} - * ${method.params} - */ - virtual int32_t ${method.Name}(${method.signature.params}${if.result.properties}${if.params}, ${end.if.params}${end.if.result.properties}${method.result.properties}) = 0; diff --git a/languages/cpp/templates/declarations/property.h b/languages/cpp/templates/declarations/property.h index 09cc5d7d..6d8890e4 100644 --- a/languages/cpp/templates/declarations/property.h +++ b/languages/cpp/templates/declarations/property.h @@ -1,5 +1,5 @@ /* - * ${method.description} - * ${method.params} - */ -virtual int32_t ${method.Name} (${method.signature.params}${if.params}, ${end.if.params}${method.result.properties}) = 0; + * ${method.description} + * ${method.params} + */ + virtual ${method.signature.result} ${method.Name}( ${method.signature.params}${if.params}, ${end.if.params}Firebolt::Error *err = nullptr ) const = 0; diff --git a/languages/cpp/templates/declarations/setter.h b/languages/cpp/templates/declarations/setter.h index 64e4d19e..b1035bc4 100644 --- a/languages/cpp/templates/declarations/setter.h +++ b/languages/cpp/templates/declarations/setter.h @@ -1,5 +1,5 @@ /* - ${method.rpc.name} - ${method.description} - */ - virtual int32_t ${method.Name}( ${method.signature.params} ) = 0; + ${method.rpc.name} + ${method.description} + */ + virtual void ${method.Name}( ${method.signature.params}${if.params}, ${end.if.params}Firebolt::Error *err = nullptr ) = 0; diff --git a/languages/cpp/templates/json-types/anyOf.c b/languages/cpp/templates/json-types/anyOf.c deleted file mode 100644 index a2682179..00000000 --- a/languages/cpp/templates/json-types/anyOf.c +++ /dev/null @@ -1 +0,0 @@ -/* AnyOf is not supported in C: ${title} */ \ No newline at end of file diff --git a/languages/cpp/templates/json-types/anyOf.h b/languages/cpp/templates/json-types/anyOf.h new file mode 100644 index 00000000..fc121f63 --- /dev/null +++ b/languages/cpp/templates/json-types/anyOf.h @@ -0,0 +1 @@ +WPEFramework::Core::JSON::VariantContainer \ No newline at end of file diff --git a/languages/cpp/templates/json-types/anyOfSchemaShape.h b/languages/cpp/templates/json-types/anyOfSchemaShape.h new file mode 100644 index 00000000..9a53ff94 --- /dev/null +++ b/languages/cpp/templates/json-types/anyOfSchemaShape.h @@ -0,0 +1 @@ + /* anyOf schema shape is supported right now */ diff --git a/languages/cpp/templates/methods/calls-metrics.c b/languages/cpp/templates/methods/calls-metrics.c index d38c499f..8b137891 100644 --- a/languages/cpp/templates/methods/calls-metrics.c +++ b/languages/cpp/templates/methods/calls-metrics.c @@ -1,29 +1 @@ -/* ${method.rpc.name} - ${method.description} */ -void Metrics_${method.Name}Dispatcher(const void*${if.result} result${end.if.result}) { - Metrics_${method.Name}(${if.result}(static_cast<${method.result.json.type}>(const_cast(result)))${end.if.result}); -} -int32_t ${info.Title}_${method.Name}( ${method.signature.params}${if.result}${if.params}, ${end.if.params}OUT ${method.result.type}* ${method.result.name}${end.if.result}${if.signature.empty}void${end.if.signature.empty} ) { - int32_t status = FireboltSDKErrorUnavailable; - FireboltSDK::Transport* transport = FireboltSDK::Accessor::Instance().GetTransport(); - if (transport != nullptr) { - - ${method.params.serialization.with.indent} - ${method.result.json.type} jsonResult; - status = transport->Invoke("${info.title}.${method.rpc.name}", jsonParameters, jsonResult); - if (status == FireboltSDKErrorNone) { - FIREBOLT_LOG_INFO(FireboltSDK::Logger::Category::OpenRPC, FireboltSDK::Logger::Module(), "${info.Title}.${method.rpc.name} is successfully invoked"); - ${method.result.instantiation.with.indent} - - void* result = nullptr; - ${if.result}result = static_cast(new ${method.result.json.type});${end.if.result} - WPEFramework::Core::ProxyType job = WPEFramework::Core::ProxyType(WPEFramework::Core::ProxyType::Create(Metrics_${method.Name}Dispatcher, result)); - WPEFramework::Core::IWorkerPool::Instance().Submit(job); - } - - } else { - FIREBOLT_LOG_ERROR(FireboltSDK::Logger::Category::OpenRPC, FireboltSDK::Logger::Module(), "Error in getting Transport err = %d", status); - } - - return status; -} diff --git a/languages/cpp/templates/methods/default.c b/languages/cpp/templates/methods/default.c index c375d30f..e69de29b 100644 --- a/languages/cpp/templates/methods/default.c +++ b/languages/cpp/templates/methods/default.c @@ -1,21 +0,0 @@ -/* ${method.rpc.name} - ${method.description} */ -int32_t ${info.Title}_${method.Name}( ${method.signature.params}${if.result}${if.params}, ${end.if.params} ${method.result.type}* ${method.result.name}${end.if.result}${if.signature.empty}void${end.if.signature.empty} ) { - - int32_t status = FireboltSDKErrorUnavailable; - FireboltSDK::Transport* transport = FireboltSDK::Accessor::Instance().GetTransport(); - if (transport != nullptr) { - - ${method.params.serialization.with.indent} - ${method.result.json.type} jsonResult; - status = transport->Invoke("${info.title.lowercase}.${method.rpc.name}", jsonParameters, jsonResult); - if (status == FireboltSDKErrorNone) { - FIREBOLT_LOG_INFO(FireboltSDK::Logger::Category::OpenRPC, FireboltSDK::Logger::Module(), "${info.Title}.${method.rpc.name} is successfully invoked"); - ${method.result.instantiation.with.indent} - } - - } else { - FIREBOLT_LOG_ERROR(FireboltSDK::Logger::Category::OpenRPC, FireboltSDK::Logger::Module(), "Error in getting Transport err = %d", status); - } - - return status; -} diff --git a/languages/cpp/templates/methods/event.c b/languages/cpp/templates/methods/event.c index 85ae3b48..8745c653 100644 --- a/languages/cpp/templates/methods/event.c +++ b/languages/cpp/templates/methods/event.c @@ -1,27 +1,33 @@ -/* ${method.rpc.name} - ${method.description} */ -static void ${info.Title}${method.Name}InnerCallback( void* userCB, const void* userData, void* response ) -{ + /* ${method.rpc.name} - ${method.description} */ + static void ${info.Title}${method.Name}InnerCallback( void* notification, const void* userData, void* jsonResponse ) + { ${event.callback.params.serialization} - ASSERT(jsonResponse->IsValid() == true); - if (jsonResponse->IsValid() == true) { + ASSERT(proxyResponse->IsValid() == true); + + if (proxyResponse->IsValid() == true) { ${event.callback.result.instantiation} - ${info.Title}${method.Name}Callback callback = reinterpret_cast<${info.Title}${method.Name}Callback>(userCB); - callback(userData, ${event.callback.response.instantiation}); - } -} -int32_t ${info.Title}_Register_${method.Name}( ${event.signature.params}${if.event.params}, ${end.if.event.params}${info.Title}${method.Name}Callback userCB, const void* userData ) -{ - const string eventName = _T("${info.title.lowercase}.${method.rpc.name}"); - int32_t status = FireboltSDKErrorNone; + proxyResponse->Release(); - if (userCB != nullptr) { - ${event.params.serialization} - status = FireboltSDK::Event::Instance().Subscribe<${event.result.json.type}>(eventName, jsonParameters, ${info.Title}${method.Name}InnerCallback, reinterpret_cast(userCB), userData); - } - return status; -} -int32_t ${info.Title}_Unregister_${method.Name}( ${info.Title}${method.Name}Callback userCB) -{ - return FireboltSDK::Event::Instance().Unsubscribe(_T("${info.title.lowercase}.${method.rpc.name}"), reinterpret_cast(userCB)); -} + I${method.Name}Notification& notifier = *(reinterpret_cast(notification)); + notifier.${method.Name}(${event.callback.response.instantiation}); + } + } + void Subscribe( ${event.signature.params}${if.event.params}, ${end.if.event.params}I${method.Name}Notification& notification, Firebolt::Error *err = nullptr ) + { + const string eventName = _T("${info.title.lowercase}.${method.rpc.name}"); + Firebolt::Error status = Firebolt::Error::None; + JsonObject jsonParameters; +${event.params.serialization} + status = FireboltSDK::Event::Instance().Subscribe<${event.result.json.type}>(eventName, jsonParameters, ${info.Title}${method.Name}InnerCallback, reinterpret_cast(¬ification), nullptr); + if (err != nullptr) { + *err = status; + } + } + void Unsubscribe( I${method.Name}Notification& notification, Firebolt::Error *err = nullptr ) + { + Firebolt::Error status = FireboltSDK::Event::Instance().Unsubscribe(_T("${info.title.lowercase}.${method.rpc.name}"), reinterpret_cast(¬ification)); + if (err != nullptr) { + *err = status; + } + } \ No newline at end of file diff --git a/languages/cpp/templates/methods/polymorphic-pull-event.c b/languages/cpp/templates/methods/polymorphic-pull-event.c index 49aa1dba..e69de29b 100644 --- a/languages/cpp/templates/methods/polymorphic-pull-event.c +++ b/languages/cpp/templates/methods/polymorphic-pull-event.c @@ -1,54 +0,0 @@ -/* ${method.rpc.name} - ${method.description} */ -static void ${info.Title}${method.Name}InnerCallback( void* userCB, const void* userData, void* response ) -{ -${event.callback.params.serialization} - ASSERT(jsonResponse->IsValid() == true); - if (jsonResponse->IsValid() == true) { - - ${info.Title}${method.Name}Callback callback = reinterpret_cast<${info.Title}${method.Name}Callback>(userCB); - - WPEFramework::Core::ProxyType<${method.pulls.param.json.type}>* requestParam = new WPEFramework::Core::ProxyType<${method.pulls.param.json.type}>(); - *requestParam = WPEFramework::Core::ProxyType<${method.pulls.param.json.type}>::Create(); - *(*requestParam) = (*jsonResponse)->${event.pulls.param.name}Parameters; - - ${method.pulls.type} result = reinterpret_cast<${method.pulls.type}>(callback(userData, reinterpret_cast<${method.pulls.param.type}>(requestParam))); - - JsonObject jsonParameters; - WPEFramework::Core::JSON::Variant CorrelationId = (*jsonResponse)->CorrelationId.Value(); - jsonParameters.Set(_T("correlationId"), CorrelationId); - - ${method.pulls.json.type}& resultObj = *(*(reinterpret_cast*>(result))); - string resultStr; - resultObj.ToString(resultStr); - WPEFramework::Core::JSON::VariantContainer resultContainer(resultStr); - WPEFramework::Core::JSON::Variant Result = resultContainer; - jsonParameters.Set(_T("result"), Result); - - FireboltSDK::Transport* transport = FireboltSDK::Accessor::Instance().GetTransport(); - if (transport != nullptr) { - WPEFramework::Core::JSON::Boolean jsonResult; - int32_t status = transport->Invoke(_T("${info.title.lowercase}.${method.pulls.for}"), jsonParameters, jsonResult); - if (status == FireboltSDKErrorNone) { - FIREBOLT_LOG_INFO(FireboltSDK::Logger::Category::OpenRPC, FireboltSDK::Logger::Module(), "${info.Title}.${method.rpc.name} is successfully pushed with status as %d", jsonResult.Value()); - } - } else { - FIREBOLT_LOG_ERROR(FireboltSDK::Logger::Category::OpenRPC, FireboltSDK::Logger::Module(), "Error in getting Transport"); - } - } -} -int32_t ${info.Title}_Register_${method.Name}( ${info.Title}${method.Name}Callback userCB, const void* userData ) -{ - const string eventName = _T("${info.title.lowercase}.${method.rpc.name}"); - int32_t status = FireboltSDKErrorNone; - - if (userCB != nullptr) { - ${event.params.serialization} - status = FireboltSDK::Event::Instance().Subscribe<${event.result.json.type}>(eventName, jsonParameters, ${info.Title}${method.Name}InnerCallback, reinterpret_cast(userCB), userData); - } - return status; -} -int32_t ${info.Title}_Unregister_${method.Name}( ${info.Title}${method.Name}Callback userCB) -{ - return FireboltSDK::Event::Instance().Unsubscribe(_T("${info.title.lowercase}.${method.rpc.name}"), reinterpret_cast(userCB)); -} - diff --git a/languages/cpp/templates/methods/polymorphic-pull.c b/languages/cpp/templates/methods/polymorphic-pull.c index 840566e2..e69de29b 100644 --- a/languages/cpp/templates/methods/polymorphic-pull.c +++ b/languages/cpp/templates/methods/polymorphic-pull.c @@ -1,22 +0,0 @@ -/* ${method.rpc.name} - ${method.description} */ -int32_t ${info.Title}_Push${method.Name}( ${method.signature.params} ) -{ - int32_t status = FireboltSDKErrorUnavailable; - - FireboltSDK::Transport* transport = FireboltSDK::Accessor::Instance().GetTransport(); - if (transport != nullptr) { - string correlationId = ""; - ${method.params.serialization.with.indent} - - WPEFramework::Core::JSON::Boolean jsonResult; - status = transport->Invoke(_T("${info.title.lowercase}.${method.rpc.name}"), jsonParameters, jsonResult); - if (status == FireboltSDKErrorNone) { - FIREBOLT_LOG_INFO(FireboltSDK::Logger::Category::OpenRPC, FireboltSDK::Logger::Module(), "${info.Title}.${method.rpc.name} is successfully pushed with status as %d", jsonResult.Value()); - status = (jsonResult.Value() == true) ? FireboltSDKErrorNone : FireboltSDKErrorNotSupported; - } - } else { - FIREBOLT_LOG_ERROR(FireboltSDK::Logger::Category::OpenRPC, FireboltSDK::Logger::Module(), "Error in getting Transport"); - } - - return status; -} diff --git a/languages/cpp/templates/methods/property.c b/languages/cpp/templates/methods/property.c index 7f375d81..f3d91141 100644 --- a/languages/cpp/templates/methods/property.c +++ b/languages/cpp/templates/methods/property.c @@ -1,14 +1,17 @@ -/* ${method.rpc.name} - ${method.description} */ -int32_t ${info.Title}_Get${method.Name}( ${method.signature.params}${if.params}, ${end.if.params} ${method.result.type}* ${method.result.name} ) -{ - const string method = _T("${info.title.lowercase}.${method.rpc.name}"); -${if.params}${method.params.serialization}${end.if.params} - ${method.result.json} jsonResult; - ${if.params}int32_t status = FireboltSDK::Properties::Get(method, jsonParameters, jsonResult);${end.if.params} - ${if.params.empty}int32_t status = FireboltSDK::Properties::Get(method, jsonResult);${end.if.params.empty} - if (status == FireboltSDKErrorNone) { + /* ${method.rpc.name} - ${method.description} */ + ${method.signature.result} ${method.Name}( ${method.signature.params}${if.params}, ${end.if.params}Firebolt::Error *err = nullptr ) const + { + const string method = _T("${info.title.lowercase}.${method.rpc.name}"); + ${if.params}${method.params.serialization}${end.if.params} + ${method.result.json} jsonResult; +${method.result.initialization} + ${if.params}Firebolt::Error status = FireboltSDK::Properties::Get(method, jsonParameters, jsonResult);${end.if.params} + ${if.params.empty}Firebolt::Error status = FireboltSDK::Properties::Get(method, jsonResult);${end.if.params.empty} + if (status == Firebolt::Error::None) { ${method.result.instantiation} - } - return status; -} -${method.setter} + } + if (err != nullptr) { + *err = status; + } + return ${method.result.name}; + }${method.setter} \ No newline at end of file diff --git a/languages/cpp/templates/modules/include/module.h b/languages/cpp/templates/modules/include/module.h index 462c9a30..6080265e 100644 --- a/languages/cpp/templates/modules/include/module.h +++ b/languages/cpp/templates/modules/include/module.h @@ -18,24 +18,28 @@ #pragma once -#include +#include "error.h" /* ${IMPORTS} */ ${if.declarations}namespace Firebolt { namespace ${info.Title} { +${if.enums} // Enums - /* ${ENUMS} */ - +/* ${ENUMS} */${end.if.enums} +${if.types} // Types /* ${TYPES} */ - +${end.if.types} struct I${info.Title} { - virtual ~I${info.Title} = default; + static I${info.Title}& Instance(); + static void Dispose(); + + virtual ~I${info.Title}() = default; -// Methods & Events -/* ${DECLARATIONS} */ + // Methods & Events + /* ${DECLARATIONS} */ }; diff --git a/languages/cpp/templates/modules/src/module.cpp b/languages/cpp/templates/modules/src/module.cpp index 8cef2390..ebdbb0b7 100644 --- a/languages/cpp/templates/modules/src/module.cpp +++ b/languages/cpp/templates/modules/src/module.cpp @@ -20,22 +20,70 @@ /* ${IMPORTS} */ #include "${info.title.lowercase}.h" -${if.types}namespace Firebolt { +${if.implementations} +namespace Firebolt { +namespace ${info.Title} { +${if.enums} -/* ${ENUMS:json-types} */ +/* ${ENUMS:json-types} */${end.if.enums} +${if.types} + // Types +/* ${TYPES:json-types} */${end.if.types} -${if.definitions}namespace ${info.Title} { + ${if.definitions}class ${info.Title}Impl : public I${info.Title} { + private: + ${info.Title}Impl() + { + ASSERT(_singleton == nullptr); + _singleton = this; + } -// Types - /* ${TYPES:json-types} */ + public: + ${info.Title}Impl(const ${info.Title}Impl&) = delete; + ${info.Title}Impl& operator=(const ${info.Title}Impl&) = delete; -// Methods -/* ${METHODS} */ + ~${info.Title}Impl() + { + ASSERT(_singleton != nullptr); + _singleton = nullptr; + } -// Events -/* ${EVENTS} */ + static ${info.Title}Impl& Instance() + { + static ${info.Title}Impl* instance = new ${info.Title}Impl(); + ASSERT(instance != nullptr); + return *instance; + } + static void Dispose() + { + if (_singleton != nullptr) { + delete _singleton; + } + } -}${end.if.definitions} -}${end.if.types} \ No newline at end of file + + // Methods + /* ${METHODS} */ + + // Events + /* ${EVENTS} */ + + private: + static ${info.Title}Impl* _singleton; + };${end.if.definitions} + + ${info.Title}Impl* ${info.Title}Impl::_singleton = nullptr; + + /* static */ I${info.Title}& I${info.Title}::Instance() + { + return (${info.Title}Impl::Instance()); + } + /* static */ void I${info.Title}::Dispose() + { + ${info.Title}Impl::Dispose(); + } + +}//namespace ${info.Title} +}${end.if.implementations} diff --git a/languages/cpp/templates/parameter-serialization/generic.cpp b/languages/cpp/templates/parameter-serialization/generic.cpp new file mode 100644 index 00000000..8ccb8295 --- /dev/null +++ b/languages/cpp/templates/parameter-serialization/generic.cpp @@ -0,0 +1,2 @@ + WPEFramework::Core::JSON::Variant ${Property} = ${property}; + jsonParameters.Set(_T("${property}"), ${Property}); \ No newline at end of file diff --git a/languages/cpp/templates/parameters/object.h b/languages/cpp/templates/parameters/nonprimitive.h similarity index 100% rename from languages/cpp/templates/parameters/object.h rename to languages/cpp/templates/parameters/nonprimitive.h diff --git a/languages/cpp/templates/parameters/result-null.h b/languages/cpp/templates/parameters/result-null.h deleted file mode 100644 index e69de29b..00000000 diff --git a/languages/cpp/templates/parameters/result.h b/languages/cpp/templates/parameters/result.h deleted file mode 100644 index 3c96807b..00000000 --- a/languages/cpp/templates/parameters/result.h +++ /dev/null @@ -1 +0,0 @@ -${method.param.type}& ${method.param.name} \ No newline at end of file diff --git a/languages/cpp/templates/result-callback/default.h b/languages/cpp/templates/result-callback/default.h new file mode 100644 index 00000000..d66fdb8a --- /dev/null +++ b/languages/cpp/templates/result-callback/default.h @@ -0,0 +1 @@ +const ${method.result.type} \ No newline at end of file diff --git a/languages/cpp/templates/result-callback/nonprimitive.h b/languages/cpp/templates/result-callback/nonprimitive.h new file mode 100644 index 00000000..84b86816 --- /dev/null +++ b/languages/cpp/templates/result-callback/nonprimitive.h @@ -0,0 +1 @@ +const ${method.result.type}& \ No newline at end of file diff --git a/languages/cpp/templates/result-callback/string.h b/languages/cpp/templates/result-callback/string.h new file mode 100644 index 00000000..84b86816 --- /dev/null +++ b/languages/cpp/templates/result-callback/string.h @@ -0,0 +1 @@ +const ${method.result.type}& \ No newline at end of file diff --git a/languages/cpp/templates/result/default.h b/languages/cpp/templates/result/default.h new file mode 100644 index 00000000..d66fdb8a --- /dev/null +++ b/languages/cpp/templates/result/default.h @@ -0,0 +1 @@ +const ${method.result.type} \ No newline at end of file diff --git a/languages/cpp/templates/schemas/include/common/module.h b/languages/cpp/templates/schemas/include/common/module.h index 5628e5b3..87ba7425 100644 --- a/languages/cpp/templates/schemas/include/common/module.h +++ b/languages/cpp/templates/schemas/include/common/module.h @@ -18,19 +18,18 @@ #pragma once -#include +#include "error.h" /* ${IMPORTS} */ -namespace Firebolt { +${if.declarations}namespace Firebolt { namespace ${info.Title} { - +${if.enums} // Enums -/* ${ENUMS} */ - +/* ${ENUMS} */${end.if.enums} +${if.types} // Types -/* ${TYPES} */ - +/* ${TYPES} */${end.if.types} } //namespace ${info.Title} -} +}${end.if.declarations} diff --git a/languages/cpp/templates/schemas/src/jsondata_module.h b/languages/cpp/templates/schemas/src/jsondata_module.h index 6e220163..916b8698 100644 --- a/languages/cpp/templates/schemas/src/jsondata_module.h +++ b/languages/cpp/templates/schemas/src/jsondata_module.h @@ -23,8 +23,8 @@ ${if.schemas}namespace Firebolt { namespace ${info.Title} { - // Types + // Types /* ${SCHEMAS:json-types} */ - } +} }${end.if.schemas} diff --git a/languages/cpp/templates/schemas/src/module_common.cpp b/languages/cpp/templates/schemas/src/module_common.cpp index 5570982c..87498ab8 100644 --- a/languages/cpp/templates/schemas/src/module_common.cpp +++ b/languages/cpp/templates/schemas/src/module_common.cpp @@ -19,23 +19,11 @@ #include "FireboltSDK.h" /* ${IMPORTS} */ #include "jsondata_${info.title.lowercase}.h" +${if.enums} -namespace Firebolt { +namespace WPEFramework { /* ${ENUMS} */ -namespace ${info.Title} { - - -// Methods -/* ${METHODS} */ - -// Events -/* ${EVENTS} */ - - -} //namespace ${info.Title} - -} - +}${end.if.enums} diff --git a/languages/cpp/templates/sections/methods.h b/languages/cpp/templates/sections/methods.h index 3ab606c0..e8200eb0 100644 --- a/languages/cpp/templates/sections/methods.h +++ b/languages/cpp/templates/sections/methods.h @@ -1,4 +1 @@ - -// Methods - ${method.list} diff --git a/languages/cpp/templates/types/additionalProperties.h b/languages/cpp/templates/types/additionalProperties.h index baa50800..05581106 100644 --- a/languages/cpp/templates/types/additionalProperties.h +++ b/languages/cpp/templates/types/additionalProperties.h @@ -1 +1 @@ -${title} value; \ No newline at end of file +std::unordered_map<${key}, ${type}> ${title}; diff --git a/languages/cpp/templates/types/additionalPropertiesKey.h b/languages/cpp/templates/types/additionalPropertiesKey.h new file mode 100644 index 00000000..9c1a95b6 --- /dev/null +++ b/languages/cpp/templates/types/additionalPropertiesKey.h @@ -0,0 +1 @@ +std::string diff --git a/languages/cpp/templates/types/anyOf.c b/languages/cpp/templates/types/anyOf.c deleted file mode 100644 index bd2ba3e5..00000000 --- a/languages/cpp/templates/types/anyOf.c +++ /dev/null @@ -1 +0,0 @@ -/* AnyOf is not supported in CPP: ${title} */ \ No newline at end of file diff --git a/languages/cpp/templates/types/anyOf.h b/languages/cpp/templates/types/anyOf.h new file mode 100644 index 00000000..c6d1c815 --- /dev/null +++ b/languages/cpp/templates/types/anyOf.h @@ -0,0 +1 @@ +std::string \ No newline at end of file diff --git a/languages/cpp/templates/types/anyOfSchemaShape.h b/languages/cpp/templates/types/anyOfSchemaShape.h new file mode 100644 index 00000000..9a53ff94 --- /dev/null +++ b/languages/cpp/templates/types/anyOfSchemaShape.h @@ -0,0 +1 @@ + /* anyOf schema shape is supported right now */ diff --git a/languages/cpp/templates/types/enum.cpp b/languages/cpp/templates/types/enum.cpp index 9c98f888..e162ef43 100644 --- a/languages/cpp/templates/types/enum.cpp +++ b/languages/cpp/templates/types/enum.cpp @@ -1,4 +1,4 @@ /* ${title} ${description} */ - ENUM_CONVERSION_BEGIN(${info.Title}_${name}) - { ${info.TITLE}_${NAME}_${key}, _T("${value}") }, - ENUM_CONVERSION_END(${info.Title}_${name}) + ENUM_CONVERSION_BEGIN(Firebolt::${info.Title}::${name}) + { Firebolt::${info.Title}::${name}::${key}, _T("${value}") }, + ENUM_CONVERSION_END(Firebolt::${info.Title}::${name}) diff --git a/languages/cpp/templates/types/namespace.h b/languages/cpp/templates/types/namespace.h index 626de353..b3afde8a 100644 --- a/languages/cpp/templates/types/namespace.h +++ b/languages/cpp/templates/types/namespace.h @@ -1 +1 @@ -${parent.Title}:: \ No newline at end of file +${if.namespace.notsame}${parent.Title}::${end.if.namespace.notsame} \ No newline at end of file diff --git a/languages/cpp/templates/types/tuple.h b/languages/cpp/templates/types/tuple.h index ce217a83..b00d2610 100644 --- a/languages/cpp/templates/types/tuple.h +++ b/languages/cpp/templates/types/tuple.h @@ -1,2 +1,2 @@ /* ${title} */ -std::pair<${type},${type}> ${title}; +std::pair<${items}> ${title}; diff --git a/languages/javascript/templates/types/tuple-delimiter.mjs b/languages/javascript/templates/types/tuple-delimiter.mjs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/languages/javascript/templates/types/tuple-delimiter.mjs @@ -0,0 +1 @@ + diff --git a/src/macrofier/engine.mjs b/src/macrofier/engine.mjs index 880357b9..ee01aba5 100644 --- a/src/macrofier/engine.mjs +++ b/src/macrofier/engine.mjs @@ -120,7 +120,7 @@ const getLinkForSchema = (schema, json, { name = '' } = {}) => { const dirs = config.createModuleDirectories const copySchemasIntoModules = config.copySchemasIntoModules - const type = types.getSchemaType(schema, json, { name: name, templateDir: state.typeTemplateDir, destination: state.destination, section: state.section }) + const type = types.getSchemaType(schema, json, { templateDir: state.typeTemplateDir, destination: state.destination, section: state.section }) // local - insert a bogus link, that we'll update later based on final table-of-contents if (json.components.schemas[type]) { @@ -858,7 +858,7 @@ function generateSchemas(json, templates, options) { else { content = content.replace(/.*\$\{schema.seeAlso\}/, '') } -// content = content.trim().length ? content.trimEnd() : content.trim() + content = content.trim().length ? content : content.trim() const isEnum = x => x.type && Array.isArray(x.enum) && x.title && ((x.type === 'string') || (x.type[0] === 'string')) @@ -1221,7 +1221,7 @@ function insertMethodMacros(template, methodObj, json, templates, examples = {}) // todo: what does prefix do in Types.mjs? need to account for it somehow const callbackResultJsonType = event && result.schema ? types.getSchemaType(result.schema, json, { name: result.name, prefix: method.alternative, templateDir: 'json-types' }) : '' - const pullsForParamType = pullsParams ? types.getSchemaType(pullsParams, json, { destination: state.destination, section: state.section }) : '' + const pullsForParamType = pullsParams ? types.getSchemaType(pullsParams, json, { destination: state.destination, section: state.section }) : '' const pullsForJsonType = pullsResult ? types.getSchemaType(pullsResult, json, { name: result.name, templateDir: 'json-types' }) : '' const pullsForParamJsonType = pullsParams ? types.getSchemaType(pullsParams, json, { name: pullsParams.title , templateDir: 'json-types' }) : '' @@ -1259,6 +1259,7 @@ function insertMethodMacros(template, methodObj, json, templates, examples = {}) .replace(/\$\{method\.params\.count}/g, methodObj.params ? methodObj.params.length : 0) .replace(/\$\{if\.params\}(.*?)\$\{end\.if\.params\}/gms, method.params.length ? '$1' : '') .replace(/\$\{if\.result\}(.*?)\$\{end\.if\.result\}/gms, resultType ? '$1' : '') + .replace(/\$\{if\.result.nonvoid\}(.*?)\$\{end\.if\.result.nonvoid\}/gms, resultType && resultType !== 'void' ? '$1' : '') .replace(/\$\{if\.result\.properties\}(.*?)\$\{end\.if\.result\.properties\}/gms, resultParams ? '$1' : '') .replace(/\$\{if\.params\.empty\}(.*?)\$\{end\.if\.params\.empty\}/gms, method.params.length === 0 ? '$1' : '') .replace(/\$\{if\.signature\.empty\}(.*?)\$\{end\.if\.signature\.empty\}/gms, (method.params.length === 0 && resultType === '') ? '$1' : '') @@ -1267,6 +1268,7 @@ function insertMethodMacros(template, methodObj, json, templates, examples = {}) .replace(/\$\{method\.params\.serialization\.with\.indent\}/g, indent(serializedParams, ' ')) // Typed signature stuff .replace(/\$\{method\.signature\.params\}/g, types.getMethodSignatureParams(methodObj, json, { destination: state.destination, section: state.section })) + .replace(/\$\{method\.signature\.result\}/g, types.getMethodSignatureResult(methodObj, json, { destination: state.destination, section: state.section })) .replace(/\$\{method\.context\}/g, method.context.join(', ')) .replace(/\$\{method\.context\.array\}/g, JSON.stringify(method.context)) .replace(/\$\{method\.context\.count}/g, method.context ? method.context.length : 0) @@ -1301,7 +1303,7 @@ function insertMethodMacros(template, methodObj, json, templates, examples = {}) .replace(/\$\{method\.result\.type\}/g, types.getSchemaType(result.schema, json, { name: result.name, templateDir: state.typeTemplateDir, title: true, asPath: false, destination: state.destination, result: true })) //, baseUrl: options.baseUrl .replace(/\$\{method\.result\.json\}/, types.getSchemaType(result.schema, json, { name: result.name, templateDir: 'json-types', destination: state.destination, section: state.section, title: true, code: false, link: false, asPath: false, expandEnums: false, namespace: true })) // todo: what does prefix do? - .replace(/\$\{event\.result\.type\}/, isEventMethod(methodObj) ? types.getSchemaType(result.schema, json, { name: result.name, prefix: method.alternative, templateDir: state.typeTemplateDir, destination: state.destination, event: true, description: methodObj.result.summary, asPath: false }) : '') + .replace(/\$\{event\.result\.type\}/g, isEventMethod(methodObj) ? types.getMethodSignatureResult(event, json, { destination: state.destination, section: state.section, callback: true }) : '') .replace(/\$\{event\.result\.json\.type\}/g, resultJsonType) .replace(/\$\{event\.result\.json\.type\}/g, callbackResultJsonType) .replace(/\$\{event\.pulls\.param\.name\}/g, pullsEventParamName) diff --git a/src/macrofier/types.mjs b/src/macrofier/types.mjs index afb775a7..275da98d 100644 --- a/src/macrofier/types.mjs +++ b/src/macrofier/types.mjs @@ -30,6 +30,8 @@ const primitives = { "string": "string" } +const isVoid = type => (type === 'void') ? true : false +const isPrimitiveType = type => primitives[type] ? true : false const allocatedPrimitiveProxies = {} function setTemplates(t) { @@ -53,17 +55,52 @@ const safeName = value => value.split(':').pop().replace(/[\.\-]/g, '_').replace // TODO: This is what's left of getMethodSignatureParams. We need to figure out / handle C's `FireboltTypes_StringHandle` function getMethodSignatureParams(method, module, { destination, callback }) { - const paramRequired = getTemplate('/parameters/default') const paramOptional = getTemplate('/parameters/optional') return method.params.map(param => { - let type = getSchemaType(param.schema, module, { destination }) + let type = getSchemaType(param.schema, module, { destination, namespace : true }) if (callback && allocatedPrimitiveProxies[type]) { type = allocatedPrimitiveProxies[type] } + + let paramRequired = '' + let jsonType = getJsonType(param.schema, module, { destination }) + if (!isPrimitiveType(jsonType) && getTemplate('/parameters/nonprimitive')) { + paramRequired = getTemplate('/parameters/nonprimitive') + } + else if ((jsonType === 'string') && getTemplate('/parameters/string')) { + paramRequired = getTemplate('/parameters/string') + } + else { + paramRequired = getTemplate('/parameters/default') + } + return (param.required ? paramRequired : paramOptional).replace(/\$\{method\.param\.name\}/g, param.name).replace(/\$\{method\.param\.type\}/g, type) }).join(', ') } +function getMethodSignatureResult(method, module, { destination, callback, overrideRule = false }) { + let type = getSchemaType(method.result.schema, module, { destination, namespace : true }) + let result = '' + + if (callback) { + let jsonType = getJsonType(method.result.schema, module, { destination }) + + if (!isVoid(type) && !isPrimitiveType(jsonType) && getTemplate('/result-callback/nonprimitive')) { + result = getTemplate('/result-callback/nonprimitive') + } + else if ((jsonType === 'string') && getTemplate('/result-callback/string')) { + result = getTemplate('/result-callback/string') + } + else { + result = getTemplate('/result-callback/default') + } + } + else { + result = getTemplate('/result/default') + } + return result.replace(/\$\{method\.result\.type\}/g, type) +} + const getTemplate = (name) => { if (name[0] !== '/') { name = '/' + name @@ -97,6 +134,7 @@ function insertSchemaMacros(content, schema, module, name, parent, property, rec .replace(/\$\{TITLE\}/g, title.toUpperCase()) .replace(/\$\{property\}/g, property) .replace(/\$\{Property\}/g, capitalize(property)) + .replace(/\$\{if\.namespace\.notsame}(.*?)\$\{end\.if\.namespace\.notsame\}/g, (module.info.title !== parent) ? '$1' : '') .replace(/\$\{parent\.title\}/g, parent) .replace(/\$\{parent\.Title\}/g, capitalize(parent)) .replace(/\$\{description\}/g, schema.description ? schema.description : '') @@ -106,10 +144,9 @@ function insertSchemaMacros(content, schema, module, name, parent, property, rec .replace(/\$\{info.title\}/g, moduleTitle) .replace(/\$\{info.Title\}/g, capitalize(moduleTitle)) .replace(/\$\{info.TITLE\}/g, moduleTitle.toUpperCase()) - // .replace(/\$\{type.link\}/g, getLinkForSchema(schema, module, { name: title })) if (recursive) { - content = content.replace(/\$\{type\}/g, getSchemaType(schema, module, { name: title, destination: state.destination, section: state.section, code: false })) + content = content.replace(/\$\{type\}/g, getSchemaType(schema, module, { destination: state.destination, section: state.section, code: false, namespace: true })) } return content } @@ -138,13 +175,40 @@ const insertEnumMacros = (content, schema, module, name, suffix, enumSuffix) => return template.join('\n') } -const insertObjectMacros = (content, schema, module, title, property, options) => { - options = options ? JSON.parse(JSON.stringify(options)) : {} +const insertObjectAdditionalPropertiesMacros = (content, schema, module, title, options) => { + const options2 = options ? JSON.parse(JSON.stringify(options)) : {} + options2.parent = title + options2.level = options.level + 1 + + const shape = getSchemaShape(schema.additionalProperties, module, options2) + let type = getSchemaType(schema.additionalProperties, module, options2).trimEnd() + const propertyNames = localizeDependencies(schema, module).propertyNames + + let jsonType = getJsonType(schema.additionalProperties, module) + if (!isPrimitiveType(jsonType)) { + jsonType = 'string' + } + + const additionalType = getPrimitiveType(jsonType, 'additional-types') + let key = (propertyNames && propertyNames.title) ? propertyNames.title : getTemplate(path.join(options.templateDir, 'additionalPropertiesKey')).trimEnd() + + content = content + .replace(/\$\{shape\}/g, shape) + .replace(/\$\{parent\.title\}/g, title) + .replace(/\$\{title\}/g, title) + .replace(/\$\{type\}/g, type) + .replace(/\$\{additional\.type\}/g, additionalType) + .replace(/\$\{key\}/g, key) + .replace(/\$\{delimiter\}(.*?)\$\{end.delimiter\}/g, '') + .replace(/\$\{if\.optional\}(.*?)\$\{end\.if\.optional\}/g, '') + + return content +} - const options2 = JSON.parse(JSON.stringify(options)) +const insertObjectMacros = (content, schema, module, title, property, options) => { + const options2 = options ? JSON.parse(JSON.stringify(options)) : {} options2.parent = title options2.level = options.level + 1 - options2.name = '' ;(['properties', 'properties.register', 'properties.assign']).forEach(macro => { const indent = (content.split('\n').find(line => line.includes("${" + macro + "}")) || '').match(/^\s+/) || [''][0] @@ -153,20 +217,6 @@ const insertObjectMacros = (content, schema, module, title, property, options) = const properties = [] - if (schema.additionalProperties && (typeof schema.additionalProperties === 'object')) { - const template = getTemplate(path.join(options.templateDir, 'additionalProperties')) - let type = getSchemaType(schema.additionalProperties, module, options2) - const shape = getSchemaShape(schema.additionalProperties, module, options2) - properties.push(template - .replace(/\$\{property\}/g, '') - .replace(/\$\{Property\}/g, '') - .replace(/\$\{shape\}/g, shape) - .replace(/\$\{parent\.title\}/g, title) - .replace(/\$\{title\}/g, type) - .replace(/\$\{delimiter\}(.*?)\$\{end.delimiter\}/g, '') - .replace(/\$\{if\.optional\}(.*?)\$\{end\.if\.optional\}/g, '')) - } - if (schema.properties) { Object.entries(schema.properties).forEach(([name, prop], i) => { options2.property = name @@ -200,7 +250,7 @@ const insertObjectMacros = (content, schema, module, title, property, options) = } // TODO: add language config feature for 'unknown' type let type; // = { type: "null" } - + if (schema.additionalProperties && (typeof schema.additionalProperties === 'object')) { type = schema.additionalProperties } @@ -252,6 +302,7 @@ const insertTupleMacros = (content, schema, module, title, options) => { const itemsTemplate = getTemplate(path.join(options.templateDir, 'items')) const propIndent = (content.split('\n').find(line => line.includes("${properties}")) || '').match(/^\s+/) || [''][0] const itemsIndent = (content.split('\n').find(line => line.includes("${items}")) || '').match(/^\s+/) || [''][0] + const tupleDelimiter = getTemplate(path.join(options.templateDir, 'tuple-delimiter')) const doMacroWork = (str, prop, i, indent) => { const schemaShape = getSchemaShape(prop, module, options) @@ -268,8 +319,8 @@ const insertTupleMacros = (content, schema, module, title, options) => { .replace(/\$\{if\.optional\}(.*?)\$\{end\.if\.optional\}/gms, '') } - content = content.replace(/\$\{properties\}/g, schema.items.map((prop, i) => doMacroWork(propTemplate, prop, i, propIndent)).join('\n')) - content = content.replace(/\$\{items\}/g, schema.items.map((prop, i) => doMacroWork(itemsTemplate, prop, i, itemsIndent)).join('\n')) + content = content.replace(/\$\{properties\}/g, schema.items.map((prop, i) => doMacroWork(propTemplate, prop, i, propIndent)).join(tupleDelimiter)) + content = content.replace(/\$\{items\}/g, schema.items.map((prop, i) => doMacroWork(itemsTemplate, prop, i, itemsIndent)).join(tupleDelimiter)) return content } @@ -288,10 +339,13 @@ const insertPrimitiveMacros = (content, schema, module, name, templateDir) => { const insertAnyOfMacros = (content, schema, module, name) => { const itemTemplate = content - content = schema.anyOf.map((item, i) => itemTemplate - .replace(/\$\{type\}/g, getSchemaType(item, module)) - .replace(/\$\{delimiter\}(.*?)\$\{end.delimiter\}/g, i === schema.anyOf.length - 1 ? '' : '$1') - ).join('') + if (content.split('\n').find(line => line.includes("${type}"))) { + content = schema.anyOf.map((item, i) => itemTemplate + .replace(/\$\{type\}/g, getSchemaType(item, module)) + .replace(/\$\{delimiter\}(.*?)\$\{end.delimiter\}/g, i === schema.anyOf.length - 1 ? '' : '$1') + ).join('') + } + return content } @@ -355,20 +409,37 @@ function getSchemaShape(schema = {}, module = {}, { templateDir = 'types', name return insertSchemaMacros(result, schema, module, theTitle, parent, property) } else if (schema.type === 'object') { - const shape = insertObjectMacros(getTemplate(path.join(templateDir, 'object' + suffix)), schema, module, theTitle, property, { level, parent, property, templateDir, descriptions, destination, section, enums }) - + let shape + const additionalPropertiesTemplate = getTemplate(path.join(templateDir, 'additionalProperties')) + if (additionalPropertiesTemplate && schema.additionalProperties && (typeof schema.additionalProperties === 'object')) { + shape = insertObjectAdditionalPropertiesMacros(additionalPropertiesTemplate, schema, module, theTitle, { level, parent, templateDir, namespace: true }) + } + else { + shape = insertObjectMacros(getTemplate(path.join(templateDir, 'object' + suffix)), schema, module, theTitle, property, { level, parent, property, templateDir, descriptions, destination, section, enums, namespace: true }) + } result = result.replace(/\$\{shape\}/g, shape) return insertSchemaMacros(result, schema, module, theTitle, parent, property) } else if (schema.anyOf || schema.oneOf) { - // borrow anyOf logic, note that schema is a copy, so we're not breaking it. - if (!schema.anyOf) { - schema.anyOf = schema.oneOf + const template = getTemplate(path.join(templateDir, 'anyOfSchemaShape' + suffix)) + let shape + if (template) { + shape = insertAnyOfMacros(template, schema, module, theTitle) + } + else { + // borrow anyOf logic, note that schema is a copy, so we're not breaking it. + if (!schema.anyOf) { + schema.anyOf = schema.oneOf + } + shape = insertAnyOfMacros(getTemplate(path.join(templateDir, 'anyOf' + suffix)), schema, module, theTitle) + } + if (shape) { + result = result.replace(/\$\{shape\}/g, shape) + return insertSchemaMacros(result, schema, module, theTitle, parent, property) + } + else { + return '' } - const shape = insertAnyOfMacros(getTemplate(path.join(templateDir, 'anyOf' + suffix)), schema, module, theTitle) - - result = result.replace(/\$\{shape\}/g, shape) - return insertSchemaMacros(result, schema, module, theTitle, parent, property) } else if (schema.allOf) { const merger = (key) => function (a, b) { @@ -482,7 +553,7 @@ function getSchemaType(schema, module, { destination, templateDir = 'types', lin if (schema['$ref'][0] === '#') { const refSchema = getPath(schema['$ref'], module) const includeNamespace = (module.info.title !== getXSchemaGroup(refSchema, module)) - return getSchemaType(refSchema, module, {destination, templateDir, link, title, code, asPath, event, result, expandEnums, baseUrl, namespace:includeNamespace })// { link: link, code: code, destination }) + return getSchemaType(refSchema, module, {destination, templateDir, link, code, asPath, event, result, expandEnums, baseUrl, namespace:includeNamespace })// { link: link, code: code, destination }) } else { // TODO: This never happens... but might be worth keeping in case we link to an opaque external schema at some point? @@ -593,7 +664,7 @@ function getSchemaType(schema, module, { destination, templateDir = 'types', lin if (schema.title) { union.title = schema.title } - return getSchemaType(union, module, { destination, link, title, code, asPath, baseUrl }) + return getSchemaType(union, module, { destination, link, title, code, asPath, baseUrl, namespace }) } else if (schema.oneOf || schema.anyOf) { if (!schema.anyOf) { @@ -616,11 +687,17 @@ function getSchemaType(schema, module, { destination, templateDir = 'types', lin // } } else if (schema.type) { - // TODO: this assumes that when type is an array of types, that it's one other primative & 'null', which isn't necessarily true. - const schemaType = !Array.isArray(schema.type) ? schema.type : schema.type.find(t => t !== 'null') - const primitive = getPrimitiveType(schemaType, templateDir) - const type = allocatedProxy ? allocatedPrimitiveProxies[schemaType] || primitive : primitive - return wrap(type, code ? '`' : '') + const template = getTemplate(path.join(templateDir, 'additionalProperties')) + if (schema.additionalProperties && template ) { + return insertSchemaMacros(getTemplate(path.join(templateDir, 'Title')), schema, module, theTitle, '', '', false) + } + else { + // TODO: this assumes that when type is an array of types, that it's one other primative & 'null', which isn't necessarily true. + const schemaType = !Array.isArray(schema.type) ? schema.type : schema.type.find(t => t !== 'null') + const primitive = getPrimitiveType(schemaType, templateDir) + const type = allocatedProxy ? allocatedPrimitiveProxies[schemaType] || primitive : primitive + return wrap(type, code ? '`' : '') + } } else { // TODO this is TypeScript specific @@ -629,7 +706,21 @@ function getSchemaType(schema, module, { destination, templateDir = 'types', lin } function getJsonType(schema, module, { destination, link = false, title = false, code = false, asPath = false, event = false, expandEnums = true, baseUrl = '' } = {}) { - return '' + + schema = sanitize(schema) + let type + if (schema['$ref']) { + if (schema['$ref'][0] === '#') { + //Ref points to local schema + //Get Path to ref in this module and getSchemaType + let definition = getPath(schema['$ref'], module) + type = getJsonType(definition, schema, {destination}) + } + } + else { + type = !Array.isArray(schema.type) ? schema.type : schema.type.find(t => t !== 'null') + } + return type } function getSchemaInstantiation(schema, module, { instantiationType }) { @@ -642,8 +733,8 @@ export default { setConvertTuples, setAllocatedPrimitiveProxies, getMethodSignatureParams, + getMethodSignatureResult, getSchemaShape, getSchemaType, - getJsonType, getSchemaInstantiation }