From 5824dbda66b2e0f384afb544e4ad051a6b201c6f Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 9 May 2019 04:14:08 -0700 Subject: [PATCH] Publish event when visiting nodes during layout Summary: @public Publish an event when visiting nodes during layouts. Reviewed By: SidharthGuglani Differential Revision: D15206965 fbshipit-source-id: c201f084b1d4186bc64560b8033be965f2549236 --- tests/EventsTest.cpp | 59 ++++++++++++++++++++++++++++++++------------ yoga/Yoga.cpp | 3 +++ yoga/events.h | 2 +- 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/tests/EventsTest.cpp b/tests/EventsTest.cpp index 99adf8e8..09a67d27 100644 --- a/tests/EventsTest.cpp +++ b/tests/EventsTest.cpp @@ -10,8 +10,10 @@ #include #include +#include #include #include +#include namespace facebook { namespace yoga { @@ -33,16 +35,18 @@ class EventTest : public ::testing::Test { static void listen(const YGNode&, Event::Type, Event::Data); public: - static EventArgs lastEvent; + static std::vector events; + static EventArgs& lastEvent() { return events.back(); } + void TearDown() override; }; TEST_F(EventTest, new_node_has_event) { auto c = YGConfigGetDefault(); auto n = YGNodeNew(); - ASSERT_EQ(lastEvent.node, n); - ASSERT_EQ(lastEvent.type, Event::NodeAllocation); - ASSERT_EQ(lastEvent.data().config, c); + ASSERT_EQ(lastEvent().node, n); + ASSERT_EQ(lastEvent().type, Event::NodeAllocation); + ASSERT_EQ(lastEvent().data().config, c); YGNodeFree(n); } @@ -51,9 +55,9 @@ TEST_F(EventTest, new_node_with_config_event) { auto c = YGConfigNew(); auto n = YGNodeNewWithConfig(c); - ASSERT_EQ(lastEvent.node, n); - ASSERT_EQ(lastEvent.type, Event::NodeAllocation); - ASSERT_EQ(lastEvent.data().config, c); + ASSERT_EQ(lastEvent().node, n); + ASSERT_EQ(lastEvent().type, Event::NodeAllocation); + ASSERT_EQ(lastEvent().data().config, c); YGNodeFree(n); YGConfigFree(c); @@ -64,9 +68,9 @@ TEST_F(EventTest, clone_node_event) { auto n = YGNodeNewWithConfig(c); auto clone = YGNodeClone(n); - ASSERT_EQ(lastEvent.node, clone); - ASSERT_EQ(lastEvent.type, Event::NodeAllocation); - ASSERT_EQ(lastEvent.data().config, c); + ASSERT_EQ(lastEvent().node, clone); + ASSERT_EQ(lastEvent().type, Event::NodeAllocation); + ASSERT_EQ(lastEvent().data().config, c); YGNodeFree(n); YGNodeFree(clone); @@ -78,13 +82,29 @@ TEST_F(EventTest, free_node_event) { auto n = YGNodeNewWithConfig(c); YGNodeFree(n); - ASSERT_EQ(lastEvent.node, n); - ASSERT_EQ(lastEvent.type, Event::NodeDeallocation); - ASSERT_EQ(lastEvent.data().config, c); + ASSERT_EQ(lastEvent().node, n); + ASSERT_EQ(lastEvent().type, Event::NodeDeallocation); + ASSERT_EQ(lastEvent().data().config, c); YGConfigFree(c); } +TEST_F(EventTest, layout_events) { + auto root = YGNodeNew(); + auto child = YGNodeNew(); + YGNodeInsertChild(root, child, 0); + + YGNodeCalculateLayout(root, 123, 456, YGDirectionLTR); + + ASSERT_EQ(events[2].node, root); + ASSERT_EQ(events[2].type, Event::NodeLayout); + + ASSERT_EQ(events[3].node, child); + ASSERT_EQ(events[3].type, Event::NodeLayout); + + YGNodeFreeRecursive(root); +} + namespace { template @@ -99,15 +119,22 @@ EventArgs createArgs(const YGNode& node, const Event::Data& data) { void EventTest::listen(const YGNode& node, Event::Type type, Event::Data data) { switch (type) { case Event::NodeAllocation: - lastEvent = createArgs(node, data); + events.push_back(createArgs(node, data)); break; case Event::NodeDeallocation: - lastEvent = createArgs(node, data); + events.push_back(createArgs(node, data)); + break; + case Event::NodeLayout: + events.push_back(createArgs(node, data)); break; } } -EventArgs EventTest::lastEvent{}; +void EventTest::TearDown() { + events.clear(); +} + +std::vector EventTest::events{}; } // namespace test } // namespace yoga diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 05fb10d2..5f6fa875 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -3667,6 +3667,9 @@ bool YGLayoutNodeInternal( const YGConfigRef config, YGMarkerLayoutData& layoutMarkerData, void* const layoutContext) { +#ifdef YG_ENABLE_EVENTS + Event::publish(node); +#endif YGLayout* layout = &node->getLayout(); gDepth++; diff --git a/yoga/events.h b/yoga/events.h index 7b04060a..e667d2d2 100644 --- a/yoga/events.h +++ b/yoga/events.h @@ -15,7 +15,7 @@ namespace facebook { namespace yoga { struct Event { - enum Type { NodeAllocation, NodeDeallocation }; + enum Type { NodeAllocation, NodeDeallocation, NodeLayout }; class Data; using Subscriber = void(const YGNode&, Type, Data);