Use RAII wrapper for method recursion depth in ecs::container
This commit is contained in:
parent
1f7d9e278f
commit
68d8e4b18a
2 changed files with 61 additions and 15 deletions
|
|
@ -9,6 +9,7 @@
|
||||||
#include <psemek/ecs/detail/without.hpp>
|
#include <psemek/ecs/detail/without.hpp>
|
||||||
#include <psemek/ecs/detail/component_registry.hpp>
|
#include <psemek/ecs/detail/component_registry.hpp>
|
||||||
#include <psemek/ecs/detail/index_container.hpp>
|
#include <psemek/ecs/detail/index_container.hpp>
|
||||||
|
#include <psemek/ecs/detail/recursion_depth_guard.hpp>
|
||||||
#include <psemek/ecs/accessor.hpp>
|
#include <psemek/ecs/accessor.hpp>
|
||||||
#include <psemek/ecs/exceptions.hpp>
|
#include <psemek/ecs/exceptions.hpp>
|
||||||
#include <psemek/ecs/statistics.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");
|
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>>(), ...);
|
(register_component<std::remove_cvref_t<Components>>(), ...);
|
||||||
|
|
||||||
|
|
@ -461,8 +462,6 @@ namespace psemek::ecs
|
||||||
|
|
||||||
finalize_method();
|
finalize_method();
|
||||||
|
|
||||||
--method_recursion_depth_;
|
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -476,7 +475,7 @@ namespace psemek::ecs
|
||||||
currently_changing_archetype_.insert(entity);
|
currently_changing_archetype_.insert(entity);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
++method_recursion_depth_;
|
detail::recursion_depth_guard guard{method_recursion_depth_};
|
||||||
|
|
||||||
(register_component<Components>(), ...);
|
(register_component<Components>(), ...);
|
||||||
|
|
||||||
|
|
@ -538,8 +537,6 @@ namespace psemek::ecs
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
finalize_method();
|
finalize_method();
|
||||||
|
|
||||||
--method_recursion_depth_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ... Components>
|
template <typename ... Components>
|
||||||
|
|
@ -552,7 +549,7 @@ namespace psemek::ecs
|
||||||
currently_changing_archetype_.insert(entity);
|
currently_changing_archetype_.insert(entity);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
++method_recursion_depth_;
|
detail::recursion_depth_guard guard{method_recursion_depth_};
|
||||||
|
|
||||||
auto detached_uuid_set = uuid_set_pool_.get();
|
auto detached_uuid_set = uuid_set_pool_.get();
|
||||||
(detached_uuid_set.insert(std::remove_const_t<Components>::uuid()), ...);
|
(detached_uuid_set.insert(std::remove_const_t<Components>::uuid()), ...);
|
||||||
|
|
@ -614,8 +611,6 @@ namespace psemek::ecs
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
finalize_method();
|
finalize_method();
|
||||||
|
|
||||||
--method_recursion_depth_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ... Components>
|
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");
|
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;
|
using invocable_type = typename detail::filter_with<detail::invocable, std::tuple<Components...>, Function>::type;
|
||||||
|
|
||||||
|
|
@ -672,8 +667,6 @@ namespace psemek::ecs
|
||||||
|
|
||||||
finalize_method();
|
finalize_method();
|
||||||
|
|
||||||
--method_recursion_depth_;
|
|
||||||
|
|
||||||
return cache;
|
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");
|
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;
|
using invocable_type = typename detail::filter_with<detail::batch_invocable, std::tuple<Components...>, Function>::type;
|
||||||
|
|
||||||
|
|
@ -710,8 +703,6 @@ namespace psemek::ecs
|
||||||
|
|
||||||
finalize_method();
|
finalize_method();
|
||||||
|
|
||||||
--method_recursion_depth_;
|
|
||||||
|
|
||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
55
libs/ecs/include/psemek/ecs/detail/recursion_depth_guard.hpp
Normal file
55
libs/ecs/include/psemek/ecs/detail/recursion_depth_guard.hpp
Normal 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_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue