diff --git a/ReactCommon/fabric/core/events/EventDispatcher.h b/ReactCommon/fabric/core/events/EventDispatcher.h index d241f3a29..0f61a010e 100644 --- a/ReactCommon/fabric/core/events/EventDispatcher.h +++ b/ReactCommon/fabric/core/events/EventDispatcher.h @@ -39,6 +39,9 @@ public: const folly::dynamic &payload, const EventPriority &priority ) const = 0; + + virtual void releaseEventTarget(const EventTarget &eventTarget) const = 0; + }; } // namespace react diff --git a/ReactCommon/fabric/core/events/EventEmitter.cpp b/ReactCommon/fabric/core/events/EventEmitter.cpp index ec42f0f1d..fdb1b9889 100644 --- a/ReactCommon/fabric/core/events/EventEmitter.cpp +++ b/ReactCommon/fabric/core/events/EventEmitter.cpp @@ -15,9 +15,18 @@ namespace react { EventEmitter::EventEmitter(const InstanceHandle &instanceHandle, const Tag &tag, const SharedEventDispatcher &eventDispatcher): instanceHandle_(instanceHandle), tag_(tag), - eventDispatcher_(eventDispatcher) {} + eventDispatcher_(eventDispatcher) { + if (eventDispatcher) { + eventTarget_ = createEventTarget(); + } +} -EventEmitter::~EventEmitter() {} +EventEmitter::~EventEmitter() { + auto &&eventDispatcher = eventDispatcher_.lock(); + if (eventDispatcher && eventTarget_) { + eventDispatcher->releaseEventTarget(eventTarget_); + } +} void EventEmitter::dispatchEvent( const std::string &type, @@ -29,7 +38,7 @@ void EventEmitter::dispatchEvent( return; } - EventTarget eventTarget = createEventTarget(); + assert(eventTarget_ && "Attempted to dispatch an event without an eventTarget."); // Mixing `target` into `payload`. assert(payload.isObject()); @@ -37,7 +46,7 @@ void EventEmitter::dispatchEvent( extendedPayload.merge_patch(payload); // TODO(T29610783): Reconsider using dynamic dispatch here. - eventDispatcher->dispatchEvent(eventTarget, type, extendedPayload, priority); + eventDispatcher->dispatchEvent(eventTarget_, type, extendedPayload, priority); } EventTarget EventEmitter::createEventTarget() const { diff --git a/ReactCommon/fabric/core/events/EventEmitter.h b/ReactCommon/fabric/core/events/EventEmitter.h index f63c59d73..d854b00ba 100644 --- a/ReactCommon/fabric/core/events/EventEmitter.h +++ b/ReactCommon/fabric/core/events/EventEmitter.h @@ -53,6 +53,7 @@ private: InstanceHandle instanceHandle_; Tag tag_; std::weak_ptr eventDispatcher_; + mutable EventTarget eventTarget_ {nullptr}; }; } // namespace react diff --git a/ReactCommon/fabric/uimanager/FabricUIManager.cpp b/ReactCommon/fabric/uimanager/FabricUIManager.cpp index 1c8f96b3d..0c17bfc00 100644 --- a/ReactCommon/fabric/uimanager/FabricUIManager.cpp +++ b/ReactCommon/fabric/uimanager/FabricUIManager.cpp @@ -102,6 +102,10 @@ void FabricUIManager::setReleaseEventHandlerFunction(std::function releaseEventTargetFunction) { + releaseEventTargetFunction_ = releaseEventTargetFunction; +} + EventTarget FabricUIManager::createEventTarget(const InstanceHandle &instanceHandle) const { return createEventTargetFunction_(instanceHandle); } @@ -115,6 +119,10 @@ void FabricUIManager::dispatchEvent(const EventTarget &eventTarget, const std::s ); } +void FabricUIManager::releaseEventTarget(const EventTarget &eventTarget) const { + releaseEventTargetFunction_(eventTarget); +} + SharedShadowNode FabricUIManager::createNode(int tag, std::string viewName, int rootTag, folly::dynamic props, InstanceHandle instanceHandle) { isLoggingEnabled && LOG(INFO) << "FabricUIManager::createNode(tag: " << tag << ", name: " << viewName << ", rootTag: " << rootTag << ", props: " << props << ")"; diff --git a/ReactCommon/fabric/uimanager/FabricUIManager.h b/ReactCommon/fabric/uimanager/FabricUIManager.h index bd16f0294..3f6691333 100644 --- a/ReactCommon/fabric/uimanager/FabricUIManager.h +++ b/ReactCommon/fabric/uimanager/FabricUIManager.h @@ -21,6 +21,7 @@ namespace react { using CreateEventTargetFunction = EventTarget (InstanceHandle instanceHandle); using DispatchEventFunction = void (EventHandler eventHandler, EventTarget eventTarget, std::string type, folly::dynamic payload); using ReleaseEventHandlerFunction = void (EventHandler eventHandler); +using ReleaseEventTargetFunction = void (EventTarget eventTarget); class FabricUIManager { public: @@ -46,11 +47,13 @@ public: void setCreateEventTargetFunction(std::function createEventTargetFunction); void setDispatchEventFunction(std::function dispatchEventFunction); void setReleaseEventHandlerFunction(std::function releaseEventHandlerFunction); + void setReleaseEventTargetFunction(std::function releaseEventTargetFunction); #pragma mark - Native-facing Interface EventTarget createEventTarget(const InstanceHandle &instanceHandle) const; void dispatchEvent(const EventTarget &eventTarget, const std::string &type, const folly::dynamic &payload) const; + void releaseEventTarget(const EventTarget &eventTarget) const; #pragma mark - JavaScript/React-facing Interface @@ -73,6 +76,7 @@ private: std::function createEventTargetFunction_; std::function dispatchEventFunction_; std::function releaseEventHandlerFunction_; + std::function releaseEventTargetFunction_; }; } // namespace react diff --git a/ReactCommon/fabric/uimanager/SchedulerEventDispatcher.cpp b/ReactCommon/fabric/uimanager/SchedulerEventDispatcher.cpp index 11d40c1d3..77d694253 100644 --- a/ReactCommon/fabric/uimanager/SchedulerEventDispatcher.cpp +++ b/ReactCommon/fabric/uimanager/SchedulerEventDispatcher.cpp @@ -27,6 +27,7 @@ void SchedulerEventDispatcher::setUIManager(std::shared_ptrcreateEventTarget(instanceHandle); } @@ -36,9 +37,19 @@ void SchedulerEventDispatcher::dispatchEvent( const folly::dynamic &payload, const EventPriority &priority ) const { + if (!uiManager_) { + return; + } // TODO: Schedule the event based on priority. uiManager_->dispatchEvent(eventTarget, normalizeEventType(type), payload); } +void SchedulerEventDispatcher::releaseEventTarget(const EventTarget &eventTarget) const { + if (!uiManager_) { + return; + } + uiManager_->releaseEventTarget(eventTarget); +} + } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/uimanager/SchedulerEventDispatcher.h b/ReactCommon/fabric/uimanager/SchedulerEventDispatcher.h index bb6fd12de..847946b57 100644 --- a/ReactCommon/fabric/uimanager/SchedulerEventDispatcher.h +++ b/ReactCommon/fabric/uimanager/SchedulerEventDispatcher.h @@ -40,6 +40,9 @@ public: const EventPriority &priority ) const override; + + void releaseEventTarget(const EventTarget &eventTarget) const override; + private: // TODO: consider using std::weak_ptr<> instead for better memory management.