diff --git a/include/dxfeed_graal_cpp_api/api/DXFeedSubscription.hpp b/include/dxfeed_graal_cpp_api/api/DXFeedSubscription.hpp index ce0e9994..ce23424a 100644 --- a/include/dxfeed_graal_cpp_api/api/DXFeedSubscription.hpp +++ b/include/dxfeed_graal_cpp_api/api/DXFeedSubscription.hpp @@ -39,6 +39,9 @@ class DXFCPP_EXPORT DXFeedSubscription : public RequireMakeShared(-1)}; + /// + using OnEventHandler = SimpleHandler> &)>; + private: friend struct DXFeed; @@ -53,7 +56,7 @@ class DXFCPP_EXPORT DXFeedSubscription : public RequireMakeShared eventListenerHandle_; - SimpleHandler> &)> onEvent_{}; + OnEventHandler onEvent_{}; std::unordered_map> changeListeners_; std::recursive_mutex changeListenersMutex_{}; @@ -64,26 +67,12 @@ class DXFCPP_EXPORT DXFeedSubscription : public RequireMakeShared getSymbolsImpl() const; - - std::vector getDecoratedSymbolsImpl() const; - public: /// The alias to a type of shared pointer to the DXFeedSubscription object using Ptr = std::shared_ptr; @@ -101,8 +90,7 @@ class DXFCPP_EXPORT DXFeedSubscription : public RequireMakeShared dxfcpp::ConvertibleTo; } #endif - DXFeedSubscription(LockExternalConstructionTag tag, EventTypeIt begin, EventTypeIt end) - : DXFeedSubscription{tag} { + DXFeedSubscription(LockExternalConstructionTag tag, EventTypeIt begin, EventTypeIt end) : DXFeedSubscription{tag} { if constexpr (Debugger::isDebug) { // ReSharper disable once CppDFAUnreachableCode Debugger::debug("DXFeedSubscription(eventTypes = " + namesToString(begin, end) + ")"); @@ -148,19 +136,7 @@ class DXFCPP_EXPORT DXFeedSubscription : public RequireMakeShared create(const EventTypeEnum &eventType) { - if constexpr (Debugger::isDebug) { - // ReSharper disable once CppDFAUnreachableCode - Debugger::debug("DXFeedSubscription::create(eventType = " + eventType.getName() + ")"); - } - - auto sub = createShared(eventType); - auto id = ApiContext::getInstance()->getManager()->registerEntity(sub); - - dxfcpp::ignore_unused(id); - - return sub; - } + static std::shared_ptr create(const EventTypeEnum &eventType); /** * Creates detached subscription for the given collection of event types. @@ -214,14 +190,7 @@ class DXFCPP_EXPORT DXFeedSubscription : public RequireMakeShareddetached subscription for the given collection of event types. */ - static std::shared_ptr create(std::initializer_list eventTypes) { - auto sub = createShared(eventTypes); - auto id = ApiContext::getInstance()->getManager()->registerEntity(sub); - - dxfcpp::ignore_unused(id); - - return sub; - } + static std::shared_ptr create(std::initializer_list eventTypes); /** * Creates detached subscription for the given collection of event types. @@ -314,7 +283,7 @@ class DXFCPP_EXPORT DXFeedSubscription : public RequireMakeShared> &)>::FAKE_ID; + return OnEventHandler::FAKE_ID; } return onEvent_ += listener; @@ -401,9 +370,7 @@ class DXFCPP_EXPORT DXFeedSubscription : public RequireMakeShared collection) const { - addSymbols(collection.begin(), collection.end()); - } + void addSymbols(std::initializer_list collection) const; /** * Removes the specified collection (using iterators) of symbols from the set of subscribed symbols. @@ -600,9 +543,7 @@ class DXFCPP_EXPORT DXFeedSubscription : public RequireMakeShared collection) const { - removeSymbols(collection.begin(), collection.end()); - } + void removeSymbols(std::initializer_list collection) const; /** * Changes the set of subscribed symbols so that it contains just the symbols from the specified collection (using @@ -661,21 +602,12 @@ class DXFCPP_EXPORT DXFeedSubscription : public RequireMakeShared collection) const { - setSymbols(collection.begin(), collection.end()); - } + void setSymbols(std::initializer_list collection) const; /** * Clears the set of subscribed symbols. */ - void clear() const { - if constexpr (Debugger::isDebug) { - // ReSharper disable once CppDFAUnreachableCode - Debugger::debug(toString() + "::clear()"); - } - - clearImpl(); - } + void clear() const; /** * Returns `true` if this subscription is closed. @@ -684,23 +616,14 @@ class DXFCPP_EXPORT DXFeedSubscription : public RequireMakeShared getEventTypes() override { - return eventTypes_; - } + std::unordered_set getEventTypes() override; /** * Returns `true` if this subscription contains the corresponding event type. @@ -710,9 +633,7 @@ class DXFCPP_EXPORT DXFeedSubscription : public RequireMakeShared getSymbols() const { - if constexpr (Debugger::isDebug) { - // ReSharper disable once CppDFAUnreachableCode - Debugger::debug(toString() + "::getSymbols()"); - } - - return getSymbolsImpl(); - } + std::vector getSymbols() const; /** * Returns a set of decorated symbols (depending on the actual implementation of subscription). @@ -739,18 +653,7 @@ class DXFCPP_EXPORT DXFeedSubscription : public RequireMakeShared getDecoratedSymbols() const { - if constexpr (Debugger::isDebug) { - // ReSharper disable once CppDFAUnreachableCode - Debugger::debug(toString() + "::getDecoratedSymbols()"); - } - - return getDecoratedSymbolsImpl(); - } - - auto getExecutor(); - - template void setExecutor(Executor &&executor); + std::vector getDecoratedSymbols() const; std::size_t addChangeListener(std::shared_ptr listener) override; diff --git a/src/api/DXFeedSubscription.cpp b/src/api/DXFeedSubscription.cpp index 303f65e3..55702bf6 100644 --- a/src/api/DXFeedSubscription.cpp +++ b/src/api/DXFeedSubscription.cpp @@ -28,6 +28,97 @@ struct DXFeedSubscription::Impl { } }; +JavaObjectHandle +DXFeedSubscription::createSubscriptionHandleFromEventClassList(const std::unique_ptr &list) { + return isolated::api::IsolatedDXFeedSubscription::create(list); +} + +void DXFeedSubscription::setEventListenerHandle(Id id) { + eventListenerHandle_ = isolated::api::IsolatedDXFeedSubscription::DXFeedEventListener::create( + dxfcpp::bit_cast(&Impl::onEvents), dxfcpp::bit_cast(id.getValue())); + + isolated::api::IsolatedDXFeedSubscription::addEventListener(handle_, eventListenerHandle_); +} + +bool DXFeedSubscription::tryToSetEventListenerHandle() { + std::lock_guard lock{eventListenerMutex_}; + + if (!eventListenerHandle_) { + auto idOpt = + ApiContext::getInstance()->getManager()->getId(sharedAs()); + + if (!idOpt) { + return false; + } + + setEventListenerHandle(idOpt.value()); + } + + return true; +} + +void DXFeedSubscription::addSymbolsImpl(void *graalSymbolList) const { + isolated::api::IsolatedDXFeedSubscription::addSymbols(handle_, graalSymbolList); +} + +void DXFeedSubscription::removeSymbolsImpl(void *graalSymbolList) const { + isolated::api::IsolatedDXFeedSubscription::removeSymbols(handle_, graalSymbolList); +} + +void DXFeedSubscription::setSymbolsImpl(void *graalSymbolList) const { + isolated::api::IsolatedDXFeedSubscription::setSymbols(handle_, graalSymbolList); +} + +DXFeedSubscription::DXFeedSubscription(LockExternalConstructionTag) + : impl_(std::make_unique()) { +} + +DXFeedSubscription::DXFeedSubscription(LockExternalConstructionTag tag, const EventTypeEnum &eventType) + : DXFeedSubscription{tag} { + if constexpr (Debugger::isDebug) { + Debugger::debug("DXFeedSubscription(eventType = " + eventType.getName() + ")"); + } + + eventTypes_ = std::unordered_set{eventType}; + handle_ = isolated::api::IsolatedDXFeedSubscription::create(eventType); +} + +std::string DXFeedSubscription::toString() const noexcept { + return fmt::format("DXFeedSubscription{{{}}}", handle_.toString()); +} + +DXFeedSubscription::~DXFeedSubscription() { + if constexpr (Debugger::isDebug) { + // ReSharper disable once CppDFAUnreachableCode + Debugger::debug("DXFeedSubscription{" + handle_.toString() + "}::~DXFeedSubscription()"); + } + + close(); +} + +std::shared_ptr DXFeedSubscription::create(const EventTypeEnum &eventType) { + if constexpr (Debugger::isDebug) { + // ReSharper disable once CppDFAUnreachableCode + Debugger::debug("DXFeedSubscription::create(eventType = " + eventType.getName() + ")"); + } + + auto sub = createShared(eventType); + auto id = ApiContext::getInstance()->getManager()->registerEntity(sub); + + dxfcpp::ignore_unused(id); + + return sub; +} + +std::shared_ptr DXFeedSubscription::create(std::initializer_list eventTypes) { + auto sub = createShared(eventTypes); + auto id = ApiContext::getInstance()->getManager()->registerEntity(sub); + + dxfcpp::ignore_unused(id); + + return sub; +} + void DXFeedSubscription::attach(std::shared_ptr feed) { if constexpr (Debugger::isDebug) { Debugger::debug(toString() + "::attach(feed = " + feed->toString() + ")"); @@ -50,135 +141,127 @@ void DXFeedSubscription::close() const { Debugger::debug(toString() + "::close()"); } - closeImpl(); + isolated::api::IsolatedDXFeedSubscription::close(handle_); } -std::size_t DXFeedSubscription::addChangeListener(std::shared_ptr listener) { - isolated::api::IsolatedDXFeedSubscription::addChangeListener(handle_, listener->getHandle()); +void DXFeedSubscription::removeEventListener(std::size_t listenerId) { + onEvent_ -= listenerId; +} - std::lock_guard guard{changeListenersMutex_}; +DXFeedSubscription::OnEventHandler &DXFeedSubscription::onEvent() { + tryToSetEventListenerHandle(); - if (lastChangeListenerId_ >= FAKE_CHANGE_LISTENER_ID - 1) { - return FAKE_CHANGE_LISTENER_ID; - } + return onEvent_; +} - auto id = ++lastChangeListenerId_; +void DXFeedSubscription::addSymbols(const SymbolWrapper &symbolWrapper) const { + if constexpr (Debugger::isDebug) { + // ReSharper disable once CppDFAUnreachableCode + Debugger::debug(toString() + "::addSymbols(symbolWrapper = " + toStringAny(symbolWrapper) + ")"); + } - changeListeners_.emplace(id, listener); + auto graal = symbolWrapper.toGraalUnique(); - return id; + isolated::api::IsolatedDXFeedSubscription::addSymbol(handle_, graal.get()); } -void DXFeedSubscription::removeChangeListener(std::size_t changeListenerId) { - std::lock_guard guard{changeListenersMutex_}; - - if (changeListenerId == FAKE_CHANGE_LISTENER_ID) { - return; +void DXFeedSubscription::removeSymbols(const SymbolWrapper &symbolWrapper) const { + if constexpr (Debugger::isDebug) { + // ReSharper disable once CppDFAUnreachableCode + Debugger::debug(toString() + "::removeSymbols(symbolWrapper = " + toStringAny(symbolWrapper) + ")"); } - if (auto found = changeListeners_.find(changeListenerId); found != changeListeners_.end()) { - auto listener = found->second; - - isolated::api::IsolatedDXFeedSubscription::removeChangeListener(handle_, listener->getHandle()); + auto graal = symbolWrapper.toGraalUnique(); - changeListeners_.erase(found); - } + isolated::api::IsolatedDXFeedSubscription::removeSymbol(handle_, graal.get()); } -void DXFeedSubscription::addSymbolImpl(void *graalSymbol) const { - isolated::api::IsolatedDXFeedSubscription::addSymbol(handle_, graalSymbol); +void DXFeedSubscription::addSymbols(std::initializer_list collection) const { + addSymbols(collection.begin(), collection.end()); } -void DXFeedSubscription::addSymbolsImpl(void *graalSymbolList) const { - isolated::api::IsolatedDXFeedSubscription::addSymbols(handle_, graalSymbolList); +void DXFeedSubscription::removeSymbols(std::initializer_list collection) const { + removeSymbols(collection.begin(), collection.end()); } -void DXFeedSubscription::removeSymbolImpl(void *graalSymbol) const { - isolated::api::IsolatedDXFeedSubscription::removeSymbol(handle_, graalSymbol); +void DXFeedSubscription::setSymbols(std::initializer_list collection) const { + setSymbols(collection.begin(), collection.end()); } -void DXFeedSubscription::removeSymbolsImpl(void *graalSymbolList) const { - isolated::api::IsolatedDXFeedSubscription::removeSymbols(handle_, graalSymbolList); -} +void DXFeedSubscription::clear() const { + if constexpr (Debugger::isDebug) { + // ReSharper disable once CppDFAUnreachableCode + Debugger::debug(toString() + "::clear()"); + } -void DXFeedSubscription::setSymbolsImpl(void *graalSymbolList) const { - isolated::api::IsolatedDXFeedSubscription::setSymbols(handle_, graalSymbolList); + isolated::api::IsolatedDXFeedSubscription::clear(handle_); } -std::vector DXFeedSubscription::getSymbolsImpl() const { - return isolated::api::IsolatedDXFeedSubscription::getSymbols(handle_); -} +bool DXFeedSubscription::isClosed() override { + if constexpr (Debugger::isDebug) { + // ReSharper disable once CppDFAUnreachableCode + Debugger::debug(toString() + "::isClosed()"); + } -std::vector DXFeedSubscription::getDecoratedSymbolsImpl() const { - return isolated::api::IsolatedDXFeedSubscription::getDecoratedSymbols(handle_); + return isolated::api::IsolatedDXFeedSubscription::isClosed(handle_); } -void DXFeedSubscription::closeImpl() const { - isolated::api::IsolatedDXFeedSubscription::close(handle_); +std::unordered_set DXFeedSubscription::getEventTypes() override { + return eventTypes_; } -void DXFeedSubscription::clearImpl() const { - isolated::api::IsolatedDXFeedSubscription::clear(handle_); +bool DXFeedSubscription::containsEventType(const EventTypeEnum &eventType) override { + return eventTypes_.contains(eventType); } -bool DXFeedSubscription::isClosedImpl() const { - return isolated::api::IsolatedDXFeedSubscription::isClosed(handle_); -} +std::vector DXFeedSubscription::getSymbols() const { + if constexpr (Debugger::isDebug) { + // ReSharper disable once CppDFAUnreachableCode + Debugger::debug(toString() + "::getSymbols()"); + } -DXFeedSubscription::DXFeedSubscription(LockExternalConstructionTag) - : impl_(std::make_unique()) { + return isolated::api::IsolatedDXFeedSubscription::getSymbols(handle_); } -DXFeedSubscription::DXFeedSubscription(LockExternalConstructionTag tag, const EventTypeEnum &eventType) - : DXFeedSubscription{tag} { +std::vector DXFeedSubscription::getDecoratedSymbols() const { if constexpr (Debugger::isDebug) { - Debugger::debug("DXFeedSubscription(eventType = " + eventType.getName() + ")"); + // ReSharper disable once CppDFAUnreachableCode + Debugger::debug(toString() + "::getDecoratedSymbols()"); } - eventTypes_ = std::unordered_set{eventType}; - handle_ = isolated::api::IsolatedDXFeedSubscription::create(eventType); + return isolated::api::IsolatedDXFeedSubscription::getDecoratedSymbols(handle_); } -JavaObjectHandle -DXFeedSubscription::createSubscriptionHandleFromEventClassList(const std::unique_ptr &list) { - return isolated::api::IsolatedDXFeedSubscription::create(list); -} +std::size_t DXFeedSubscription::addChangeListener(std::shared_ptr listener) { + isolated::api::IsolatedDXFeedSubscription::addChangeListener(handle_, listener->getHandle()); -void DXFeedSubscription::setEventListenerHandle(Id id) { - eventListenerHandle_ = isolated::api::IsolatedDXFeedSubscription::DXFeedEventListener::create( - dxfcpp::bit_cast(&Impl::onEvents), dxfcpp::bit_cast(id.getValue())); + std::lock_guard guard{changeListenersMutex_}; - isolated::api::IsolatedDXFeedSubscription::addEventListener(handle_, eventListenerHandle_); -} + if (lastChangeListenerId_ >= FAKE_CHANGE_LISTENER_ID - 1) { + return FAKE_CHANGE_LISTENER_ID; + } -bool DXFeedSubscription::tryToSetEventListenerHandle() { - std::lock_guard lock{eventListenerMutex_}; + auto id = ++lastChangeListenerId_; - if (!eventListenerHandle_) { - auto idOpt = - ApiContext::getInstance()->getManager()->getId(sharedAs()); + changeListeners_.emplace(id, listener); - if (!idOpt) { - return false; - } + return id; +} - setEventListenerHandle(idOpt.value()); +void DXFeedSubscription::removeChangeListener(std::size_t changeListenerId) { + std::lock_guard guard{changeListenersMutex_}; + + if (changeListenerId == FAKE_CHANGE_LISTENER_ID) { + return; } - return true; -} + if (auto found = changeListeners_.find(changeListenerId); found != changeListeners_.end()) { + auto listener = found->second; -std::string DXFeedSubscription::toString() const noexcept { - return fmt::format("DXFeedSubscription{{{}}}", handle_.toString()); -} + isolated::api::IsolatedDXFeedSubscription::removeChangeListener(handle_, listener->getHandle()); -DXFeedSubscription::~DXFeedSubscription() { - if constexpr (Debugger::isDebug) { - // ReSharper disable once CppDFAUnreachableCode - Debugger::debug("DXFeedSubscription{" + handle_.toString() + "}::~DXFeedSubscription()"); + changeListeners_.erase(found); } - - closeImpl(); } DXFCPP_END_NAMESPACE \ No newline at end of file