CObject.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #pragma once
  2. #include <AK/String.h>
  3. #include <AK/Function.h>
  4. #include <AK/IntrusiveList.h>
  5. #include <AK/StdLibExtras.h>
  6. #include <AK/Vector.h>
  7. #include <AK/Weakable.h>
  8. namespace AK {
  9. class JsonObject;
  10. }
  11. class CEvent;
  12. class CChildEvent;
  13. class CCustomEvent;
  14. class CTimerEvent;
  15. #define C_OBJECT(klass) \
  16. public: \
  17. virtual const char* class_name() const override { return #klass; }
  18. class CObject : public Weakable<CObject> {
  19. // NOTE: No C_OBJECT macro for CObject itself.
  20. public:
  21. IntrusiveListNode m_all_objects_list_node;
  22. virtual ~CObject();
  23. virtual const char* class_name() const = 0;
  24. virtual void event(CEvent&);
  25. const String& name() const { return m_name; }
  26. void set_name(const StringView& name) { m_name = name; }
  27. Vector<CObject*>& children() { return m_children; }
  28. const Vector<CObject*>& children() const { return m_children; }
  29. template<typename Callback>
  30. void for_each_child(Callback callback)
  31. {
  32. for (auto* child : m_children) {
  33. if (callback(*child) == IterationDecision::Break)
  34. return;
  35. }
  36. }
  37. template<typename T, typename Callback>
  38. void for_each_child_of_type(Callback callback);
  39. bool is_ancestor_of(const CObject&) const;
  40. CObject* parent() { return m_parent; }
  41. const CObject* parent() const { return m_parent; }
  42. void start_timer(int ms);
  43. void stop_timer();
  44. bool has_timer() const { return m_timer_id; }
  45. void add_child(CObject&);
  46. void remove_child(CObject&);
  47. void delete_later();
  48. void dump_tree(int indent = 0);
  49. void deferred_invoke(Function<void(CObject&)>);
  50. bool is_widget() const { return m_widget; }
  51. virtual bool is_window() const { return false; }
  52. virtual void save_to(AK::JsonObject&);
  53. static IntrusiveList<CObject, &CObject::m_all_objects_list_node>& all_objects();
  54. void dispatch_event(CEvent&, CObject* stay_within = nullptr);
  55. protected:
  56. explicit CObject(CObject* parent = nullptr, bool is_widget = false);
  57. virtual void timer_event(CTimerEvent&);
  58. virtual void custom_event(CCustomEvent&);
  59. // NOTE: You may get child events for children that are not yet fully constructed!
  60. virtual void child_event(CChildEvent&);
  61. private:
  62. CObject* m_parent { nullptr };
  63. String m_name;
  64. int m_timer_id { 0 };
  65. bool m_widget { false };
  66. Vector<CObject*> m_children;
  67. };
  68. template<typename T>
  69. inline bool is(const CObject&) { return false; }
  70. template<>
  71. inline bool is<CObject>(const CObject&) { return true; }
  72. template<typename T>
  73. inline T& to(CObject& object)
  74. {
  75. ASSERT(is<typename RemoveConst<T>::Type>(object));
  76. return static_cast<T&>(object);
  77. }
  78. template<typename T>
  79. inline const T& to(const CObject& object)
  80. {
  81. ASSERT(is<typename RemoveConst<T>::Type>(object));
  82. return static_cast<const T&>(object);
  83. }
  84. template<typename T, typename Callback>
  85. inline void CObject::for_each_child_of_type(Callback callback)
  86. {
  87. for_each_child([&](auto& child) {
  88. if (is<T>(child))
  89. return callback(to<T>(child));
  90. return IterationDecision::Continue;
  91. });
  92. }
  93. inline const LogStream& operator<<(const LogStream& stream, const CObject& object)
  94. {
  95. return stream << object.class_name() << '{' << &object << '}';
  96. }