From 4475528df236fe0340431c16b2af4d8ac955e6d1 Mon Sep 17 00:00:00 2001 From: moraaar Date: Fri, 9 Jul 2021 19:48:04 +0100 Subject: [PATCH] Fixed Event Hander's copy constructor and copy assignments It was missing to save the event before connecting to it. (#2026) Signed-off-by: moraaar --- Code/Framework/AzCore/AzCore/EBus/Event.inl | 23 ++++++++--- Code/Framework/AzCore/Tests/EventTests.cpp | 42 +++++++++++++++++++++ 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/EBus/Event.inl b/Code/Framework/AzCore/AzCore/EBus/Event.inl index 006ff81e34..493dea4a3f 100644 --- a/Code/Framework/AzCore/AzCore/EBus/Event.inl +++ b/Code/Framework/AzCore/AzCore/EBus/Event.inl @@ -27,11 +27,17 @@ namespace AZ template EventHandler::EventHandler(const EventHandler& rhs) : m_callback(rhs.m_callback) + , m_event(rhs.m_event) { - // Copy the callback function, then perform a Connect with the new event - if (rhs.m_event) + // Copy the callback and event, then perform a Connect to the event + if (m_callback && m_event) + { + m_event->Connect(*this); + } + else { - rhs.m_event->Connect(*this); + // It was not possible to connect to the event, set it to nullptr + m_event = nullptr; } } @@ -65,9 +71,16 @@ namespace AZ { Disconnect(); m_callback = rhs.m_callback; - if (rhs.m_event) + m_event = rhs.m_event; + // Copy the callback and event, then perform a Connect to the event + if (m_callback && m_event) + { + m_event->Connect(*this); + } + else { - rhs.m_event->Connect(*this); + // It was not possible to connect to the event, set it to nullptr + m_event = nullptr; } } diff --git a/Code/Framework/AzCore/Tests/EventTests.cpp b/Code/Framework/AzCore/Tests/EventTests.cpp index 7640201e0d..571bdd5345 100644 --- a/Code/Framework/AzCore/Tests/EventTests.cpp +++ b/Code/Framework/AzCore/Tests/EventTests.cpp @@ -257,6 +257,48 @@ namespace UnitTest EXPECT_FALSE(testEvent1.HasHandlerConnected()); EXPECT_TRUE(testEvent2.HasHandlerConnected()); } + + TEST_F(EventTests, TestHandlerCopyConstructorOperator) + { + int32_t invokedCounter = 0; + + AZ::Event<> testEvent; + AZ::Event<>::Handler testHandler([&invokedCounter]() { invokedCounter++; }); + + testHandler.Connect(testEvent); + + AZ::Event<>::Handler testHandler2(testHandler); + + EXPECT_TRUE(testHandler.IsConnected()); + EXPECT_TRUE(testHandler2.IsConnected()); + + EXPECT_TRUE(invokedCounter == 0); + testEvent.Signal(); + EXPECT_TRUE(invokedCounter == 2); + } + + TEST_F(EventTests, TestHandlerCopyAssignmentOperator) + { + int32_t invokedCounter = 0; + + AZ::Event<> testEvent; + AZ::Event<>::Handler testHandler([&invokedCounter]() { invokedCounter++; }); + + testHandler.Connect(testEvent); + + AZ::Event<>::Handler testHandler2; + + EXPECT_TRUE(testHandler.IsConnected()); + EXPECT_FALSE(testHandler2.IsConnected()); + + testHandler2 = testHandler; + + EXPECT_TRUE(testHandler2.IsConnected()); + + EXPECT_TRUE(invokedCounter == 0); + testEvent.Signal(); + EXPECT_TRUE(invokedCounter == 2); + } } #if defined(HAVE_BENCHMARK)