Skip to content

Commit ed6181c

Browse files
committed
Fix GameStateSnapshots not being freed
Updated GameStateSnapshot to inherit from RefCounted, to be automatically deleted when reference count reaches zero, and removed GameStateSnapshotRef wrapper class.
1 parent 7ed0b61 commit ed6181c

File tree

4 files changed

+25
-49
lines changed

4 files changed

+25
-49
lines changed

modules/objectdb_profiler/editor/objectdb_profiler_panel.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@
4141
#include "core/os/time.h"
4242
#include "editor/debugger/editor_debugger_node.h"
4343
#include "editor/debugger/script_editor_debugger.h"
44+
#include "editor/docks/inspector_dock.h"
4445
#include "editor/editor_node.h"
46+
#include "editor/inspector/editor_inspector.h"
4547
#include "editor/themes/editor_scale.h"
4648
#include "scene/gui/button.h"
4749
#include "scene/gui/label.h"
@@ -167,7 +169,7 @@ TreeItem *ObjectDBProfilerPanel::_add_snapshot_button(const String &p_snapshot_f
167169
void ObjectDBProfilerPanel::_show_selected_snapshot() {
168170
if (snapshot_list->get_selected()->get_text(0) == (String)diff_button->get_selected_metadata()) {
169171
for (int i = 0; i < diff_button->get_item_count(); i++) {
170-
if (diff_button->get_item_text(i) == current_snapshot->get_snapshot()->name) {
172+
if (diff_button->get_item_text(i) == current_snapshot->name) {
171173
diff_button->select(i);
172174
break;
173175
}
@@ -184,7 +186,7 @@ void ObjectDBProfilerPanel::_on_snapshot_deselected() {
184186
_update_enabled_diff_items();
185187
}
186188

187-
Ref<GameStateSnapshotRef> ObjectDBProfilerPanel::get_snapshot(const String &p_snapshot_file_name) {
189+
Ref<GameStateSnapshot> ObjectDBProfilerPanel::get_snapshot(const String &p_snapshot_file_name) {
188190
if (snapshot_cache.has(p_snapshot_file_name)) {
189191
return snapshot_cache.get(p_snapshot_file_name);
190192
}
@@ -201,7 +203,7 @@ Ref<GameStateSnapshotRef> ObjectDBProfilerPanel::get_snapshot(const String &p_sn
201203
Vector<uint8_t> content = snapshot_file->get_buffer(snapshot_file->get_length()); // We want to split on newlines, so normalize them.
202204
ERR_FAIL_COND_V_MSG(content.is_empty(), nullptr, "ObjectDB Snapshot file is empty: " + full_file_path);
203205

204-
Ref<GameStateSnapshotRef> snapshot = GameStateSnapshot::create_ref(p_snapshot_file_name, content);
206+
Ref<GameStateSnapshot> snapshot = GameStateSnapshot::create_ref(p_snapshot_file_name, content);
205207
if (snapshot.is_valid()) {
206208
snapshot_cache.insert(p_snapshot_file_name, snapshot);
207209
}
@@ -225,8 +227,8 @@ void ObjectDBProfilerPanel::_view_tab_changed(int p_tab_idx) {
225227
// Populating tabs only on tab changed because we're handling a lot of data,
226228
// and the editor freezes for a while if we try to populate every tab at once.
227229
SnapshotView *view = cast_to<SnapshotView>(view_tabs->get_current_tab_control());
228-
GameStateSnapshot *snapshot = current_snapshot.is_null() ? nullptr : current_snapshot->get_snapshot();
229-
GameStateSnapshot *diff = diff_snapshot.is_null() ? nullptr : diff_snapshot->get_snapshot();
230+
GameStateSnapshot *snapshot = current_snapshot.ptr();
231+
GameStateSnapshot *diff = diff_snapshot.ptr();
230232
if (snapshot != nullptr && !view->is_showing_snapshot(snapshot, diff)) {
231233
view->show_snapshot(snapshot, diff);
232234
}
@@ -237,6 +239,11 @@ void ObjectDBProfilerPanel::clear_snapshot(bool p_update_view_tabs) {
237239
view->clear_snapshot();
238240
}
239241

242+
const Object *edited_object = InspectorDock::get_inspector_singleton()->get_edited_object();
243+
if (Object::cast_to<SnapshotDataObject>(edited_object)) {
244+
EditorNode::get_singleton()->push_item(nullptr);
245+
}
246+
240247
current_snapshot.unref();
241248
diff_snapshot.unref();
242249

@@ -333,7 +340,7 @@ void ObjectDBProfilerPanel::_edit_snapshot_name() {
333340
ObjectDBProfilerPanel::ObjectDBProfilerPanel() {
334341
set_name(TTRC("ObjectDB Profiler"));
335342

336-
snapshot_cache = LRUCache<String, Ref<GameStateSnapshotRef>>(SNAPSHOT_CACHE_MAX_SIZE);
343+
snapshot_cache = LRUCache<String, Ref<GameStateSnapshot>>(SNAPSHOT_CACHE_MAX_SIZE);
337344

338345
EditorDebuggerNode::get_singleton()->get_current_debugger()->connect("breaked", callable_mp(this, &ObjectDBProfilerPanel::_on_debug_breaked));
339346

modules/objectdb_profiler/editor/objectdb_profiler_panel.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ class ObjectDBProfilerPanel : public Control {
6969
HashMap<int, PartialSnapshot> partial_snapshots;
7070

7171
LocalVector<SnapshotView *> views;
72-
Ref<GameStateSnapshotRef> current_snapshot;
73-
Ref<GameStateSnapshotRef> diff_snapshot;
74-
LRUCache<String, Ref<GameStateSnapshotRef>> snapshot_cache;
72+
Ref<GameStateSnapshot> current_snapshot;
73+
Ref<GameStateSnapshot> diff_snapshot;
74+
LRUCache<String, Ref<GameStateSnapshot>> snapshot_cache;
7575

7676
void _request_object_snapshot();
7777
void _begin_object_snapshot();
@@ -95,7 +95,7 @@ class ObjectDBProfilerPanel : public Control {
9595
void receive_snapshot(int p_request_id);
9696
void show_snapshot(const String &p_snapshot_file_name, const String &p_snapshot_diff_file_name);
9797
void clear_snapshot(bool p_update_view_tabs = true);
98-
Ref<GameStateSnapshotRef> get_snapshot(const String &p_snapshot_file_name);
98+
Ref<GameStateSnapshot> get_snapshot(const String &p_snapshot_file_name);
9999
void set_enabled(bool p_enabled);
100100
void add_view(SnapshotView *p_to_add);
101101

modules/objectdb_profiler/editor/snapshot_data.cpp

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -318,11 +318,9 @@ void GameStateSnapshot::recompute_references() {
318318
}
319319
}
320320

321-
Ref<GameStateSnapshotRef> GameStateSnapshot::create_ref(const String &p_snapshot_name, const Vector<uint8_t> &p_snapshot_buffer) {
322-
// A ref to a refcounted object which is a wrapper of a non-refcounted object.
323-
Ref<GameStateSnapshotRef> sn;
324-
sn.instantiate(memnew(GameStateSnapshot));
325-
GameStateSnapshot *snapshot = sn->get_snapshot();
321+
Ref<GameStateSnapshot> GameStateSnapshot::create_ref(const String &p_snapshot_name, const Vector<uint8_t> &p_snapshot_buffer) {
322+
Ref<GameStateSnapshot> snapshot;
323+
snapshot.instantiate();
326324
snapshot->name = p_snapshot_name;
327325

328326
// Snapshots may have been created by an older version of the editor. Handle parsing old snapshot versions here based on the version number.
@@ -347,29 +345,17 @@ Ref<GameStateSnapshotRef> GameStateSnapshot::create_ref(const String &p_snapshot
347345
continue;
348346
}
349347

350-
snapshot->objects[obj.id] = memnew(SnapshotDataObject(obj, snapshot, resource_cache));
348+
snapshot->objects[obj.id] = memnew(SnapshotDataObject(obj, snapshot.ptr(), resource_cache));
351349
snapshot->objects[obj.id]->extra_debug_data = (Dictionary)snapshot_data[i + 3];
352350
}
353351

354352
snapshot->recompute_references();
355353
print_verbose("Resource cache hits: " + String::num(resource_cache.hits) + ". Resource cache misses: " + String::num(resource_cache.misses));
356-
return sn;
354+
return snapshot;
357355
}
358356

359357
GameStateSnapshot::~GameStateSnapshot() {
360358
for (const KeyValue<ObjectID, SnapshotDataObject *> &item : objects) {
361359
memdelete(item.value);
362360
}
363361
}
364-
365-
bool GameStateSnapshotRef::unreference() {
366-
bool die = RefCounted::unreference();
367-
if (die) {
368-
memdelete(gamestate_snapshot);
369-
}
370-
return die;
371-
}
372-
373-
GameStateSnapshot *GameStateSnapshotRef::get_snapshot() {
374-
return gamestate_snapshot;
375-
}

modules/objectdb_profiler/editor/snapshot_data.h

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
#include "editor/debugger/editor_debugger_inspector.h"
3434

3535
class GameStateSnapshot;
36-
class GameStateSnapshotRef;
3736

3837
class SnapshotDataObject : public Object {
3938
GDCLASS(SnapshotDataObject, Object);
@@ -77,8 +76,8 @@ class SnapshotDataObject : public Object {
7776
static void _bind_methods();
7877
};
7978

80-
class GameStateSnapshot : public Object {
81-
GDCLASS(GameStateSnapshot, Object);
79+
class GameStateSnapshot : public RefCounted {
80+
GDCLASS(GameStateSnapshot, RefCounted);
8281

8382
void _get_outbound_references(Variant &p_var, HashMap<String, ObjectID> &r_ret_val, const String &p_current_path = "");
8483
void _get_rc_cycles(SnapshotDataObject *p_obj, SnapshotDataObject *p_source_obj, HashSet<SnapshotDataObject *> p_traversed_objs, LocalVector<String> &r_ret_val, const String &p_current_path = "");
@@ -88,24 +87,8 @@ class GameStateSnapshot : public Object {
8887
HashMap<ObjectID, SnapshotDataObject *> objects;
8988
Dictionary snapshot_context;
9089

91-
// Ideally, this would extend EditorDebuggerRemoteObject and be refcounted, but we can't have it both ways.
92-
// So, instead we have this static 'constructor' that returns a RefCounted wrapper around a GameStateSnapshot.
93-
static Ref<GameStateSnapshotRef> create_ref(const String &p_snapshot_name, const Vector<uint8_t> &p_snapshot_buffer);
90+
static Ref<GameStateSnapshot> create_ref(const String &p_snapshot_name, const Vector<uint8_t> &p_snapshot_buffer);
9491
~GameStateSnapshot();
9592

9693
void recompute_references();
9794
};
98-
99-
// Thin RefCounted wrapper around a GameStateSnapshot.
100-
class GameStateSnapshotRef : public RefCounted {
101-
GDCLASS(GameStateSnapshotRef, RefCounted);
102-
103-
GameStateSnapshot *gamestate_snapshot = nullptr;
104-
105-
public:
106-
GameStateSnapshotRef(GameStateSnapshot *p_gss) :
107-
gamestate_snapshot(p_gss) {}
108-
109-
bool unreference();
110-
GameStateSnapshot *get_snapshot();
111-
};

0 commit comments

Comments
 (0)