PHP WebShell
Текущая директория: /usr/lib/node_modules/bitgo/node_modules/react-native/ReactCommon/react/renderer/core
Просмотр файла: EventBeat.h
/*
* 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 <atomic>
#include <functional>
#include <memory>
namespace facebook::react {
class RuntimeScheduler;
}
namespace facebook::jsi {
class Runtime;
}
namespace facebook::react {
/*
* Event Beat serves two interleaving purposes: synchronization of event queues
* and ensuring that event dispatching happens on proper threads.
*
* You must set beat callback by calling `EventBeat::setBeatCallback` before
* calling `EventBeat::request` and `EventBeat::requestSynchronous`.
*
* EventBeat is meant to be subclassed by platform-specific implementations.
* The platform-specific implementation must call EventBeat::induce(). The
* appropriate time to call induce is when the host platform events were queued
* in the EventQueue for a given UI frame. For example, on iOS,
* EventBeat::induce() is called before the main run loop goes to sleep. On
* Android, EventBeat::induce() is called from Android's Choreographer.
*/
class EventBeat {
public:
/*
* The concept of `Owner`
* The purpose of `EventBeat` is handling an asynchronous callback to itself
* which is being delivered on a different thread. That brings a challenge
* of ensuring that the `EventBeat` object stays valid during the timeframe of
* callback execution. The concept of Owner helps with that. The owner is a
* shared pointer that retains (probably indirectly) the `EventBeat` object.
* To ensure the correctness of the call, `EventBeat` retains the owner
* weakly during executing the callback. If the pointer to the owner is
* already null, `EventBeat` skips executing the callback. It's impossible to
* retain itself directly or refer to the shared pointer to itself from a
* constructor. `OwnerBox` is designed to work around this issue; it can
* store the pointer after the creation of some other object that
* owns an `EventBeat`.
*/
struct OwnerBox {
std::weak_ptr<const void> owner;
};
using Factory = std::function<std::unique_ptr<EventBeat>(
std::shared_ptr<OwnerBox> ownerBox)>;
using BeatCallback = std::function<void(jsi::Runtime& runtime)>;
explicit EventBeat(
std::shared_ptr<OwnerBox> ownerBox,
RuntimeScheduler& runtimeScheduler);
virtual ~EventBeat() = default;
// not copyable
EventBeat(const EventBeat& other) = delete;
EventBeat& operator=(const EventBeat& other) = delete;
/*
* Communicates to the Beat that a consumer (for example EventQueue) is
* waiting for the coming beat. A consumer must request coming beat after the
* previous beat happened to receive a next coming one.
*
* Callback, that was set by `setBeatCallback`, will be dispatched to
* JavaScript thread asynchronously via `RuntimeScheduler::scheduleWork`.
*
* tick (provided by host platform)
* UI │
* thread─┬───────┬─▼──────┬─────────────────────────────▶
* │request│ │induce│ ┌────────────┐
* └───────┘ └──────┴─▶│scheduleWork│
* └───────────┬┘
* JS │
* thread─────────────────────────────────▼─────────────┬▶
* │beat callback│
* └─────────────┘
*
*/
virtual void request() const;
/*
* Communicates to the Beat that a consumer (for example EventQueue) is
* waiting for the coming beat. A consumer must request coming beat after the
* previous beat happened to receive a next coming one.
*
* Callback, that was set by `setBeatCallback`, will be called on the thread
* where `induce` is called synchronously via via
* `RuntimeScheduler::executeNowOnTheSameThread`. Both threads are blocked
* until beat callback finishes.
*
* tick
* UI │
* thread─┬───────┬─▼──────┬─┬─────────────────────────┬▶
* │request│ │induce│ │executeNowOnTheSameThread│
* └───────┘ └──────┴▶├─────────────────────────┤
* JS │ beat callback │
* thread────────────────────┴─────────────────────────┴▶
* Both JS and UI thread are
* blocked.
*/
virtual void requestSynchronous() const;
/*
* The callback will be executed once a consumer (for example EventQueue)
* calls either `EventBeat::request` or `EventBeat::requestSynchronous`. The
* callback will be executed on the proper thread.
*/
void setBeatCallback(BeatCallback beatCallback);
/*
* The callback will be executed once a consumer (for example EventQueue)
* calls either `EventBeat::request` or `EventBeat::requestSynchronous`. The
* callback will be executed on the UI thread.
*
* If not set, this is a no-op and callback won't be called.
*/
void unstable_setInduceCallback(std::function<void()> callback);
protected:
/*
* Induces the next beat to happen as soon as possible.
* Receiver might ignore the call if a beat was not requested.
*/
void induce() const;
BeatCallback beatCallback_;
std::function<void()> induceCallback_;
std::shared_ptr<OwnerBox> ownerBox_;
/*
* Indicates if event beat was requested to avoid redundant requests.
*/
mutable std::atomic<bool> isEventBeatRequested_{false};
private:
RuntimeScheduler& runtimeScheduler_;
mutable std::atomic<bool> isBeatCallbackScheduled_{false};
mutable std::atomic<bool> isSynchronousRequested_{false};
};
} // namespace facebook::react
Выполнить команду
Для локальной разработки. Не используйте в интернете!