| 
									
										
										
										
											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> | 
					
						
							| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  |  * modification, are permitted provided that the following conditions are met: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 1. Redistributions of source code must retain the above copyright notice, this | 
					
						
							|  |  |  |  *    list of conditions and the following disclaimer. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 2. Redistributions in binary form must reproduce the above copyright notice, | 
					
						
							|  |  |  |  *    this list of conditions and the following disclaimer in the documentation | 
					
						
							|  |  |  |  *    and/or other materials provided with the distribution. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 
					
						
							|  |  |  |  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
					
						
							|  |  |  |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 
					
						
							|  |  |  |  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | 
					
						
							|  |  |  |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
					
						
							|  |  |  |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 
					
						
							|  |  |  |  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | 
					
						
							|  |  |  |  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | 
					
						
							|  |  |  |  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
					
						
							|  |  |  |  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-04-16 16:33:24 +04:30
										 |  |  | IntrusiveList<Object, RawPtr<Object>, &Object::m_all_objects_list_node>& Object::all_objects() | 
					
						
							| 
									
										
										
										
											2019-08-17 11:26:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-04-16 16:33:24 +04:30
										 |  |  |     static IntrusiveList<Object, RawPtr<Object>, &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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | void Object::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); | 
					
						
							| 
									
										
										
										
											2019-05-05 01:09:49 +02:00
										 |  |  |     object.m_parent = this; | 
					
						
							| 
									
										
										
										
											2019-09-22 00:17:53 +02:00
										 |  |  |     m_children.append(object); | 
					
						
							| 
									
										
										
										
											2020-07-16 20:44:21 +02:00
										 |  |  |     Core::ChildEvent child_event(Core::Event::ChildAdded, object); | 
					
						
							|  |  |  |     event(child_event); | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							|  |  |  |         printf(" "); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-09-14 13:00:51 +02:00
										 |  |  |     printf("%s{%p}", class_name(), this); | 
					
						
							|  |  |  |     if (!name().is_null()) | 
					
						
							|  |  |  |         printf(" %s", name().characters()); | 
					
						
							|  |  |  |     printf("\n"); | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | void Object::deferred_invoke(Function<void(Object&)> invokee) | 
					
						
							| 
									
										
										
										
											2019-04-07 14:36:10 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  |     Core::EventLoop::current().post_event(*this, make<Core::DeferredInvocationEvent>(move(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()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-04 13:41:13 +01:00
										 |  |  | JsonValue Object::property(const StringView& 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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-05 15:46:00 +01:00
										 |  |  | bool Object::set_property(const StringView& name, const JsonValue& value) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | bool Object::is_ancestor_of(const Object& 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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-05 14:40:47 +01:00
										 |  |  | void Object::increment_inspector_count(Badge<RPCClient>) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ++m_inspector_count; | 
					
						
							|  |  |  |     if (m_inspector_count == 1) | 
					
						
							|  |  |  |         did_begin_inspection(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Object::decrement_inspector_count(Badge<RPCClient>) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     --m_inspector_count; | 
					
						
							|  |  |  |     if (!m_inspector_count) | 
					
						
							|  |  |  |         did_end_inspection(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-15 21:33:37 +02:00
										 |  |  | void Object::register_property(const String& name, Function<JsonValue()> getter, Function<bool(const JsonValue&)> setter) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     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); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  | } |