diff options
author | Andreas Kling <kling@serenityos.org> | 2020-03-05 14:40:47 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-03-05 14:40:47 +0100 |
commit | d16f8214d89348062c19908d8651ac94d13c5aa9 (patch) | |
tree | 7fcba8afe7ea37927cdf5c23428987d2d10c409c | |
parent | 37c71bad8a4a0ce158e45a08010c1adfce454766 (diff) | |
download | serenity-d16f8214d89348062c19908d8651ac94d13c5aa9.zip |
LibCore: Allow RPC clients to specify the currently inspected object
Add a SetInspectedObject call that tells us which Core::Object a remote
client is currently looking it. Objects get notified when they gain
their first inspector, and when they lose their last one.
-rw-r--r-- | Libraries/LibCore/EventLoop.cpp | 15 | ||||
-rw-r--r-- | Libraries/LibCore/Object.cpp | 19 | ||||
-rw-r--r-- | Libraries/LibCore/Object.h | 11 |
3 files changed, 43 insertions, 2 deletions
diff --git a/Libraries/LibCore/EventLoop.cpp b/Libraries/LibCore/EventLoop.cpp index 1f2efb2333..741ddda934 100644 --- a/Libraries/LibCore/EventLoop.cpp +++ b/Libraries/LibCore/EventLoop.cpp @@ -112,6 +112,8 @@ public: } virtual ~RPCClient() override { + if (m_inspected_object) + m_inspected_object->decrement_inspector_count({}); } void send_response(const JsonObject& response) @@ -161,6 +163,18 @@ public: return; } + if (type == "SetInspectedObject") { + auto address = request.get("address").to_number<uintptr_t>(); + for (auto& object : Object::all_objects()) { + if ((uintptr_t)&object == address) { + if (m_inspected_object) + m_inspected_object->decrement_inspector_count({}); + m_inspected_object = object.make_weak_ptr(); + m_inspected_object->increment_inspector_count({}); + } + } + } + if (type == "Disconnect") { shutdown(); return; @@ -175,6 +189,7 @@ public: private: RefPtr<LocalSocket> m_socket; + WeakPtr<Object> m_inspected_object; int m_client_id { -1 }; }; diff --git a/Libraries/LibCore/Object.cpp b/Libraries/LibCore/Object.cpp index eccdbc967e..ff7e7150ac 100644 --- a/Libraries/LibCore/Object.cpp +++ b/Libraries/LibCore/Object.cpp @@ -25,6 +25,7 @@ */ #include <AK/Assertions.h> +#include <AK/Badge.h> #include <AK/JsonObject.h> #include <LibCore/Event.h> #include <LibCore/EventLoop.h> @@ -167,9 +168,9 @@ void Object::deferred_invoke(Function<void(Object&)> invokee) void Object::save_to(JsonObject& json) { json.set("class_name", class_name()); - json.set("address", String::format("%p", this)); + json.set("address", (uintptr_t)this); json.set("name", name()); - json.set("parent", String::format("%p", parent())); + json.set("parent", (uintptr_t)parent()); } bool Object::is_ancestor_of(const Object& other) const @@ -205,6 +206,20 @@ bool Object::is_visible_for_timer_purposes() const return true; } +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(); +} + const LogStream& operator<<(const LogStream& stream, const Object& object) { return stream << object.class_name() << '{' << &object << '}'; diff --git a/Libraries/LibCore/Object.h b/Libraries/LibCore/Object.h index 6f4a106a4f..bacee96d0a 100644 --- a/Libraries/LibCore/Object.h +++ b/Libraries/LibCore/Object.h @@ -36,6 +36,8 @@ namespace Core { +class RPCClient; + enum class TimerShouldFireWhenNotVisible { No = 0, Yes @@ -130,6 +132,11 @@ public: virtual bool is_visible_for_timer_purposes() const; + bool is_being_inspected() const { return m_inspector_count; } + + void increment_inspector_count(Badge<RPCClient>); + void decrement_inspector_count(Badge<RPCClient>); + protected: explicit Object(Object* parent = nullptr, bool is_widget = false); @@ -139,10 +146,14 @@ protected: // NOTE: You may get child events for children that are not yet fully constructed! virtual void child_event(ChildEvent&); + virtual void did_begin_inspection() {} + virtual void did_end_inspection() {} + private: Object* m_parent { nullptr }; String m_name; int m_timer_id { 0 }; + unsigned m_inspector_count { 0 }; bool m_widget { false }; NonnullRefPtrVector<Object> m_children; }; |