Files
react-native/ReactCommon/react/renderer/core/EventQueue.cpp
T
Samuel Susla 285406103d Introduce EventQueueProcessor
Summary:
Changelog: [internal]

Pulling out event queue processing to its separate class. We will be adding more logic there so it makes sense to separate it for simplicity and testability purposes.

Alternative names that came to mind: `EventsProcessor`, `EventsDispatcher`.

Reviewed By: JoshuaGross

Differential Revision: D28572283

fbshipit-source-id: 1cb2459f616b9995f66da80d50c401e68002da7f
2021-05-25 01:16:04 -07:00

120 lines
2.9 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "EventQueue.h"
#include "EventEmitter.h"
#include "ShadowNodeFamily.h"
namespace facebook {
namespace react {
EventQueue::EventQueue(
EventQueueProcessor eventProcessor,
std::unique_ptr<EventBeat> eventBeat)
: eventProcessor_(std::move(eventProcessor)),
eventBeat_(std::move(eventBeat)) {
eventBeat_->setBeatCallback(
std::bind(&EventQueue::onBeat, this, std::placeholders::_1));
}
void EventQueue::enqueueEvent(RawEvent &&rawEvent) const {
{
std::lock_guard<std::mutex> lock(queueMutex_);
eventQueue_.push_back(std::move(rawEvent));
}
onEnqueue();
}
void EventQueue::enqueueUniqueEvent(RawEvent &&rawEvent) const {
{
std::lock_guard<std::mutex> lock(queueMutex_);
auto repeatedEvent = eventQueue_.rend();
for (auto it = eventQueue_.rbegin(); it != eventQueue_.rend(); ++it) {
if (it->type == rawEvent.type &&
it->eventTarget == rawEvent.eventTarget) {
repeatedEvent = it;
break;
} else if (it->eventTarget == rawEvent.eventTarget) {
// It is necessary to maintain order of different event types
// for the same target. If the same target has event types A1, B1
// in the event queue and event A2 occurs. A1 has to stay in the
// queue.
break;
}
}
if (repeatedEvent == eventQueue_.rend()) {
eventQueue_.push_back(std::move(rawEvent));
} else {
*repeatedEvent = std::move(rawEvent);
}
}
onEnqueue();
}
void EventQueue::enqueueStateUpdate(StateUpdate &&stateUpdate) const {
{
std::lock_guard<std::mutex> lock(queueMutex_);
if (!stateUpdateQueue_.empty()) {
auto const position = stateUpdateQueue_.back();
if (stateUpdate.family == position.family) {
stateUpdateQueue_.pop_back();
}
}
stateUpdateQueue_.push_back(std::move(stateUpdate));
}
onEnqueue();
}
void EventQueue::onBeat(jsi::Runtime &runtime) const {
flushEvents(runtime);
flushStateUpdates();
}
void EventQueue::flushEvents(jsi::Runtime &runtime) const {
std::vector<RawEvent> queue;
{
std::lock_guard<std::mutex> lock(queueMutex_);
if (eventQueue_.size() == 0) {
return;
}
queue = std::move(eventQueue_);
eventQueue_.clear();
}
eventProcessor_.flushEvents(runtime, std::move(queue));
}
void EventQueue::flushStateUpdates() const {
std::vector<StateUpdate> stateUpdateQueue;
{
std::lock_guard<std::mutex> lock(queueMutex_);
if (stateUpdateQueue_.empty()) {
return;
}
stateUpdateQueue = std::move(stateUpdateQueue_);
stateUpdateQueue_.clear();
}
eventProcessor_.flushStateUpdates(std::move(stateUpdateQueue));
}
} // namespace react
} // namespace facebook