From a25c8561b0d8a855b6659543eb42e84a3a50c903 Mon Sep 17 00:00:00 2001 From: Tim Ebbeke Date: Thu, 18 Jul 2024 16:15:20 +0200 Subject: [PATCH] Added flag to Observed<> ctor. This avoids accidentally using the EventContext* constructor. --- .../nui/event_system/observed_value.hpp | 51 ++++++++++++++----- nui/include/nui/utility/assert.hpp | 26 ++++++++++ nui/test/nui/test_events.hpp | 12 ++--- 3 files changed, 69 insertions(+), 20 deletions(-) create mode 100644 nui/include/nui/utility/assert.hpp diff --git a/nui/include/nui/event_system/observed_value.hpp b/nui/include/nui/event_system/observed_value.hpp index 4291ef3..19063d3 100644 --- a/nui/include/nui/event_system/observed_value.hpp +++ b/nui/include/nui/event_system/observed_value.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -26,7 +27,7 @@ namespace Nui class ObservedBase { public: - explicit ObservedBase(EventContext* ctx) + explicit ObservedBase(CustomEventContextFlag_t, EventContext* ctx) : eventContext_{ctx} , attachedEvents_{} , attachedOneshotEvents_{} @@ -49,7 +50,6 @@ namespace Nui ObservedBase& operator=(ObservedBase&& other) { eventContext_ = other.eventContext_; - other.eventContext_ = nullptr; for (auto& event : other.attachedEvents_) attachedEvents_.push_back(std::move(event)); for (auto& event : other.attachedOneshotEvents_) @@ -96,7 +96,7 @@ namespace Nui virtual void update(bool /*force*/ = false) const { - assert(eventContext_ != nullptr); + NUI_ASSERT(eventContext_ != nullptr, "Event context must never be null."); for (auto& event : attachedEvents_) { @@ -114,7 +114,7 @@ namespace Nui void updateNow(bool force = false) const { - assert(eventContext_ != nullptr); + NUI_ASSERT(eventContext_ != nullptr, "Event context must never be null."); update(force); eventContext_->executeActiveEventsImmediately(); @@ -182,7 +182,7 @@ namespace Nui public: ModifiableObserved() - : ObservedBase{&globalEventContext} + : ObservedBase{CustomEventContextFlag, &globalEventContext} , contained_{} {} ModifiableObserved(const ModifiableObserved&) = delete; @@ -219,15 +219,21 @@ namespace Nui template explicit ModifiableObserved(T&& t) - : ObservedBase{&globalEventContext} + : ObservedBase{CustomEventContextFlag, &globalEventContext} , contained_{std::forward(t)} {} - explicit ModifiableObserved(EventContext* ctx) - : ObservedBase{ctx} + explicit ModifiableObserved(CustomEventContextFlag_t, EventContext* ctx) + : ObservedBase{CustomEventContextFlag, ctx} , contained_{} {} + template + explicit ModifiableObserved(CustomEventContextFlag_t, EventContext* ctx, T&& t) + : ObservedBase{CustomEventContextFlag, ctx} + , contained_{std::forward(t)} + {} + /** * @brief Assign a completely new value. * @@ -584,8 +590,8 @@ namespace Nui using ModifiableObserved::update; public: - explicit ObservedContainer(EventContext* ctx) - : ModifiableObserved{ctx} + explicit ObservedContainer(CustomEventContextFlag_t, EventContext* ctx) + : ModifiableObserved{CustomEventContextFlag, ctx} , rangeContext_{0} , afterEffectId_{registerAfterEffect()} {} @@ -595,6 +601,12 @@ namespace Nui , afterEffectId_{registerAfterEffect()} {} template + explicit ObservedContainer(CustomEventContextFlag_t, EventContext* ctx, T&& t) + : ModifiableObserved{CustomEventContextFlag, ctx, std::forward(t)} + , rangeContext_{static_cast(contained_.size())} + , afterEffectId_{registerAfterEffect()} + {} + template explicit ObservedContainer(T&& t) : ModifiableObserved{std::forward(t)} , rangeContext_{static_cast(contained_.size())} @@ -605,12 +617,23 @@ namespace Nui , rangeContext_{std::move(rangeContext)} , afterEffectId_{registerAfterEffect()} {} + explicit ObservedContainer(CustomEventContextFlag_t, EventContext* ctx, RangeEventContext&& rangeContext) + : ModifiableObserved{CustomEventContextFlag, ctx} + , rangeContext_{std::move(rangeContext)} + , afterEffectId_{registerAfterEffect()} + {} template ObservedContainer(T&& t, RangeEventContext&& rangeContext) : ModifiableObserved{std::forward(t)} , rangeContext_{std::move(rangeContext)} , afterEffectId_{registerAfterEffect()} {} + template + ObservedContainer(CustomEventContextFlag_t, EventContext* ctx, T&& t, RangeEventContext&& rangeContext) + : ModifiableObserved{CustomEventContextFlag, ctx, std::forward(t)} + , rangeContext_{std::move(rangeContext)} + , afterEffectId_{registerAfterEffect()} + {} ObservedContainer(const ObservedContainer&) = delete; ObservedContainer(ObservedContainer&&) = default; @@ -785,7 +808,7 @@ namespace Nui decltype(std::declval().insert(std::declval()))> insert(const value_type& value) { - assert(ObservedBase::eventContext_ != nullptr); + NUI_ASSERT(ObservedBase::eventContext_ != nullptr, "Event context must never be null."); const auto result = contained_.insert(value); rangeContext_.performFullRangeUpdate(); @@ -799,7 +822,7 @@ namespace Nui decltype(std::declval().insert(std::declval()))> insert(value_type&& value) { - assert(ObservedBase::eventContext_ != nullptr); + NUI_ASSERT(ObservedBase::eventContext_ != nullptr, "Event context must never be null."); const auto result = contained_.insert(std::move(value)); rangeContext_.performFullRangeUpdate(); @@ -1014,7 +1037,7 @@ namespace Nui { std::function doInsert; doInsert = [&](int retries) { - assert(ObservedBase::eventContext_ != nullptr); + NUI_ASSERT(ObservedBase::eventContext_ != nullptr, "Event context must never be null."); const auto result = rangeContext_.insertModificationRange(contained_.size(), low, high, type); if (result == RangeEventContext::InsertResult::Final) @@ -1043,7 +1066,7 @@ namespace Nui auto registerAfterEffect() { - assert(ObservedBase::eventContext_ != nullptr); + NUI_ASSERT(ObservedBase::eventContext_ != nullptr, "Event context must never be null."); return ObservedBase::eventContext_->registerAfterEffect(Event{[this](EventContext::EventIdType) { rangeContext_.reset(static_cast(contained_.size()), true); return true; diff --git a/nui/include/nui/utility/assert.hpp b/nui/include/nui/utility/assert.hpp new file mode 100644 index 0000000..b1ad120 --- /dev/null +++ b/nui/include/nui/utility/assert.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include + +namespace Nui +{ + inline void assertImpl(bool condition, const char* message) + { + if (!condition) + { +#ifdef __cpp_exceptions + throw std::runtime_error(message); +#else + Nui::val::global("console").call("error", message); +#endif + } + } + +#ifdef NDEBUG +# define NUI_ASSERT(condition, message) +#else +# define NUI_ASSERT(condition, message) assertImpl(condition, message) +#endif +} \ No newline at end of file diff --git a/nui/test/nui/test_events.hpp b/nui/test/nui/test_events.hpp index d3e471d..78850d1 100644 --- a/nui/test/nui/test_events.hpp +++ b/nui/test/nui/test_events.hpp @@ -144,7 +144,7 @@ namespace Nui::Tests { EventContext eventContext; - Observed obs{&eventContext}; + Observed obs{CustomEventContextFlag, &eventContext}; int calledWith = 77; listen(eventContext, obs, [&calledWith](int const& value) -> bool { @@ -162,7 +162,7 @@ namespace Nui::Tests { EventContext eventContext; - Observed obs{&eventContext}; + Observed obs{CustomEventContextFlag, &eventContext}; int calledWith = 77; listen(eventContext, obs, [&calledWith](int const& value) -> void { @@ -179,7 +179,7 @@ namespace Nui::Tests { EventContext eventContext; - std::shared_ptr> obs = std::make_shared>(&eventContext); + std::shared_ptr> obs = std::make_shared>(CustomEventContextFlag, &eventContext); int calledWith = 77; listen(eventContext, obs, [&calledWith](int const& value) -> void { @@ -196,7 +196,7 @@ namespace Nui::Tests { EventContext eventContext; - std::shared_ptr> obs = std::make_shared>(&eventContext); + std::shared_ptr> obs = std::make_shared>(CustomEventContextFlag, &eventContext); int calledWith = 77; listen(eventContext, obs, [&calledWith](int const& value) -> bool { @@ -217,7 +217,7 @@ namespace Nui::Tests { EventContext eventContext; - std::shared_ptr> obs = std::make_shared>(&eventContext); + std::shared_ptr> obs = std::make_shared>(CustomEventContextFlag, &eventContext); int calledWith = 77; listen(eventContext, obs, [&calledWith](int const& value) -> bool { @@ -254,7 +254,7 @@ namespace Nui::Tests { EventContext eventContext; - Observed obs{&eventContext}; + Observed obs{CustomEventContextFlag, &eventContext}; int calledWith = 77; listen(eventContext, obs, [&calledWith](int const& value) -> bool {