#include "object_manager_impl.h" #include #include using boost::asio::io_context; using boost::asio::post; object_manager main_ob; extern io_context main_ctx; object_manager::impl::~impl() { for (auto &item: obj_pool) { auto &obj_st = item.second; obj_st.del_func(obj_st.ptr); } } object_manager::impl::obj_st_type * object_manager::impl::query_st(object_manager::name_type obj_name) { auto iter = obj_pool.find(obj_name); assert(iter != obj_pool.end()); return &iter->second; } void *object_manager::impl::query_placeholder(name_type obj_name, std::type_index obj_type) { auto iter = obj_pool.find(obj_name); if (iter == obj_pool.end()) [[unlikely]] return nullptr; auto &obj_st = iter->second; assert(obj_st.type == obj_type); return obj_st.ptr; } std::type_index object_manager::impl::query_type(obj_name_type obj_name) { auto iter = obj_pool.find(obj_name); assert(iter != obj_pool.end()); return iter->second.type; } void object_manager::impl::create_placeholder(name_type obj_name, std::type_index obj_type, void *ptr, del_func_type del_func) { assert(!obj_pool.contains(obj_name)); obj_pool.emplace(std::piecewise_construct, std::forward_as_tuple(obj_name), std::forward_as_tuple(ptr, del_func, obj_type)); } void object_manager::impl::notify_signal(name_type obj_name) { auto obj_st = query_st(obj_name); if (!obj_st->is_pending) { post(main_ctx, [=] { obj_st->is_running = true; for (const auto &ob_st: obj_st->ob_list) { ob_st.func(obj_name); } obj_st->is_pending = false; obj_st->is_running = false; }); obj_st->is_pending = true; } } object_manager::de_ob_func_type object_manager::impl::observe(name_type obj_name, const ob_type &cb_func, priority_type pri) { auto obj_st = query_st(obj_name); assert(!obj_st->is_running); obj_st->ob_list.emplace_front(cb_func, pri); auto ob_list = &obj_st->ob_list; auto ob_iter = ob_list->begin(); ob_list->sort(); // sort to ensure priority order auto exit_func = [=] { assert(!obj_st->is_running); obj_st->ob_list.erase(ob_iter); }; return exit_func; } object_manager::object_manager() : pimpl(std::make_unique()) {} object_manager::~object_manager() = default; void *object_manager::query_placeholder(name_type obj_name, std::type_index obj_type) { return pimpl->query_placeholder(obj_name, obj_type); } std::type_index object_manager::query_type(name_type obj_name) { return pimpl->query_type(obj_name); } void object_manager::create_placeholder(name_type obj_name, std::type_index obj_type, void *ptr, del_func_type del_func) { pimpl->create_placeholder(obj_name, obj_type, ptr, del_func); } void object_manager::notify_signal(name_type obj_name) { pimpl->notify_signal(obj_name); } object_manager::de_ob_func_type object_manager::observe(name_type obj_name, const ob_type &cb_func, priority_type pri) { return pimpl->observe(obj_name, cb_func, pri); }