#include "object_manager_impl.h" #include #include using boost::asio::io_context; using boost::asio::post; object_manager::impl::obj_st_type::~obj_st_type() { assert(del_func != nullptr); del_func(ptr); } object_manager::impl::obj_st_type * object_manager::impl::query_st(name_type obj_name) { assert(switch_ctx() == nullptr); auto iter = obj_pool.find(obj_name); assert(iter != obj_pool.end()); return &iter->second; } std::optional object_manager::impl::query_info(name_type obj_name) { assert(obj_name != invalid_obj_name); assert(switch_ctx() == nullptr); auto iter = obj_pool.find(obj_name); if (iter == obj_pool.end()) [[unlikely]] return {}; auto &st = iter->second; return obj_info{ .type = st.type, .pl_ptr = st.ptr, .meta = &st.meta, .sig = &st.sig, .last_save_ts = st.stats_timer.last_ts()}; } object_manager::obj_stats object_manager::impl::query_obj_stats(name_type obj_name) { auto obj_st = query_st(obj_name); auto info = obj_st->stats_timer.query(); auto ret = obj_stats{ .save_interval = info.interval, .save_frequency = info.frequency}; return ret; } void object_manager::impl::create_placeholder(name_type obj_name, std::type_index obj_type, void *ptr, del_func_type del_func) { assert(switch_ctx() == nullptr); if (auto iter = obj_pool.find(obj_name); iter != obj_pool.end()) { obj_pool.erase(iter); } 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 cur_ts = current_timestamp(); auto obj_st = query_st(obj_name); if (!obj_st->is_pending) { post(*ctx, [=] { obj_st->sig(obj_name); obj_st->is_pending = false; }); obj_st->is_pending = true; } obj_st->stats_timer.record(cur_ts); } io_context *object_manager::impl::switch_ctx() const { if (std::this_thread::get_id() == tid) [[likely]] return nullptr; return ctx; } object_manager::object_manager(create_config conf) : pimpl(std::make_unique()) { pimpl->ctx = conf.ctx; } object_manager::~object_manager() = default; 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); } std::optional object_manager::query_info(name_type obj_name) { return pimpl->query_info(obj_name); } object_manager::obj_stats object_manager::query_obj_stats(name_type obj_name) { return pimpl->query_obj_stats(obj_name); } io_context *object_manager::switch_ctx() { return pimpl->switch_ctx(); } void object_manager::notify_signal(name_type obj_name) { pimpl->notify_signal(obj_name); }