#ifndef DEPTHGUIDE_OBJECT_MANAGER_H #define DEPTHGUIDE_OBJECT_MANAGER_H #include #include #include #include #include #include class object_manager { public: using name_type = uint16_t; object_manager(); ~object_manager(); template void save(name_type obj_name, T &&ptr) { using RT = std::remove_cvref_t; auto pl_ptr = query_placeholder(obj_name, typeid(RT)); if (pl_ptr == nullptr) { static_assert(std::is_default_constructible_v); create_placeholder(obj_name, typeid(RT), new RT{}, [](void *ptr) { delete (RT *) ptr; }); pl_ptr = query_placeholder(obj_name, typeid(RT)); } assert(pl_ptr != nullptr); static_assert(std::is_copy_assignable_v); *(RT *) pl_ptr = ptr; notify_signal(obj_name); } template T query(name_type obj_name) { auto pl_ptr = query_placeholder(obj_name, typeid(T)); assert(pl_ptr != nullptr); static_assert(std::is_copy_constructible_v); return *(T *) pl_ptr; } std::type_index query_type(name_type obj_name); using priority_type = int; using ob_type = std::function; using de_ob_func_type = std::function; de_ob_func_type observe(name_type obj_name, const ob_type &cb_func, priority_type pri = 0); private: using del_func_type = void (*)(void *); void *query_placeholder(name_type obj_name, std::type_index obj_type); void create_placeholder(name_type obj_name, std::type_index obj_type, void *ptr, del_func_type del_func); void notify_signal(name_type obj_name); struct impl; std::unique_ptr pimpl; }; using obj_name_type = object_manager::name_type; static constexpr obj_name_type invalid_obj_name = -1; extern object_manager main_ob; #define OBJ_QUERY(type, name) \ main_ob.query(name) #define OBJ_TYPE(name) \ main_ob.query_type(name) #define OBJ_SAVE(name, val) \ main_ob.save(name, val) #define OBJ_OBSERVE(name, func) \ main_ob.observe(name, func) #define OBJ_OBSERVE_PRI(name, func, pri) \ main_ob.observe(name, func, pri) #endif //DEPTHGUIDE_OBJECT_MANAGER_H