RemoteObjectGraphModel.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #include "RemoteObjectGraphModel.h"
  2. #include <AK/JsonObject.h>
  3. #include <AK/JsonValue.h>
  4. #include <LibDraw/PNGLoader.h>
  5. #include <LibGUI/GApplication.h>
  6. #include <stdio.h>
  7. RemoteObjectGraphModel::RemoteObjectGraphModel(pid_t pid)
  8. : m_pid(pid)
  9. {
  10. m_object_icon.set_bitmap_for_size(16, load_png("/res/icons/gear16.png"));
  11. }
  12. RemoteObjectGraphModel::~RemoteObjectGraphModel()
  13. {
  14. }
  15. GModelIndex RemoteObjectGraphModel::index(int row, int column, const GModelIndex& parent) const
  16. {
  17. if (!parent.is_valid()) {
  18. if (m_remote_roots.is_empty())
  19. return {};
  20. return create_index(row, column, &m_remote_roots.at(row));
  21. }
  22. auto& remote_parent = *static_cast<RemoteObject*>(parent.internal_data());
  23. return create_index(row, column, remote_parent.children.at(row));
  24. }
  25. int RemoteObjectGraphModel::row_count(const GModelIndex& index) const
  26. {
  27. if (!index.is_valid())
  28. return m_remote_roots.size();
  29. auto& remote_object = *static_cast<RemoteObject*>(index.internal_data());
  30. return remote_object.children.size();
  31. }
  32. int RemoteObjectGraphModel::column_count(const GModelIndex&) const
  33. {
  34. return 1;
  35. }
  36. GVariant RemoteObjectGraphModel::data(const GModelIndex& index, Role role) const
  37. {
  38. auto* remote_object = static_cast<RemoteObject*>(index.internal_data());
  39. if (role == Role::Icon) {
  40. return m_object_icon;
  41. }
  42. if (role == Role::Display) {
  43. return String::format("%s{%s} (%d)", remote_object->class_name.characters(), remote_object->address.characters(), remote_object->children.size());
  44. }
  45. return {};
  46. }
  47. void RemoteObjectGraphModel::update()
  48. {
  49. auto success = m_socket.connect(CSocketAddress::local(String::format("/tmp/rpc.%d", m_pid)));
  50. if (!success) {
  51. fprintf(stderr, "Couldn't connect to PID %d\n", m_pid);
  52. exit(1);
  53. }
  54. m_socket.on_connected = [this] {
  55. dbg() << "Connected to PID " << m_pid;
  56. };
  57. m_socket.on_ready_to_read = [this] {
  58. if (m_socket.eof()) {
  59. dbg() << "Disconnected from PID " << m_pid;
  60. m_socket.close();
  61. return;
  62. }
  63. auto data = m_socket.read_all();
  64. auto json_value = JsonValue::from_string(data);
  65. ASSERT(json_value.is_array());
  66. m_json = json_value.as_array();
  67. Vector<NonnullOwnPtr<RemoteObject>> remote_objects;
  68. HashMap<String, RemoteObject*> objects_by_address;
  69. for (auto& value : m_json.values()) {
  70. ASSERT(value.is_object());
  71. auto& object = value.as_object();
  72. auto remote_object = make<RemoteObject>();
  73. remote_object->address = object.get("address").to_string();
  74. remote_object->parent_address = object.get("parent").to_string();
  75. remote_object->name = object.get("name").to_string();
  76. remote_object->class_name = object.get("class_name").to_string();
  77. objects_by_address.set(remote_object->address, remote_object);
  78. remote_objects.append(move(remote_object));
  79. }
  80. for (int i = 0; i < remote_objects.size(); ++i) {
  81. auto& remote_object = remote_objects[i];
  82. auto* parent = objects_by_address.get(remote_object->parent_address).value_or(nullptr);
  83. if (!parent) {
  84. m_remote_roots.append(move(remote_object));
  85. } else {
  86. remote_object->parent = parent;
  87. parent->children.append(move(remote_object));
  88. }
  89. }
  90. //dbg() << m_json.to_string();
  91. did_update();
  92. };
  93. }