CObject.h 3.6 KB

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