CObject.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #include <AK/Assertions.h>
  2. #include <AK/kstdio.h>
  3. #include <LibCore/CEvent.h>
  4. #include <LibCore/CEventLoop.h>
  5. #include <LibCore/CObject.h>
  6. #include <stdio.h>
  7. CObject::CObject(CObject* parent, bool is_widget)
  8. : m_parent(parent)
  9. , m_widget(is_widget)
  10. {
  11. if (m_parent)
  12. m_parent->add_child(*this);
  13. }
  14. CObject::~CObject()
  15. {
  16. stop_timer();
  17. if (m_parent)
  18. m_parent->remove_child(*this);
  19. auto children_to_delete = move(m_children);
  20. for (auto* child : children_to_delete)
  21. delete child;
  22. }
  23. void CObject::event(CEvent& event)
  24. {
  25. switch (event.type()) {
  26. case CEvent::Timer:
  27. return timer_event(static_cast<CTimerEvent&>(event));
  28. case CEvent::DeferredDestroy:
  29. delete this;
  30. break;
  31. case CEvent::ChildAdded:
  32. case CEvent::ChildRemoved:
  33. return child_event(static_cast<CChildEvent&>(event));
  34. case CEvent::Invalid:
  35. ASSERT_NOT_REACHED();
  36. break;
  37. default:
  38. break;
  39. }
  40. }
  41. void CObject::add_child(CObject& object)
  42. {
  43. // FIXME: Should we support reparenting objects?
  44. ASSERT(!object.parent() || object.parent() == this);
  45. object.m_parent = this;
  46. m_children.append(&object);
  47. event(*make<CChildEvent>(CEvent::ChildAdded, object));
  48. }
  49. void CObject::remove_child(CObject& object)
  50. {
  51. for (ssize_t i = 0; i < m_children.size(); ++i) {
  52. if (m_children[i] == &object) {
  53. m_children.remove(i);
  54. event(*make<CChildEvent>(CEvent::ChildRemoved, object));
  55. return;
  56. }
  57. }
  58. }
  59. void CObject::timer_event(CTimerEvent&)
  60. {
  61. }
  62. void CObject::child_event(CChildEvent&)
  63. {
  64. }
  65. void CObject::start_timer(int ms)
  66. {
  67. if (m_timer_id) {
  68. dbgprintf("CObject{%p} already has a timer!\n", this);
  69. ASSERT_NOT_REACHED();
  70. }
  71. m_timer_id = CEventLoop::register_timer(*this, ms, true);
  72. }
  73. void CObject::stop_timer()
  74. {
  75. if (!m_timer_id)
  76. return;
  77. bool success = CEventLoop::unregister_timer(m_timer_id);
  78. ASSERT(success);
  79. m_timer_id = 0;
  80. }
  81. void CObject::delete_later()
  82. {
  83. CEventLoop::current().post_event(*this, make<CEvent>(CEvent::DeferredDestroy));
  84. }
  85. void CObject::dump_tree(int indent)
  86. {
  87. for (int i = 0; i < indent; ++i) {
  88. printf(" ");
  89. }
  90. printf("%s{%p}\n", class_name(), this);
  91. for_each_child([&](auto& child) {
  92. child.dump_tree(indent + 2);
  93. return IterationDecision::Continue;
  94. });
  95. }
  96. void CObject::deferred_invoke(Function<void(CObject&)> invokee)
  97. {
  98. CEventLoop::current().post_event(*this, make<CDeferredInvocationEvent>(move(invokee)));
  99. }