mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
introduce EventEmitter::experimental_flushSync (#43592)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/43592 changelog: [internal] Exposing experimental API EventEmitter::experimental_flushSync to trigger synchronous event from native. The API will be changed in the future, this is exposed only for experimentation. Reviewed By: javache Differential Revision: D54805494 fbshipit-source-id: fb395588cf1dc944a920ec4a2257390552850263
This commit is contained in:
committed by
Facebook GitHub Bot
parent
15a5638c62
commit
223e6dc898
@@ -18,9 +18,12 @@ namespace facebook::react {
|
||||
EventDispatcher::EventDispatcher(
|
||||
const EventQueueProcessor& eventProcessor,
|
||||
const EventBeat::Factory& asynchronousEventBeatFactory,
|
||||
const EventBeat::SharedOwnerBox& ownerBox)
|
||||
: eventQueue_(
|
||||
EventQueue(eventProcessor, asynchronousEventBeatFactory(ownerBox))) {}
|
||||
const EventBeat::SharedOwnerBox& ownerBox,
|
||||
RuntimeScheduler& runtimeScheduler)
|
||||
: eventQueue_(EventQueue(
|
||||
eventProcessor,
|
||||
asynchronousEventBeatFactory(ownerBox),
|
||||
runtimeScheduler)) {}
|
||||
|
||||
void EventDispatcher::dispatchEvent(RawEvent&& rawEvent) const {
|
||||
// Allows the event listener to interrupt default event dispatch
|
||||
@@ -35,6 +38,10 @@ void EventDispatcher::dispatchEvent(RawEvent&& rawEvent) const {
|
||||
eventQueue_.enqueueEvent(std::move(rawEvent));
|
||||
}
|
||||
|
||||
void EventDispatcher::experimental_flushSync() const {
|
||||
eventQueue_.experimental_flushSync();
|
||||
}
|
||||
|
||||
void EventDispatcher::dispatchStateUpdate(StateUpdate&& stateUpdate) const {
|
||||
eventQueue_.enqueueStateUpdate(std::move(stateUpdate));
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
namespace facebook::react {
|
||||
|
||||
struct RawEvent;
|
||||
class RuntimeScheduler;
|
||||
|
||||
/*
|
||||
* Represents event-delivery infrastructure.
|
||||
@@ -29,13 +30,19 @@ class EventDispatcher {
|
||||
EventDispatcher(
|
||||
const EventQueueProcessor& eventProcessor,
|
||||
const EventBeat::Factory& asynchronousEventBeatFactory,
|
||||
const EventBeat::SharedOwnerBox& ownerBox);
|
||||
const EventBeat::SharedOwnerBox& ownerBox,
|
||||
RuntimeScheduler& runtimeScheduler);
|
||||
|
||||
/*
|
||||
* Dispatches a raw event with given priority using event-delivery pipe.
|
||||
*/
|
||||
void dispatchEvent(RawEvent&& rawEvent) const;
|
||||
|
||||
/*
|
||||
* Experimental API exposed to support EventEmitter::experimental_flushSync.
|
||||
*/
|
||||
void experimental_flushSync() const;
|
||||
|
||||
/*
|
||||
* Dispatches a raw event with asynchronous batched priority. Before the
|
||||
* dispatch we make sure that no other RawEvent of same type and same target
|
||||
|
||||
@@ -57,6 +57,20 @@ class EventEmitter {
|
||||
|
||||
const SharedEventTarget& getEventTarget() const;
|
||||
|
||||
/*
|
||||
* Experimental API that will change in the future.
|
||||
*/
|
||||
template <typename Lambda>
|
||||
void experimental_flushSync(Lambda syncFunc) const {
|
||||
auto eventDispatcher = eventDispatcher_.lock();
|
||||
if (!eventDispatcher) {
|
||||
return;
|
||||
}
|
||||
|
||||
syncFunc();
|
||||
eventDispatcher->experimental_flushSync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Initiates an event delivery process.
|
||||
* Is used by particular subclasses only.
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "EventQueue.h"
|
||||
|
||||
#include <react/renderer/runtimescheduler/RuntimeScheduler.h>
|
||||
#include "EventEmitter.h"
|
||||
#include "ShadowNodeFamily.h"
|
||||
|
||||
@@ -14,9 +15,11 @@ namespace facebook::react {
|
||||
|
||||
EventQueue::EventQueue(
|
||||
EventQueueProcessor eventProcessor,
|
||||
std::unique_ptr<EventBeat> eventBeat)
|
||||
std::unique_ptr<EventBeat> eventBeat,
|
||||
RuntimeScheduler& runtimeScheduler)
|
||||
: eventProcessor_(std::move(eventProcessor)),
|
||||
eventBeat_(std::move(eventBeat)) {
|
||||
eventBeat_(std::move(eventBeat)),
|
||||
runtimeScheduler_(&runtimeScheduler) {
|
||||
eventBeat_->setBeatCallback(
|
||||
[this](jsi::Runtime& runtime) { onBeat(runtime); });
|
||||
}
|
||||
@@ -76,10 +79,26 @@ void EventQueue::enqueueStateUpdate(StateUpdate&& stateUpdate) const {
|
||||
}
|
||||
|
||||
void EventQueue::onEnqueue() const {
|
||||
if (synchronousAccessRequested_) {
|
||||
// Sync flush has been scheduled, no need to request access to the runtime.
|
||||
return;
|
||||
}
|
||||
eventBeat_->request();
|
||||
}
|
||||
|
||||
void EventQueue::experimental_flushSync() const {
|
||||
synchronousAccessRequested_ = true;
|
||||
runtimeScheduler_->executeNowOnTheSameThread([this](jsi::Runtime& runtime) {
|
||||
synchronousAccessRequested_ = false;
|
||||
onBeat(runtime);
|
||||
});
|
||||
}
|
||||
|
||||
void EventQueue::onBeat(jsi::Runtime& runtime) const {
|
||||
if (synchronousAccessRequested_) {
|
||||
// Sync flush has been scheduled, let's yield to it.
|
||||
return;
|
||||
}
|
||||
flushStateUpdates();
|
||||
flushEvents(runtime);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
class RuntimeScheduler;
|
||||
|
||||
/*
|
||||
* Event Queue synchronized with given Event Beat and dispatching event
|
||||
* using given Event Pipe.
|
||||
@@ -27,7 +29,8 @@ class EventQueue {
|
||||
public:
|
||||
EventQueue(
|
||||
EventQueueProcessor eventProcessor,
|
||||
std::unique_ptr<EventBeat> eventBeat);
|
||||
std::unique_ptr<EventBeat> eventBeat,
|
||||
RuntimeScheduler& runtimeScheduler);
|
||||
|
||||
/*
|
||||
* Enqueues and (probably later) dispatch a given event.
|
||||
@@ -48,6 +51,11 @@ class EventQueue {
|
||||
*/
|
||||
void enqueueStateUpdate(StateUpdate&& stateUpdate) const;
|
||||
|
||||
/*
|
||||
* Experimental API exposed to support EventEmitter::experimental_flushSync.
|
||||
*/
|
||||
void experimental_flushSync() const;
|
||||
|
||||
protected:
|
||||
/*
|
||||
* Called on any enqueue operation.
|
||||
@@ -67,6 +75,10 @@ class EventQueue {
|
||||
mutable std::vector<RawEvent> eventQueue_;
|
||||
mutable std::vector<StateUpdate> stateUpdateQueue_;
|
||||
mutable std::mutex queueMutex_;
|
||||
|
||||
// TODO: T183075253
|
||||
RuntimeScheduler* runtimeScheduler_;
|
||||
mutable std::atomic_bool synchronousAccessRequested_{false};
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
@@ -84,7 +84,8 @@ Scheduler::Scheduler(
|
||||
eventDispatcher_->emplace(
|
||||
EventQueueProcessor(eventPipe, eventPipeConclusion, statePipe),
|
||||
schedulerToolbox.asynchronousEventBeatFactory,
|
||||
eventOwnerBox);
|
||||
eventOwnerBox,
|
||||
*runtimeScheduler);
|
||||
|
||||
// Casting to `std::shared_ptr<EventDispatcher const>`.
|
||||
auto eventDispatcher =
|
||||
|
||||
Reference in New Issue
Block a user