Various fixes and style nitpicks
This commit is contained in:
@@ -57,11 +57,7 @@ int ClassData::get_recursive_instance_count(HashMap<String, ClassData> &p_all_cl
|
||||
}
|
||||
|
||||
SnapshotClassView::SnapshotClassView() {
|
||||
set_name(TTR("Classes"));
|
||||
|
||||
class_tree = nullptr;
|
||||
object_list = nullptr;
|
||||
diff_object_list = nullptr;
|
||||
set_name(TTRC("Classes"));
|
||||
}
|
||||
|
||||
void SnapshotClassView::show_snapshot(GameStateSnapshot *p_data, GameStateSnapshot *p_diff_data) {
|
||||
@@ -84,45 +80,43 @@ void SnapshotClassView::show_snapshot(GameStateSnapshot *p_data, GameStateSnapsh
|
||||
|
||||
class_tree = memnew(Tree);
|
||||
|
||||
TreeSortAndFilterBar *filter_bar = memnew(TreeSortAndFilterBar(class_tree, TTR("Filter Classes")));
|
||||
filter_bar->add_sort_option(TTR("Name"), TreeSortAndFilterBar::SortType::ALPHA_SORT, 0);
|
||||
TreeSortAndFilterBar *filter_bar = memnew(TreeSortAndFilterBar(class_tree, TTRC("Filter Classes")));
|
||||
filter_bar->add_sort_option(TTRC("Name"), TreeSortAndFilterBar::SortType::ALPHA_SORT, 0);
|
||||
|
||||
TreeSortAndFilterBar::SortOptionIndexes default_sort;
|
||||
if (!diff_data) {
|
||||
default_sort = filter_bar->add_sort_option(TTR("Count"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, 1);
|
||||
default_sort = filter_bar->add_sort_option(TTRC("Count"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, 1);
|
||||
} else {
|
||||
filter_bar->add_sort_option(TTR("A Count"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, 1);
|
||||
filter_bar->add_sort_option(TTR("B Count"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, 2);
|
||||
default_sort = filter_bar->add_sort_option(TTR("Delta"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, 3);
|
||||
filter_bar->add_sort_option(TTRC("A Count"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, 1);
|
||||
filter_bar->add_sort_option(TTRC("B Count"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, 2);
|
||||
default_sort = filter_bar->add_sort_option(TTRC("Delta"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, 3);
|
||||
}
|
||||
class_list_column->add_child(filter_bar);
|
||||
|
||||
class_tree->set_select_mode(Tree::SelectMode::SELECT_ROW);
|
||||
class_tree->set_custom_minimum_size(Size2(200 * EDSCALE, 0));
|
||||
class_tree->set_hide_folding(false);
|
||||
class_list_column->add_child(class_tree);
|
||||
class_tree->set_hide_root(true);
|
||||
class_tree->set_columns(diff_data ? 4 : 2);
|
||||
class_tree->set_column_titles_visible(true);
|
||||
class_tree->set_column_title(0, TTR("Object Class"));
|
||||
class_tree->set_column_title(0, TTRC("Class"));
|
||||
class_tree->set_column_expand(0, true);
|
||||
class_tree->set_column_custom_minimum_width(0, 200 * EDSCALE);
|
||||
class_tree->set_column_title(1, diff_data ? TTR("A Count") : TTR("Count"));
|
||||
class_tree->set_column_title(1, diff_data ? TTRC("A Count") : TTRC("Count"));
|
||||
class_tree->set_column_expand(1, false);
|
||||
if (diff_data) {
|
||||
class_tree->set_column_title(2, TTR("B Count"));
|
||||
class_tree->set_column_title_tooltip_text(1, vformat(TTR("A: %s"), snapshot_data->name));
|
||||
class_tree->set_column_title_tooltip_text(2, vformat(TTR("B: %s"), diff_data->name));
|
||||
class_tree->set_column_title(2, TTRC("B Count"));
|
||||
class_tree->set_column_expand(2, false);
|
||||
class_tree->set_column_title(3, TTR("Delta"));
|
||||
class_tree->set_column_title(3, TTRC("Delta"));
|
||||
class_tree->set_column_expand(3, false);
|
||||
|
||||
// Add tooltip with the names of snapshot A and B
|
||||
class_tree->set_column_title_tooltip_text(1, TTR("A: ") + snapshot_data->name);
|
||||
class_tree->set_column_title_tooltip_text(2, TTR("B: ") + diff_data->name);
|
||||
}
|
||||
class_tree->connect(SceneStringName(item_selected), callable_mp(this, &SnapshotClassView::_class_selected));
|
||||
class_tree->set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
class_tree->set_v_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
class_tree->set_anchors_preset(LayoutPreset::PRESET_FULL_RECT);
|
||||
class_list_column->add_child(class_tree);
|
||||
|
||||
VSplitContainer *object_lists = memnew(VSplitContainer);
|
||||
classes_view->add_child(object_lists);
|
||||
@@ -130,10 +124,10 @@ void SnapshotClassView::show_snapshot(GameStateSnapshot *p_data, GameStateSnapsh
|
||||
object_lists->set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
object_lists->set_v_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
if (!diff_data) {
|
||||
object_lists->add_child(object_list = _make_object_list_tree(TTR("Objects")));
|
||||
object_lists->add_child(object_list = _make_object_list_tree(TTRC("Objects")));
|
||||
} else {
|
||||
object_lists->add_child(object_list = _make_object_list_tree(TTR("A Objects")));
|
||||
object_lists->add_child(diff_object_list = _make_object_list_tree(TTR("B Objects")));
|
||||
object_lists->add_child(object_list = _make_object_list_tree(TTRC("A Objects")));
|
||||
object_lists->add_child(diff_object_list = _make_object_list_tree(TTRC("B Objects")));
|
||||
}
|
||||
|
||||
HashMap<String, ClassData> grouped_by_class;
|
||||
@@ -149,12 +143,13 @@ void SnapshotClassView::show_snapshot(GameStateSnapshot *p_data, GameStateSnapsh
|
||||
classes_todo.push_front(c);
|
||||
}
|
||||
while (classes_todo.size() > 0) {
|
||||
String next_class_name = classes_todo.get(0);
|
||||
String next_class_name = classes_todo.front()->get();
|
||||
classes_todo.pop_front();
|
||||
ClassData &next = grouped_by_class[next_class_name];
|
||||
ClassData &nexts_parent = grouped_by_class[next.parent_class_name];
|
||||
next.tree_node = class_tree->create_item(nexts_parent.tree_node);
|
||||
next.tree_node->set_text(0, next_class_name + " (" + String::num_int64(next.instance_count(snapshot_data)) + ")");
|
||||
next.tree_node->set_auto_translate_mode(0, AUTO_TRANSLATE_MODE_DISABLED);
|
||||
int a_count = next.get_recursive_instance_count(grouped_by_class, snapshot_data);
|
||||
next.tree_node->set_text(1, String::num_int64(a_count));
|
||||
if (diff_data) {
|
||||
@@ -193,13 +188,13 @@ Tree *SnapshotClassView::_make_object_list_tree(const String &p_column_name) {
|
||||
|
||||
void SnapshotClassView::_add_objects_to_class_map(HashMap<String, ClassData> &p_class_map, GameStateSnapshot *p_objects) {
|
||||
for (const KeyValue<ObjectID, SnapshotDataObject *> &pair : p_objects->objects) {
|
||||
StringName class_name = StringName(pair.value->type_name);
|
||||
StringName parent_class_name = class_name != StringName() && ClassDB::class_exists(class_name) ? ClassDB::get_parent_class(class_name) : "";
|
||||
StringName class_name = pair.value->type_name;
|
||||
StringName parent_class_name = !class_name.is_empty() && ClassDB::class_exists(class_name) ? ClassDB::get_parent_class(class_name) : "";
|
||||
|
||||
p_class_map[class_name].instances.push_back(pair.value);
|
||||
|
||||
// Go up the tree and insert all parents/grandparents.
|
||||
while (class_name != StringName()) {
|
||||
while (!class_name.is_empty()) {
|
||||
if (!p_class_map.has(class_name)) {
|
||||
p_class_map[class_name] = ClassData(class_name, parent_class_name);
|
||||
}
|
||||
@@ -212,7 +207,7 @@ void SnapshotClassView::_add_objects_to_class_map(HashMap<String, ClassData> &p_
|
||||
p_class_map[parent_class_name].child_classes.insert(class_name);
|
||||
|
||||
class_name = parent_class_name;
|
||||
parent_class_name = class_name != StringName() ? ClassDB::get_parent_class(class_name) : "";
|
||||
parent_class_name = !class_name.is_empty() ? ClassDB::get_parent_class(class_name) : "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -230,45 +225,58 @@ void SnapshotClassView::_object_selected(Tree *p_tree) {
|
||||
}
|
||||
}
|
||||
ObjectID object_id = p_tree->get_selected()->get_metadata(0);
|
||||
EditorNode::get_singleton()->push_item((Object *)snapshot->objects[object_id]);
|
||||
EditorNode::get_singleton()->push_item(static_cast<Object *>(snapshot->objects[object_id]));
|
||||
}
|
||||
|
||||
void SnapshotClassView::_class_selected() {
|
||||
if (!diff_data) {
|
||||
_populate_object_list(snapshot_data, object_list, TTR("Objects"));
|
||||
} else {
|
||||
_populate_object_list(snapshot_data, object_list, TTR("A Objects"));
|
||||
_populate_object_list(diff_data, diff_object_list, TTR("B Objects"));
|
||||
}
|
||||
_update_lists();
|
||||
}
|
||||
|
||||
void SnapshotClassView::_populate_object_list(GameStateSnapshot *p_snapshot, Tree *p_list, const String &p_name_base) {
|
||||
p_list->clear();
|
||||
String class_name = class_tree->get_selected()->get_metadata(0);
|
||||
|
||||
TreeItem *selected_item = class_tree->get_selected();
|
||||
if (selected_item == nullptr) {
|
||||
p_list->set_column_title(0, vformat("%s (0)", TTR(p_name_base)));
|
||||
return;
|
||||
}
|
||||
|
||||
String class_name = selected_item->get_metadata(0);
|
||||
TreeItem *root = p_list->create_item();
|
||||
int object_count = 0;
|
||||
for (const KeyValue<ObjectID, SnapshotDataObject *> &pair : p_snapshot->objects) {
|
||||
if (pair.value->type_name == class_name) {
|
||||
TreeItem *item = p_list->create_item(root);
|
||||
item->set_auto_translate_mode(0, AUTO_TRANSLATE_MODE_DISABLED);
|
||||
item->set_text(0, pair.value->get_name());
|
||||
item->set_metadata(0, pair.value->remote_object_id);
|
||||
item->set_text_overrun_behavior(0, TextServer::OverrunBehavior::OVERRUN_NO_TRIMMING);
|
||||
object_count++;
|
||||
}
|
||||
}
|
||||
p_list->set_column_title(0, p_name_base + " (" + itos(object_count) + ")");
|
||||
|
||||
p_list->set_column_title(0, vformat("%s (%d)", TTR(p_name_base), object_count));
|
||||
}
|
||||
|
||||
void SnapshotClassView::_update_lists() {
|
||||
if (snapshot_data == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!diff_data) {
|
||||
_populate_object_list(snapshot_data, object_list, TTRC("Objects"));
|
||||
} else {
|
||||
_populate_object_list(snapshot_data, object_list, TTRC("A Objects"));
|
||||
_populate_object_list(diff_data, diff_object_list, TTRC("B Objects"));
|
||||
}
|
||||
}
|
||||
|
||||
void SnapshotClassView::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE:
|
||||
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
|
||||
case NOTIFICATION_THEME_CHANGED:
|
||||
case NOTIFICATION_TRANSLATION_CHANGED: {
|
||||
for (TreeItem *item : _get_children_recursive(class_tree)) {
|
||||
item->set_icon(0, EditorNode::get_singleton()->get_class_icon(item->get_metadata(0), ""));
|
||||
}
|
||||
|
||||
} break;
|
||||
if (p_what == NOTIFICATION_THEME_CHANGED) {
|
||||
for (TreeItem *item : _get_children_recursive(class_tree)) {
|
||||
item->set_icon(0, EditorNode::get_singleton()->get_class_icon(item->get_metadata(0), ""));
|
||||
}
|
||||
} else if (p_what == NOTIFICATION_TRANSLATION_CHANGED) {
|
||||
_update_lists();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ struct ClassData {
|
||||
String class_name;
|
||||
String parent_class_name;
|
||||
HashSet<String> child_classes;
|
||||
List<SnapshotDataObject *> instances;
|
||||
LocalVector<SnapshotDataObject *> instances;
|
||||
TreeItem *tree_node = nullptr;
|
||||
HashMap<GameStateSnapshot *, int> recursive_instance_count_cache;
|
||||
|
||||
@@ -66,6 +66,7 @@ protected:
|
||||
|
||||
Tree *_make_object_list_tree(const String &p_column_name);
|
||||
void _populate_object_list(GameStateSnapshot *p_snapshot, Tree *p_list, const String &p_name_base);
|
||||
void _update_lists();
|
||||
|
||||
public:
|
||||
SnapshotClassView();
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* json_view.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "json_view.h"
|
||||
|
||||
#include "shared_controls.h"
|
||||
|
||||
#include "core/io/json.h"
|
||||
#include "scene/gui/center_container.h"
|
||||
#include "scene/gui/split_container.h"
|
||||
|
||||
SnapshotJsonView::SnapshotJsonView() {
|
||||
set_name(TTR("JSON"));
|
||||
}
|
||||
|
||||
void SnapshotJsonView::show_snapshot(GameStateSnapshot *p_data, GameStateSnapshot *p_diff_data) {
|
||||
// Lock isn't released until the data processing background thread has finished running
|
||||
// and the json has been passed back to the main thread and displayed.
|
||||
SnapshotView::show_snapshot(p_data, p_diff_data);
|
||||
|
||||
HSplitContainer *box = memnew(HSplitContainer);
|
||||
box->set_anchors_preset(LayoutPreset::PRESET_FULL_RECT);
|
||||
add_child(box);
|
||||
|
||||
loading_panel = memnew(DarkPanelContainer);
|
||||
CenterContainer *loading_center = memnew(CenterContainer);
|
||||
Label *loading_label = memnew(Label(TTR("Loading")));
|
||||
add_child(loading_panel);
|
||||
loading_panel->add_child(loading_center);
|
||||
loading_center->add_child(loading_label);
|
||||
loading_panel->set_anchors_preset(LayoutPreset::PRESET_FULL_RECT);
|
||||
loading_center->set_anchors_preset(LayoutPreset::PRESET_FULL_RECT);
|
||||
|
||||
VBoxContainer *json_box = memnew(VBoxContainer);
|
||||
json_box->set_v_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
json_box->set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
box->add_child(json_box);
|
||||
String hdr_a_text = diff_data ? TTR("Snapshot A JSON") : TTR("Snapshot JSON");
|
||||
SpanningHeader *hdr_a = memnew(SpanningHeader(hdr_a_text));
|
||||
if (diff_data) {
|
||||
hdr_a->set_tooltip_text(TTR("Snapshot A:") + " " + snapshot_data->name);
|
||||
}
|
||||
json_box->add_child(hdr_a);
|
||||
|
||||
Ref<EditorJsonVisualizerSyntaxHighlighter> syntax_highlighter;
|
||||
syntax_highlighter.instantiate(List<String>());
|
||||
|
||||
json_content = memnew(EditorJsonVisualizer);
|
||||
json_content->load_theme(syntax_highlighter);
|
||||
json_content->set_name(hdr_a_text);
|
||||
json_content->set_v_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
json_content->set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
json_box->add_child(json_content);
|
||||
|
||||
if (diff_data) {
|
||||
VBoxContainer *diff_json_box = memnew(VBoxContainer);
|
||||
diff_json_box->set_v_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
diff_json_box->set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
box->add_child(diff_json_box);
|
||||
String hrd_b_text = TTR("Snapshot B JSON");
|
||||
SpanningHeader *hdr_b = memnew(SpanningHeader(hrd_b_text));
|
||||
hdr_b->set_tooltip_text(TTR("Snapshot B:") + " " + diff_data->name);
|
||||
diff_json_box->add_child(hdr_b);
|
||||
|
||||
diff_json_content = memnew(EditorJsonVisualizer);
|
||||
diff_json_content->load_theme(syntax_highlighter);
|
||||
diff_json_content->set_name(hrd_b_text);
|
||||
diff_json_content->set_v_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
diff_json_content->set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
diff_json_box->add_child(diff_json_content);
|
||||
}
|
||||
|
||||
WorkerThreadPool::get_singleton()->add_native_task(&SnapshotJsonView::_serialization_worker, this);
|
||||
}
|
||||
|
||||
String SnapshotJsonView::_snapshot_to_json(GameStateSnapshot *p_snapshot) {
|
||||
if (p_snapshot == nullptr) {
|
||||
return "";
|
||||
}
|
||||
Dictionary json_data;
|
||||
json_data["name"] = p_snapshot->name;
|
||||
Dictionary objects;
|
||||
for (const KeyValue<ObjectID, SnapshotDataObject *> &obj : p_snapshot->objects) {
|
||||
Dictionary obj_data;
|
||||
obj_data["type_name"] = obj.value->type_name;
|
||||
|
||||
Array prop_list;
|
||||
for (const PropertyInfo &prop : obj.value->prop_list) {
|
||||
prop_list.push_back((Dictionary)prop);
|
||||
}
|
||||
objects["prop_list"] = prop_list;
|
||||
|
||||
Dictionary prop_values;
|
||||
for (const KeyValue<StringName, Variant> &prop : obj.value->prop_values) {
|
||||
// should only ever be one entry in this context
|
||||
prop_values[prop.key] = prop.value;
|
||||
}
|
||||
obj_data["prop_values"] = prop_values;
|
||||
|
||||
objects[obj.key] = obj_data;
|
||||
}
|
||||
json_data["objects"] = objects;
|
||||
return JSON::stringify(json_data, " ", true, true);
|
||||
}
|
||||
|
||||
void SnapshotJsonView::_serialization_worker(void *p_ud) {
|
||||
// About 0.3s to serialize snapshots in a small game.
|
||||
SnapshotJsonView *self = static_cast<SnapshotJsonView *>(p_ud);
|
||||
GameStateSnapshot *snapshot_data = self->snapshot_data;
|
||||
GameStateSnapshot *diff_data = self->diff_data;
|
||||
// let the message queue figure out if self is still a valid object or if it's been destroyed.
|
||||
MessageQueue::get_singleton()->push_call(self, "_update_text",
|
||||
snapshot_data, diff_data,
|
||||
_snapshot_to_json(snapshot_data),
|
||||
_snapshot_to_json(diff_data));
|
||||
}
|
||||
|
||||
void SnapshotJsonView::_update_text(GameStateSnapshot *p_data_ptr, GameStateSnapshot *p_diff_ptr, const String &p_data_str, const String &p_diff_data_str) {
|
||||
if (p_data_ptr != snapshot_data || p_diff_ptr != diff_data) {
|
||||
// If the GameStateSnapshots we generated strings for no longer match the snapshots we asked for,
|
||||
// throw these results away. We'll get more from a different worker process.
|
||||
return;
|
||||
}
|
||||
|
||||
// About 5s to insert the string into the editor.
|
||||
json_content->set_text(p_data_str);
|
||||
if (diff_data) {
|
||||
diff_json_content->set_text(p_diff_data_str);
|
||||
}
|
||||
loading_panel->queue_free();
|
||||
// Loading json done, release the lock.
|
||||
}
|
||||
|
||||
void SnapshotJsonView::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_update_text", "p_data_ptr", "p_diff_ptr", "p_data_str", "p_diff_data_str"), &SnapshotJsonView::_update_text);
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* json_view.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../snapshot_data.h"
|
||||
#include "snapshot_view.h"
|
||||
|
||||
#include "editor/editor_json_visualizer.h"
|
||||
|
||||
class SnapshotJsonView : public SnapshotView {
|
||||
GDCLASS(SnapshotJsonView, SnapshotView);
|
||||
|
||||
protected:
|
||||
static void _serialization_worker(void *p_ud);
|
||||
void _update_text(GameStateSnapshot *p_data_ptr, GameStateSnapshot *p_diff_ptr, const String &p_data_str, const String &p_diff_data_str);
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
EditorJsonVisualizer *json_content = nullptr;
|
||||
EditorJsonVisualizer *diff_json_content = nullptr;
|
||||
|
||||
Control *loading_panel = nullptr;
|
||||
|
||||
void _load_theme_settings();
|
||||
static String _snapshot_to_json(GameStateSnapshot *p_snapshot);
|
||||
|
||||
public:
|
||||
SnapshotJsonView();
|
||||
virtual void show_snapshot(GameStateSnapshot *p_data, GameStateSnapshot *p_diff_data) override;
|
||||
};
|
||||
@@ -33,10 +33,11 @@
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/themes/editor_scale.h"
|
||||
#include "scene/gui/check_button.h"
|
||||
#include "scene/gui/popup_menu.h"
|
||||
#include "scene/gui/split_container.h"
|
||||
|
||||
SnapshotNodeView::SnapshotNodeView() {
|
||||
set_name("Nodes");
|
||||
set_name(TTRC("Nodes"));
|
||||
}
|
||||
|
||||
void SnapshotNodeView::show_snapshot(GameStateSnapshot *p_data, GameStateSnapshot *p_diff_data) {
|
||||
@@ -49,13 +50,12 @@ void SnapshotNodeView::show_snapshot(GameStateSnapshot *p_data, GameStateSnapsho
|
||||
diff_sides->set_anchors_preset(LayoutPreset::PRESET_FULL_RECT);
|
||||
add_child(diff_sides);
|
||||
|
||||
bool show_diff_label = diff_data && combined_diff_view;
|
||||
main_tree = _make_node_tree(diff_data && !combined_diff_view ? TTR("A Nodes") : TTR("Nodes"), snapshot_data);
|
||||
main_tree = _make_node_tree(diff_data && !combined_diff_view ? TTRC("A Nodes") : TTRC("Nodes"));
|
||||
diff_sides->add_child(main_tree.root);
|
||||
_add_snapshot_to_tree(main_tree.tree, snapshot_data, show_diff_label ? "-" : "");
|
||||
_add_snapshot_to_tree(main_tree.tree, snapshot_data, diff_data && combined_diff_view ? DIFF_GROUP_REMOVED : DIFF_GROUP_NONE);
|
||||
|
||||
if (diff_data) {
|
||||
CheckButton *diff_mode_toggle = memnew(CheckButton(TTR("Combine Diff")));
|
||||
CheckButton *diff_mode_toggle = memnew(CheckButton(TTRC("Combine Diff")));
|
||||
diff_mode_toggle->set_pressed(combined_diff_view);
|
||||
diff_mode_toggle->connect(SceneStringName(toggled), callable_mp(this, &SnapshotNodeView::_toggle_diff_mode));
|
||||
main_tree.filter_bar->add_child(diff_mode_toggle);
|
||||
@@ -63,12 +63,12 @@ void SnapshotNodeView::show_snapshot(GameStateSnapshot *p_data, GameStateSnapsho
|
||||
|
||||
if (combined_diff_view) {
|
||||
// Merge the snapshots together and add a diff.
|
||||
_add_snapshot_to_tree(main_tree.tree, diff_data, "+");
|
||||
_add_snapshot_to_tree(main_tree.tree, diff_data, DIFF_GROUP_ADDED);
|
||||
} else {
|
||||
// Add a second column with the diff snapshot.
|
||||
diff_tree = _make_node_tree(TTR("B Nodes"), diff_data);
|
||||
diff_tree = _make_node_tree(TTRC("B Nodes"));
|
||||
diff_sides->add_child(diff_tree.root);
|
||||
_add_snapshot_to_tree(diff_tree.tree, diff_data, "");
|
||||
_add_snapshot_to_tree(diff_tree.tree, diff_data, DIFF_GROUP_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,12 +84,12 @@ void SnapshotNodeView::show_snapshot(GameStateSnapshot *p_data, GameStateSnapsho
|
||||
choose_object_menu->connect(SceneStringName(id_pressed), callable_mp(this, &SnapshotNodeView::_choose_object_pressed).bind(false));
|
||||
}
|
||||
|
||||
NodeTreeElements SnapshotNodeView::_make_node_tree(const String &p_tree_name, GameStateSnapshot *p_snapshot) {
|
||||
NodeTreeElements SnapshotNodeView::_make_node_tree(const String &p_tree_name) {
|
||||
NodeTreeElements elements;
|
||||
elements.root = memnew(VBoxContainer);
|
||||
elements.root->set_anchors_preset(LayoutPreset::PRESET_FULL_RECT);
|
||||
elements.tree = memnew(Tree);
|
||||
elements.filter_bar = memnew(TreeSortAndFilterBar(elements.tree, TTR("Filter Nodes")));
|
||||
elements.filter_bar = memnew(TreeSortAndFilterBar(elements.tree, TTRC("Filter Nodes")));
|
||||
elements.root->add_child(elements.filter_bar);
|
||||
elements.tree->set_select_mode(Tree::SelectMode::SELECT_ROW);
|
||||
elements.tree->set_custom_minimum_size(Size2(150, 0) * EDSCALE);
|
||||
@@ -125,14 +125,12 @@ void SnapshotNodeView::_node_selected(Tree *p_tree_selected_from) {
|
||||
}
|
||||
}
|
||||
|
||||
List<SnapshotDataObject *> &objects = tree_item_owners[p_tree_selected_from->get_selected()];
|
||||
if (objects.is_empty()) {
|
||||
const LocalVector<SnapshotDataObject *> &item_data = tree_item_data[p_tree_selected_from->get_selected()];
|
||||
if (item_data.is_empty()) {
|
||||
return;
|
||||
}
|
||||
if (objects.size() == 1) {
|
||||
EditorNode::get_singleton()->push_item((Object *)objects.get(0));
|
||||
}
|
||||
if (objects.size() == 2) {
|
||||
} else if (item_data.size() == 1) {
|
||||
EditorNode::get_singleton()->push_item(static_cast<Object *>(item_data[0]));
|
||||
} else if (item_data.size() == 2) {
|
||||
// This happens if we're in the combined diff view and the node exists in both trees
|
||||
// The user has to specify which version of the node they want to see in the inspector.
|
||||
_show_choose_object_menu();
|
||||
@@ -145,89 +143,105 @@ void SnapshotNodeView::_toggle_diff_mode(bool p_state) {
|
||||
}
|
||||
|
||||
void SnapshotNodeView::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE:
|
||||
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
|
||||
case NOTIFICATION_THEME_CHANGED:
|
||||
case NOTIFICATION_TRANSLATION_CHANGED: {
|
||||
_refresh_icons();
|
||||
} break;
|
||||
if (p_what == NOTIFICATION_THEME_CHANGED) {
|
||||
_refresh_icons();
|
||||
}
|
||||
}
|
||||
|
||||
void SnapshotNodeView::_add_snapshot_to_tree(Tree *p_tree, GameStateSnapshot *p_snapshot, const String &p_diff_group_name) {
|
||||
void SnapshotNodeView::_add_snapshot_to_tree(Tree *p_tree, GameStateSnapshot *p_snapshot, DiffGroup p_diff_group) {
|
||||
SnapshotDataObject *scene_root = nullptr;
|
||||
LocalVector<SnapshotDataObject *> orphan_nodes;
|
||||
|
||||
for (const KeyValue<ObjectID, SnapshotDataObject *> &kv : p_snapshot->objects) {
|
||||
if (kv.value->is_node() && !kv.value->extra_debug_data.has("node_parent")) {
|
||||
TreeItem *root_item = _add_child_named(p_tree, p_tree->get_root(), kv.value, p_diff_group_name);
|
||||
_add_object_to_tree(root_item, kv.value, p_diff_group_name);
|
||||
if (kv.value->extra_debug_data["node_is_scene_root"]) {
|
||||
scene_root = kv.value;
|
||||
} else {
|
||||
orphan_nodes.push_back(kv.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (scene_root != nullptr) {
|
||||
TreeItem *root_item = _add_item_to_tree(p_tree, p_tree->get_root(), scene_root, p_diff_group);
|
||||
_add_children_to_tree(root_item, scene_root, p_diff_group);
|
||||
}
|
||||
|
||||
if (!orphan_nodes.is_empty()) {
|
||||
TreeItem *orphans_item = _add_item_to_tree(p_tree, p_tree->get_root(), TTRC("Orphan Nodes"), p_diff_group);
|
||||
for (SnapshotDataObject *orphan_node : orphan_nodes) {
|
||||
TreeItem *orphan_item = _add_item_to_tree(p_tree, orphans_item, orphan_node, p_diff_group);
|
||||
_add_children_to_tree(orphan_item, orphan_node, p_diff_group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SnapshotNodeView::_add_object_to_tree(TreeItem *p_parent_item, SnapshotDataObject *p_data, const String &p_diff_group_name) {
|
||||
for (const Variant &v : (Array)p_data->extra_debug_data["node_children"]) {
|
||||
SnapshotDataObject *child_object = p_data->snapshot->objects[ObjectID((uint64_t)v)];
|
||||
TreeItem *child_item = _add_child_named(p_parent_item->get_tree(), p_parent_item, child_object, p_diff_group_name);
|
||||
_add_object_to_tree(child_item, child_object, p_diff_group_name);
|
||||
void SnapshotNodeView::_add_children_to_tree(TreeItem *p_parent_item, SnapshotDataObject *p_data, DiffGroup p_diff_group) {
|
||||
for (const Variant &child_id : (Array)p_data->extra_debug_data["node_children"]) {
|
||||
SnapshotDataObject *child_object = p_data->snapshot->objects[ObjectID((uint64_t)child_id)];
|
||||
TreeItem *child_item = _add_item_to_tree(p_parent_item->get_tree(), p_parent_item, child_object, p_diff_group);
|
||||
_add_children_to_tree(child_item, child_object, p_diff_group);
|
||||
}
|
||||
}
|
||||
|
||||
TreeItem *SnapshotNodeView::_add_child_named(Tree *p_tree, TreeItem *p_item, SnapshotDataObject *p_item_owner, const String &p_diff_group_name) {
|
||||
bool has_group = !p_diff_group_name.is_empty();
|
||||
const String &item_name = p_item_owner->extra_debug_data["node_name"];
|
||||
TreeItem *SnapshotNodeView::_add_item_to_tree(Tree *p_tree, TreeItem *p_parent, const String &p_item_name, DiffGroup p_diff_group) {
|
||||
// Find out if this node already exists.
|
||||
TreeItem *child_item = nullptr;
|
||||
if (has_group) {
|
||||
for (int idx = 0; idx < p_item->get_child_count(); idx++) {
|
||||
TreeItem *child = p_item->get_child(idx);
|
||||
if (child->get_text(0) == item_name) {
|
||||
child_item = child;
|
||||
TreeItem *item = nullptr;
|
||||
if (p_diff_group != DIFF_GROUP_NONE) {
|
||||
for (int idx = 0; idx < p_parent->get_child_count(); idx++) {
|
||||
TreeItem *child = p_parent->get_child(idx);
|
||||
if (child->get_text(0) == p_item_name) {
|
||||
item = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (child_item) {
|
||||
if (item) {
|
||||
// If it exists, clear the background color because we now know it exists in both trees.
|
||||
child_item->clear_custom_bg_color(0);
|
||||
item->clear_custom_bg_color(0);
|
||||
} else {
|
||||
// Add the new node and set it's background color to green or red depending on which snapshot it's a part of.
|
||||
if (p_item_owner->extra_debug_data["node_is_scene_root"]) {
|
||||
child_item = p_tree->get_root() ? p_tree->get_root() : p_tree->create_item();
|
||||
} else {
|
||||
child_item = p_tree->create_item(p_item);
|
||||
}
|
||||
if (has_group) {
|
||||
if (p_diff_group_name == "+") {
|
||||
child_item->set_custom_bg_color(0, Color(0, 1, 0, 0.1));
|
||||
}
|
||||
if (p_diff_group_name == "-") {
|
||||
child_item->set_custom_bg_color(0, Color(1, 0, 0, 0.1));
|
||||
}
|
||||
// Add the new node and set its background color to green or red depending on which snapshot it's a part of.
|
||||
item = p_tree->create_item(p_parent);
|
||||
|
||||
if (p_diff_group == DIFF_GROUP_ADDED) {
|
||||
item->set_custom_bg_color(0, Color(0, 1, 0, 0.1));
|
||||
} else if (p_diff_group == DIFF_GROUP_REMOVED) {
|
||||
item->set_custom_bg_color(0, Color(1, 0, 0, 0.1));
|
||||
}
|
||||
}
|
||||
|
||||
child_item->set_text(0, item_name);
|
||||
_add_tree_item_owner(child_item, p_item_owner);
|
||||
return child_item;
|
||||
item->set_text(0, p_item_name);
|
||||
item->set_auto_translate_mode(0, AUTO_TRANSLATE_MODE_DISABLED);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
// Each node in the tree may be part of one or two snapshots. This tracks that relationship
|
||||
// so we can display the correct data in the inspector if a node is clicked.
|
||||
void SnapshotNodeView::_add_tree_item_owner(TreeItem *p_item, SnapshotDataObject *p_owner) {
|
||||
if (!tree_item_owners.has(p_item)) {
|
||||
tree_item_owners.insert(p_item, List<SnapshotDataObject *>());
|
||||
}
|
||||
tree_item_owners[p_item].push_back(p_owner);
|
||||
TreeItem *SnapshotNodeView::_add_item_to_tree(Tree *p_tree, TreeItem *p_parent, SnapshotDataObject *p_data, DiffGroup p_diff_group) {
|
||||
String node_name = p_data->extra_debug_data["node_name"];
|
||||
TreeItem *child_item = _add_item_to_tree(p_tree, p_parent, node_name, p_diff_group);
|
||||
tree_item_data[child_item].push_back(p_data);
|
||||
return child_item;
|
||||
}
|
||||
|
||||
void SnapshotNodeView::_refresh_icons() {
|
||||
for (TreeItem *item : _get_children_recursive(main_tree.tree)) {
|
||||
item->set_icon(0, EditorNode::get_singleton()->get_class_icon(tree_item_owners[item].get(0)->type_name, ""));
|
||||
HashMap<TreeItem *, LocalVector<SnapshotDataObject *>>::Iterator E = tree_item_data.find(item);
|
||||
if (E && !E->value.is_empty()) {
|
||||
item->set_icon(0, EditorNode::get_singleton()->get_class_icon(E->value[0]->type_name));
|
||||
} else {
|
||||
item->set_icon(0, EditorNode::get_singleton()->get_class_icon("MissingNode"));
|
||||
}
|
||||
}
|
||||
|
||||
if (diff_tree.tree) {
|
||||
for (TreeItem *item : _get_children_recursive(diff_tree.tree)) {
|
||||
item->set_icon(0, EditorNode::get_singleton()->get_class_icon(tree_item_owners[item].get(0)->type_name, ""));
|
||||
HashMap<TreeItem *, LocalVector<SnapshotDataObject *>>::Iterator E = tree_item_data.find(item);
|
||||
if (E && !E->value.is_empty()) {
|
||||
item->set_icon(0, EditorNode::get_singleton()->get_class_icon(E->value[0]->type_name));
|
||||
} else {
|
||||
item->set_icon(0, EditorNode::get_singleton()->get_class_icon("MissingNode"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,7 +249,7 @@ void SnapshotNodeView::_refresh_icons() {
|
||||
void SnapshotNodeView::clear_snapshot() {
|
||||
SnapshotView::clear_snapshot();
|
||||
|
||||
tree_item_owners.clear();
|
||||
tree_item_data.clear();
|
||||
main_tree.tree = nullptr;
|
||||
main_tree.filter_bar = nullptr;
|
||||
main_tree.root = nullptr;
|
||||
@@ -246,16 +260,15 @@ void SnapshotNodeView::clear_snapshot() {
|
||||
}
|
||||
|
||||
void SnapshotNodeView::_choose_object_pressed(int p_object_idx, bool p_confirm_override) {
|
||||
List<SnapshotDataObject *> &objects = tree_item_owners[active_tree->get_selected()];
|
||||
EditorNode::get_singleton()->push_item((Object *)objects.get(p_object_idx));
|
||||
EditorNode::get_singleton()->push_item(static_cast<Object *>(tree_item_data[active_tree->get_selected()][p_object_idx]));
|
||||
}
|
||||
|
||||
void SnapshotNodeView::_show_choose_object_menu() {
|
||||
remove_child(choose_object_menu);
|
||||
add_child(choose_object_menu);
|
||||
choose_object_menu->clear(false);
|
||||
choose_object_menu->add_item(TTR("Snapshot A"), 0);
|
||||
choose_object_menu->add_item(TTR("Snapshot B"), 1);
|
||||
choose_object_menu->add_item(TTRC("Snapshot A"), 0);
|
||||
choose_object_menu->add_item(TTRC("Snapshot B"), 1);
|
||||
choose_object_menu->reset_size();
|
||||
choose_object_menu->set_position(get_screen_position() + get_local_mouse_position());
|
||||
choose_object_menu->popup();
|
||||
|
||||
@@ -52,31 +52,32 @@ struct NodeTreeElements {
|
||||
class SnapshotNodeView : public SnapshotView {
|
||||
GDCLASS(SnapshotNodeView, SnapshotView);
|
||||
|
||||
protected:
|
||||
enum DiffGroup {
|
||||
DIFF_GROUP_NONE,
|
||||
DIFF_GROUP_ADDED,
|
||||
DIFF_GROUP_REMOVED
|
||||
};
|
||||
|
||||
NodeTreeElements main_tree;
|
||||
NodeTreeElements diff_tree;
|
||||
Tree *active_tree = nullptr;
|
||||
PopupMenu *choose_object_menu = nullptr;
|
||||
bool combined_diff_view = true;
|
||||
HashMap<TreeItem *, List<SnapshotDataObject *>> tree_item_owners;
|
||||
HashMap<TreeItem *, LocalVector<SnapshotDataObject *>> tree_item_data;
|
||||
|
||||
void _node_selected(Tree *p_tree_selected_from);
|
||||
void _notification(int p_what);
|
||||
NodeTreeElements _make_node_tree(const String &p_tree_name, GameStateSnapshot *p_snapshot);
|
||||
NodeTreeElements _make_node_tree(const String &p_tree_name);
|
||||
void _apply_filters();
|
||||
void _refresh_icons();
|
||||
void _toggle_diff_mode(bool p_state);
|
||||
void _choose_object_pressed(int p_object_idx, bool p_confirm_override);
|
||||
void _show_choose_object_menu();
|
||||
|
||||
// `_add_snapshot_to_tree`, `_add_object_to_tree`, and `_add_child_named` work together to add items to the node tree.
|
||||
// They support adding two snapshots to the same tree, and will highlight rows to show additions and removals.
|
||||
// `_add_snapshot_to_tree` walks the root items in the tree and adds them first, then `_add_object_to_tree` recursively
|
||||
// adds all the child items. `_add_child_named` is used by both to add each individual items.
|
||||
void _add_snapshot_to_tree(Tree *p_tree, GameStateSnapshot *p_snapshot, const String &p_diff_group_name = "");
|
||||
void _add_object_to_tree(TreeItem *p_parent_item, SnapshotDataObject *p_data, const String &p_diff_group_name = "");
|
||||
TreeItem *_add_child_named(Tree *p_tree, TreeItem *p_item, SnapshotDataObject *p_item_owner, const String &p_diff_group_name = "");
|
||||
void _add_tree_item_owner(TreeItem *p_item, SnapshotDataObject *p_owner);
|
||||
void _add_snapshot_to_tree(Tree *p_tree, GameStateSnapshot *p_snapshot, DiffGroup p_diff_group = DIFF_GROUP_NONE);
|
||||
void _add_children_to_tree(TreeItem *p_parent_item, SnapshotDataObject *p_data, DiffGroup p_diff_group = DIFF_GROUP_NONE);
|
||||
TreeItem *_add_item_to_tree(Tree *p_tree, TreeItem *p_parent, const String &p_item_name, DiffGroup p_diff_group = DIFF_GROUP_NONE);
|
||||
TreeItem *_add_item_to_tree(Tree *p_tree, TreeItem *p_parent, SnapshotDataObject *p_data, DiffGroup p_diff_group = DIFF_GROUP_NONE);
|
||||
|
||||
public:
|
||||
SnapshotNodeView();
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include "scene/gui/split_container.h"
|
||||
|
||||
SnapshotObjectView::SnapshotObjectView() {
|
||||
set_name(TTR("Objects"));
|
||||
set_name(TTRC("Objects"));
|
||||
}
|
||||
|
||||
void SnapshotObjectView::show_snapshot(GameStateSnapshot *p_data, GameStateSnapshot *p_diff_data) {
|
||||
@@ -60,17 +60,17 @@ void SnapshotObjectView::show_snapshot(GameStateSnapshot *p_data, GameStateSnaps
|
||||
|
||||
object_list = memnew(Tree);
|
||||
|
||||
filter_bar = memnew(TreeSortAndFilterBar(object_list, TTR("Filter Objects")));
|
||||
filter_bar = memnew(TreeSortAndFilterBar(object_list, TTRC("Filter Objects")));
|
||||
object_column->add_child(filter_bar);
|
||||
int sort_idx = 0;
|
||||
if (diff_data) {
|
||||
filter_bar->add_sort_option(TTR("Snapshot"), TreeSortAndFilterBar::SortType::ALPHA_SORT, sort_idx++);
|
||||
filter_bar->add_sort_option(TTRC("Snapshot"), TreeSortAndFilterBar::SortType::ALPHA_SORT, sort_idx++);
|
||||
}
|
||||
filter_bar->add_sort_option(TTR("Class"), TreeSortAndFilterBar::SortType::ALPHA_SORT, sort_idx++);
|
||||
filter_bar->add_sort_option(TTR("Name"), TreeSortAndFilterBar::SortType::ALPHA_SORT, sort_idx++);
|
||||
filter_bar->add_sort_option(TTR("Inbound References"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, sort_idx++);
|
||||
filter_bar->add_sort_option(TTRC("Class"), TreeSortAndFilterBar::SortType::ALPHA_SORT, sort_idx++);
|
||||
filter_bar->add_sort_option(TTRC("Name"), TreeSortAndFilterBar::SortType::ALPHA_SORT, sort_idx++);
|
||||
filter_bar->add_sort_option(TTRC("Inbound References"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, sort_idx++);
|
||||
TreeSortAndFilterBar::SortOptionIndexes default_sort = filter_bar->add_sort_option(
|
||||
TTR("Outbound References"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, sort_idx++);
|
||||
TTRC("Outbound References"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, sort_idx++);
|
||||
|
||||
// Tree of objects.
|
||||
object_list->set_select_mode(Tree::SelectMode::SELECT_ROW);
|
||||
@@ -82,27 +82,27 @@ void SnapshotObjectView::show_snapshot(GameStateSnapshot *p_data, GameStateSnaps
|
||||
object_list->set_column_titles_visible(true);
|
||||
int offset = 0;
|
||||
if (diff_data) {
|
||||
object_list->set_column_title(0, TTR("Snapshot"));
|
||||
object_list->set_column_title(0, TTRC("Snapshot"));
|
||||
object_list->set_column_expand(0, false);
|
||||
object_list->set_column_title_tooltip_text(0, "A: " + snapshot_data->name + ", B: " + diff_data->name);
|
||||
offset++;
|
||||
}
|
||||
object_list->set_column_title(offset + 0, TTR("Class"));
|
||||
object_list->set_column_title(offset + 0, TTRC("Class"));
|
||||
object_list->set_column_expand(offset + 0, true);
|
||||
object_list->set_column_title_tooltip_text(offset + 0, TTR("Object's class"));
|
||||
object_list->set_column_title(offset + 1, TTR("Object"));
|
||||
object_list->set_column_title_tooltip_text(offset + 0, TTRC("Object's class"));
|
||||
object_list->set_column_title(offset + 1, TTRC("Object"));
|
||||
object_list->set_column_expand(offset + 1, true);
|
||||
object_list->set_column_expand_ratio(offset + 1, 2);
|
||||
object_list->set_column_title_tooltip_text(offset + 1, TTR("Object's name"));
|
||||
object_list->set_column_title(offset + 2, TTR("In"));
|
||||
object_list->set_column_title_tooltip_text(offset + 1, TTRC("Object's name"));
|
||||
object_list->set_column_title(offset + 2, TTRC("In"));
|
||||
object_list->set_column_expand(offset + 2, false);
|
||||
object_list->set_column_clip_content(offset + 2, false);
|
||||
object_list->set_column_title_tooltip_text(offset + 2, TTR("Number of inbound references"));
|
||||
object_list->set_column_title_tooltip_text(offset + 2, TTRC("Number of inbound references"));
|
||||
object_list->set_column_custom_minimum_width(offset + 2, 30 * EDSCALE);
|
||||
object_list->set_column_title(offset + 3, TTR("Out"));
|
||||
object_list->set_column_title(offset + 3, TTRC("Out"));
|
||||
object_list->set_column_expand(offset + 3, false);
|
||||
object_list->set_column_clip_content(offset + 3, false);
|
||||
object_list->set_column_title_tooltip_text(offset + 3, TTR("Number of outbound references"));
|
||||
object_list->set_column_title_tooltip_text(offset + 3, TTRC("Number of outbound references"));
|
||||
object_list->set_column_custom_minimum_width(offset + 2, 30 * EDSCALE);
|
||||
object_list->connect(SceneStringName(item_selected), callable_mp(this, &SnapshotObjectView::_object_selected));
|
||||
object_list->set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
@@ -115,9 +115,9 @@ void SnapshotObjectView::show_snapshot(GameStateSnapshot *p_data, GameStateSnaps
|
||||
object_details->set_v_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
|
||||
object_list->create_item();
|
||||
_insert_data(snapshot_data, TTR("A"));
|
||||
_insert_data(snapshot_data, TTRC("A"));
|
||||
if (diff_data) {
|
||||
_insert_data(diff_data, TTR("B"));
|
||||
_insert_data(diff_data, TTRC("B"));
|
||||
}
|
||||
|
||||
filter_bar->select_sort(default_sort.descending);
|
||||
@@ -136,8 +136,11 @@ void SnapshotObjectView::_insert_data(GameStateSnapshot *p_snapshot, const Strin
|
||||
if (diff_data) {
|
||||
item->set_text(0, p_name);
|
||||
item->set_tooltip_text(0, p_snapshot->name);
|
||||
item->set_auto_translate_mode(0, AUTO_TRANSLATE_MODE_DISABLED);
|
||||
offset = 1;
|
||||
}
|
||||
item->set_auto_translate_mode(offset + 0, AUTO_TRANSLATE_MODE_DISABLED);
|
||||
item->set_auto_translate_mode(offset + 1, AUTO_TRANSLATE_MODE_DISABLED);
|
||||
item->set_text(offset + 0, pair.value->type_name);
|
||||
item->set_text(offset + 1, pair.value->get_name());
|
||||
item->set_text(offset + 2, String::num_uint64(pair.value->inbound_references.size()));
|
||||
@@ -155,7 +158,7 @@ void SnapshotObjectView::_object_selected() {
|
||||
}
|
||||
|
||||
SnapshotDataObject *d = item_data_map[object_list->get_selected()];
|
||||
EditorNode::get_singleton()->push_item((Object *)d);
|
||||
EditorNode::get_singleton()->push_item(static_cast<Object *>(d));
|
||||
|
||||
DarkPanelContainer *object_panel = memnew(DarkPanelContainer);
|
||||
VBoxContainer *object_panel_content = memnew(VBoxContainer);
|
||||
@@ -177,22 +180,28 @@ void SnapshotObjectView::_object_selected() {
|
||||
properties_scroll->add_child(properties_container);
|
||||
properties_container->add_theme_constant_override("separation", 8);
|
||||
|
||||
inbound_tree = _make_references_list(properties_container, TTR("Inbound References"), TTR("Source"), TTR("Other object referencing this object"), TTR("Property"), TTR("Property of other object referencing this object"));
|
||||
inbound_tree = _make_references_list(properties_container, TTRC("Inbound References"), TTRC("Source"), TTRC("Other object referencing this object"), TTRC("Property"), TTRC("Property of other object referencing this object"));
|
||||
inbound_tree->connect(SceneStringName(item_selected), callable_mp(this, &SnapshotObjectView::_reference_selected).bind(inbound_tree));
|
||||
TreeItem *ib_root = inbound_tree->create_item();
|
||||
for (const KeyValue<String, ObjectID> &ob : d->inbound_references) {
|
||||
TreeItem *i = inbound_tree->create_item(ib_root);
|
||||
i->set_auto_translate_mode(0, AUTO_TRANSLATE_MODE_DISABLED);
|
||||
i->set_auto_translate_mode(1, AUTO_TRANSLATE_MODE_DISABLED);
|
||||
|
||||
SnapshotDataObject *target = d->snapshot->objects[ob.value];
|
||||
i->set_text(0, target->get_name());
|
||||
i->set_text(1, ob.key);
|
||||
reference_item_map[i] = data_item_map[target];
|
||||
}
|
||||
|
||||
outbound_tree = _make_references_list(properties_container, TTR("Outbound References"), TTR("Property"), TTR("Property of this object referencing other object"), TTR("Target"), TTR("Other object being referenced"));
|
||||
outbound_tree = _make_references_list(properties_container, TTRC("Outbound References"), TTRC("Property"), TTRC("Property of this object referencing other object"), TTRC("Target"), TTRC("Other object being referenced"));
|
||||
outbound_tree->connect(SceneStringName(item_selected), callable_mp(this, &SnapshotObjectView::_reference_selected).bind(outbound_tree));
|
||||
TreeItem *ob_root = outbound_tree->create_item();
|
||||
for (const KeyValue<String, ObjectID> &ob : d->outbound_references) {
|
||||
TreeItem *i = outbound_tree->create_item(ob_root);
|
||||
i->set_auto_translate_mode(0, AUTO_TRANSLATE_MODE_DISABLED);
|
||||
i->set_auto_translate_mode(1, AUTO_TRANSLATE_MODE_DISABLED);
|
||||
|
||||
SnapshotDataObject *target = d->snapshot->objects[ob.value];
|
||||
i->set_text(0, ob.key);
|
||||
i->set_text(1, target->get_name());
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include "scene/gui/split_container.h"
|
||||
|
||||
SnapshotRefCountedView::SnapshotRefCountedView() {
|
||||
set_name(TTR("RefCounted"));
|
||||
set_name(TTRC("RefCounted"));
|
||||
}
|
||||
|
||||
void SnapshotRefCountedView::show_snapshot(GameStateSnapshot *p_data, GameStateSnapshot *p_diff_data) {
|
||||
@@ -59,21 +59,21 @@ void SnapshotRefCountedView::show_snapshot(GameStateSnapshot *p_data, GameStateS
|
||||
// Tree of Refs.
|
||||
refs_list = memnew(Tree);
|
||||
|
||||
filter_bar = memnew(TreeSortAndFilterBar(refs_list, TTR("Filter RefCounteds")));
|
||||
filter_bar = memnew(TreeSortAndFilterBar(refs_list, TTRC("Filter RefCounteds")));
|
||||
refs_column->add_child(filter_bar);
|
||||
int offset = diff_data ? 1 : 0;
|
||||
if (diff_data) {
|
||||
filter_bar->add_sort_option(TTR("Snapshot"), TreeSortAndFilterBar::SortType::ALPHA_SORT, 0);
|
||||
filter_bar->add_sort_option(TTRC("Snapshot"), TreeSortAndFilterBar::SortType::ALPHA_SORT, 0);
|
||||
}
|
||||
filter_bar->add_sort_option(TTR("Class"), TreeSortAndFilterBar::SortType::ALPHA_SORT, offset + 0);
|
||||
filter_bar->add_sort_option(TTR("Name"), TreeSortAndFilterBar::SortType::ALPHA_SORT, offset + 1);
|
||||
filter_bar->add_sort_option(TTRC("Class"), TreeSortAndFilterBar::SortType::ALPHA_SORT, offset + 0);
|
||||
filter_bar->add_sort_option(TTRC("Name"), TreeSortAndFilterBar::SortType::ALPHA_SORT, offset + 1);
|
||||
TreeSortAndFilterBar::SortOptionIndexes default_sort = filter_bar->add_sort_option(
|
||||
TTR("Native Refs"),
|
||||
TTRC("Native Refs"),
|
||||
TreeSortAndFilterBar::SortType::NUMERIC_SORT,
|
||||
offset + 2);
|
||||
filter_bar->add_sort_option(TTR("ObjectDB Refs"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, offset + 3);
|
||||
filter_bar->add_sort_option(TTR("Total Refs"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, offset + 4);
|
||||
filter_bar->add_sort_option(TTR("ObjectDB Cycles"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, offset + 5);
|
||||
filter_bar->add_sort_option(TTRC("ObjectDB Refs"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, offset + 3);
|
||||
filter_bar->add_sort_option(TTRC("Total Refs"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, offset + 4);
|
||||
filter_bar->add_sort_option(TTRC("ObjectDB Cycles"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, offset + 5);
|
||||
|
||||
refs_list->set_select_mode(Tree::SelectMode::SELECT_ROW);
|
||||
refs_list->set_custom_minimum_size(Size2(200, 0) * EDSCALE);
|
||||
@@ -82,30 +82,38 @@ void SnapshotRefCountedView::show_snapshot(GameStateSnapshot *p_data, GameStateS
|
||||
refs_list->set_hide_root(true);
|
||||
refs_list->set_columns(diff_data ? 7 : 6);
|
||||
refs_list->set_column_titles_visible(true);
|
||||
|
||||
if (diff_data) {
|
||||
refs_list->set_column_title(0, TTR("Snapshot"));
|
||||
refs_list->set_column_title(0, TTRC("Snapshot"));
|
||||
refs_list->set_column_expand(0, false);
|
||||
refs_list->set_column_title_tooltip_text(0, "A: " + snapshot_data->name + ", B: " + diff_data->name);
|
||||
}
|
||||
refs_list->set_column_title(offset + 0, TTR("Class"));
|
||||
|
||||
refs_list->set_column_title(offset + 0, TTRC("Class"));
|
||||
refs_list->set_column_expand(offset + 0, true);
|
||||
refs_list->set_column_title_tooltip_text(offset + 0, TTR("Object's class"));
|
||||
refs_list->set_column_title(offset + 1, TTR("Name"));
|
||||
refs_list->set_column_title_tooltip_text(offset + 0, TTRC("Object's class"));
|
||||
|
||||
refs_list->set_column_title(offset + 1, TTRC("Name"));
|
||||
refs_list->set_column_expand(offset + 1, true);
|
||||
refs_list->set_column_expand_ratio(offset + 1, 2);
|
||||
refs_list->set_column_title_tooltip_text(offset + 1, TTR("Object's name"));
|
||||
refs_list->set_column_title(offset + 2, TTR("Native Refs"));
|
||||
refs_list->set_column_title_tooltip_text(offset + 1, TTRC("Object's name"));
|
||||
|
||||
refs_list->set_column_title(offset + 2, TTRC("Native Refs"));
|
||||
refs_list->set_column_expand(offset + 2, false);
|
||||
refs_list->set_column_title_tooltip_text(offset + 2, TTR("References not owned by the ObjectDB"));
|
||||
refs_list->set_column_title(offset + 3, TTR("ObjectDB Refs"));
|
||||
refs_list->set_column_title_tooltip_text(offset + 2, TTRC("References not owned by the ObjectDB"));
|
||||
|
||||
refs_list->set_column_title(offset + 3, TTRC("ObjectDB Refs"));
|
||||
refs_list->set_column_expand(offset + 3, false);
|
||||
refs_list->set_column_title_tooltip_text(offset + 3, TTR("References owned by the ObjectDB"));
|
||||
refs_list->set_column_title(offset + 4, TTR("Total Refs"));
|
||||
refs_list->set_column_title_tooltip_text(offset + 3, TTRC("References owned by the ObjectDB"));
|
||||
|
||||
refs_list->set_column_title(offset + 4, TTRC("Total Refs"));
|
||||
refs_list->set_column_expand(offset + 4, false);
|
||||
refs_list->set_column_title_tooltip_text(offset + 4, TTR("ObjectDB References + Native References"));
|
||||
refs_list->set_column_title(offset + 5, TTR("ObjectDB Cycles"));
|
||||
refs_list->set_column_title_tooltip_text(offset + 4, TTRC("ObjectDB References + Native References"));
|
||||
|
||||
refs_list->set_column_title(offset + 5, TTRC("ObjectDB Cycles"));
|
||||
refs_list->set_column_expand(offset + 5, false);
|
||||
refs_list->set_column_title_tooltip_text(offset + 5, TTR("Cycles detected in the ObjectDB"));
|
||||
refs_list->set_column_title_tooltip_text(offset + 5, TTRC("Cycles detected in the ObjectDB"));
|
||||
|
||||
refs_list->connect(SceneStringName(item_selected), callable_mp(this, &SnapshotRefCountedView::_refcounted_selected));
|
||||
refs_list->set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
refs_list->set_v_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
@@ -118,9 +126,9 @@ void SnapshotRefCountedView::show_snapshot(GameStateSnapshot *p_data, GameStateS
|
||||
ref_details->set_v_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
|
||||
refs_list->create_item();
|
||||
_insert_data(snapshot_data, TTR("A"));
|
||||
_insert_data(snapshot_data, TTRC("A"));
|
||||
if (diff_data) {
|
||||
_insert_data(diff_data, TTR("B"));
|
||||
_insert_data(diff_data, TTRC("B"));
|
||||
}
|
||||
|
||||
// Push the split as far right as possible.
|
||||
@@ -154,11 +162,14 @@ void SnapshotRefCountedView::_insert_data(GameStateSnapshot *p_snapshot, const S
|
||||
if (diff_data) {
|
||||
item->set_text(0, p_name);
|
||||
item->set_tooltip_text(0, p_snapshot->name);
|
||||
item->set_auto_translate_mode(0, AUTO_TRANSLATE_MODE_DISABLED);
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
item->set_text(offset + 0, pair.value->type_name);
|
||||
item->set_auto_translate_mode(offset + 0, AUTO_TRANSLATE_MODE_DISABLED);
|
||||
item->set_text(offset + 1, pair.value->get_name());
|
||||
item->set_auto_translate_mode(offset + 1, AUTO_TRANSLATE_MODE_DISABLED);
|
||||
item->set_text(offset + 2, String::num_uint64(native_refs));
|
||||
item->set_text(offset + 3, String::num_uint64(objectdb_refs));
|
||||
item->set_text(offset + 4, String::num_uint64(total_refs));
|
||||
@@ -179,7 +190,7 @@ void SnapshotRefCountedView::_refcounted_selected() {
|
||||
}
|
||||
|
||||
SnapshotDataObject *d = item_data_map[refs_list->get_selected()];
|
||||
EditorNode::get_singleton()->push_item((Object *)d);
|
||||
EditorNode::get_singleton()->push_item(static_cast<Object *>(d));
|
||||
|
||||
DarkPanelContainer *refcounted_panel = memnew(DarkPanelContainer);
|
||||
VBoxContainer *refcounted_panel_content = memnew(VBoxContainer);
|
||||
@@ -211,10 +222,10 @@ void SnapshotRefCountedView::_refcounted_selected() {
|
||||
Array ref_cycles = (Array)d->extra_debug_data["ref_cycles"];
|
||||
|
||||
String count_str = "[ul]\n";
|
||||
count_str += TTR(" Native References: ") + String::num_uint64(native_refs) + "\n";
|
||||
count_str += TTR(" ObjectDB References: ") + String::num_uint64(objectdb_refs) + "\n";
|
||||
count_str += TTR(" Total References: ") + String::num_uint64(total_refs) + "\n";
|
||||
count_str += TTR(" ObjectDB Cycles: ") + String::num_uint64(ref_cycles.size()) + "\n";
|
||||
count_str += vformat(TTRC("Native References: %d\n"), native_refs);
|
||||
count_str += vformat(TTRC("ObjectDB References: %d\n"), objectdb_refs);
|
||||
count_str += vformat(TTRC("Total References: %d\n"), total_refs);
|
||||
count_str += vformat(TTRC("ObjectDB Cycles: %d\n"), ref_cycles.size());
|
||||
count_str += "[/ul]\n";
|
||||
RichTextLabel *counts = memnew(RichTextLabel(count_str));
|
||||
counts->set_use_bbcode(true);
|
||||
@@ -223,7 +234,7 @@ void SnapshotRefCountedView::_refcounted_selected() {
|
||||
properties_container->add_child(counts);
|
||||
|
||||
if (d->inbound_references.size() > 0) {
|
||||
RichTextLabel *inbound_lbl = memnew(RichTextLabel(TTR("[center]ObjectDB References[center]")));
|
||||
RichTextLabel *inbound_lbl = memnew(RichTextLabel(TTRC("[center]ObjectDB References[center]")));
|
||||
inbound_lbl->set_fit_content(true);
|
||||
inbound_lbl->set_use_bbcode(true);
|
||||
properties_container->add_child(inbound_lbl);
|
||||
@@ -234,17 +245,17 @@ void SnapshotRefCountedView::_refcounted_selected() {
|
||||
inbound_tree->set_hide_root(true);
|
||||
inbound_tree->set_columns(3);
|
||||
inbound_tree->set_column_titles_visible(true);
|
||||
inbound_tree->set_column_title(0, TTR("Source"));
|
||||
inbound_tree->set_column_title(0, TTRC("Source"));
|
||||
inbound_tree->set_column_expand(0, true);
|
||||
inbound_tree->set_column_clip_content(0, false);
|
||||
inbound_tree->set_column_title_tooltip_text(0, TTR("Other object referencing this object"));
|
||||
inbound_tree->set_column_title(1, TTR("Property"));
|
||||
inbound_tree->set_column_title_tooltip_text(0, TTRC("Other object referencing this object"));
|
||||
inbound_tree->set_column_title(1, TTRC("Property"));
|
||||
inbound_tree->set_column_expand(1, true);
|
||||
inbound_tree->set_column_clip_content(1, true);
|
||||
inbound_tree->set_column_title_tooltip_text(1, TTR("Property of other object referencing this object"));
|
||||
inbound_tree->set_column_title(2, TTR("Duplicate?"));
|
||||
inbound_tree->set_column_title_tooltip_text(1, TTRC("Property of other object referencing this object"));
|
||||
inbound_tree->set_column_title(2, TTRC("Duplicate?"));
|
||||
inbound_tree->set_column_expand(2, false);
|
||||
inbound_tree->set_column_title_tooltip_text(2, TTR("Was the same reference returned by multiple getters on the source object?"));
|
||||
inbound_tree->set_column_title_tooltip_text(2, TTRC("Was the same reference returned by multiple getters on the source object?"));
|
||||
inbound_tree->set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
inbound_tree->set_v_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
inbound_tree->set_v_scroll_enabled(false);
|
||||
@@ -266,14 +277,16 @@ void SnapshotRefCountedView::_refcounted_selected() {
|
||||
TreeItem *i = inbound_tree->create_item(root);
|
||||
SnapshotDataObject *target = d->snapshot->objects[ob.value];
|
||||
i->set_text(0, target->get_name());
|
||||
i->set_auto_translate_mode(0, AUTO_TRANSLATE_MODE_DISABLED);
|
||||
i->set_text(1, ob.key);
|
||||
i->set_text(2, property_repeat_count[ob.value] > 1 ? TTR("Yes") : TTR("No"));
|
||||
i->set_auto_translate_mode(1, AUTO_TRANSLATE_MODE_DISABLED);
|
||||
i->set_text(2, property_repeat_count[ob.value] > 1 ? TTRC("Yes") : TTRC("No"));
|
||||
reference_item_map[i] = data_item_map[target];
|
||||
}
|
||||
}
|
||||
|
||||
if (ref_cycles.size() > 0) {
|
||||
properties_container->add_child(memnew(SpanningHeader(TTR("ObjectDB Cycles"))));
|
||||
properties_container->add_child(memnew(SpanningHeader(TTRC("ObjectDB Cycles"))));
|
||||
Tree *cycles_tree = memnew(Tree);
|
||||
cycles_tree->set_hide_folding(true);
|
||||
properties_container->add_child(cycles_tree);
|
||||
|
||||
@@ -56,7 +56,7 @@ DarkPanelContainer::DarkPanelContainer() {
|
||||
Ref<StyleBoxFlat> content_wrapper_sbf;
|
||||
content_wrapper_sbf.instantiate();
|
||||
content_wrapper_sbf->set_bg_color(EditorNode::get_singleton()->get_editor_theme()->get_color("dark_color_2", "Editor"));
|
||||
add_theme_style_override("panel", content_wrapper_sbf);
|
||||
add_theme_style_override(SceneStringName(panel), content_wrapper_sbf);
|
||||
}
|
||||
|
||||
void TreeSortAndFilterBar::_apply_filter(TreeItem *p_current_node) {
|
||||
@@ -68,7 +68,7 @@ void TreeSortAndFilterBar::_apply_filter(TreeItem *p_current_node) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset ourself to default state.
|
||||
// Reset ourselves to default state.
|
||||
p_current_node->set_visible(true);
|
||||
p_current_node->clear_custom_color(0);
|
||||
|
||||
@@ -98,7 +98,7 @@ void TreeSortAndFilterBar::_apply_filter(TreeItem *p_current_node) {
|
||||
// We have a visible child.
|
||||
p_current_node->set_custom_color(0, get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor)));
|
||||
} else {
|
||||
// We and out children aren't visible.
|
||||
// We and our children are not visible.
|
||||
p_current_node->set_visible(false);
|
||||
}
|
||||
}
|
||||
@@ -121,7 +121,8 @@ void TreeSortAndFilterBar::_apply_sort() {
|
||||
TreeItem *to_sort = items_to_sort.front()->get();
|
||||
items_to_sort.pop_front();
|
||||
|
||||
List<TreeItemColumn> items;
|
||||
LocalVector<TreeItemColumn> items;
|
||||
items.reserve(to_sort->get_child_count());
|
||||
for (int i = 0; i < to_sort->get_child_count(); i++) {
|
||||
items.push_back(TreeItemColumn(to_sort->get_child(i), sort.column));
|
||||
}
|
||||
@@ -187,15 +188,10 @@ TreeSortAndFilterBar::TreeSortAndFilterBar(Tree *p_managed_tree, const String &p
|
||||
void TreeSortAndFilterBar::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_POSTINITIALIZE:
|
||||
case NOTIFICATION_ENTER_TREE:
|
||||
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
|
||||
case NOTIFICATION_THEME_CHANGED:
|
||||
case NOTIFICATION_TRANSLATION_CHANGED: {
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
filter_edit->set_right_icon(get_editor_theme_icon(SNAME("Search")));
|
||||
sort_button->set_button_icon(get_editor_theme_icon(SNAME("Sort")));
|
||||
|
||||
apply();
|
||||
|
||||
} break;
|
||||
}
|
||||
}
|
||||
@@ -203,11 +199,11 @@ void TreeSortAndFilterBar::_notification(int p_what) {
|
||||
TreeSortAndFilterBar::SortOptionIndexes TreeSortAndFilterBar::add_sort_option(const String &p_new_option, SortType p_sort_type, int p_sort_column, bool p_is_default) {
|
||||
sort_button->set_visible(true);
|
||||
bool is_first_item = sort_items.is_empty();
|
||||
SortItem item_ascending(sort_items.size(), TTR("Sort By ") + p_new_option + TTR(" (Ascending)"), p_sort_type, true, p_sort_column);
|
||||
SortItem item_ascending(sort_items.size(), vformat(TTRC("Sort By %s (Ascending)"), p_new_option), p_sort_type, true, p_sort_column);
|
||||
sort_items[item_ascending.id] = item_ascending;
|
||||
sort_button->get_popup()->add_radio_check_item(item_ascending.label, item_ascending.id);
|
||||
|
||||
SortItem item_descending(sort_items.size(), TTR("Sort By ") + p_new_option + TTR(" (Descending)"), p_sort_type, false, p_sort_column);
|
||||
SortItem item_descending(sort_items.size(), vformat(TTRC("Sort By %s (Descending)"), p_new_option), p_sort_type, false, p_sort_column);
|
||||
sort_items[item_descending.id] = item_descending;
|
||||
sort_button->get_popup()->add_radio_check_item(item_descending.label, item_descending.id);
|
||||
|
||||
@@ -240,10 +236,6 @@ void TreeSortAndFilterBar::apply() {
|
||||
return;
|
||||
}
|
||||
|
||||
OS::get_singleton()->benchmark_begin_measure("odb profiler", "TreeSortAndFilterBar::apply _apply_sort");
|
||||
_apply_sort();
|
||||
OS::get_singleton()->benchmark_end_measure("odb profiler", "TreeSortAndFilterBar::apply _apply_sort");
|
||||
OS::get_singleton()->benchmark_begin_measure("odb profiler", "TreeSortAndFilterBar::apply _apply_filter");
|
||||
_apply_filter();
|
||||
OS::get_singleton()->benchmark_end_measure("odb profiler", "TreeSortAndFilterBar::apply _apply_filter");
|
||||
}
|
||||
|
||||
@@ -50,8 +50,8 @@ bool SnapshotView::is_showing_snapshot(GameStateSnapshot *p_data, GameStateSnaps
|
||||
return p_data == snapshot_data && p_diff_data == diff_data;
|
||||
}
|
||||
|
||||
List<TreeItem *> SnapshotView::_get_children_recursive(Tree *p_tree) {
|
||||
List<TreeItem *> found_items;
|
||||
Vector<TreeItem *> SnapshotView::_get_children_recursive(Tree *p_tree) {
|
||||
Vector<TreeItem *> found_items;
|
||||
List<TreeItem *> items_to_check;
|
||||
if (p_tree && p_tree->get_root()) {
|
||||
items_to_check.push_back(p_tree->get_root());
|
||||
|
||||
@@ -44,7 +44,7 @@ protected:
|
||||
GameStateSnapshot *snapshot_data = nullptr;
|
||||
GameStateSnapshot *diff_data = nullptr;
|
||||
|
||||
List<TreeItem *> _get_children_recursive(Tree *p_tree);
|
||||
Vector<TreeItem *> _get_children_recursive(Tree *p_tree);
|
||||
|
||||
public:
|
||||
String view_name;
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include "scene/resources/style_box_flat.h"
|
||||
|
||||
SnapshotSummaryView::SnapshotSummaryView() {
|
||||
set_name("Summary");
|
||||
set_name(TTRC("Summary"));
|
||||
|
||||
set_v_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);
|
||||
@@ -70,7 +70,7 @@ SnapshotSummaryView::SnapshotSummaryView() {
|
||||
pc->add_theme_style_override("panel", sbf);
|
||||
content->add_child(pc);
|
||||
pc->set_anchors_preset(LayoutPreset::PRESET_TOP_WIDE);
|
||||
Label *title = memnew(Label(TTR("ObjectDB Snapshot Summary")));
|
||||
Label *title = memnew(Label(TTRC("ObjectDB Snapshot Summary")));
|
||||
pc->add_child(title);
|
||||
title->set_horizontal_alignment(HorizontalAlignment::HORIZONTAL_ALIGNMENT_CENTER);
|
||||
title->set_vertical_alignment(VerticalAlignment::VERTICAL_ALIGNMENT_CENTER);
|
||||
@@ -81,9 +81,9 @@ SnapshotSummaryView::SnapshotSummaryView() {
|
||||
content->add_child(explainer_text);
|
||||
VBoxContainer *explainer_lines = memnew(VBoxContainer);
|
||||
explainer_text->add_child(explainer_lines);
|
||||
Label *l1 = memnew(Label(TTR("Press 'Take ObjectDB Snapshot' to snapshot the ObjectDB.")));
|
||||
Label *l2 = memnew(Label(TTR("Memory in Godot is either owned natively by the engine or owned by the ObjectDB.")));
|
||||
Label *l3 = memnew(Label(TTR("ObjectDB Snapshots capture only memory owned by the ObjectDB.")));
|
||||
Label *l1 = memnew(Label(TTRC("Press 'Take ObjectDB Snapshot' to snapshot the ObjectDB.")));
|
||||
Label *l2 = memnew(Label(TTRC("Memory in Godot is either owned natively by the engine or owned by the ObjectDB.")));
|
||||
Label *l3 = memnew(Label(TTRC("ObjectDB Snapshots capture only memory owned by the ObjectDB.")));
|
||||
l1->set_horizontal_alignment(HorizontalAlignment::HORIZONTAL_ALIGNMENT_CENTER);
|
||||
l2->set_horizontal_alignment(HorizontalAlignment::HORIZONTAL_ALIGNMENT_CENTER);
|
||||
l3->set_horizontal_alignment(HorizontalAlignment::HORIZONTAL_ALIGNMENT_CENTER);
|
||||
@@ -107,27 +107,27 @@ void SnapshotSummaryView::show_snapshot(GameStateSnapshot *p_data, GameStateSnap
|
||||
SnapshotView::show_snapshot(p_data, p_diff_data);
|
||||
explainer_text->set_visible(false);
|
||||
|
||||
String snapshot_a_name = diff_data == nullptr ? TTR("Snapshot") : TTR("Snapshot A");
|
||||
String snapshot_b_name = TTR("Snapshot B");
|
||||
String snapshot_a_name = diff_data == nullptr ? TTRC("Snapshot") : TTRC("Snapshot A");
|
||||
String snapshot_b_name = TTRC("Snapshot B");
|
||||
|
||||
_push_overview_blurb(snapshot_a_name + " " + TTR("Overview"), snapshot_data);
|
||||
_push_overview_blurb(snapshot_a_name + " " + TTRC("Overview"), snapshot_data);
|
||||
if (diff_data) {
|
||||
_push_overview_blurb(snapshot_b_name + " " + TTR("Overview"), diff_data);
|
||||
_push_overview_blurb(snapshot_b_name + " " + TTRC("Overview"), diff_data);
|
||||
}
|
||||
|
||||
_push_node_blurb(snapshot_a_name + " " + TTR("Nodes"), snapshot_data);
|
||||
_push_node_blurb(snapshot_a_name + " " + TTRC("Nodes"), snapshot_data);
|
||||
if (diff_data) {
|
||||
_push_node_blurb(snapshot_b_name + " " + TTR("Nodes"), diff_data);
|
||||
_push_node_blurb(snapshot_b_name + " " + TTRC("Nodes"), diff_data);
|
||||
}
|
||||
|
||||
_push_refcounted_blurb(snapshot_a_name + " " + TTR("RefCounteds"), snapshot_data);
|
||||
_push_refcounted_blurb(snapshot_a_name + " " + TTRC("RefCounteds"), snapshot_data);
|
||||
if (diff_data) {
|
||||
_push_refcounted_blurb(snapshot_b_name + " " + TTR("RefCounteds"), diff_data);
|
||||
_push_refcounted_blurb(snapshot_b_name + " " + TTRC("RefCounteds"), diff_data);
|
||||
}
|
||||
|
||||
_push_object_blurb(snapshot_a_name + " " + TTR("Objects"), snapshot_data);
|
||||
_push_object_blurb(snapshot_a_name + " " + TTRC("Objects"), snapshot_data);
|
||||
if (diff_data) {
|
||||
_push_object_blurb(snapshot_b_name + " " + TTR("Objects"), diff_data);
|
||||
_push_object_blurb(snapshot_b_name + " " + TTRC("Objects"), diff_data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,6 +149,7 @@ SummaryBlurb::SummaryBlurb(const String &p_title, const String &p_rtl_content) {
|
||||
|
||||
label = memnew(RichTextLabel);
|
||||
label->add_theme_constant_override(SceneStringName(line_separation), 6);
|
||||
label->set_text_direction(Control::TEXT_DIRECTION_INHERITED);
|
||||
label->set_fit_content(true);
|
||||
label->set_use_bbcode(true);
|
||||
label->add_newline();
|
||||
@@ -183,11 +184,6 @@ void SnapshotSummaryView::_push_overview_blurb(const String &p_title, GameStateS
|
||||
if (p_snapshot->snapshot_context.has("mem_max_usage")) {
|
||||
c += vformat(" [i]%s[/i] %s\n", TTR("Max Memory Used:"), String::num((double)((uint64_t)p_snapshot->snapshot_context["mem_max_usage"]) * bytes_to_mb, 3) + " MB");
|
||||
}
|
||||
if (p_snapshot->snapshot_context.has("mem_available")) {
|
||||
// I'm guessing pretty hard about what this is supposed to be. It's hard coded to be -1 cast to a uint64_t in Memory.h,
|
||||
// so it _could_ be checking if we're on a 64 bit system, I think...
|
||||
c += vformat(" [i]%s[/i] %s\n", TTR("Max uint64 Value:"), String::num_uint64((uint64_t)p_snapshot->snapshot_context["mem_available"]));
|
||||
}
|
||||
c += vformat(" [i]%s[/i] %s\n", TTR("Total Objects:"), itos(p_snapshot->objects.size()));
|
||||
|
||||
int node_count = 0;
|
||||
@@ -203,11 +199,13 @@ void SnapshotSummaryView::_push_overview_blurb(const String &p_title, GameStateS
|
||||
}
|
||||
|
||||
void SnapshotSummaryView::_push_node_blurb(const String &p_title, GameStateSnapshot *p_snapshot) {
|
||||
List<String> nodes;
|
||||
LocalVector<String> nodes;
|
||||
nodes.reserve(p_snapshot->objects.size());
|
||||
|
||||
for (const KeyValue<ObjectID, SnapshotDataObject *> &pair : p_snapshot->objects) {
|
||||
// if it's a node AND it doesn't have a parent node
|
||||
if (pair.value->is_node() && !pair.value->extra_debug_data.has("node_parent") && pair.value->extra_debug_data.has("node_is_scene_root") && !pair.value->extra_debug_data["node_is_scene_root"]) {
|
||||
const String &node_name = pair.value->extra_debug_data["node_name"];
|
||||
String node_name = pair.value->extra_debug_data["node_name"];
|
||||
nodes.push_back(node_name != "" ? node_name : pair.value->get_name());
|
||||
}
|
||||
}
|
||||
@@ -216,7 +214,7 @@ void SnapshotSummaryView::_push_node_blurb(const String &p_title, GameStateSnaps
|
||||
return;
|
||||
}
|
||||
|
||||
String c = TTR("Multiple root nodes [i](possible call to 'remove_child' without 'queue_free')[/i]\n");
|
||||
String c = TTRC("Multiple root nodes [i](possible call to 'remove_child' without 'queue_free')[/i]\n");
|
||||
c += "[ul]\n";
|
||||
for (const String &node : nodes) {
|
||||
c += " " + node + "\n";
|
||||
@@ -227,7 +225,9 @@ void SnapshotSummaryView::_push_node_blurb(const String &p_title, GameStateSnaps
|
||||
}
|
||||
|
||||
void SnapshotSummaryView::_push_refcounted_blurb(const String &p_title, GameStateSnapshot *p_snapshot) {
|
||||
List<String> rcs;
|
||||
LocalVector<String> rcs;
|
||||
rcs.reserve(p_snapshot->objects.size());
|
||||
|
||||
for (const KeyValue<ObjectID, SnapshotDataObject *> &pair : p_snapshot->objects) {
|
||||
if (pair.value->is_refcounted()) {
|
||||
int ref_count = (uint64_t)pair.value->extra_debug_data["ref_count"];
|
||||
@@ -243,7 +243,7 @@ void SnapshotSummaryView::_push_refcounted_blurb(const String &p_title, GameStat
|
||||
return;
|
||||
}
|
||||
|
||||
String c = TTR("RefCounted objects only referenced in cycles [i](cycles often indicate a memory leaks)[/i]\n");
|
||||
String c = TTRC("RefCounted objects only referenced in cycles [i](cycles often indicate a memory leaks)[/i]\n");
|
||||
c += "[ul]\n";
|
||||
for (const String &rc : rcs) {
|
||||
c += " " + rc + "\n";
|
||||
@@ -254,7 +254,9 @@ void SnapshotSummaryView::_push_refcounted_blurb(const String &p_title, GameStat
|
||||
}
|
||||
|
||||
void SnapshotSummaryView::_push_object_blurb(const String &p_title, GameStateSnapshot *p_snapshot) {
|
||||
List<String> objects;
|
||||
LocalVector<String> objects;
|
||||
objects.reserve(p_snapshot->objects.size());
|
||||
|
||||
for (const KeyValue<ObjectID, SnapshotDataObject *> &pair : p_snapshot->objects) {
|
||||
if (pair.value->inbound_references.is_empty() && pair.value->outbound_references.is_empty()) {
|
||||
if (!pair.value->get_script().is_null()) {
|
||||
@@ -271,7 +273,7 @@ void SnapshotSummaryView::_push_object_blurb(const String &p_title, GameStateSna
|
||||
return;
|
||||
}
|
||||
|
||||
String c = TTR("Scripted objects not referenced by any other objects [i](unreferenced objects may indicate a memory leak)[/i]\n");
|
||||
String c = TTRC("Scripted objects not referenced by any other objects [i](unreferenced objects may indicate a memory leak)[/i]\n");
|
||||
c += "[ul]\n";
|
||||
for (const String &object : objects) {
|
||||
c += " " + object + "\n";
|
||||
|
||||
Reference in New Issue
Block a user