From 71295bcdac5f046c6355ca30fa272d3a16c6ee6f Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 27 Aug 2018 07:21:18 -0700 Subject: [PATCH] Fabric: Enabling and disabling EventEmitter at post commit phase Summary: @public We need that to ensure that we will not deliver events to nodes with invalid state. Reviewed By: mdvacca Differential Revision: D8886234 fbshipit-source-id: 1d6ca129c97a5dca0411e85909aea48185f46c54 --- ReactCommon/fabric/uimanager/ShadowTree.cpp | 26 +++++++++++++++++++-- ReactCommon/fabric/uimanager/ShadowTree.h | 7 +++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/ReactCommon/fabric/uimanager/ShadowTree.cpp b/ReactCommon/fabric/uimanager/ShadowTree.cpp index 1a1df2c48ff..702d8d4f7f2 100644 --- a/ReactCommon/fabric/uimanager/ShadowTree.cpp +++ b/ReactCommon/fabric/uimanager/ShadowTree.cpp @@ -86,7 +86,7 @@ void ShadowTree::complete(UnsharedRootShadowNode newRootShadowNode) { newRootShadowNode ); - if (commit(oldRootShadowNode, newRootShadowNode)) { + if (commit(oldRootShadowNode, newRootShadowNode, instructions)) { emitLayoutEvents(instructions); if (delegate_) { @@ -95,7 +95,11 @@ void ShadowTree::complete(UnsharedRootShadowNode newRootShadowNode) { } } -bool ShadowTree::commit(const SharedRootShadowNode &oldRootShadowNode, const SharedRootShadowNode &newRootShadowNode) { +bool ShadowTree::commit( + const SharedRootShadowNode &oldRootShadowNode, + const SharedRootShadowNode &newRootShadowNode, + const TreeMutationInstructionList &mutationInstructions +) { std::lock_guard lock(commitMutex_); if (oldRootShadowNode != rootShadowNode_) { @@ -103,6 +107,8 @@ bool ShadowTree::commit(const SharedRootShadowNode &oldRootShadowNode, const Sha } rootShadowNode_ = newRootShadowNode; + + toggleEventEmitters(mutationInstructions); return true; } @@ -153,6 +159,22 @@ void ShadowTree::emitLayoutEvents(const TreeMutationInstructionList &instruction } } +void ShadowTree::toggleEventEmitters(const TreeMutationInstructionList &instructions) { + std::lock_guard lock(EventEmitter::DispatchMutex()); + + for (const auto &instruction : instructions) { + if (instruction.getType() == TreeMutationInstruction::Deletion) { + instruction.getOldChildNode()->getEventEmitter()->setEnabled(false); + } + } + + for (const auto &instruction : instructions) { + if (instruction.getType() == TreeMutationInstruction::Creation) { + instruction.getNewChildNode()->getEventEmitter()->setEnabled(true); + } + } +} + #pragma mark - Delegate void ShadowTree::setDelegate(ShadowTreeDelegate *delegate) { diff --git a/ReactCommon/fabric/uimanager/ShadowTree.h b/ReactCommon/fabric/uimanager/ShadowTree.h index 4366fc8d451..66cb22eea8f 100644 --- a/ReactCommon/fabric/uimanager/ShadowTree.h +++ b/ReactCommon/fabric/uimanager/ShadowTree.h @@ -77,7 +77,12 @@ private: UnsharedRootShadowNode cloneRootShadowNode(const LayoutConstraints &layoutConstraints, const LayoutContext &layoutContext) const; void complete(UnsharedRootShadowNode newRootShadowNode); - bool commit(const SharedRootShadowNode &oldRootShadowNode, const SharedRootShadowNode &newRootShadowNode); + bool commit( + const SharedRootShadowNode &oldRootShadowNode, + const SharedRootShadowNode &newRootShadowNode, + const TreeMutationInstructionList &mutationInstructions + ); + void toggleEventEmitters(const TreeMutationInstructionList &instructions); void emitLayoutEvents(const TreeMutationInstructionList &instructions); const Tag rootTag_;