diff --git a/packages/react-native/ReactCommon/react/renderer/core/CMakeLists.txt b/packages/react-native/ReactCommon/react/renderer/core/CMakeLists.txt index cbbaa6f1f3999e..c8786aa0099c4e 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/renderer/core/CMakeLists.txt @@ -23,6 +23,7 @@ target_link_libraries(react_render_core folly_runtime glog jsi + logger react_config react_debug react_render_debug diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.cpp b/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.cpp index 22a12a2ffb43fe..ecc23247180051 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.cpp @@ -84,7 +84,7 @@ void EventEmitter::dispatchEvent( eventDispatcher->dispatchEvent( RawEvent( normalizeEventType(std::move(type)), - payloadFactory, + std::make_shared(payloadFactory), eventTarget_, category), priority); @@ -102,7 +102,7 @@ void EventEmitter::dispatchUniqueEvent( eventDispatcher->dispatchUniqueEvent(RawEvent( normalizeEventType(std::move(type)), - payloadFactory, + std::make_shared(payloadFactory), eventTarget_, RawEvent::Category::Continuous)); } diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.h b/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.h index c02d605b43b77d..df0c12c93a4f76 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.h +++ b/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.h @@ -12,9 +12,11 @@ #include #include +#include #include #include #include +#include namespace facebook::react { diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventPayload.h b/packages/react-native/ReactCommon/react/renderer/core/EventPayload.h new file mode 100644 index 00000000000000..ef9f2bc8aad8ac --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/core/EventPayload.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +namespace facebook::react { + +/** + * Abstract base class for all event payload types. + */ +struct EventPayload { + virtual ~EventPayload() = default; + + EventPayload() = default; + EventPayload(const EventPayload &) = default; + EventPayload &operator=(const EventPayload &) = default; + EventPayload(EventPayload &&) = default; + EventPayload &operator=(EventPayload &&) = default; + + virtual jsi::Value asJSIValue(jsi::Runtime &runtime) const = 0; +}; + +using SharedEventPayload = std::shared_ptr; + +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventPipe.h b/packages/react-native/ReactCommon/react/renderer/core/EventPipe.h index 53d41488418d3e..a31bc54d5ad5c5 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventPipe.h +++ b/packages/react-native/ReactCommon/react/renderer/core/EventPipe.h @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -22,6 +23,6 @@ using EventPipe = std::function; + const EventPayload &payload)>; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventQueueProcessor.cpp b/packages/react-native/ReactCommon/react/renderer/core/EventQueueProcessor.cpp index 4ff9406f60bbe1..9ba86af056e8c4 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventQueueProcessor.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/EventQueueProcessor.cpp @@ -6,6 +6,7 @@ */ #include +#include #include "EventEmitter.h" #include "EventLogger.h" #include "EventQueue.h" @@ -53,12 +54,18 @@ void EventQueueProcessor::flushEvents( eventLogger->onEventDispatch(event.loggingTag); } + if (event.eventPayload == nullptr) { + react_native_log_error( + "EventQueueProcessor: Unexpected null event payload"); + continue; + } + eventPipe_( runtime, event.eventTarget.get(), event.type, reactPriority, - event.payloadFactory); + *event.eventPayload); if (eventLogger != nullptr) { eventLogger->onEventEnd(event.loggingTag); diff --git a/packages/react-native/ReactCommon/react/renderer/core/RawEvent.cpp b/packages/react-native/ReactCommon/react/renderer/core/RawEvent.cpp index 646ce4aea3ad86..d0fa7f28466974 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/RawEvent.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/RawEvent.cpp @@ -11,11 +11,11 @@ namespace facebook::react { RawEvent::RawEvent( std::string type, - ValueFactory payloadFactory, + SharedEventPayload eventPayload, SharedEventTarget eventTarget, Category category) : type(std::move(type)), - payloadFactory(std::move(payloadFactory)), + eventPayload(std::move(eventPayload)), eventTarget(std::move(eventTarget)), category(category) {} diff --git a/packages/react-native/ReactCommon/react/renderer/core/RawEvent.h b/packages/react-native/ReactCommon/react/renderer/core/RawEvent.h index d9ec02c796e79a..03a2f0857aa1a0 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/RawEvent.h +++ b/packages/react-native/ReactCommon/react/renderer/core/RawEvent.h @@ -11,8 +11,8 @@ #include #include +#include #include -#include namespace facebook::react { @@ -60,12 +60,12 @@ struct RawEvent { RawEvent( std::string type, - ValueFactory payloadFactory, + SharedEventPayload eventPayload, SharedEventTarget eventTarget, Category category = Category::Unspecified); std::string type; - ValueFactory payloadFactory; + SharedEventPayload eventPayload; SharedEventTarget eventTarget; Category category; EventTag loggingTag{0}; diff --git a/packages/react-native/ReactCommon/react/renderer/core/ValueFactoryEventPayload.cpp b/packages/react-native/ReactCommon/react/renderer/core/ValueFactoryEventPayload.cpp new file mode 100644 index 00000000000000..fc5e81d3646f76 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/core/ValueFactoryEventPayload.cpp @@ -0,0 +1,19 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "ValueFactoryEventPayload.h" + +namespace facebook::react { + +ValueFactoryEventPayload::ValueFactoryEventPayload(ValueFactory factory) + : valueFactory_(std::move(factory)) {} + +jsi::Value ValueFactoryEventPayload::asJSIValue(jsi::Runtime &runtime) const { + return valueFactory_(runtime); +} + +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/core/ValueFactoryEventPayload.h b/packages/react-native/ReactCommon/react/renderer/core/ValueFactoryEventPayload.h new file mode 100644 index 00000000000000..08486966dd5905 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/core/ValueFactoryEventPayload.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +namespace facebook::react { + +class ValueFactoryEventPayload : public EventPayload { + public: + explicit ValueFactoryEventPayload(ValueFactory factory); + jsi::Value asJSIValue(jsi::Runtime &runtime) const override; + + private: + ValueFactory valueFactory_; +}; + +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/core/tests/EventQueueProcessorTest.cpp b/packages/react-native/ReactCommon/react/renderer/core/tests/EventQueueProcessorTest.cpp index e88013b9e555b6..3bc03bf1a39974 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/tests/EventQueueProcessorTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/tests/EventQueueProcessorTest.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -26,7 +27,7 @@ class EventQueueProcessorTest : public testing::Test { const EventTarget * /*eventTarget*/, const std::string &type, ReactEventPriority priority, - const ValueFactory & /*payloadFactory*/) { + const EventPayload & /*payload*/) { eventTypes_.push_back(type); eventPriorities_.push_back(priority); }; @@ -49,7 +50,7 @@ TEST_F(EventQueueProcessorTest, singleUnspecifiedEvent) { *runtime_, {RawEvent( "my type", - dummyValueFactory_, + std::make_shared(dummyValueFactory_), nullptr, RawEvent::Category::Unspecified)}); @@ -63,22 +64,22 @@ TEST_F(EventQueueProcessorTest, continuousEvent) { *runtime_, {RawEvent( "touchStart", - dummyValueFactory_, + std::make_shared(dummyValueFactory_), nullptr, RawEvent::Category::ContinuousStart), RawEvent( "touchMove", - dummyValueFactory_, + std::make_shared(dummyValueFactory_), nullptr, RawEvent::Category::Unspecified), RawEvent( "touchEnd", - dummyValueFactory_, + std::make_shared(dummyValueFactory_), nullptr, RawEvent::Category::ContinuousEnd), RawEvent( "custom event", - dummyValueFactory_, + std::make_shared(dummyValueFactory_), nullptr, RawEvent::Category::Unspecified)}); @@ -103,7 +104,7 @@ TEST_F(EventQueueProcessorTest, alwaysContinuousEvent) { { RawEvent( "onScroll", - dummyValueFactory_, + std::make_shared(dummyValueFactory_), nullptr, RawEvent::Category::Continuous), }); @@ -120,7 +121,7 @@ TEST_F(EventQueueProcessorTest, alwaysDiscreteEvent) { { RawEvent( "onChange", - dummyValueFactory_, + std::make_shared(dummyValueFactory_), nullptr, RawEvent::Category::Discrete), }); diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp index 1d812fcccf845a..990912be9cbe77 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp @@ -60,11 +60,11 @@ Scheduler::Scheduler( const EventTarget *eventTarget, const std::string &type, ReactEventPriority priority, - const ValueFactory &payloadFactory) { + const EventPayload &payload) { uiManager->visitBinding( [&](UIManagerBinding const &uiManagerBinding) { uiManagerBinding.dispatchEvent( - runtime, eventTarget, type, priority, payloadFactory); + runtime, eventTarget, type, priority, payload); }, runtime); if (runtimeScheduler != nullptr) { diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp index ef4100ef6c4df9..e56132e02c226f 100644 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp +++ b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp @@ -93,10 +93,10 @@ void UIManagerBinding::dispatchEvent( EventTarget const *eventTarget, std::string const &type, ReactEventPriority priority, - ValueFactory const &payloadFactory) const { + const EventPayload &eventPayload) const { SystraceSection s("UIManagerBinding::dispatchEvent", "type", type); - auto payload = payloadFactory(runtime); + auto payload = eventPayload.asJSIValue(runtime); // If a payload is null, the factory has decided to cancel the event if (payload.isNull()) { diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.h b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.h index b2180ea4ede328..7f5adc03f4c122 100644 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.h +++ b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.h @@ -52,7 +52,7 @@ class UIManagerBinding : public jsi::HostObject { EventTarget const *eventTarget, std::string const &type, ReactEventPriority priority, - ValueFactory const &payloadFactory) const; + const EventPayload &payload) const; /* * Invalidates the binding and underlying UIManager.