summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-03-05 14:40:47 +0100
committerAndreas Kling <kling@serenityos.org>2020-03-05 14:40:47 +0100
commitd16f8214d89348062c19908d8651ac94d13c5aa9 (patch)
tree7fcba8afe7ea37927cdf5c23428987d2d10c409c
parent37c71bad8a4a0ce158e45a08010c1adfce454766 (diff)
downloadserenity-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.cpp15
-rw-r--r--Libraries/LibCore/Object.cpp19
-rw-r--r--Libraries/LibCore/Object.h11
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;
};