X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgame%2Fsystem.h;h=8c9c8b1316428258c2c4e3f84858386a75f73a20;hb=423b49f2857f8e1597b652bfd41dbf3ae45f7ec5;hp=3d62c06276553821694651c0c5f15020845cc083;hpb=a99b57a74252fd3de649d544d070b747f91fcf4d;p=libs%2Fgame.git diff --git a/source/game/system.h b/source/game/system.h index 3d62c06..8c9c8b1 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" @@ -19,7 +20,11 @@ public: READ_FRESH = 3, WRITE = 4, UPDATE = READ_OLD | WRITE, - CHAINED_UPDATE = READ_FRESH | WRITE + CHAINED_UPDATE = READ_FRESH | WRITE, + DATA_MASK = 7, + RUN_BEFORE = 8, + RUN_AFTER = 16, + ORDER_MASK = 24 }; struct Dependency @@ -28,6 +33,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) { } }; @@ -74,7 +81,9 @@ protected: template inline void System::declare_dependency(DependencyFlags flags) { - if(!std::is_base_of_v) + if((flags&DATA_MASK) && !std::is_base_of_v) + throw std::invalid_argument("System::declare_dependency"); + if((flags&ORDER_MASK) && !std::is_base_of_v) throw std::invalid_argument("System::declare_dependency"); const Reflection::ClassBase &type = stage.get_reflector().get_or_create_class(); @@ -82,15 +91,29 @@ inline void System::declare_dependency(DependencyFlags flags) if(i!=dependencies.end()) flags = static_cast(flags|i->flags); + if((flags&RUN_BEFORE) && (flags&RUN_AFTER)) + throw std::logic_error("conflicting order 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