UNPKG

2.83 kBtext/x-cView Raw
1/**
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#include "EventEmitter.h"
9
10#include <folly/dynamic.h>
11#include <jsi/JSIDynamic.h>
12#include <jsi/jsi.h>
13#include <react/debug/SystraceSection.h>
14
15#include "RawEvent.h"
16
17namespace facebook {
18namespace react {
19
20// TODO(T29874519): Get rid of "top" prefix once and for all.
21/*
22 * Capitalizes the first letter of the event type and adds "top" prefix if
23 * necessary (e.g. "layout" becames "topLayout").
24 */
25static std::string normalizeEventType(const std::string &type) {
26 auto prefixedType = type;
27 if (type.find("top", 0) != 0) {
28 prefixedType.insert(0, "top");
29 prefixedType[3] = toupper(prefixedType[3]);
30 }
31 return prefixedType;
32}
33
34std::mutex &EventEmitter::DispatchMutex() {
35 static std::mutex mutex;
36 return mutex;
37}
38
39ValueFactory EventEmitter::defaultPayloadFactory() {
40 static auto payloadFactory =
41 ValueFactory{[](jsi::Runtime &runtime) { return jsi::Object(runtime); }};
42 return payloadFactory;
43}
44
45EventEmitter::EventEmitter(
46 SharedEventTarget eventTarget,
47 Tag tag,
48 WeakEventDispatcher eventDispatcher)
49 : eventTarget_(std::move(eventTarget)),
50 eventDispatcher_(std::move(eventDispatcher)) {}
51
52void EventEmitter::dispatchEvent(
53 const std::string &type,
54 const folly::dynamic &payload,
55 const EventPriority &priority) const {
56 dispatchEvent(
57 type,
58 [payload](jsi::Runtime &runtime) {
59 return valueFromDynamic(runtime, payload);
60 },
61 priority);
62}
63
64void EventEmitter::dispatchEvent(
65 const std::string &type,
66 const ValueFactory &payloadFactory,
67 const EventPriority &priority) const {
68 SystraceSection s("EventEmitter::dispatchEvent");
69
70 auto eventDispatcher = eventDispatcher_.lock();
71 if (!eventDispatcher) {
72 return;
73 }
74
75 eventDispatcher->dispatchEvent(
76 RawEvent(normalizeEventType(type), payloadFactory, eventTarget_),
77 priority);
78}
79
80void EventEmitter::setEnabled(bool enabled) const {
81 enableCounter_ += enabled ? 1 : -1;
82
83 bool shouldBeEnabled = enableCounter_ > 0;
84 if (isEnabled_ != shouldBeEnabled) {
85 isEnabled_ = shouldBeEnabled;
86 if (eventTarget_) {
87 eventTarget_->setEnabled(isEnabled_);
88 }
89 }
90
91 // Note: Initially, the state of `eventTarget_` and the value `enableCounter_`
92 // is mismatched intentionally (it's `non-null` and `0` accordingly). We need
93 // this to support an initial nebula state where the event target must be
94 // retained without any associated mounted node.
95 bool shouldBeRetained = enableCounter_ > 0;
96 if (shouldBeRetained != (eventTarget_ != nullptr)) {
97 if (!shouldBeRetained) {
98 eventTarget_.reset();
99 }
100 }
101}
102
103} // namespace react
104} // namespace facebook