diff --git a/native/android/app/CMakeLists.txt b/native/android/app/CMakeLists.txt --- a/native/android/app/CMakeLists.txt +++ b/native/android/app/CMakeLists.txt @@ -135,6 +135,7 @@ # React dependencies ${_react_native_dir}/ReactCommon/jsi/jsi/jsi.cpp + ${_react_native_dir}/ReactCommon/jsi/jsi/JSIDynamic.cpp ${_react_native_dir}/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/CallInvokerHolder.cpp ${_react_native_dir}/ReactCommon/react/nativemodule/core/ReactCommon/TurboModule.cpp ${_react_native_dir}/ReactCommon/react/bridging/LongLivedObject.cpp diff --git a/native/cpp/CommonCpp/CryptoTools/DeviceID.h b/native/cpp/CommonCpp/CryptoTools/DeviceID.h --- a/native/cpp/CommonCpp/CryptoTools/DeviceID.h +++ b/native/cpp/CommonCpp/CryptoTools/DeviceID.h @@ -1,3 +1,5 @@ +#pragma once + #include "lib.rs.h" #include #include diff --git a/native/cpp/CommonCpp/NativeModules/InternalModules/RustPromiseManager.h b/native/cpp/CommonCpp/NativeModules/InternalModules/RustPromiseManager.h new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/InternalModules/RustPromiseManager.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include +#include + +#include +#include + +namespace comm { + +using namespace facebook::react; + +class RustPromiseManager { + std::atomic id{0}; + + RustPromiseManager(); + + uint32_t getNextID() { + return this->id++; + }; + +public: + static RustPromiseManager instance; + uint32_t addPromise( + std::shared_ptr promise, + std::shared_ptr jsInvoker, + facebook::jsi::Runtime &rt); + void removePromise(uint32_t id); + void resolvePromise(uint32_t id, folly::dynamic ret); + void rejectPromise(uint32_t id, const std::string &error); + + struct PromiseInfo { + std::shared_ptr promise; + std::shared_ptr jsInvoker; + facebook::jsi::Runtime &rt; + }; + std::unordered_map promises; + std::shared_mutex mutex; +}; +} // namespace comm diff --git a/native/cpp/CommonCpp/NativeModules/InternalModules/RustPromiseManager.cpp b/native/cpp/CommonCpp/NativeModules/InternalModules/RustPromiseManager.cpp new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/InternalModules/RustPromiseManager.cpp @@ -0,0 +1,62 @@ +#include "RustPromiseManager.h" + +namespace comm { +RustPromiseManager RustPromiseManager::instance; + +RustPromiseManager::RustPromiseManager(){}; + +uint32_t RustPromiseManager::addPromise( + std::shared_ptr promise, + std::shared_ptr jsInvoker, + facebook::jsi::Runtime &rt) { + uint32_t id = getNextID(); + PromiseInfo info = {promise, jsInvoker, rt}; + // Acquire a lock for writing + std::unique_lock lock(mutex); + promises.insert({id, info}); + return id; +} + +void RustPromiseManager::removePromise(uint32_t id) { + // Acquire a lock for writing + std::unique_lock lock(mutex); + promises.erase(id); +} + +void RustPromiseManager::resolvePromise(uint32_t id, folly::dynamic ret) { + // Acquire a shared lock for reading + std::shared_lock lock(mutex); + auto it = promises.find(id); + if (it != promises.end()) { + // Release the shared lock + lock.unlock(); + auto promiseInfo = it->second; + if (promiseInfo.jsInvoker) { + promiseInfo.jsInvoker->invokeAsync([promiseInfo, ret]() { + promiseInfo.promise->resolve(valueFromDynamic(promiseInfo.rt, ret)); + }); + } else { + promiseInfo.promise->resolve(valueFromDynamic(promiseInfo.rt, ret)); + } + removePromise(id); + } +} + +void RustPromiseManager::rejectPromise(uint32_t id, const std::string &error) { + // Acquire a shared lock for reading + std::shared_lock lock(mutex); + auto it = promises.find(id); + if (it != promises.end()) { + // Release the shared lock + lock.unlock(); + if (it->second.jsInvoker) { + it->second.jsInvoker->invokeAsync( + [promise = it->second.promise, error]() { promise->reject(error); }); + } else { + it->second.promise->reject(error); + } + removePromise(id); + } +} + +} // namespace comm