diff --git a/CMakeLists.txt b/CMakeLists.txt index f100aee1..45f75ded 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -190,6 +190,7 @@ set(dxFeedGraalCxxApi_Exceptions_Sources ) set(dxFeedGraalCxxApi_Isolated_Sources + src/isolated/api/IsolatedDXFeed.cpp src/isolated/api/IsolatedDXEndpoint.cpp src/isolated/api/IsolatedDXFeedSubscription.cpp src/isolated/api/IsolatedDXPublisher.cpp diff --git a/include/dxfeed_graal_cpp_api/api.hpp b/include/dxfeed_graal_cpp_api/api.hpp index a9e7c98b..34366040 100644 --- a/include/dxfeed_graal_cpp_api/api.hpp +++ b/include/dxfeed_graal_cpp_api/api.hpp @@ -52,6 +52,7 @@ DXFCXX_DISABLE_MSC_WARNINGS_PUSH(4251 4996) #include "exceptions/JavaException.hpp" #include "exceptions/GraalException.hpp" +#include "isolated/api/IsolatedDXFeed.hpp" #include "isolated/api/IsolatedDXEndpoint.hpp" #include "isolated/api/IsolatedDXFeedSubscription.hpp" #include "isolated/api/IsolatedDXPublisher.hpp" diff --git a/include/dxfeed_graal_cpp_api/api/DXFeed.hpp b/include/dxfeed_graal_cpp_api/api/DXFeed.hpp index c264d79e..a1765062 100644 --- a/include/dxfeed_graal_cpp_api/api/DXFeed.hpp +++ b/include/dxfeed_graal_cpp_api/api/DXFeed.hpp @@ -12,6 +12,7 @@ DXFCXX_DISABLE_MSC_WARNINGS_PUSH(4251) #include "../internal/Handler.hpp" #include "../internal/Isolate.hpp" #include "../internal/JavaObjectHandle.hpp" +#include "../promise/Promise.hpp" #include "DXFeedSubscription.hpp" @@ -146,7 +147,7 @@ struct DXFCPP_EXPORT DXFeed : SharedEntity { * * @return The DXFeed instance */ - static std::shared_ptr getInstance() noexcept; + static std::shared_ptr getInstance(); /** * Attaches the given subscription to this feed. This method does nothing if the @@ -164,7 +165,7 @@ struct DXFCPP_EXPORT DXFeed : SharedEntity { * @param subscription The subscription. * @see DXFeedSubscription */ - void attachSubscription(std::shared_ptr subscription) noexcept; + void attachSubscription(std::shared_ptr subscription); /** * Detaches the given subscription from this feed. This method does nothing if the @@ -178,7 +179,7 @@ struct DXFCPP_EXPORT DXFeed : SharedEntity { * @param subscription The subscription. * @see DXFeedSubscription */ - void detachSubscription(std::shared_ptr subscription) noexcept; + void detachSubscription(std::shared_ptr subscription); /** * Detaches the given subscription from this feed and clears data delivered to this subscription @@ -188,7 +189,7 @@ struct DXFCPP_EXPORT DXFeed : SharedEntity { * @param subscription The subscription. * @see DXFeed::detachSubscription() */ - void detachSubscriptionAndClear(std::shared_ptr subscription) noexcept; + void detachSubscriptionAndClear(std::shared_ptr subscription); /** * Creates new subscription for a single event type that is attached to this feed. @@ -202,7 +203,7 @@ struct DXFCPP_EXPORT DXFeed : SharedEntity { * @param eventType The type of event * @return The new subscription */ - std::shared_ptr createSubscription(const EventTypeEnum &eventType) noexcept; + std::shared_ptr createSubscription(const EventTypeEnum &eventType); /** * Creates new subscription for multiple event types that is attached to this feed. @@ -235,7 +236,7 @@ struct DXFCPP_EXPORT DXFeed : SharedEntity { * @return The new subscription */ template - std::shared_ptr createSubscription(EventTypeIt begin, EventTypeIt end) noexcept { + std::shared_ptr createSubscription(EventTypeIt begin, EventTypeIt end) { if constexpr (Debugger::isDebug) { Debugger::debug("{}::createSubscription(eventTypes = " + namesToString(begin, end) + ")"); } @@ -259,7 +260,7 @@ struct DXFCPP_EXPORT DXFeed : SharedEntity { * @param eventTypes The initializer list of event types * @return The new subscription */ - std::shared_ptr createSubscription(std::initializer_list eventTypes) noexcept; + std::shared_ptr createSubscription(std::initializer_list eventTypes); /** * Creates new subscription for multiple event types that is attached to this feed. @@ -281,7 +282,7 @@ struct DXFCPP_EXPORT DXFeed : SharedEntity { * @return The new subscription */ template - std::shared_ptr createSubscription(EventTypesCollection &&eventTypes) noexcept { + std::shared_ptr createSubscription(EventTypesCollection &&eventTypes) { if constexpr (Debugger::isDebug) { Debugger::debug(toString() + "::createSubscription(eventTypes = " + namesToString(std::begin(eventTypes), std::end(eventTypes)) + ")"); @@ -294,6 +295,10 @@ struct DXFCPP_EXPORT DXFeed : SharedEntity { return sub; } + Promise>> getTimeSeriesPromise(const EventTypeEnum &eventType, + const SymbolWrapper &symbol, std::int64_t fromTime, + std::int64_t toTime); + std::string toString() const noexcept override; }; diff --git a/include/dxfeed_graal_cpp_api/internal/JavaObjectHandle.hpp b/include/dxfeed_graal_cpp_api/internal/JavaObjectHandle.hpp index 7474193c..7dd5b613 100644 --- a/include/dxfeed_graal_cpp_api/internal/JavaObjectHandle.hpp +++ b/include/dxfeed_graal_cpp_api/internal/JavaObjectHandle.hpp @@ -55,6 +55,47 @@ template struct JavaObjectHandle { std::unique_ptr impl_; }; +template struct JavaObjectHandleList { +#if DXFCPP_DEBUG == 1 + static auto getDebugName() { + return std::string("JavaObjectHandleList<") + typeid(T).name() + ">"; + } +#endif + + using Type = T; + + static DXFCPP_EXPORT void deleter(void *handle) noexcept; + explicit JavaObjectHandleList(void *handle = nullptr) noexcept : impl_{handle, &deleter} { + if constexpr (Debugger::isDebug) { + Debugger::debug(getDebugName() + "(handle = " + dxfcpp::toString(handle) + ")"); + } + } + + JavaObjectHandleList(const JavaObjectHandleList &) = delete; + JavaObjectHandleList(JavaObjectHandleList &&) noexcept = default; + JavaObjectHandleList &operator=(const JavaObjectHandleList &) = delete; + JavaObjectHandleList &operator=(JavaObjectHandleList &&) noexcept = default; + virtual ~JavaObjectHandleList() noexcept = default; + + [[nodiscard]] std::string toString() const noexcept { + if (impl_) + return dxfcpp::toString(impl_.get()); + else + return "nullptr"; + } + + [[nodiscard]] void *get() const noexcept { + return impl_.get(); + } + + explicit operator bool() const noexcept { + return static_cast(impl_); + } + + private: + std::unique_ptr impl_; +}; + DXFCPP_END_NAMESPACE DXFCXX_DISABLE_MSC_WARNINGS_POP() \ No newline at end of file diff --git a/include/dxfeed_graal_cpp_api/isolated/api/IsolatedDXFeed.hpp b/include/dxfeed_graal_cpp_api/isolated/api/IsolatedDXFeed.hpp new file mode 100644 index 00000000..8fe95894 --- /dev/null +++ b/include/dxfeed_graal_cpp_api/isolated/api/IsolatedDXFeed.hpp @@ -0,0 +1,48 @@ +// Copyright (c) 2024 Devexperts LLC. +// SPDX-License-Identifier: MPL-2.0 + +#pragma once + +#include "../../internal/Conf.hpp" + +DXFCXX_DISABLE_MSC_WARNINGS_PUSH(4251) + +#include "../../api/DXFeed.hpp" + +DXFCPP_BEGIN_NAMESPACE + +namespace isolated::api::IsolatedDXFeed { + +/* + +dxfg_feed_t* dxfg_DXFeed_getInstance(graal_isolatethread_t *thread); +dxfg_subscription_t* dxfg_DXFeed_createSubscription(graal_isolatethread_t *thread, dxfg_feed_t *feed, dxfg_event_clazz_t eventClazz); +dxfg_subscription_t* dxfg_DXFeed_createSubscription2(graal_isolatethread_t *thread, dxfg_feed_t *feed, dxfg_event_clazz_list_t *eventClazzes); +dxfg_time_series_subscription_t* dxfg_DXFeed_createTimeSeriesSubscription(graal_isolatethread_t *thread, dxfg_feed_t *feed, dxfg_event_clazz_t eventClazz); +dxfg_time_series_subscription_t* dxfg_DXFeed_createTimeSeriesSubscription2(graal_isolatethread_t *thread, dxfg_feed_t *feed, dxfg_event_clazz_list_t *eventClazzes); +int32_t dxfg_DXFeed_attachSubscription(graal_isolatethread_t *thread, dxfg_feed_t *feed, dxfg_subscription_t *sub); +int32_t dxfg_DXFeed_detachSubscription(graal_isolatethread_t *thread, dxfg_feed_t *feed, dxfg_subscription_t *sub); +int32_t dxfg_DXFeed_detachSubscriptionAndClear(graal_isolatethread_t *thread, dxfg_feed_t *feed, dxfg_subscription_t *sub); +dxfg_event_type_t* dxfg_DXFeed_getLastEventIfSubscribed(graal_isolatethread_t *thread, dxfg_feed_t *feed, dxfg_event_clazz_t eventClazz, dxfg_symbol_t *symbol); +dxfg_event_type_list* dxfg_DXFeed_getIndexedEventsIfSubscribed(graal_isolatethread_t *thread, dxfg_feed_t *feed, dxfg_event_clazz_t eventClazz, dxfg_symbol_t *symbol, const char *source); +dxfg_event_type_list* dxfg_DXFeed_getTimeSeriesIfSubscribed(graal_isolatethread_t *thread, dxfg_feed_t *feed, dxfg_event_clazz_t eventClazz, dxfg_symbol_t *symbol, int64_t from_time, int64_t to_time); +// use dxfg_EventType_new to create an empty structure so that java tries to free up memory when replacing subjects +int32_t dxfg_DXFeed_getLastEvent(graal_isolatethread_t *thread, dxfg_feed_t *feed, dxfg_event_type_t *event); +int32_t dxfg_DXFeed_getLastEvents(graal_isolatethread_t *thread, dxfg_feed_t *feed, dxfg_event_type_list *events); +dxfg_promise_event_t* dxfg_DXFeed_getLastEventPromise(graal_isolatethread_t *thread, dxfg_feed_t *feed, dxfg_event_clazz_t eventClazz, dxfg_symbol_t *symbol); +dxfg_promise_list* dxfg_DXFeed_getLastEventsPromises(graal_isolatethread_t *thread, dxfg_feed_t *feed, dxfg_event_clazz_t eventClazz, dxfg_symbol_list *symbols); +dxfg_promise_events_t* dxfg_DXFeed_getIndexedEventsPromise(graal_isolatethread_t *thread, dxfg_feed_t *feed, dxfg_event_clazz_t eventClazz, dxfg_symbol_t *symbol, dxfg_indexed_event_source_t* source); +dxfg_promise_events_t* dxfg_DXFeed_getTimeSeriesPromise(graal_isolatethread_t *thread, dxfg_feed_t *feed, dxfg_event_clazz_t clazz, dxfg_symbol_t *symbol, int64_t fromTime, int64_t toTime); + +*/ + + +/* dxfg_promise_events_t* */ void* getTimeSeriesPromise(/* dxfg_feed_t * */ const JavaObjectHandle& feed, /* dxfg_event_clazz_t */ const EventTypeEnum &eventType, /* dxfg_symbol_t * */ const SymbolWrapper &symbol, std::int64_t fromTime, + std::int64_t toTime); + + +} + +DXFCPP_END_NAMESPACE + +DXFCXX_DISABLE_MSC_WARNINGS_POP() \ No newline at end of file diff --git a/include/dxfeed_graal_cpp_api/promise/Promise.hpp b/include/dxfeed_graal_cpp_api/promise/Promise.hpp index 09ff4bb5..738480fb 100644 --- a/include/dxfeed_graal_cpp_api/promise/Promise.hpp +++ b/include/dxfeed_graal_cpp_api/promise/Promise.hpp @@ -7,16 +7,57 @@ DXFCXX_DISABLE_MSC_WARNINGS_PUSH(4251) +#include +#include + DXFCPP_BEGIN_NAMESPACE -template -struct Promise {}; +struct TimeSeriesEvent; +struct LastingEvent; + +struct PromiseImpl { + +}; + +template struct Promise { +}; + +template +concept Derived = std::is_base_of_v; -template <> -struct Promise> { +template T> struct Promise> { }; +template T> struct Promise> { + +}; + +template T> struct Promise>> { + +}; + + +// +// Promise> x{}; +// auto _ = x.z(); +// +// template struct PromiseSFINAE { +// int x() { +// return {}; +// } +// }; +// +// template +// struct PromiseSFINAE::value>::type> { +// int z() { +// return 0; +// } +// }; +// +// PromiseSFINAE> xx{}; +// auto __ = xx.z(); + DXFCPP_END_NAMESPACE DXFCXX_DISABLE_MSC_WARNINGS_POP() \ No newline at end of file diff --git a/src/api/DXFeed.cpp b/src/api/DXFeed.cpp index 087c05fc..170f95c3 100644 --- a/src/api/DXFeed.cpp +++ b/src/api/DXFeed.cpp @@ -16,7 +16,7 @@ DXFCPP_BEGIN_NAMESPACE -std::shared_ptr DXFeed::getInstance() noexcept { +std::shared_ptr DXFeed::getInstance() { if constexpr (Debugger::isDebug) { Debugger::debug("DXFeed::getInstance()"); } @@ -24,7 +24,7 @@ std::shared_ptr DXFeed::getInstance() noexcept { return DXEndpoint::getInstance()->getFeed(); } -void DXFeed::attachSubscription(std::shared_ptr subscription) noexcept { +void DXFeed::attachSubscription(std::shared_ptr subscription) { if constexpr (Debugger::isDebug) { Debugger::debug(toString() + "::attachSubscription(" + subscription->toString() + ")"); } @@ -43,7 +43,7 @@ void DXFeed::attachSubscription(std::shared_ptr subscription } } -void DXFeed::detachSubscription(std::shared_ptr subscription) noexcept { +void DXFeed::detachSubscription(std::shared_ptr subscription) { if constexpr (Debugger::isDebug) { Debugger::debug(toString() + "::detachSubscription(" + subscription->toString() + ")"); } @@ -62,7 +62,7 @@ void DXFeed::detachSubscription(std::shared_ptr subscription } } -void DXFeed::detachSubscriptionAndClear(std::shared_ptr subscription) noexcept { +void DXFeed::detachSubscriptionAndClear(std::shared_ptr subscription) { if constexpr (Debugger::isDebug) { Debugger::debug(toString() + "::detachSubscriptionAndClear(" + subscription->toString() + ")"); } @@ -81,7 +81,7 @@ void DXFeed::detachSubscriptionAndClear(std::shared_ptr subs } } -std::shared_ptr DXFeed::createSubscription(const EventTypeEnum &eventType) noexcept { +std::shared_ptr DXFeed::createSubscription(const EventTypeEnum &eventType) { if constexpr (Debugger::isDebug) { Debugger::debug(toString() + "::createSubscription(eventType = " + eventType.getName() + ")"); } @@ -93,8 +93,7 @@ std::shared_ptr DXFeed::createSubscription(const EventTypeEn return sub; } -std::shared_ptr -DXFeed::createSubscription(std::initializer_list eventTypes) noexcept { +std::shared_ptr DXFeed::createSubscription(std::initializer_list eventTypes) { if constexpr (Debugger::isDebug) { Debugger::debug(toString() + "::createSubscription(eventTypes = " + namesToString(eventTypes.begin(), eventTypes.end()) + ")"); @@ -122,6 +121,16 @@ std::shared_ptr DXFeed::create(void *feedHandle) { return feed; } +Promise>> DXFeed::getTimeSeriesPromise(const EventTypeEnum &eventType, + const SymbolWrapper &symbol, + std::int64_t fromTime, + std::int64_t toTime) { + + // TODO: impelement + + return {}; +} + std::string DXFeed::toString() const noexcept { return fmt::format("DXFeed{{{}}}", handle_.toString()); } diff --git a/src/internal/JavaObjectHandle.cpp b/src/internal/JavaObjectHandle.cpp index 21893ddc..87e84284 100644 --- a/src/internal/JavaObjectHandle.cpp +++ b/src/internal/JavaObjectHandle.cpp @@ -26,7 +26,31 @@ template void JavaObjectHandle::deleter(void *handle) noexcept { dxfcpp::ignore_unused(result); if constexpr (Debugger::isDebug) { - Debugger::debug(getDebugName() + "::deleter(handle = " + dxfcpp::toString(handle) + ") -> " + dxfcpp::toString(result)); + Debugger::debug(getDebugName() + "::deleter(handle = " + dxfcpp::toString(handle) + ") -> " + + dxfcpp::toString(result)); + } +} + +template void JavaObjectHandleList::deleter(void *handle) noexcept { + auto result = runIsolatedOrElse( + [handle = handle](auto threadHandle) { + if constexpr (Debugger::isDebug) { + Debugger::debug(getDebugName() + "::deleter(handle = " + dxfcpp::toString(handle) + ")"); + } + + if (handle) { + return dxfg_CList_JavaObjectHandler_release(static_cast(threadHandle), + static_cast(handle)) == 0; + } + + return true; + }, + false); + dxfcpp::ignore_unused(result); + + if constexpr (Debugger::isDebug) { + Debugger::debug(getDebugName() + "::deleter(handle = " + dxfcpp::toString(handle) + ") -> " + + dxfcpp::toString(result)); } } diff --git a/src/isolated/api/IsolatedDXFeed.cpp b/src/isolated/api/IsolatedDXFeed.cpp new file mode 100644 index 00000000..1358bd75 --- /dev/null +++ b/src/isolated/api/IsolatedDXFeed.cpp @@ -0,0 +1,36 @@ +// Copyright (c) 2024 Devexperts LLC. +// SPDX-License-Identifier: MPL-2.0 + +#include + +#include +#include + +DXFCPP_BEGIN_NAMESPACE + +namespace isolated::api::IsolatedDXFeed { + +/* dxfg_promise_events_t* */ void *getTimeSeriesPromise(/* dxfg_feed_t * */ const JavaObjectHandle &feed, + /* dxfg_event_clazz_t */ const EventTypeEnum &eventType, + /* dxfg_symbol_t * */ const SymbolWrapper &symbol, + std::int64_t fromTime, std::int64_t toTime) { + if (!feed) { + throw std::invalid_argument( + "Unable to execute function `dxfg_DXFeed_getTimeSeriesPromise`. The `feed` handle is invalid"); + } + + auto graalSymbol = symbol.toGraal(); + + auto result = dxfcpp::bit_cast( + runGraalFunctionAndThrowIfNullptr(dxfg_DXFeed_getTimeSeriesPromise, static_cast(feed.get()), + static_cast(eventType.getId()), + static_cast(graalSymbol), fromTime, toTime)); + + SymbolWrapper::freeGraal(graalSymbol); + + return result; +} + +} // namespace isolated::api::IsolatedDXFeed + +DXFCPP_END_NAMESPACE \ No newline at end of file