From 68d8e4b18a2fe8eb19b7d971e37ecfbbcaf0eed0 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Thu, 13 Aug 2026 16:50:53 +0300 Subject: [PATCH] Use RAII wrapper for method recursion depth in ecs::container --- libs/ecs/include/psemek/ecs/container.hpp | 21 ++----- .../ecs/detail/recursion_depth_guard.hpp | 55 +++++++++++++++++++ 2 files changed, 61 insertions(+), 15 deletions(-) create mode 100644 libs/ecs/include/psemek/ecs/detail/recursion_depth_guard.hpp diff --git a/libs/ecs/include/psemek/ecs/container.hpp b/libs/ecs/include/psemek/ecs/container.hpp index f39e59bf..4f567503 100644 --- a/libs/ecs/include/psemek/ecs/container.hpp +++ b/libs/ecs/include/psemek/ecs/container.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -423,7 +424,7 @@ namespace psemek::ecs { static_assert(detail::all_different_types_v...>, "all component types must be different"); - ++method_recursion_depth_; + detail::recursion_depth_guard guard{method_recursion_depth_}; (register_component>(), ...); @@ -461,8 +462,6 @@ namespace psemek::ecs finalize_method(); - --method_recursion_depth_; - return handle; } @@ -476,7 +475,7 @@ namespace psemek::ecs currently_changing_archetype_.insert(entity); #endif - ++method_recursion_depth_; + detail::recursion_depth_guard guard{method_recursion_depth_}; (register_component(), ...); @@ -538,8 +537,6 @@ namespace psemek::ecs #endif finalize_method(); - - --method_recursion_depth_; } template @@ -552,7 +549,7 @@ namespace psemek::ecs currently_changing_archetype_.insert(entity); #endif - ++method_recursion_depth_; + detail::recursion_depth_guard guard{method_recursion_depth_}; auto detached_uuid_set = uuid_set_pool_.get(); (detached_uuid_set.insert(std::remove_const_t::uuid()), ...); @@ -614,8 +611,6 @@ namespace psemek::ecs #endif finalize_method(); - - --method_recursion_depth_; } template @@ -641,7 +636,7 @@ namespace psemek::ecs { static_assert(detail::all_different_types_v...>, "all component types must be different"); - ++method_recursion_depth_; + detail::recursion_depth_guard guard{method_recursion_depth_}; using invocable_type = typename detail::filter_with, Function>::type; @@ -672,8 +667,6 @@ namespace psemek::ecs finalize_method(); - --method_recursion_depth_; - return cache; } @@ -682,7 +675,7 @@ namespace psemek::ecs { static_assert(detail::all_different_types_v...>, "all component types must be different"); - ++method_recursion_depth_; + detail::recursion_depth_guard guard{method_recursion_depth_}; using invocable_type = typename detail::filter_with, Function>::type; @@ -710,8 +703,6 @@ namespace psemek::ecs finalize_method(); - --method_recursion_depth_; - return cache; } diff --git a/libs/ecs/include/psemek/ecs/detail/recursion_depth_guard.hpp b/libs/ecs/include/psemek/ecs/detail/recursion_depth_guard.hpp new file mode 100644 index 00000000..a25aeb7b --- /dev/null +++ b/libs/ecs/include/psemek/ecs/detail/recursion_depth_guard.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include +#include + +namespace psemek::ecs::detail +{ + + struct recursion_depth_guard + { + recursion_depth_guard(std::size_t & value) + : depth_(&value) + { + ++value; + } + + recursion_depth_guard(recursion_depth_guard && other) + : depth_(other.depth_) + { + other.depth_ = nullptr; + } + + recursion_depth_guard & operator = (recursion_depth_guard && other) + { + if (this != &other) + { + reset(); + depth_ = other.release(); + } + + return *this; + } + + ~recursion_depth_guard() + { + reset(); + } + + void reset() + { + if (depth_) + --*depth_; + depth_ = nullptr; + } + + std::size_t * release() + { + return std::exchange(depth_, nullptr); + } + + private: + std::size_t * depth_; + }; + +}