diff --git a/ReactCommon/fabric/events/BUCK b/ReactCommon/fabric/events/BUCK index 9823eb1e3..ac3280037 100644 --- a/ReactCommon/fabric/events/BUCK +++ b/ReactCommon/fabric/events/BUCK @@ -56,6 +56,7 @@ rn_xplat_cxx_library( "xplat//folly:memory", "xplat//folly:molly", "xplat//jsi:jsi", + "xplat//jsi:JSIDynamic", "xplat//third-party/glog:glog", react_native_xplat_target("fabric/debug:debug"), ], diff --git a/ReactCommon/fabric/events/EventEmitter.cpp b/ReactCommon/fabric/events/EventEmitter.cpp index 016ecc9e3..437a4df78 100644 --- a/ReactCommon/fabric/events/EventEmitter.cpp +++ b/ReactCommon/fabric/events/EventEmitter.cpp @@ -8,6 +8,8 @@ #include "EventEmitter.h" #include +#include +#include #include #include "RawEvent.h" @@ -34,6 +36,12 @@ std::recursive_mutex &EventEmitter::DispatchMutex() { return mutex; } +ValueFactory EventEmitter::defaultPayloadFactory() { + static auto payloadFactory = + ValueFactory{[](jsi::Runtime &runtime) { return jsi::Object(runtime); }}; + return payloadFactory; +} + EventEmitter::EventEmitter( SharedEventTarget eventTarget, Tag tag, @@ -46,6 +54,18 @@ void EventEmitter::dispatchEvent( const std::string &type, const folly::dynamic &payload, const EventPriority &priority) const { + dispatchEvent( + type, + [payload](jsi::Runtime &runtime) { + return valueFromDynamic(runtime, payload); + }, + priority); +} + +void EventEmitter::dispatchEvent( + const std::string &type, + const ValueFactory &payloadFactory, + const EventPriority &priority) const { SystraceSection s("EventEmitter::dispatchEvent"); auto eventDispatcher = eventDispatcher_.lock(); @@ -54,7 +74,8 @@ void EventEmitter::dispatchEvent( } eventDispatcher->dispatchEvent( - RawEvent(normalizeEventType(type), payload, eventTarget_), priority); + RawEvent(normalizeEventType(type), payloadFactory, eventTarget_), + priority); } void EventEmitter::enable() const { diff --git a/ReactCommon/fabric/events/EventEmitter.h b/ReactCommon/fabric/events/EventEmitter.h index a4ef8772f..72989bfca 100644 --- a/ReactCommon/fabric/events/EventEmitter.h +++ b/ReactCommon/fabric/events/EventEmitter.h @@ -45,6 +45,8 @@ class EventEmitter { public: static std::recursive_mutex &DispatchMutex(); + static ValueFactory defaultPayloadFactory(); + EventEmitter( SharedEventTarget eventTarget, Tag tag, @@ -76,7 +78,13 @@ class EventEmitter { */ void dispatchEvent( const std::string &type, - const folly::dynamic &payload = folly::dynamic::object(), + const ValueFactory &payloadFactory = + EventEmitter::defaultPayloadFactory(), + const EventPriority &priority = EventPriority::AsynchronousBatched) const; + + void dispatchEvent( + const std::string &type, + const folly::dynamic &payload, const EventPriority &priority = EventPriority::AsynchronousBatched) const; private: diff --git a/ReactCommon/fabric/events/EventQueue.cpp b/ReactCommon/fabric/events/EventQueue.cpp index 2ec13d5c1..c58e0f037 100644 --- a/ReactCommon/fabric/events/EventQueue.cpp +++ b/ReactCommon/fabric/events/EventQueue.cpp @@ -44,7 +44,10 @@ void EventQueue::onBeat(jsi::Runtime &runtime) const { for (const auto &event : queue) { eventPipe_( - runtime, event.eventTarget.lock().get(), event.type, event.payload); + runtime, + event.eventTarget.lock().get(), + event.type, + event.payloadFactory); } } } diff --git a/ReactCommon/fabric/events/RawEvent.cpp b/ReactCommon/fabric/events/RawEvent.cpp index e73d06dcd..d95cdfa3d 100644 --- a/ReactCommon/fabric/events/RawEvent.cpp +++ b/ReactCommon/fabric/events/RawEvent.cpp @@ -12,10 +12,10 @@ namespace react { RawEvent::RawEvent( std::string type, - folly::dynamic payload, + ValueFactory payloadFactory, WeakEventTarget eventTarget) : type(std::move(type)), - payload(std::move(payload)), + payloadFactory(std::move(payloadFactory)), eventTarget(std::move(eventTarget)) {} } // namespace react diff --git a/ReactCommon/fabric/events/RawEvent.h b/ReactCommon/fabric/events/RawEvent.h index 1b34f884f..3d585b64f 100644 --- a/ReactCommon/fabric/events/RawEvent.h +++ b/ReactCommon/fabric/events/RawEvent.h @@ -9,6 +9,7 @@ #include #include +#include #include namespace facebook { @@ -21,11 +22,11 @@ class RawEvent { public: RawEvent( std::string type, - folly::dynamic payload, + ValueFactory payloadFactory, WeakEventTarget eventTarget); const std::string type; - const folly::dynamic payload; + const ValueFactory payloadFactory; const WeakEventTarget eventTarget; }; diff --git a/ReactCommon/fabric/events/primitives.h b/ReactCommon/fabric/events/primitives.h index cd8a61a9e..d07d8bd5c 100644 --- a/ReactCommon/fabric/events/primitives.h +++ b/ReactCommon/fabric/events/primitives.h @@ -47,11 +47,13 @@ struct EventTarget {}; using SharedEventTarget = std::shared_ptr; using WeakEventTarget = std::weak_ptr; +using ValueFactory = std::function; + using EventPipe = std::function; + const ValueFactory &payloadFactory)>; } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/uimanager/Scheduler.cpp b/ReactCommon/fabric/uimanager/Scheduler.cpp index 7030a1ce8..cf08d8fc2 100644 --- a/ReactCommon/fabric/uimanager/Scheduler.cpp +++ b/ReactCommon/fabric/uimanager/Scheduler.cpp @@ -37,8 +37,8 @@ Scheduler::Scheduler(const SharedContextContainer &contextContainer) jsi::Runtime &runtime, const EventTarget *eventTarget, const std::string &type, - const folly::dynamic &payload) { - uiManagerBinding->dispatchEvent(runtime, eventTarget, type, payload); + const ValueFactory &payloadFactory) { + uiManagerBinding->dispatchEvent(runtime, eventTarget, type, payloadFactory); }; auto eventDispatcher = std::make_shared( diff --git a/ReactCommon/fabric/uimanager/UIManagerBinding.cpp b/ReactCommon/fabric/uimanager/UIManagerBinding.cpp index 06f706e5c..bc20f4ed6 100644 --- a/ReactCommon/fabric/uimanager/UIManagerBinding.cpp +++ b/ReactCommon/fabric/uimanager/UIManagerBinding.cpp @@ -67,11 +67,11 @@ void UIManagerBinding::dispatchEvent( jsi::Runtime &runtime, const EventTarget *eventTarget, const std::string &type, - const folly::dynamic &payload) const { + const ValueFactory &payloadFactory) const { SystraceSection s("UIManagerBinding::dispatchEvent"); + auto payload = payloadFactory(runtime); auto eventTargetValue = jsi::Value::null(); - folly::dynamic extendedPayload; if (eventTarget) { auto &eventTargetWrapper = @@ -83,10 +83,8 @@ void UIManagerBinding::dispatchEvent( // Mixing `target` into `payload`. assert(payload.isObject()); - extendedPayload = folly::dynamic::object("target", eventTargetWrapper.tag); - extendedPayload.merge_patch(payload); - } else { - extendedPayload = payload; + payload.asObject(runtime).setProperty( + runtime, "target", eventTargetWrapper.tag); } auto &eventHandlerWrapper = @@ -95,7 +93,7 @@ void UIManagerBinding::dispatchEvent( runtime, {std::move(eventTargetValue), jsi::String::createFromUtf8(runtime, type), - jsi::valueFromDynamic(runtime, extendedPayload)}); + std::move(payload)}); } void UIManagerBinding::invalidate() const { diff --git a/ReactCommon/fabric/uimanager/UIManagerBinding.h b/ReactCommon/fabric/uimanager/UIManagerBinding.h index f52d69594..b74f5d2c8 100644 --- a/ReactCommon/fabric/uimanager/UIManagerBinding.h +++ b/ReactCommon/fabric/uimanager/UIManagerBinding.h @@ -49,7 +49,7 @@ class UIManagerBinding : public jsi::HostObject { jsi::Runtime &runtime, const EventTarget *eventTarget, const std::string &type, - const folly::dynamic &payload) const; + const ValueFactory &payloadFactory) const; /* * Invalidates the binding and underlying UIManager.