object_manager.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #include "object_manager_impl.h"
  2. #include <boost/asio/io_context.hpp>
  3. #include <boost/asio/post.hpp>
  4. using boost::asio::io_context;
  5. using boost::asio::post;
  6. object_manager main_ob;
  7. extern io_context main_ctx;
  8. object_manager::impl::~impl() {
  9. for (auto &item: obj_pool) {
  10. auto &obj_st = item.second;
  11. obj_st.del_func(obj_st.ptr);
  12. }
  13. }
  14. object_manager::impl::obj_st_type *
  15. object_manager::impl::query_st(object_manager::name_type obj_name) {
  16. auto iter = obj_pool.find(obj_name);
  17. assert(iter != obj_pool.end());
  18. return &iter->second;
  19. }
  20. void *object_manager::impl::query_placeholder(name_type obj_name, std::type_index obj_type) {
  21. auto iter = obj_pool.find(obj_name);
  22. if (iter == obj_pool.end()) [[unlikely]] return nullptr;
  23. auto &obj_st = iter->second;
  24. assert(obj_st.type == obj_type);
  25. return obj_st.ptr;
  26. }
  27. std::type_index object_manager::impl::query_type(obj_name_type obj_name) {
  28. auto iter = obj_pool.find(obj_name);
  29. assert(iter != obj_pool.end());
  30. return iter->second.type;
  31. }
  32. void object_manager::impl::create_placeholder(name_type obj_name, std::type_index obj_type,
  33. void *ptr, del_func_type del_func) {
  34. assert(!obj_pool.contains(obj_name));
  35. obj_pool.emplace(std::piecewise_construct,
  36. std::forward_as_tuple(obj_name),
  37. std::forward_as_tuple(ptr, del_func, obj_type));
  38. }
  39. void object_manager::impl::notify_signal(name_type obj_name) {
  40. auto obj_st = query_st(obj_name);
  41. if (!obj_st->is_pending) {
  42. post(main_ctx, [=] {
  43. obj_st->is_running = true;
  44. for (const auto &ob_st: obj_st->ob_list) {
  45. ob_st.func(obj_name);
  46. }
  47. obj_st->is_pending = false;
  48. obj_st->is_running = false;
  49. });
  50. obj_st->is_pending = true;
  51. }
  52. }
  53. object_manager::de_ob_func_type
  54. object_manager::impl::observe(name_type obj_name, const ob_type &cb_func, priority_type pri) {
  55. auto obj_st = query_st(obj_name);
  56. assert(!obj_st->is_running);
  57. obj_st->ob_list.emplace_front(cb_func, pri);
  58. auto ob_list = &obj_st->ob_list;
  59. auto ob_iter = ob_list->begin();
  60. ob_list->sort(); // sort to ensure priority order
  61. auto exit_func = [=] {
  62. assert(!obj_st->is_running);
  63. obj_st->ob_list.erase(ob_iter);
  64. };
  65. return exit_func;
  66. }
  67. object_manager::object_manager()
  68. : pimpl(std::make_unique<impl>()) {}
  69. object_manager::~object_manager() = default;
  70. void *object_manager::query_placeholder(name_type obj_name, std::type_index obj_type) {
  71. return pimpl->query_placeholder(obj_name, obj_type);
  72. }
  73. std::type_index object_manager::query_type(name_type obj_name) {
  74. return pimpl->query_type(obj_name);
  75. }
  76. void object_manager::create_placeholder(name_type obj_name, std::type_index obj_type,
  77. void *ptr, del_func_type del_func) {
  78. pimpl->create_placeholder(obj_name, obj_type, ptr, del_func);
  79. }
  80. void object_manager::notify_signal(name_type obj_name) {
  81. pimpl->notify_signal(obj_name);
  82. }
  83. object_manager::de_ob_func_type
  84. object_manager::observe(name_type obj_name, const ob_type &cb_func, priority_type pri) {
  85. return pimpl->observe(obj_name, cb_func, pri);
  86. }