1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 02:38:11 +00:00

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.
This commit is contained in:
Andreas Kling 2020-03-05 14:40:47 +01:00
parent 37c71bad8a
commit d16f8214d8
3 changed files with 43 additions and 2 deletions

View file

@ -112,6 +112,8 @@ public:
} }
virtual ~RPCClient() override virtual ~RPCClient() override
{ {
if (m_inspected_object)
m_inspected_object->decrement_inspector_count({});
} }
void send_response(const JsonObject& response) void send_response(const JsonObject& response)
@ -161,6 +163,18 @@ public:
return; 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") { if (type == "Disconnect") {
shutdown(); shutdown();
return; return;
@ -175,6 +189,7 @@ public:
private: private:
RefPtr<LocalSocket> m_socket; RefPtr<LocalSocket> m_socket;
WeakPtr<Object> m_inspected_object;
int m_client_id { -1 }; int m_client_id { -1 };
}; };

View file

@ -25,6 +25,7 @@
*/ */
#include <AK/Assertions.h> #include <AK/Assertions.h>
#include <AK/Badge.h>
#include <AK/JsonObject.h> #include <AK/JsonObject.h>
#include <LibCore/Event.h> #include <LibCore/Event.h>
#include <LibCore/EventLoop.h> #include <LibCore/EventLoop.h>
@ -167,9 +168,9 @@ void Object::deferred_invoke(Function<void(Object&)> invokee)
void Object::save_to(JsonObject& json) void Object::save_to(JsonObject& json)
{ {
json.set("class_name", class_name()); 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("name", name());
json.set("parent", String::format("%p", parent())); json.set("parent", (uintptr_t)parent());
} }
bool Object::is_ancestor_of(const Object& other) const bool Object::is_ancestor_of(const Object& other) const
@ -205,6 +206,20 @@ bool Object::is_visible_for_timer_purposes() const
return true; 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) const LogStream& operator<<(const LogStream& stream, const Object& object)
{ {
return stream << object.class_name() << '{' << &object << '}'; return stream << object.class_name() << '{' << &object << '}';

View file

@ -36,6 +36,8 @@
namespace Core { namespace Core {
class RPCClient;
enum class TimerShouldFireWhenNotVisible { enum class TimerShouldFireWhenNotVisible {
No = 0, No = 0,
Yes Yes
@ -130,6 +132,11 @@ public:
virtual bool is_visible_for_timer_purposes() const; 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: protected:
explicit Object(Object* parent = nullptr, bool is_widget = false); 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! // NOTE: You may get child events for children that are not yet fully constructed!
virtual void child_event(ChildEvent&); virtual void child_event(ChildEvent&);
virtual void did_begin_inspection() {}
virtual void did_end_inspection() {}
private: private:
Object* m_parent { nullptr }; Object* m_parent { nullptr };
String m_name; String m_name;
int m_timer_id { 0 }; int m_timer_id { 0 };
unsigned m_inspector_count { 0 };
bool m_widget { false }; bool m_widget { false };
NonnullRefPtrVector<Object> m_children; NonnullRefPtrVector<Object> m_children;
}; };