/* * 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 #include #include "PlatformTimerRegistry.h" namespace facebook::react { using TimerHandle = int; enum class TimerSource { Unknown, SetTimeout, SetInterval, RequestAnimationFrame }; /* * Wraps a jsi::Function to make it copyable so we can pass it into a lambda. */ struct TimerCallback { TimerCallback( jsi::Function callback, std::vector args, bool repeat, TimerSource source = TimerSource::Unknown) : callback_(std::move(callback)), args_(std::move(args)), repeat(repeat), source(source) {} void invoke(jsi::Runtime& runtime) { callback_.call(runtime, args_.data(), args_.size()); } jsi::Function callback_; const std::vector args_; bool repeat; TimerSource source; }; class TimerManager { public: explicit TimerManager( std::unique_ptr platformTimerRegistry) noexcept; void setRuntimeExecutor(RuntimeExecutor runtimeExecutor) noexcept; void callReactNativeMicrotasks(jsi::Runtime& runtime); void callTimer(TimerHandle handle); void attachGlobals(jsi::Runtime& runtime); private: TimerHandle createReactNativeMicrotask( jsi::Function&& callback, std::vector&& args); void deleteReactNativeMicrotask(jsi::Runtime& runtime, TimerHandle handle); TimerHandle createTimer( jsi::Function&& callback, std::vector&& args, double delay, TimerSource source = TimerSource::Unknown); void deleteTimer(jsi::Runtime& runtime, TimerHandle handle); TimerHandle createRecurringTimer( jsi::Function&& callback, std::vector&& args, double delay, TimerSource source = TimerSource::Unknown); void deleteRecurringTimer(jsi::Runtime& runtime, TimerHandle handle); RuntimeExecutor runtimeExecutor_; std::unique_ptr platformTimerRegistry_; // A map (id => callback func) of the currently active JS timers std::unordered_map timers_; // Each timeout that is registered on this queue gets a sequential id. This // is the global count from which those are assigned. TimerHandle timerIndex_{0}; // The React Native microtask queue is used to back public APIs including // `queueMicrotask`, `clearImmediate`, and `setImmediate` (which is used by // the Promise polyfill) when the JSVM microtask mechanism is not used. std::vector reactNativeMicrotasksQueue_; }; } // namespace facebook::react