From 047914562e5f08fc4ff49c31bb29144ee91ad523 Mon Sep 17 00:00:00 2001 From: Andrew Datsenko Date: Fri, 11 Apr 2025 14:35:03 -0700 Subject: [PATCH] move rncxx utils (#50668) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/50668 Changelog: [Internal] Reviewed By: zeyap Differential Revision: D72800712 fbshipit-source-id: f966906d10df1fac818fc9998dbe5e0b8d67be3f --- .../ReactCxxPlatform/react/utils/EnumHelper.h | 20 +++++++ .../react/utils/PlatformRunLoopObserver.h | 46 +++++++++++++++ .../react/utils/RunLoopObserverManager.cpp | 59 +++++++++++++++++++ .../react/utils/RunLoopObserverManager.h | 33 +++++++++++ 4 files changed, 158 insertions(+) create mode 100644 packages/react-native/ReactCxxPlatform/react/utils/EnumHelper.h create mode 100644 packages/react-native/ReactCxxPlatform/react/utils/PlatformRunLoopObserver.h create mode 100644 packages/react-native/ReactCxxPlatform/react/utils/RunLoopObserverManager.cpp create mode 100644 packages/react-native/ReactCxxPlatform/react/utils/RunLoopObserverManager.h diff --git a/packages/react-native/ReactCxxPlatform/react/utils/EnumHelper.h b/packages/react-native/ReactCxxPlatform/react/utils/EnumHelper.h new file mode 100644 index 00000000000..86850d3f198 --- /dev/null +++ b/packages/react-native/ReactCxxPlatform/react/utils/EnumHelper.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +namespace std { + +// mimics the c++23 std::to_underlying +template +constexpr auto to_underlying(Enum e) noexcept { + return static_cast>(e); +} + +} // namespace std diff --git a/packages/react-native/ReactCxxPlatform/react/utils/PlatformRunLoopObserver.h b/packages/react-native/ReactCxxPlatform/react/utils/PlatformRunLoopObserver.h new file mode 100644 index 00000000000..b50ac8170fd --- /dev/null +++ b/packages/react-native/ReactCxxPlatform/react/utils/PlatformRunLoopObserver.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include + +namespace facebook::react { + +class PlatformRunLoopObserver; + +class PlatformRunLoopObserver : public RunLoopObserver { + public: + PlatformRunLoopObserver( + RunLoopObserver::Activity activities, + const RunLoopObserver::WeakOwner& owner) + : RunLoopObserver(activities, owner) {} + ~PlatformRunLoopObserver() override = default; + + PlatformRunLoopObserver(PlatformRunLoopObserver& other) = delete; + PlatformRunLoopObserver& operator=(PlatformRunLoopObserver& other) = delete; + PlatformRunLoopObserver(PlatformRunLoopObserver&& other) = delete; + PlatformRunLoopObserver& operator=(PlatformRunLoopObserver&& other) = delete; + + bool isOnRunLoopThread() const noexcept override { + return false; + } + + void onRender() const noexcept { + if (auto owner = owner_.lock()) { + activityDidChange(activities_); + } + } + + private: + void startObserving() const noexcept override {} + void stopObserving() const noexcept override {} +}; + +} // namespace facebook::react diff --git a/packages/react-native/ReactCxxPlatform/react/utils/RunLoopObserverManager.cpp b/packages/react-native/ReactCxxPlatform/react/utils/RunLoopObserverManager.cpp new file mode 100644 index 00000000000..cd02314d271 --- /dev/null +++ b/packages/react-native/ReactCxxPlatform/react/utils/RunLoopObserverManager.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "RunLoopObserverManager.h" + +#include + +namespace facebook::react { + +/* + * Event beat associated with JavaScript runtime. The beat is called on + * RuntimeScheduler's thread induced by the UI thread event loop. + */ +class EventBeatImpl : public EventBeat, public RunLoopObserver::Delegate { + public: + EventBeatImpl( + std::shared_ptr ownerBox, + std::shared_ptr uiRunLoopObserver, + RuntimeScheduler& runtimeScheduler) + : EventBeat(std::move(ownerBox), runtimeScheduler), + uiRunLoopObserver_(std::move(uiRunLoopObserver)) { + uiRunLoopObserver_->setDelegate(this); + uiRunLoopObserver_->enable(); + } + +#pragma mark - RunLoopObserver::Delegate + + void activityDidChange( + const RunLoopObserver::Delegate* delegate, + RunLoopObserver::Activity /*activity*/) const noexcept override { + react_native_assert(delegate == this); + induce(); + } + + private: + std::shared_ptr uiRunLoopObserver_; +}; + +std::unique_ptr RunLoopObserverManager::createEventBeat( + std::shared_ptr ownerBox, + RuntimeScheduler& runtimeScheduler) { + auto observer = std::make_shared( + RunLoopObserver::Activity::BeforeWaiting, ownerBox->owner); + observer_ = observer; + return std::make_unique( + std::move(ownerBox), std::move(observer), runtimeScheduler); +} + +void RunLoopObserverManager::onRender() const noexcept { + if (auto observer = observer_.lock()) { + observer->onRender(); + } +} + +} // namespace facebook::react diff --git a/packages/react-native/ReactCxxPlatform/react/utils/RunLoopObserverManager.h b/packages/react-native/ReactCxxPlatform/react/utils/RunLoopObserverManager.h new file mode 100644 index 00000000000..1f565b1ccb4 --- /dev/null +++ b/packages/react-native/ReactCxxPlatform/react/utils/RunLoopObserverManager.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include "PlatformRunLoopObserver.h" + +#include +#include +#include + +namespace facebook::react { + +class RunLoopObserverManager + : std::enable_shared_from_this { + public: + std::unique_ptr createEventBeat( + std::shared_ptr ownerBox, + RuntimeScheduler& runtimeScheduler); + + void onRender() const noexcept; + + void induce() const noexcept; + + private: + std::weak_ptr observer_; +}; + +} // namespace facebook::react