From ffbfe95f51058c4de3c898b1a02e2fadba2b8134 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 4 Dec 2022 22:13:56 +0200 Subject: [PATCH] Enforce correct access to buffered components --- source/game/accessguard.h | 16 ++++++++++++++++ source/game/component.h | 15 ++++++++++++++- source/game/system.cpp | 12 ++++++++++++ source/game/system.h | 15 +++++++++++++++ 4 files changed, 57 insertions(+), 1 deletion(-) diff --git a/source/game/accessguard.h b/source/game/accessguard.h index c64efe7..26bbb4e 100644 --- a/source/game/accessguard.h +++ b/source/game/accessguard.h @@ -6,6 +6,7 @@ #include #include #include +#include namespace Msp::Game { @@ -21,6 +22,8 @@ class AccessGuard public: struct Create { static std::string describe() { return "create"; } }; struct Destroy { static std::string describe() { return "destroy"; } }; + template struct Read { static std::string describe(); }; + template struct Write { static std::string describe(); }; template struct BlockForScope: NonCopyable @@ -94,6 +97,19 @@ template<> inline void AccessGuard::unblock() { unblock_all(); } + +template +inline std::string AccessGuard::Read::describe() +{ + return "read "+Debug::demangle(typeid(T).name()); +} + +template +inline std::string AccessGuard::Write::describe() +{ + return "write "+Debug::demangle(typeid(T).name()); +} + } // namespace Msp::Game #endif diff --git a/source/game/component.h b/source/game/component.h index 44927ff..6406cb5 100644 --- a/source/game/component.h +++ b/source/game/component.h @@ -2,6 +2,7 @@ #define MSP_GAME_COMPONENT_H_ #include +#include "accessguard.h" #include "handle.h" namespace Msp::Game { @@ -34,7 +35,7 @@ protected: BufferedComponent(Handle e): Component(e) { } - const T &read() const { return data[read_index]; } + const T &read() const; T &write(); public: @@ -42,9 +43,21 @@ public: virtual void commit_tick() { if(written) read_index = write_index; } }; +template +const T &BufferedComponent::read() const +{ +#ifdef DEBUG + AccessGuard::get_instance().check>(); +#endif + return data[read_index]; +} + template T &BufferedComponent::write() { +#ifdef DEBUG + AccessGuard::get_instance().check>(); +#endif if(!written && write_index!=read_index) { data[write_index] = data[read_index]; diff --git a/source/game/system.cpp b/source/game/system.cpp index 33157c3..4c1f4fb 100644 --- a/source/game/system.cpp +++ b/source/game/system.cpp @@ -13,15 +13,27 @@ void System::begin_tick() active = this; for(const Dependency &d: dependencies) + { +#ifdef DEBUG + if(d.unblock) + d.unblock(d.flags); +#endif if(d.prepare) d.prepare(stage); + } } void System::end_tick() { for(const Dependency &d: dependencies) + { if(d.commit) d.commit(stage); +#ifdef DEBUG + if(d.block) + d.block(d.flags); +#endif + } if(active==this) active = nullptr; diff --git a/source/game/system.h b/source/game/system.h index 3d62c06..e3d7117 100644 --- a/source/game/system.h +++ b/source/game/system.h @@ -3,6 +3,7 @@ #include #include +#include "accessguard.h" #include "component.h" #include "reflection.h" #include "stage.h" @@ -28,6 +29,8 @@ public: const Reflection::ClassBase &type; void (*prepare)(Stage &) = nullptr; void (*commit)(Stage &) = nullptr; + void (*unblock)(DependencyFlags) = nullptr; + void (*block)(DependencyFlags) = nullptr; Dependency(const Reflection::ClassBase &t): type(t) { } }; @@ -86,11 +89,23 @@ inline void System::declare_dependency(DependencyFlags flags) Dependency &dep = (i!=dependencies.end() ? *i : dependencies.emplace_back(type)); dep.flags = flags; if constexpr(requires(T &c) { typename T::Data; c.prepare_tick(); c.commit_tick(); }) + { +#ifdef DEBUG + dep.unblock = +[](DependencyFlags f){ + if(f&READ_OLD) AccessGuard::get_instance().unblock>(); + if(f&WRITE) AccessGuard::get_instance().unblock>(); + }; + dep.block = +[](DependencyFlags f){ + if(f&READ_OLD) AccessGuard::get_instance().block>(); + if(f&WRITE) AccessGuard::get_instance().block>(); + }; +#endif if(flags&WRITE) { dep.prepare = +[](Stage &s){ s.iterate_objects([](T &c){ c.prepare_tick(); }); }; dep.commit = +[](Stage &s){ s.iterate_objects([](T &c){ c.commit_tick(); }); }; } + } } } // namespace Msp::Game -- 2.43.0