1 #ifndef MSP_GAME_ACCESSGUARD_H_
2 #define MSP_GAME_ACCESSGUARD_H_
8 #include <msp/core/noncopyable.h>
12 class invalid_access: public std::logic_error
15 invalid_access(const std::string &w): logic_error(w) { }
22 struct Create { static std::string describe() { return "create"; } };
23 struct Destroy { static std::string describe() { return "destroy"; } };
25 template<typename T = void>
26 struct BlockForScope: NonCopyable
28 BlockForScope() { get_instance().block<T>(); }
29 ~BlockForScope() { get_instance().unblock<T>(); }
33 const uint8_t UNBLOCKED = 0;
34 const uint8_t BLOCKED = 1;
36 std::uint8_t default_flag = UNBLOCKED;
37 std::vector<std::uint8_t> flags;
39 static thread_local AccessGuard *instance;
43 AccessGuard(AccessGuard &&);
44 AccessGuard &operator=(AccessGuard &&);
47 static AccessGuard &get_instance();
53 static unsigned get_next_index();
56 static unsigned get_index();
63 void block() { get<T>() = BLOCKED; }
66 void unblock() { get<T>() = UNBLOCKED; }
69 void check() { if(get<T>()!=UNBLOCKED) throw invalid_access(T::describe()); }
74 inline unsigned AccessGuard::get_index()
76 static unsigned index = get_next_index();
81 inline std::uint8_t &AccessGuard::get()
83 unsigned index = get_index<T>();
84 if(flags.size()<=index)
85 flags.resize(index+1, default_flag);
90 inline void AccessGuard::block<void>()
94 inline void AccessGuard::unblock<void>()
97 } // namespace Msp::Game