Skip to content

Commit c5c01fb

Browse files
committed
Refactor event pipeline to accept typed event payloads (#38276)
Summary: Pull Request resolved: #38276 Changelog: [Internal] Refactor Fabric event pipeline to accept typed event payloads As a first step towards my project of managing the Pointer Capture API by intercepting events in UIManagerBinding I need infrastructure to be able to safely & efficently read the properties of the event payload which is what this diff lays the ground work of addressing. Currently the events are passed from the EventEmitter all the way to UIManagerBinding with only a ValueFactory (std::function lambda) which is called to produce the jsi::Value. My diff introduces a new virtual base class, EventPayload, which provides the same functionality but in a member function, asJSIValue. To ease the transition to this new paradigm I also introduce the first concrete subclass of EventPayload: ValueFactoryEventPayload — which simply stores and calls a ValueFactory so that we can incrementally migrate to typed events (or frankly, continue to be used for events that we don't *need* to be typed, as the only real use-case in the beginning will be for Pointer Events). This diff notably does not change any behavior and should behave the exact same way it did before — it is in later diffs where I will begin applying this to the pointer events. Reviewed By: NickGerleman Differential Revision: D47299631 fbshipit-source-id: ff2301ab5da3abe0119920b943f5f20439885bf4
1 parent 5ba8de0 commit c5c01fb

File tree

13 files changed

+107
-22
lines changed

13 files changed

+107
-22
lines changed

packages/react-native/ReactCommon/react/renderer/core/EventEmitter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ void EventEmitter::dispatchEvent(
8484
eventDispatcher->dispatchEvent(
8585
RawEvent(
8686
normalizeEventType(std::move(type)),
87-
payloadFactory,
87+
std::make_shared<ValueFactoryEventPayload>(payloadFactory),
8888
eventTarget_,
8989
category),
9090
priority);
@@ -102,7 +102,7 @@ void EventEmitter::dispatchUniqueEvent(
102102

103103
eventDispatcher->dispatchUniqueEvent(RawEvent(
104104
normalizeEventType(std::move(type)),
105-
payloadFactory,
105+
std::make_shared<ValueFactoryEventPayload>(payloadFactory),
106106
eventTarget_,
107107
RawEvent::Category::Continuous));
108108
}

packages/react-native/ReactCommon/react/renderer/core/EventEmitter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212

1313
#include <folly/dynamic.h>
1414
#include <react/renderer/core/EventDispatcher.h>
15+
#include <react/renderer/core/EventPayload.h>
1516
#include <react/renderer/core/EventPriority.h>
1617
#include <react/renderer/core/EventTarget.h>
1718
#include <react/renderer/core/ReactPrimitives.h>
19+
#include <react/renderer/core/ValueFactoryEventPayload.h>
1820

1921
namespace facebook::react {
2022

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and 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+
#pragma once
9+
10+
#include <jsi/jsi.h>
11+
12+
namespace facebook::react {
13+
14+
/**
15+
* Abstract base class for all event payload types.
16+
*/
17+
struct EventPayload {
18+
virtual ~EventPayload() = default;
19+
20+
EventPayload() = default;
21+
EventPayload(const EventPayload &) = default;
22+
EventPayload &operator=(const EventPayload &) = default;
23+
EventPayload(EventPayload &&) = default;
24+
EventPayload &operator=(EventPayload &&) = default;
25+
26+
virtual jsi::Value asJSIValue(jsi::Runtime &runtime) const = 0;
27+
};
28+
29+
using SharedEventPayload = std::shared_ptr<const EventPayload>;
30+
31+
} // namespace facebook::react

packages/react-native/ReactCommon/react/renderer/core/EventPipe.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <string>
1212

1313
#include <jsi/jsi.h>
14+
#include <react/renderer/core/EventPayload.h>
1415
#include <react/renderer/core/EventTarget.h>
1516
#include <react/renderer/core/ReactEventPriority.h>
1617
#include <react/renderer/core/ValueFactory.h>
@@ -22,6 +23,6 @@ using EventPipe = std::function<void(
2223
const EventTarget *eventTarget,
2324
const std::string &type,
2425
ReactEventPriority priority,
25-
const ValueFactory &payloadFactory)>;
26+
const EventPayload &payload)>;
2627

2728
} // namespace facebook::react

packages/react-native/ReactCommon/react/renderer/core/EventQueueProcessor.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#include <cxxreact/JSExecutor.h>
9+
#include <logger/react_native_log.h>
910
#include "EventEmitter.h"
1011
#include "EventLogger.h"
1112
#include "EventQueue.h"
@@ -53,12 +54,18 @@ void EventQueueProcessor::flushEvents(
5354
eventLogger->onEventDispatch(event.loggingTag);
5455
}
5556

57+
if (event.eventPayload == nullptr) {
58+
react_native_log_error(
59+
"EventQueueProcessor: Unexpected null event payload");
60+
continue;
61+
}
62+
5663
eventPipe_(
5764
runtime,
5865
event.eventTarget.get(),
5966
event.type,
6067
reactPriority,
61-
event.payloadFactory);
68+
*event.eventPayload);
6269

6370
if (eventLogger != nullptr) {
6471
eventLogger->onEventEnd(event.loggingTag);

packages/react-native/ReactCommon/react/renderer/core/RawEvent.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ namespace facebook::react {
1111

1212
RawEvent::RawEvent(
1313
std::string type,
14-
ValueFactory payloadFactory,
14+
SharedEventPayload eventPayload,
1515
SharedEventTarget eventTarget,
1616
Category category)
1717
: type(std::move(type)),
18-
payloadFactory(std::move(payloadFactory)),
18+
eventPayload(std::move(eventPayload)),
1919
eventTarget(std::move(eventTarget)),
2020
category(category) {}
2121

packages/react-native/ReactCommon/react/renderer/core/RawEvent.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
#include <string>
1212

1313
#include <react/renderer/core/EventLogger.h>
14+
#include <react/renderer/core/EventPayload.h>
1415
#include <react/renderer/core/EventTarget.h>
15-
#include <react/renderer/core/ValueFactory.h>
1616

1717
namespace facebook::react {
1818

@@ -60,12 +60,12 @@ struct RawEvent {
6060

6161
RawEvent(
6262
std::string type,
63-
ValueFactory payloadFactory,
63+
SharedEventPayload eventPayload,
6464
SharedEventTarget eventTarget,
6565
Category category = Category::Unspecified);
6666

6767
std::string type;
68-
ValueFactory payloadFactory;
68+
SharedEventPayload eventPayload;
6969
SharedEventTarget eventTarget;
7070
Category category;
7171
EventTag loggingTag{0};
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and 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 "ValueFactoryEventPayload.h"
9+
10+
namespace facebook::react {
11+
12+
ValueFactoryEventPayload::ValueFactoryEventPayload(ValueFactory factory)
13+
: valueFactory_(std::move(factory)) {}
14+
15+
jsi::Value ValueFactoryEventPayload::asJSIValue(jsi::Runtime &runtime) const {
16+
return valueFactory_(runtime);
17+
}
18+
19+
} // namespace facebook::react
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and 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+
#pragma once
9+
10+
#include <react/renderer/core/EventPayload.h>
11+
#include <react/renderer/core/ValueFactory.h>
12+
13+
namespace facebook::react {
14+
15+
class ValueFactoryEventPayload : public EventPayload {
16+
public:
17+
explicit ValueFactoryEventPayload(ValueFactory factory);
18+
jsi::Value asJSIValue(jsi::Runtime &runtime) const override;
19+
20+
private:
21+
ValueFactory valueFactory_;
22+
};
23+
24+
} // namespace facebook::react

packages/react-native/ReactCommon/react/renderer/core/tests/EventQueueProcessorTest.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <react/renderer/core/EventPipe.h>
1212
#include <react/renderer/core/EventQueueProcessor.h>
1313
#include <react/renderer/core/StatePipe.h>
14+
#include <react/renderer/core/ValueFactoryEventPayload.h>
1415

1516
#include <memory>
1617

@@ -26,7 +27,7 @@ class EventQueueProcessorTest : public testing::Test {
2627
const EventTarget * /*eventTarget*/,
2728
const std::string &type,
2829
ReactEventPriority priority,
29-
const ValueFactory & /*payloadFactory*/) {
30+
const EventPayload & /*payload*/) {
3031
eventTypes_.push_back(type);
3132
eventPriorities_.push_back(priority);
3233
};
@@ -49,7 +50,7 @@ TEST_F(EventQueueProcessorTest, singleUnspecifiedEvent) {
4950
*runtime_,
5051
{RawEvent(
5152
"my type",
52-
dummyValueFactory_,
53+
std::make_shared<ValueFactoryEventPayload>(dummyValueFactory_),
5354
nullptr,
5455
RawEvent::Category::Unspecified)});
5556

@@ -63,22 +64,22 @@ TEST_F(EventQueueProcessorTest, continuousEvent) {
6364
*runtime_,
6465
{RawEvent(
6566
"touchStart",
66-
dummyValueFactory_,
67+
std::make_shared<ValueFactoryEventPayload>(dummyValueFactory_),
6768
nullptr,
6869
RawEvent::Category::ContinuousStart),
6970
RawEvent(
7071
"touchMove",
71-
dummyValueFactory_,
72+
std::make_shared<ValueFactoryEventPayload>(dummyValueFactory_),
7273
nullptr,
7374
RawEvent::Category::Unspecified),
7475
RawEvent(
7576
"touchEnd",
76-
dummyValueFactory_,
77+
std::make_shared<ValueFactoryEventPayload>(dummyValueFactory_),
7778
nullptr,
7879
RawEvent::Category::ContinuousEnd),
7980
RawEvent(
8081
"custom event",
81-
dummyValueFactory_,
82+
std::make_shared<ValueFactoryEventPayload>(dummyValueFactory_),
8283
nullptr,
8384
RawEvent::Category::Unspecified)});
8485

@@ -103,7 +104,7 @@ TEST_F(EventQueueProcessorTest, alwaysContinuousEvent) {
103104
{
104105
RawEvent(
105106
"onScroll",
106-
dummyValueFactory_,
107+
std::make_shared<ValueFactoryEventPayload>(dummyValueFactory_),
107108
nullptr,
108109
RawEvent::Category::Continuous),
109110
});
@@ -120,7 +121,7 @@ TEST_F(EventQueueProcessorTest, alwaysDiscreteEvent) {
120121
{
121122
RawEvent(
122123
"onChange",
123-
dummyValueFactory_,
124+
std::make_shared<ValueFactoryEventPayload>(dummyValueFactory_),
124125
nullptr,
125126
RawEvent::Category::Discrete),
126127
});

0 commit comments

Comments
 (0)