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
Notes: sideshowbarker 2024-07-19 08:54:03 +09:00
3 changed files with 43 additions and 2 deletions

View file

@ -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 };
};

View file

@ -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 << '}';

View file

@ -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;
};