Use RAII wrapper for method recursion depth in ecs::container

This commit is contained in:
Nikita Lisitsa 2026-08-13 16:50:53 +03:00
parent 1f7d9e278f
commit 68d8e4b18a
2 changed files with 61 additions and 15 deletions

View file

@ -9,6 +9,7 @@
#include <psemek/ecs/detail/without.hpp>
#include <psemek/ecs/detail/component_registry.hpp>
#include <psemek/ecs/detail/index_container.hpp>
#include <psemek/ecs/detail/recursion_depth_guard.hpp>
#include <psemek/ecs/accessor.hpp>
#include <psemek/ecs/exceptions.hpp>
#include <psemek/ecs/statistics.hpp>
@ -423,7 +424,7 @@ namespace psemek::ecs
{
static_assert(detail::all_different_types_v<std::remove_cvref_t<Components>...>, "all component types must be different");
++method_recursion_depth_;
detail::recursion_depth_guard guard{method_recursion_depth_};
(register_component<std::remove_cvref_t<Components>>(), ...);
@ -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<Components>(), ...);
@ -538,8 +537,6 @@ namespace psemek::ecs
#endif
finalize_method();
--method_recursion_depth_;
}
template <typename ... Components>
@ -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<Components>::uuid()), ...);
@ -614,8 +611,6 @@ namespace psemek::ecs
#endif
finalize_method();
--method_recursion_depth_;
}
template <typename ... Components>
@ -641,7 +636,7 @@ namespace psemek::ecs
{
static_assert(detail::all_different_types_v<std::remove_const_t<Components>...>, "all component types must be different");
++method_recursion_depth_;
detail::recursion_depth_guard guard{method_recursion_depth_};
using invocable_type = typename detail::filter_with<detail::invocable, std::tuple<Components...>, 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<std::remove_const_t<Components>...>, "all component types must be different");
++method_recursion_depth_;
detail::recursion_depth_guard guard{method_recursion_depth_};
using invocable_type = typename detail::filter_with<detail::batch_invocable, std::tuple<Components...>, Function>::type;
@ -710,8 +703,6 @@ namespace psemek::ecs
finalize_method();
--method_recursion_depth_;
return cache;
}

View file

@ -0,0 +1,55 @@
#pragma once
#include <cstddef>
#include <utility>
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_;
};
}