From af92d6fac441333b9cd1774049acb48cb985ae70 Mon Sep 17 00:00:00 2001 From: Anatoly Kalin <132361707+AnatolyKalin@users.noreply.github.com> Date: Fri, 19 May 2023 11:24:45 +0300 Subject: [PATCH] [DXFC-401] Create entity managers and API context. (#6) --- include/dxfeed_graal_cpp_api/api.hpp | 5 + .../dxfeed_graal_cpp_api/api/DXEndpoint.hpp | 23 ++- include/dxfeed_graal_cpp_api/api/DXFeed.hpp | 5 +- .../api/DXFeedSubscription.hpp | 52 +++++-- .../dxfeed_graal_cpp_api/event/EventType.hpp | 20 +++ .../event/IndexedEventSource.hpp | 8 +- .../event/market/OrderSource.hpp | 24 +++- .../event/market/Profile.hpp | 8 +- .../event/market/Quote.hpp | 8 +- .../event/market/Summary.hpp | 8 +- .../event/market/TimeAndSale.hpp | 10 +- .../event/market/Trade.hpp | 8 +- .../event/market/TradeETH.hpp | 10 +- .../event/option/Greeks.hpp | 8 +- .../event/option/Series.hpp | 8 +- .../event/option/TheoPrice.hpp | 10 +- .../event/option/Underlying.hpp | 10 +- .../dxfeed_graal_cpp_api/internal/Common.hpp | 44 ++++++ .../internal/context/ApiContext.hpp | 34 +++++ .../internal/managers/DXEndpointManager.hpp | 19 +++ .../managers/DXFeedSubscriptionManager.hpp | 19 +++ .../internal/managers/EntityManager.hpp | 96 +++++++++++++ .../managers/ErrorHandlingManager.hpp | 82 +++++++++++ samples/cpp/PrintQuoteEvents/src/main.cpp | 118 +++------------- src/api/DXEndpoint.cpp | 88 ++++++------ src/api/DXFeed.cpp | 10 +- src/api/DXFeedSubscription.cpp | 37 +++-- tests/api/DXEndpointTest.cpp | 131 +++++++++--------- 28 files changed, 554 insertions(+), 349 deletions(-) create mode 100644 include/dxfeed_graal_cpp_api/internal/context/ApiContext.hpp create mode 100644 include/dxfeed_graal_cpp_api/internal/managers/DXEndpointManager.hpp create mode 100644 include/dxfeed_graal_cpp_api/internal/managers/DXFeedSubscriptionManager.hpp create mode 100644 include/dxfeed_graal_cpp_api/internal/managers/EntityManager.hpp create mode 100644 include/dxfeed_graal_cpp_api/internal/managers/ErrorHandlingManager.hpp diff --git a/include/dxfeed_graal_cpp_api/api.hpp b/include/dxfeed_graal_cpp_api/api.hpp index 268c1823..c5ddefa9 100644 --- a/include/dxfeed_graal_cpp_api/api.hpp +++ b/include/dxfeed_graal_cpp_api/api.hpp @@ -3,9 +3,14 @@ #pragma once +#include "dxfeed_graal_cpp_api/internal/managers/ErrorHandlingManager.hpp" #include "internal/CEntryPointErrors.hpp" #include "internal/Common.hpp" #include "internal/Enum.hpp" +#include "internal/context/ApiContext.hpp" +#include "internal/managers/DXEndpointManager.hpp" +#include "internal/managers/DXFeedSubscriptionManager.hpp" +#include "internal/managers/EntityManager.hpp" #include "api/DXEndpoint.hpp" #include "api/DXFeed.hpp" diff --git a/include/dxfeed_graal_cpp_api/api/DXEndpoint.hpp b/include/dxfeed_graal_cpp_api/api/DXEndpoint.hpp index dda5adb5..43e1ad5f 100644 --- a/include/dxfeed_graal_cpp_api/api/DXEndpoint.hpp +++ b/include/dxfeed_graal_cpp_api/api/DXEndpoint.hpp @@ -463,7 +463,6 @@ struct DXEndpoint : std::enable_shared_from_this { static inline std::mutex MTX{}; static std::unordered_map> INSTANCES; - mutable std::recursive_mutex mtx_{}; handler_utils::JavaObjectHandler handler_; Role role_ = Role::FEED; std::string name_{}; @@ -480,7 +479,7 @@ struct DXEndpoint : std::enable_shared_from_this { void closeImpl(); protected: - DXEndpoint() : mtx_{}, handler_{}, role_{}, feed_{}, publisher_{}, stateChangeListenerHandler_{}, onStateChange_{} { + DXEndpoint() : handler_{}, role_{}, feed_{}, publisher_{}, stateChangeListenerHandler_{}, onStateChange_{} { if constexpr (isDebug) { debug("DXEndpoint()"); } @@ -491,8 +490,6 @@ struct DXEndpoint : std::enable_shared_from_this { if constexpr (isDebug) { debug("DXEndpoint{{{}}}::~DXEndpoint()", handler_.toString()); } - - tryCallWithLock(mtx_, [this] { closeImpl(); }); } /** @@ -619,7 +616,7 @@ struct DXEndpoint : std::enable_shared_from_this { * @return the listener id */ template - std::size_t addStateChangeListener(StateChangeListener &&listener) + std::size_t addStateChangeListener(StateChangeListener &&listener) noexcept requires requires { { listener(State{}, State{}) } -> std::same_as; } @@ -633,7 +630,7 @@ struct DXEndpoint : std::enable_shared_from_this { * * @param listenerId The listener id to remove */ - void removeStateChangeListener(std::size_t listenerId) { onStateChange_ -= listenerId; } + void removeStateChangeListener(std::size_t listenerId) noexcept { onStateChange_ -= listenerId; } /** * Returns the onStateChange @ref Handler "handler" that can be used to add or remove @@ -641,7 +638,7 @@ struct DXEndpoint : std::enable_shared_from_this { * * @return onStateChange handler with `void(State, State)` signature */ - auto &onStateChange() { return onStateChange_; } + auto &onStateChange() noexcept { return onStateChange_; } // TODO: implement template void executor(Executor &&) {} @@ -753,8 +750,6 @@ struct DXEndpoint : std::enable_shared_from_this { debug("DXEndpoint{{{}}}::close()", handler_.toString()); } - std::lock_guard guard(mtx_); - closeImpl(); } @@ -810,12 +805,12 @@ struct DXEndpoint : std::enable_shared_from_this { class Builder : public std::enable_shared_from_this { friend DXEndpoint; - mutable std::recursive_mutex mtx_{}; +// mutable std::recursive_mutex mtx_{}; handler_utils::JavaObjectHandler handler_; Role role_ = Role::FEED; std::unordered_map properties_; - Builder() : mtx_{}, handler_{}, properties_{} { + Builder() : handler_{}, properties_{} { if constexpr (isDebug) { debug("DXEndpoint::Builder::Builder()"); } @@ -899,8 +894,6 @@ struct DXEndpoint : std::enable_shared_from_this { properties.size()); } - std::lock_guard guard(mtx_); - for (auto &&[k, v] : properties) { withProperty(k, v); } @@ -939,5 +932,9 @@ struct DXEndpoint : std::enable_shared_from_this { return Builder::create(); } + + std::string toString() const { + return fmt::format("DXEndpoint{{{}}}", handler_.toString()); + } }; } // namespace dxfcpp \ No newline at end of file diff --git a/include/dxfeed_graal_cpp_api/api/DXFeed.hpp b/include/dxfeed_graal_cpp_api/api/DXFeed.hpp index 2e6b3810..59bcb7c6 100644 --- a/include/dxfeed_graal_cpp_api/api/DXFeed.hpp +++ b/include/dxfeed_graal_cpp_api/api/DXFeed.hpp @@ -27,7 +27,6 @@ struct DXFeed : std::enable_shared_from_this { friend struct DXEndpoint; private: - mutable std::recursive_mutex mtx_{}; handler_utils::JavaObjectHandler handler_; std::unordered_set> subscriptions_{}; @@ -35,7 +34,7 @@ struct DXFeed : std::enable_shared_from_this { static std::shared_ptr create(void *feedHandle) noexcept; protected: - DXFeed() noexcept : mtx_(), handler_{} { + DXFeed() noexcept : handler_{} { if constexpr (isDebug) { debug("DXFeed()"); } @@ -98,8 +97,6 @@ struct DXFeed : std::enable_shared_from_this { } std::string toString() const { - std::lock_guard guard(mtx_); - return fmt::format("DXFeed{{{}}}", handler_.toString()); } }; diff --git a/include/dxfeed_graal_cpp_api/api/DXFeedSubscription.hpp b/include/dxfeed_graal_cpp_api/api/DXFeedSubscription.hpp index 4f3e0b38..9f05fd58 100644 --- a/include/dxfeed_graal_cpp_api/api/DXFeedSubscription.hpp +++ b/include/dxfeed_graal_cpp_api/api/DXFeedSubscription.hpp @@ -27,7 +27,7 @@ class DXFeedSubscription : public std::enable_shared_from_this createSubscriptionHandlerFromEventClassList(const std::unique_ptr &list) noexcept; - void setEventListenerHandler() noexcept; + void setEventListenerHandler(Id id) noexcept; template DXFeedSubscription(EventTypeIt begin, EventTypeIt end) noexcept @@ -55,7 +55,6 @@ class DXFeedSubscription : public std::enable_shared_from_this eventTypes) noexcept @@ -74,11 +73,7 @@ class DXFeedSubscription : public std::enable_shared_from_this(new DXFeedSubscription(eventType)); + auto sub = std::shared_ptr(new DXFeedSubscription(eventType)); + auto id = ApiContext::getInstance()->getDxFeedSubscriptionManager()->registerEntity(sub); + + sub->setEventListenerHandler(id); + + return sub; } /** @@ -115,7 +115,12 @@ class DXFeedSubscription : public std::enable_shared_from_this(new DXFeedSubscription(begin, end)); + auto sub = std::shared_ptr(new DXFeedSubscription(begin, end)); + auto id = ApiContext::getInstance()->getDxFeedSubscriptionManager()->registerEntity(sub); + + sub->setEventListenerHandler(id); + + return sub; } /** @@ -125,7 +130,12 @@ class DXFeedSubscription : public std::enable_shared_from_thisdetached subscription for the given collection of event types. */ static std::shared_ptr create(std::initializer_list eventTypes) noexcept { - return std::shared_ptr(new DXFeedSubscription(eventTypes)); + auto sub = std::shared_ptr(new DXFeedSubscription(eventTypes)); + auto id = ApiContext::getInstance()->getDxFeedSubscriptionManager()->registerEntity(sub); + + sub->setEventListenerHandler(id); + + return sub; } /** @@ -139,8 +149,13 @@ class DXFeedSubscription : public std::enable_shared_from_this create(EventTypesCollection &&eventTypes) noexcept requires requires { ElementTypeIs; } { - return std::shared_ptr( - new DXFeedSubscription(std::forward(eventTypes))); + auto sub = + std::shared_ptr(new DXFeedSubscription(std::forward(eventTypes))); + auto id = ApiContext::getInstance()->getDxFeedSubscriptionManager()->registerEntity(sub); + + sub->setEventListenerHandler(id); + + return sub; } /** @@ -174,11 +189,18 @@ class DXFeedSubscription : public std::enable_shared_from_this std::size_t addEventListener(EventListener &&listener) noexcept; + template + std::size_t addEventListener(EventListener &&listener) noexcept + requires requires { + { listener(std::vector>{}) } -> std::same_as; + } + { + return onEvent_ += listener; + } - void removeEventListener(std::size_t listenerId) noexcept; + void removeEventListener(std::size_t listenerId) noexcept { onEvent_ -= listenerId; } - auto onEvent() noexcept; + const auto &onEvent() noexcept { return onEvent_; } template void addSymbol(Symbol &&symbol) noexcept; diff --git a/include/dxfeed_graal_cpp_api/event/EventType.hpp b/include/dxfeed_graal_cpp_api/event/EventType.hpp index c598ec6f..cbd50251 100644 --- a/include/dxfeed_graal_cpp_api/event/EventType.hpp +++ b/include/dxfeed_graal_cpp_api/event/EventType.hpp @@ -56,6 +56,26 @@ struct EventType : public SharedEntity { virtual void setEventTime(std::int64_t eventTime){ // The default implementation is empty }; + + /** + * Returns a string representation of the current object. + * + * @return a string representation + */ + virtual std::string toString() const noexcept { return "EventType{}"; } + + friend std::ostream &operator<<(std::ostream &os, const EventType &e) { return os << e.toString(); } + + friend std::ostream &operator<<(std::ostream &os, const std::shared_ptr &e) { + return os << e->toString(); + } + + template + friend std::ostream &operator<<(std::ostream &os, const std::shared_ptr &e) + requires(std::is_base_of_v) + { + return os << e->toString(); + } }; /** diff --git a/include/dxfeed_graal_cpp_api/event/IndexedEventSource.hpp b/include/dxfeed_graal_cpp_api/event/IndexedEventSource.hpp index 269fce2d..bceafdc6 100644 --- a/include/dxfeed_graal_cpp_api/event/IndexedEventSource.hpp +++ b/include/dxfeed_graal_cpp_api/event/IndexedEventSource.hpp @@ -29,28 +29,28 @@ class IndexedEventSource { * @param id The source id * @param name The source name */ - IndexedEventSource(unsigned id, std::string name) : id_{id}, name_{std::move(name)} {} + IndexedEventSource(unsigned id, std::string name) noexcept : id_{id}, name_{std::move(name)} {} /** * Returns the source identifier. Source identifier is non-negative. * * @return The source identifier. */ - std::uint32_t id() const { return id_; } + std::uint32_t id() const noexcept { return id_; } /** * Returns the string representation of the object. * * @return The string representation of the object. */ - const std::string &name() const { return name_; } + const std::string &name() const noexcept { return name_; } /** * Returns the string representation of the object. * * @return The string representation of the object. */ - std::string toString() const { return name_; } + std::string toString() const noexcept { return name_; } }; } // namespace dxfcpp \ No newline at end of file diff --git a/include/dxfeed_graal_cpp_api/event/market/OrderSource.hpp b/include/dxfeed_graal_cpp_api/event/market/OrderSource.hpp index 0758f8da..85e39ec5 100644 --- a/include/dxfeed_graal_cpp_api/event/market/OrderSource.hpp +++ b/include/dxfeed_graal_cpp_api/event/market/OrderSource.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "../../internal/Common.hpp" #include "../IndexedEventSource.hpp" @@ -14,13 +15,7 @@ namespace dxfcpp { // TODO: implement -template