Files
react-native/ReactCommon/react/renderer/core/EventEmitter.cpp
T
Samuel Susla 09cb12c26c Pass eventPriority by value instead of reference
Summary:
Changelog: [internal]

EventPriority is backed by int, passing it by reference doesn't provide any performance benefits. Quite contrary, it can make it slower because of indirectness (in our case it is probably negligible).

Reviewed By: mdvacca

Differential Revision: D27938600

fbshipit-source-id: 37d1312627dd5a8f9012dfb35d21afe716a16ad7
2021-04-24 03:21:08 -07:00

119 lines
3.1 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 "EventEmitter.h"
#include <folly/dynamic.h>
#include <jsi/JSIDynamic.h>
#include <jsi/jsi.h>
#include <react/renderer/debug/SystraceSection.h>
#include "RawEvent.h"
namespace facebook {
namespace react {
// TODO(T29874519): Get rid of "top" prefix once and for all.
/*
* Capitalizes the first letter of the event type and adds "top" prefix if
* necessary (e.g. "layout" becames "topLayout").
*/
static std::string normalizeEventType(const std::string &type) {
auto prefixedType = type;
if (type.find("top", 0) != 0) {
prefixedType.insert(0, "top");
prefixedType[3] = toupper(prefixedType[3]);
}
return prefixedType;
}
std::mutex &EventEmitter::DispatchMutex() {
static std::mutex mutex;
return mutex;
}
ValueFactory EventEmitter::defaultPayloadFactory() {
static auto payloadFactory =
ValueFactory{[](jsi::Runtime &runtime) { return jsi::Object(runtime); }};
return payloadFactory;
}
EventEmitter::EventEmitter(
SharedEventTarget eventTarget,
Tag tag,
EventDispatcher::Weak eventDispatcher)
: eventTarget_(std::move(eventTarget)),
eventDispatcher_(std::move(eventDispatcher)) {}
void EventEmitter::dispatchEvent(
const std::string &type,
const folly::dynamic &payload,
EventPriority priority) const {
dispatchEvent(
type,
[payload](jsi::Runtime &runtime) {
return valueFromDynamic(runtime, payload);
},
priority);
}
void EventEmitter::dispatchEvent(
const std::string &type,
const ValueFactory &payloadFactory,
EventPriority priority) const {
SystraceSection s("EventEmitter::dispatchEvent");
auto eventDispatcher = eventDispatcher_.lock();
if (!eventDispatcher) {
return;
}
eventDispatcher->dispatchEvent(
RawEvent(normalizeEventType(type), payloadFactory, eventTarget_),
priority);
}
void EventEmitter::dispatchUniqueEvent(
const std::string &type,
const ValueFactory &payloadFactory) const {
SystraceSection s("EventEmitter::dispatchUniqueEvent");
auto eventDispatcher = eventDispatcher_.lock();
if (!eventDispatcher) {
return;
}
eventDispatcher->dispatchUniqueEvent(
RawEvent(normalizeEventType(type), payloadFactory, eventTarget_));
}
void EventEmitter::setEnabled(bool enabled) const {
enableCounter_ += enabled ? 1 : -1;
bool shouldBeEnabled = enableCounter_ > 0;
if (isEnabled_ != shouldBeEnabled) {
isEnabled_ = shouldBeEnabled;
if (eventTarget_) {
eventTarget_->setEnabled(isEnabled_);
}
}
// Note: Initially, the state of `eventTarget_` and the value `enableCounter_`
// is mismatched intentionally (it's `non-null` and `0` accordingly). We need
// this to support an initial nebula state where the event target must be
// retained without any associated mounted node.
bool shouldBeRetained = enableCounter_ > 0;
if (shouldBeRetained != (eventTarget_ != nullptr)) {
if (!shouldBeRetained) {
eventTarget_.reset();
}
}
}
} // namespace react
} // namespace facebook