| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2021-03-28 11:16:33 +02:00
										 |  |  |  * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org> | 
					
						
							| 
									
										
										
										
											2022-02-26 09:09:45 -07:00
										 |  |  |  * Copyright (c) 2022, the SerenityOS developers. | 
					
						
							| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-04-22 01:24:48 -07:00
										 |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 11:53:16 +02:00
										 |  |  | #include <AK/Assertions.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-05 14:40:47 +01:00
										 |  |  | #include <AK/Badge.h>
 | 
					
						
							| 
									
										
										
										
											2019-08-18 20:36:37 +02:00
										 |  |  | #include <AK/JsonObject.h>
 | 
					
						
							| 
									
										
										
										
											2020-02-06 15:04:03 +01:00
										 |  |  | #include <LibCore/Event.h>
 | 
					
						
							|  |  |  | #include <LibCore/EventLoop.h>
 | 
					
						
							|  |  |  | #include <LibCore/Object.h>
 | 
					
						
							| 
									
										
										
										
											2019-03-19 00:01:02 +01:00
										 |  |  | #include <stdio.h>
 | 
					
						
							| 
									
										
										
										
											2018-10-10 15:12:38 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | namespace Core { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-09 16:30:59 +04:30
										 |  |  | IntrusiveList<&Object::m_all_objects_list_node>& Object::all_objects() | 
					
						
							| 
									
										
										
										
											2019-08-17 11:26:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-09 16:30:59 +04:30
										 |  |  |     static IntrusiveList<&Object::m_all_objects_list_node> objects; | 
					
						
							| 
									
										
										
										
											2019-08-17 11:26:19 +02:00
										 |  |  |     return objects; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-01 16:02:16 +01:00
										 |  |  | Object::Object(Object* parent) | 
					
						
							| 
									
										
										
										
											2018-10-10 15:12:38 +02:00
										 |  |  |     : m_parent(parent) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-08-17 11:26:19 +02:00
										 |  |  |     all_objects().append(*this); | 
					
						
							| 
									
										
										
										
											2018-10-10 16:49:36 +02:00
										 |  |  |     if (m_parent) | 
					
						
							| 
									
										
										
										
											2019-01-31 17:31:23 +01:00
										 |  |  |         m_parent->add_child(*this); | 
					
						
							| 
									
										
										
										
											2020-09-15 21:33:37 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     REGISTER_READONLY_STRING_PROPERTY("class_name", class_name); | 
					
						
							|  |  |  |     REGISTER_STRING_PROPERTY("name", name, set_name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     register_property( | 
					
						
							|  |  |  |         "address", [this] { return FlatPtr(this); }, | 
					
						
							|  |  |  |         [](auto&) { return false; }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     register_property( | 
					
						
							|  |  |  |         "parent", [this] { return FlatPtr(this->parent()); }, | 
					
						
							|  |  |  |         [](auto&) { return false; }); | 
					
						
							| 
									
										
										
										
											2018-10-10 15:12:38 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | Object::~Object() | 
					
						
							| 
									
										
										
										
											2018-10-10 15:12:38 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-09-22 00:17:53 +02:00
										 |  |  |     // NOTE: We move our children out to a stack vector to prevent other
 | 
					
						
							|  |  |  |     //       code from trying to iterate over them.
 | 
					
						
							|  |  |  |     auto children = move(m_children); | 
					
						
							|  |  |  |     // NOTE: We also unparent the children, so that they won't try to unparent
 | 
					
						
							|  |  |  |     //       themselves in their own destructors.
 | 
					
						
							|  |  |  |     for (auto& child : children) | 
					
						
							|  |  |  |         child.m_parent = nullptr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-17 11:26:19 +02:00
										 |  |  |     all_objects().remove(*this); | 
					
						
							| 
									
										
										
										
											2019-02-05 10:31:37 +01:00
										 |  |  |     stop_timer(); | 
					
						
							| 
									
										
										
										
											2018-10-10 16:49:36 +02:00
										 |  |  |     if (m_parent) | 
					
						
							| 
									
										
										
										
											2019-01-31 17:31:23 +01:00
										 |  |  |         m_parent->remove_child(*this); | 
					
						
							| 
									
										
										
										
											2018-10-10 15:12:38 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | void Object::event(Core::Event& event) | 
					
						
							| 
									
										
										
										
											2018-10-10 15:12:38 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     switch (event.type()) { | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  |     case Core::Event::Timer: | 
					
						
							|  |  |  |         return timer_event(static_cast<TimerEvent&>(event)); | 
					
						
							|  |  |  |     case Core::Event::ChildAdded: | 
					
						
							|  |  |  |     case Core::Event::ChildRemoved: | 
					
						
							|  |  |  |         return child_event(static_cast<ChildEvent&>(event)); | 
					
						
							|  |  |  |     case Core::Event::Invalid: | 
					
						
							| 
									
										
										
										
											2021-02-23 20:42:32 +01:00
										 |  |  |         VERIFY_NOT_REACHED(); | 
					
						
							| 
									
										
										
										
											2018-10-10 15:12:38 +02:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  |     case Core::Event::Custom: | 
					
						
							|  |  |  |         return custom_event(static_cast<CustomEvent&>(event)); | 
					
						
							| 
									
										
										
										
											2018-10-10 15:12:38 +02:00
										 |  |  |     default: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-10-10 16:49:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-24 13:09:51 +01:00
										 |  |  | ErrorOr<void> Object::try_add_child(Object& object) | 
					
						
							| 
									
										
										
										
											2018-10-10 16:49:36 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-05 01:09:49 +02:00
										 |  |  |     // FIXME: Should we support reparenting objects?
 | 
					
						
							| 
									
										
										
										
											2021-02-23 20:42:32 +01:00
										 |  |  |     VERIFY(!object.parent() || object.parent() == this); | 
					
						
							| 
									
										
										
										
											2021-11-24 13:09:51 +01:00
										 |  |  |     TRY(m_children.try_append(object)); | 
					
						
							| 
									
										
										
										
											2019-05-05 01:09:49 +02:00
										 |  |  |     object.m_parent = this; | 
					
						
							| 
									
										
										
										
											2020-07-16 20:44:21 +02:00
										 |  |  |     Core::ChildEvent child_event(Core::Event::ChildAdded, object); | 
					
						
							|  |  |  |     event(child_event); | 
					
						
							| 
									
										
										
										
											2021-11-24 13:09:51 +01:00
										 |  |  |     return {}; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Object::add_child(Object& object) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MUST(try_add_child(object)); | 
					
						
							| 
									
										
										
										
											2018-10-10 16:49:36 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | void Object::insert_child_before(Object& new_child, Object& before_child) | 
					
						
							| 
									
										
										
										
											2019-11-05 20:41:27 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     // FIXME: Should we support reparenting objects?
 | 
					
						
							| 
									
										
										
										
											2021-02-23 20:42:32 +01:00
										 |  |  |     VERIFY(!new_child.parent() || new_child.parent() == this); | 
					
						
							| 
									
										
										
										
											2019-11-05 20:41:27 +01:00
										 |  |  |     new_child.m_parent = this; | 
					
						
							|  |  |  |     m_children.insert_before_matching(new_child, [&](auto& existing_child) { return existing_child.ptr() == &before_child; }); | 
					
						
							| 
									
										
										
										
											2020-07-16 20:44:21 +02:00
										 |  |  |     Core::ChildEvent child_event(Core::Event::ChildAdded, new_child, &before_child); | 
					
						
							|  |  |  |     event(child_event); | 
					
						
							| 
									
										
										
										
											2019-11-05 20:41:27 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | void Object::remove_child(Object& object) | 
					
						
							| 
									
										
										
										
											2018-10-10 16:49:36 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-25 14:49:47 +01:00
										 |  |  |     for (size_t i = 0; i < m_children.size(); ++i) { | 
					
						
							| 
									
										
										
										
											2019-09-22 00:17:53 +02:00
										 |  |  |         if (m_children.ptr_at(i).ptr() == &object) { | 
					
						
							|  |  |  |             // NOTE: We protect the child so it survives the handling of ChildRemoved.
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  |             NonnullRefPtr<Object> protector = object; | 
					
						
							| 
									
										
										
										
											2019-09-22 00:17:53 +02:00
										 |  |  |             object.m_parent = nullptr; | 
					
						
							| 
									
										
										
										
											2018-10-13 01:19:25 +02:00
										 |  |  |             m_children.remove(i); | 
					
						
							| 
									
										
										
										
											2020-07-16 20:44:21 +02:00
										 |  |  |             Core::ChildEvent child_event(Core::Event::ChildRemoved, object); | 
					
						
							|  |  |  |             event(child_event); | 
					
						
							| 
									
										
										
										
											2018-10-13 01:19:25 +02:00
										 |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-10-10 16:49:36 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-02-23 20:42:32 +01:00
										 |  |  |     VERIFY_NOT_REACHED(); | 
					
						
							| 
									
										
										
										
											2018-10-10 16:49:36 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-10-12 12:18:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-27 17:14:44 +01:00
										 |  |  | void Object::remove_all_children() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     while (!m_children.is_empty()) | 
					
						
							|  |  |  |         m_children.first().remove_from_parent(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | void Object::timer_event(Core::TimerEvent&) | 
					
						
							| 
									
										
										
										
											2018-10-12 12:18:59 +02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | void Object::child_event(Core::ChildEvent&) | 
					
						
							| 
									
										
										
										
											2019-03-15 16:12:06 +01:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | void Object::custom_event(CustomEvent&) | 
					
						
							| 
									
										
										
										
											2019-07-14 10:27:27 +02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | void Object::start_timer(int ms, TimerShouldFireWhenNotVisible fire_when_not_visible) | 
					
						
							| 
									
										
										
										
											2018-10-12 12:18:59 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-01-31 17:31:23 +01:00
										 |  |  |     if (m_timer_id) { | 
					
						
							| 
									
										
										
										
											2021-01-10 10:02:20 +01:00
										 |  |  |         dbgln("{} {:p} already has a timer!", class_name(), this); | 
					
						
							| 
									
										
										
										
											2021-02-23 20:42:32 +01:00
										 |  |  |         VERIFY_NOT_REACHED(); | 
					
						
							| 
									
										
										
										
											2018-10-12 12:18:59 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-02-01 03:50:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  |     m_timer_id = Core::EventLoop::register_timer(*this, ms, true, fire_when_not_visible); | 
					
						
							| 
									
										
										
										
											2018-10-12 12:18:59 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | void Object::stop_timer() | 
					
						
							| 
									
										
										
										
											2018-10-12 12:18:59 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-01-31 17:31:23 +01:00
										 |  |  |     if (!m_timer_id) | 
					
						
							| 
									
										
										
										
											2018-10-12 12:18:59 +02:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  |     bool success = Core::EventLoop::unregister_timer(m_timer_id); | 
					
						
							| 
									
										
										
										
											2021-02-23 20:42:32 +01:00
										 |  |  |     VERIFY(success); | 
					
						
							| 
									
										
										
										
											2019-01-31 17:31:23 +01:00
										 |  |  |     m_timer_id = 0; | 
					
						
							| 
									
										
										
										
											2018-10-12 12:18:59 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | void Object::dump_tree(int indent) | 
					
						
							| 
									
										
										
										
											2019-03-19 00:01:02 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     for (int i = 0; i < indent; ++i) { | 
					
						
							| 
									
										
										
										
											2021-05-31 15:00:38 +01:00
										 |  |  |         out(" "); | 
					
						
							| 
									
										
										
										
											2019-03-19 00:01:02 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-05-31 15:00:38 +01:00
										 |  |  |     out("{}{{{:p}}}", class_name(), this); | 
					
						
							| 
									
										
										
										
											2020-09-14 13:00:51 +02:00
										 |  |  |     if (!name().is_null()) | 
					
						
							| 
									
										
										
										
											2021-05-31 15:00:38 +01:00
										 |  |  |         out(" {}", name()); | 
					
						
							|  |  |  |     outln(); | 
					
						
							| 
									
										
										
										
											2019-03-19 00:01:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 11:53:16 +02:00
										 |  |  |     for_each_child([&](auto& child) { | 
					
						
							| 
									
										
										
										
											2019-05-27 03:52:19 +02:00
										 |  |  |         child.dump_tree(indent + 2); | 
					
						
							|  |  |  |         return IterationDecision::Continue; | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2019-04-07 14:36:10 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-03-19 00:01:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-30 10:43:28 +00:00
										 |  |  | void Object::deferred_invoke(Function<void()> invokee) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Core::deferred_invoke([invokee = move(invokee), strong_this = NonnullRefPtr(*this)] { invokee(); }); | 
					
						
							| 
									
										
										
										
											2019-03-19 00:01:02 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-08-18 20:36:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | void Object::save_to(JsonObject& json) | 
					
						
							| 
									
										
										
										
											2019-08-18 20:36:37 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-15 21:33:37 +02:00
										 |  |  |     for (auto& it : m_properties) { | 
					
						
							|  |  |  |         auto& property = it.value; | 
					
						
							|  |  |  |         json.set(property->name(), property->get()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-04 18:02:33 +00:00
										 |  |  | JsonValue Object::property(DeprecatedString const& name) const | 
					
						
							| 
									
										
										
										
											2020-09-15 21:33:37 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     auto it = m_properties.find(name); | 
					
						
							|  |  |  |     if (it == m_properties.end()) | 
					
						
							|  |  |  |         return JsonValue(); | 
					
						
							|  |  |  |     return it->value->get(); | 
					
						
							| 
									
										
										
										
											2019-08-18 20:36:37 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-09-20 20:37:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-04 18:02:33 +00:00
										 |  |  | bool Object::set_property(DeprecatedString const& name, JsonValue const& value) | 
					
						
							| 
									
										
										
										
											2020-03-05 15:46:00 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-15 21:33:37 +02:00
										 |  |  |     auto it = m_properties.find(name); | 
					
						
							|  |  |  |     if (it == m_properties.end()) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     return it->value->set(value); | 
					
						
							| 
									
										
										
										
											2020-03-05 15:46:00 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 20:58:27 +03:00
										 |  |  | bool Object::is_ancestor_of(Object const& other) const | 
					
						
							| 
									
										
										
										
											2019-09-20 20:37:31 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (&other == this) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     for (auto* ancestor = other.parent(); ancestor; ancestor = ancestor->parent()) { | 
					
						
							|  |  |  |         if (ancestor == this) | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | void Object::dispatch_event(Core::Event& e, Object* stay_within) | 
					
						
							| 
									
										
										
										
											2019-09-20 20:37:31 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-23 20:42:32 +01:00
										 |  |  |     VERIFY(!stay_within || stay_within == this || stay_within->is_ancestor_of(*this)); | 
					
						
							| 
									
										
										
										
											2019-09-20 20:37:31 +02:00
										 |  |  |     auto* target = this; | 
					
						
							|  |  |  |     do { | 
					
						
							| 
									
										
										
										
											2021-03-28 11:16:33 +02:00
										 |  |  |         // If there's an event filter on this target, ask if it wants to swallow this event.
 | 
					
						
							|  |  |  |         if (target->m_event_filter && !target->m_event_filter(e)) | 
					
						
							|  |  |  |             return; | 
					
						
							| 
									
										
										
										
											2019-09-20 20:37:31 +02:00
										 |  |  |         target->event(e); | 
					
						
							|  |  |  |         target = target->parent(); | 
					
						
							| 
									
										
										
										
											2020-01-21 21:37:49 +01:00
										 |  |  |         if (target == stay_within) { | 
					
						
							|  |  |  |             // Prevent the event from bubbling any further.
 | 
					
						
							| 
									
										
										
										
											2021-01-09 00:01:11 +01:00
										 |  |  |             return; | 
					
						
							| 
									
										
										
										
											2020-01-21 21:37:49 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-01-23 18:08:18 +01:00
										 |  |  |     } while (target && !e.is_accepted()); | 
					
						
							| 
									
										
										
										
											2019-09-20 20:37:31 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-12-29 15:58:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | bool Object::is_visible_for_timer_purposes() const | 
					
						
							| 
									
										
										
										
											2019-12-29 15:58:07 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     if (parent()) | 
					
						
							|  |  |  |         return parent()->is_visible_for_timer_purposes(); | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-13 22:42:11 +02:00
										 |  |  | void Object::increment_inspector_count(Badge<InspectorServerConnection>) | 
					
						
							| 
									
										
										
										
											2020-03-05 14:40:47 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     ++m_inspector_count; | 
					
						
							|  |  |  |     if (m_inspector_count == 1) | 
					
						
							|  |  |  |         did_begin_inspection(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-13 22:42:11 +02:00
										 |  |  | void Object::decrement_inspector_count(Badge<InspectorServerConnection>) | 
					
						
							| 
									
										
										
										
											2020-03-05 14:40:47 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     --m_inspector_count; | 
					
						
							|  |  |  |     if (!m_inspector_count) | 
					
						
							|  |  |  |         did_end_inspection(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-04 18:02:33 +00:00
										 |  |  | void Object::register_property(DeprecatedString const& name, Function<JsonValue()> getter, Function<bool(JsonValue const&)> setter) | 
					
						
							| 
									
										
										
										
											2020-09-15 21:33:37 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     m_properties.set(name, make<Property>(name, move(getter), move(setter))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-28 11:16:33 +02:00
										 |  |  | void Object::set_event_filter(Function<bool(Core::Event&)> filter) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_event_filter = move(filter); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-28 02:38:23 -06:00
										 |  |  | static HashMap<StringView, ObjectClassRegistration*>& object_classes() | 
					
						
							| 
									
										
										
										
											2021-04-04 15:40:34 -06:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-01-28 21:22:13 +01:00
										 |  |  |     static HashMap<StringView, ObjectClassRegistration*> s_map; | 
					
						
							|  |  |  |     return s_map; | 
					
						
							| 
									
										
										
										
											2021-04-04 15:40:34 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-25 20:19:28 -05:00
										 |  |  | ObjectClassRegistration::ObjectClassRegistration(StringView class_name, Function<RefPtr<Object>()> factory, ObjectClassRegistration* parent_class) | 
					
						
							| 
									
										
										
										
											2021-04-04 15:40:34 -06:00
										 |  |  |     : m_class_name(class_name) | 
					
						
							|  |  |  |     , m_factory(move(factory)) | 
					
						
							|  |  |  |     , m_parent_class(parent_class) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     object_classes().set(class_name, this); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 20:58:27 +03:00
										 |  |  | bool ObjectClassRegistration::is_derived_from(ObjectClassRegistration const& base_class) const | 
					
						
							| 
									
										
										
										
											2021-04-04 15:40:34 -06:00
										 |  |  | { | 
					
						
							|  |  |  |     if (&base_class == this) | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     if (!m_parent_class) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     return m_parent_class->is_derived_from(base_class); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 20:58:27 +03:00
										 |  |  | void ObjectClassRegistration::for_each(Function<void(ObjectClassRegistration const&)> callback) | 
					
						
							| 
									
										
										
										
											2021-04-04 15:40:34 -06:00
										 |  |  | { | 
					
						
							|  |  |  |     for (auto& it : object_classes()) { | 
					
						
							|  |  |  |         callback(*it.value); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 20:58:27 +03:00
										 |  |  | ObjectClassRegistration const* ObjectClassRegistration::find(StringView class_name) | 
					
						
							| 
									
										
										
										
											2021-04-04 15:40:34 -06:00
										 |  |  | { | 
					
						
							|  |  |  |     return object_classes().get(class_name).value_or(nullptr); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | } |