object_manager.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #ifndef DEPTHGUIDE_OBJECT_MANAGER_H
  2. #define DEPTHGUIDE_OBJECT_MANAGER_H
  3. #include <cassert>
  4. #include <cstdint>
  5. #include <functional>
  6. #include <memory>
  7. #include <typeindex>
  8. #include <typeinfo>
  9. class object_manager {
  10. public:
  11. using name_type = uint16_t;
  12. object_manager();
  13. ~object_manager();
  14. template<typename T>
  15. void save(name_type obj_name, T &&ptr) {
  16. using RT = std::remove_cvref_t<T>;
  17. auto pl_ptr = query_placeholder(obj_name, typeid(RT));
  18. if (pl_ptr == nullptr) {
  19. static_assert(std::is_default_constructible_v<RT>);
  20. create_placeholder(obj_name, typeid(RT),
  21. new RT{}, [](void *ptr) { delete (RT *) ptr; });
  22. pl_ptr = query_placeholder(obj_name, typeid(RT));
  23. }
  24. assert(pl_ptr != nullptr);
  25. static_assert(std::is_copy_assignable_v<RT>);
  26. *(RT *) pl_ptr = ptr;
  27. notify_signal(obj_name);
  28. }
  29. template<typename T>
  30. T query(name_type obj_name) {
  31. auto pl_ptr = query_placeholder(obj_name, typeid(T));
  32. assert(pl_ptr != nullptr);
  33. static_assert(std::is_copy_constructible_v<T>);
  34. return *(T *) pl_ptr;
  35. }
  36. std::type_index query_type(name_type obj_name);
  37. using priority_type = int;
  38. using ob_type = std::function<void(name_type)>;
  39. using de_ob_func_type = std::function<void()>;
  40. de_ob_func_type observe(name_type obj_name, const ob_type &cb_func, priority_type pri = 0);
  41. private:
  42. using del_func_type = void (*)(void *);
  43. void *query_placeholder(name_type obj_name, std::type_index obj_type);
  44. void create_placeholder(name_type obj_name, std::type_index obj_type,
  45. void *ptr, del_func_type del_func);
  46. void notify_signal(name_type obj_name);
  47. struct impl;
  48. std::unique_ptr<impl> pimpl;
  49. };
  50. using obj_name_type = object_manager::name_type;
  51. static constexpr obj_name_type invalid_obj_name = -1;
  52. extern object_manager main_ob;
  53. #define OBJ_QUERY(type, name) \
  54. main_ob.query<type>(name)
  55. #define OBJ_TYPE(name) \
  56. main_ob.query_type(name)
  57. #define OBJ_SAVE(name, val) \
  58. main_ob.save(name, val)
  59. #define OBJ_OBSERVE(name, func) \
  60. main_ob.observe(name, func)
  61. #define OBJ_OBSERVE_PRI(name, func, pri) \
  62. main_ob.observe(name, func, pri)
  63. #endif //DEPTHGUIDE_OBJECT_MANAGER_H