Merge pull request #42 from limbonaut/debugger-improvements
Debugger improvements
This commit is contained in:
commit
78c61d459d
|
@ -17,4 +17,9 @@
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
|
<members>
|
||||||
|
<member name="update_interval_msec" type="int" setter="set_update_interval_msec" getter="get_update_interval_msec" default="0">
|
||||||
|
Minimum delay between two updates (in milliseconds). Set to higher values for a lower CPU load.
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
</class>
|
</class>
|
||||||
|
|
|
@ -25,7 +25,6 @@ Array BehaviorTreeData::serialize(const Ref<BTTask> &p_tree_instance, const Node
|
||||||
// Flatten tree into list depth first
|
// Flatten tree into list depth first
|
||||||
List<Ref<BTTask>> stack;
|
List<Ref<BTTask>> stack;
|
||||||
stack.push_back(p_tree_instance);
|
stack.push_back(p_tree_instance);
|
||||||
int id = 0;
|
|
||||||
while (stack.size()) {
|
while (stack.size()) {
|
||||||
Ref<BTTask> task = stack[0];
|
Ref<BTTask> task = stack[0];
|
||||||
stack.pop_front();
|
stack.pop_front();
|
||||||
|
@ -41,7 +40,7 @@ Array BehaviorTreeData::serialize(const Ref<BTTask> &p_tree_instance, const Node
|
||||||
script_path = s->get_path();
|
script_path = s->get_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
arr.push_back(id);
|
arr.push_back(task->get_instance_id());
|
||||||
arr.push_back(task->get_task_name());
|
arr.push_back(task->get_task_name());
|
||||||
arr.push_back(!task->get_custom_name().is_empty());
|
arr.push_back(!task->get_custom_name().is_empty());
|
||||||
arr.push_back(num_children);
|
arr.push_back(num_children);
|
||||||
|
@ -49,8 +48,6 @@ Array BehaviorTreeData::serialize(const Ref<BTTask> &p_tree_instance, const Node
|
||||||
arr.push_back(task->get_elapsed_time());
|
arr.push_back(task->get_elapsed_time());
|
||||||
arr.push_back(task->get_class());
|
arr.push_back(task->get_class());
|
||||||
arr.push_back(script_path);
|
arr.push_back(script_path);
|
||||||
|
|
||||||
id += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return arr;
|
return arr;
|
||||||
|
@ -89,7 +86,6 @@ Ref<BehaviorTreeData> BehaviorTreeData::create_from_tree_instance(const Ref<BTTa
|
||||||
// Flatten tree into list depth first
|
// Flatten tree into list depth first
|
||||||
List<Ref<BTTask>> stack;
|
List<Ref<BTTask>> stack;
|
||||||
stack.push_back(p_tree_instance);
|
stack.push_back(p_tree_instance);
|
||||||
int id = 0;
|
|
||||||
while (stack.size()) {
|
while (stack.size()) {
|
||||||
Ref<BTTask> task = stack[0];
|
Ref<BTTask> task = stack[0];
|
||||||
stack.pop_front();
|
stack.pop_front();
|
||||||
|
@ -106,7 +102,7 @@ Ref<BehaviorTreeData> BehaviorTreeData::create_from_tree_instance(const Ref<BTTa
|
||||||
}
|
}
|
||||||
|
|
||||||
data->tasks.push_back(TaskData(
|
data->tasks.push_back(TaskData(
|
||||||
id,
|
task->get_instance_id(),
|
||||||
task->get_task_name(),
|
task->get_task_name(),
|
||||||
!task->get_custom_name().is_empty(),
|
!task->get_custom_name().is_empty(),
|
||||||
num_children,
|
num_children,
|
||||||
|
@ -114,7 +110,6 @@ Ref<BehaviorTreeData> BehaviorTreeData::create_from_tree_instance(const Ref<BTTa
|
||||||
task->get_elapsed_time(),
|
task->get_elapsed_time(),
|
||||||
task->get_class(),
|
task->get_class(),
|
||||||
script_path));
|
script_path));
|
||||||
id += 1;
|
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct TaskData {
|
struct TaskData {
|
||||||
int id = 0;
|
uint64_t id = 0;
|
||||||
String name;
|
String name;
|
||||||
bool is_custom_name = false;
|
bool is_custom_name = false;
|
||||||
int num_children = 0;
|
int num_children = 0;
|
||||||
|
@ -31,7 +31,7 @@ public:
|
||||||
String type_name;
|
String type_name;
|
||||||
String script_path;
|
String script_path;
|
||||||
|
|
||||||
TaskData(int p_id, const String &p_name, bool p_is_custom_name, int p_num_children, int p_status, double p_elapsed_time, const String &p_type_name, const String &p_script_path) {
|
TaskData(uint64_t p_id, const String &p_name, bool p_is_custom_name, int p_num_children, int p_status, double p_elapsed_time, const String &p_type_name, const String &p_script_path) {
|
||||||
id = p_id;
|
id = p_id;
|
||||||
name = p_name;
|
name = p_name;
|
||||||
is_custom_name = p_is_custom_name;
|
is_custom_name = p_is_custom_name;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "core/math/color.h"
|
#include "core/math/color.h"
|
||||||
#include "core/math/math_defs.h"
|
#include "core/math/math_defs.h"
|
||||||
#include "core/object/callable_method_pointer.h"
|
#include "core/object/callable_method_pointer.h"
|
||||||
|
#include "core/os/time.h"
|
||||||
#include "core/typedefs.h"
|
#include "core/typedefs.h"
|
||||||
#include "editor/editor_scale.h"
|
#include "editor/editor_scale.h"
|
||||||
#include "editor/editor_settings.h"
|
#include "editor/editor_settings.h"
|
||||||
|
@ -30,6 +31,7 @@
|
||||||
|
|
||||||
#ifdef LIMBOAI_GDEXTENSION
|
#ifdef LIMBOAI_GDEXTENSION
|
||||||
#include <godot_cpp/classes/editor_interface.hpp>
|
#include <godot_cpp/classes/editor_interface.hpp>
|
||||||
|
#include <godot_cpp/classes/time.hpp>
|
||||||
#endif // LIMBOAI_GDEXTENSION
|
#endif // LIMBOAI_GDEXTENSION
|
||||||
|
|
||||||
void BehaviorTreeView::_draw_running_status(Object *p_obj, Rect2 p_rect) {
|
void BehaviorTreeView::_draw_running_status(Object *p_obj, Rect2 p_rect) {
|
||||||
|
@ -52,7 +54,7 @@ void BehaviorTreeView::_item_collapsed(Object *p_obj) {
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int id = item->get_metadata(0);
|
uint64_t id = item->get_metadata(0);
|
||||||
bool collapsed = item->is_collapsed();
|
bool collapsed = item->is_collapsed();
|
||||||
if (!collapsed_ids.has(id) && collapsed) {
|
if (!collapsed_ids.has(id) && collapsed) {
|
||||||
collapsed_ids.push_back(item->get_metadata(0));
|
collapsed_ids.push_back(item->get_metadata(0));
|
||||||
|
@ -69,69 +71,137 @@ double BehaviorTreeView::_get_editor_scale() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void _item_set_elapsed_time(TreeItem *p_item, double p_elapsed) {
|
||||||
|
p_item->set_text(2, rtos(Math::snapped(p_elapsed, 0.01)).pad_decimals(2));
|
||||||
|
}
|
||||||
|
|
||||||
void BehaviorTreeView::update_tree(const Ref<BehaviorTreeData> &p_data) {
|
void BehaviorTreeView::update_tree(const Ref<BehaviorTreeData> &p_data) {
|
||||||
|
update_data = p_data;
|
||||||
|
update_pending = true;
|
||||||
|
_notification(NOTIFICATION_PROCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BehaviorTreeView::_update_tree(const Ref<BehaviorTreeData> &p_data) {
|
||||||
// Remember selected.
|
// Remember selected.
|
||||||
int selected_id = -1;
|
uint64_t selected_id = 0;
|
||||||
if (tree->get_selected()) {
|
if (tree->get_selected()) {
|
||||||
selected_id = tree->get_selected()->get_metadata(0);
|
selected_id = tree->get_selected()->get_metadata(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
tree->clear();
|
if (last_root_id != 0 && p_data->tasks.size() > 0 && last_root_id == (uint64_t)p_data->tasks[0].id) {
|
||||||
TreeItem *parent = nullptr;
|
// * Update tree.
|
||||||
List<Pair<TreeItem *, int>> parents;
|
// ! Update routine is built on assumption that the behavior tree does NOT mutate. With little work it could detect mutations.
|
||||||
for (const BehaviorTreeData::TaskData &task_data : p_data->tasks) {
|
|
||||||
// Figure out parent.
|
TreeItem *item = tree->get_root();
|
||||||
parent = nullptr;
|
int idx = 0;
|
||||||
if (parents.size()) {
|
while (item) {
|
||||||
Pair<TreeItem *, int> &p = parents[0];
|
ERR_FAIL_COND(idx >= p_data->tasks.size());
|
||||||
parent = p.first;
|
|
||||||
if (!(--p.second)) {
|
const BTTask::Status current_status = (BTTask::Status)p_data->tasks[idx].status;
|
||||||
// No children left, remove it.
|
const BTTask::Status last_status = VariantCaster<BTTask::Status>::cast(item->get_metadata(1));
|
||||||
parents.pop_front();
|
const bool status_changed = last_status != p_data->tasks[idx].status;
|
||||||
|
|
||||||
|
if (status_changed) {
|
||||||
|
item->set_metadata(1, current_status);
|
||||||
|
if (current_status == BTTask::SUCCESS) {
|
||||||
|
item->set_custom_draw(0, this, LW_NAME(_draw_success_status));
|
||||||
|
item->set_icon(1, theme_cache.icon_success);
|
||||||
|
} else if (current_status == BTTask::FAILURE) {
|
||||||
|
item->set_custom_draw(0, this, LW_NAME(_draw_failure_status));
|
||||||
|
item->set_icon(1, theme_cache.icon_failure);
|
||||||
|
} else if (current_status == BTTask::RUNNING) {
|
||||||
|
item->set_custom_draw(0, this, LW_NAME(_draw_running_status));
|
||||||
|
item->set_icon(1, theme_cache.icon_running);
|
||||||
|
} else {
|
||||||
|
item->set_custom_draw(0, this, LW_NAME(_draw_fresh));
|
||||||
|
item->set_icon(1, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status_changed || current_status == BTTask::RUNNING) {
|
||||||
|
_item_set_elapsed_time(item, p_data->tasks[idx].elapsed_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item->get_first_child()) {
|
||||||
|
item = item->get_first_child();
|
||||||
|
} else if (item->get_next()) {
|
||||||
|
item = item->get_next();
|
||||||
|
} else {
|
||||||
|
while (item) {
|
||||||
|
item = item->get_parent();
|
||||||
|
if (item && item->get_next()) {
|
||||||
|
item = item->get_next();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
idx += 1;
|
||||||
}
|
}
|
||||||
|
ERR_FAIL_COND(idx != p_data->tasks.size());
|
||||||
|
} else {
|
||||||
|
// * Create new tree.
|
||||||
|
|
||||||
TreeItem *item = tree->create_item(parent);
|
last_root_id = p_data->tasks.size() > 0 ? p_data->tasks[0].id : 0;
|
||||||
// Do this first because it resets properties of the cell...
|
|
||||||
item->set_cell_mode(0, TreeItem::CELL_MODE_CUSTOM);
|
|
||||||
item->set_cell_mode(1, TreeItem::CELL_MODE_ICON);
|
|
||||||
|
|
||||||
item->set_metadata(0, task_data.id);
|
tree->clear();
|
||||||
|
TreeItem *parent = nullptr;
|
||||||
|
List<Pair<TreeItem *, int>> parents;
|
||||||
|
for (const BehaviorTreeData::TaskData &task_data : p_data->tasks) {
|
||||||
|
// Figure out parent.
|
||||||
|
parent = nullptr;
|
||||||
|
if (parents.size()) {
|
||||||
|
Pair<TreeItem *, int> &p = parents[0];
|
||||||
|
parent = p.first;
|
||||||
|
if (!(--p.second)) {
|
||||||
|
// No children left, remove it.
|
||||||
|
parents.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
item->set_text(0, task_data.name);
|
TreeItem *item = tree->create_item(parent);
|
||||||
if (task_data.is_custom_name) {
|
// Do this first because it resets properties of the cell...
|
||||||
item->set_custom_font(0, theme_cache.font_custom_name);
|
item->set_cell_mode(0, TreeItem::CELL_MODE_CUSTOM);
|
||||||
}
|
item->set_cell_mode(1, TreeItem::CELL_MODE_ICON);
|
||||||
|
|
||||||
item->set_text_alignment(2, HORIZONTAL_ALIGNMENT_RIGHT);
|
item->set_metadata(0, task_data.id);
|
||||||
item->set_text(2, rtos(Math::snapped(task_data.elapsed_time, 0.01)).pad_decimals(2));
|
item->set_metadata(1, task_data.status);
|
||||||
|
|
||||||
String cors = (task_data.script_path.is_empty()) ? task_data.type_name : task_data.script_path;
|
item->set_text(0, task_data.name);
|
||||||
item->set_icon(0, LimboUtility::get_singleton()->get_task_icon(cors));
|
if (task_data.is_custom_name) {
|
||||||
item->set_icon_max_width(0, 16 * _get_editor_scale()); // Force user icon size.
|
item->set_custom_font(0, theme_cache.font_custom_name);
|
||||||
|
}
|
||||||
|
|
||||||
if (task_data.status == BTTask::SUCCESS) {
|
item->set_text_alignment(2, HORIZONTAL_ALIGNMENT_RIGHT);
|
||||||
item->set_custom_draw(0, this, LW_NAME(_draw_success_status));
|
_item_set_elapsed_time(item, task_data.elapsed_time);
|
||||||
item->set_icon(1, theme_cache.icon_success);
|
|
||||||
} else if (task_data.status == BTTask::FAILURE) {
|
|
||||||
item->set_custom_draw(0, this, LW_NAME(_draw_failure_status));
|
|
||||||
item->set_icon(1, theme_cache.icon_failure);
|
|
||||||
} else if (task_data.status == BTTask::RUNNING) {
|
|
||||||
item->set_custom_draw(0, this, LW_NAME(_draw_running_status));
|
|
||||||
item->set_icon(1, theme_cache.icon_running);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (task_data.id == selected_id) {
|
String cors = (task_data.script_path.is_empty()) ? task_data.type_name : task_data.script_path;
|
||||||
tree->set_selected(item, 0);
|
item->set_icon(0, LimboUtility::get_singleton()->get_task_icon(cors));
|
||||||
}
|
item->set_icon_max_width(0, 16 * _get_editor_scale()); // Force user icon size.
|
||||||
|
|
||||||
if (collapsed_ids.has(task_data.id)) {
|
if (task_data.status == BTTask::SUCCESS) {
|
||||||
item->set_collapsed(true);
|
item->set_custom_draw(0, this, LW_NAME(_draw_success_status));
|
||||||
}
|
item->set_icon(1, theme_cache.icon_success);
|
||||||
|
} else if (task_data.status == BTTask::FAILURE) {
|
||||||
|
item->set_custom_draw(0, this, LW_NAME(_draw_failure_status));
|
||||||
|
item->set_icon(1, theme_cache.icon_failure);
|
||||||
|
} else if (task_data.status == BTTask::RUNNING) {
|
||||||
|
item->set_custom_draw(0, this, LW_NAME(_draw_running_status));
|
||||||
|
item->set_icon(1, theme_cache.icon_running);
|
||||||
|
}
|
||||||
|
|
||||||
// Add in front of parents stack if it expects children.
|
if (task_data.id == selected_id) {
|
||||||
if (task_data.num_children) {
|
tree->set_selected(item, 0);
|
||||||
parents.push_front(Pair<TreeItem *, int>(item, task_data.num_children));
|
}
|
||||||
|
|
||||||
|
if (collapsed_ids.has(task_data.id)) {
|
||||||
|
item->set_collapsed(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add in front of parents stack if children are expected.
|
||||||
|
if (task_data.num_children) {
|
||||||
|
parents.push_front(Pair<TreeItem *, int>(item, task_data.num_children));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,6 +209,7 @@ void BehaviorTreeView::update_tree(const Ref<BehaviorTreeData> &p_data) {
|
||||||
void BehaviorTreeView::clear() {
|
void BehaviorTreeView::clear() {
|
||||||
tree->clear();
|
tree->clear();
|
||||||
collapsed_ids.clear();
|
collapsed_ids.clear();
|
||||||
|
last_root_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BehaviorTreeView::_do_update_theme_item_cache() {
|
void BehaviorTreeView::_do_update_theme_item_cache() {
|
||||||
|
@ -197,6 +268,17 @@ void BehaviorTreeView::_notification(int p_what) {
|
||||||
case NOTIFICATION_THEME_CHANGED: {
|
case NOTIFICATION_THEME_CHANGED: {
|
||||||
_do_update_theme_item_cache();
|
_do_update_theme_item_cache();
|
||||||
} break;
|
} break;
|
||||||
|
case NOTIFICATION_VISIBILITY_CHANGED: {
|
||||||
|
set_process(is_visible_in_tree());
|
||||||
|
} break;
|
||||||
|
case NOTIFICATION_PROCESS: {
|
||||||
|
int ticks_msec = Time::get_singleton()->get_ticks_msec();
|
||||||
|
if (update_pending && (ticks_msec - last_update_msec) >= update_interval_msec) {
|
||||||
|
_update_tree(update_data);
|
||||||
|
update_pending = false;
|
||||||
|
last_update_msec = ticks_msec;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,6 +288,10 @@ void BehaviorTreeView::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("_draw_failure_status"), &BehaviorTreeView::_draw_failure_status);
|
ClassDB::bind_method(D_METHOD("_draw_failure_status"), &BehaviorTreeView::_draw_failure_status);
|
||||||
ClassDB::bind_method(D_METHOD("_item_collapsed"), &BehaviorTreeView::_item_collapsed);
|
ClassDB::bind_method(D_METHOD("_item_collapsed"), &BehaviorTreeView::_item_collapsed);
|
||||||
ClassDB::bind_method(D_METHOD("update_tree", "p_behavior_tree_data"), &BehaviorTreeView::update_tree);
|
ClassDB::bind_method(D_METHOD("update_tree", "p_behavior_tree_data"), &BehaviorTreeView::update_tree);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_update_interval_msec", "p_milliseconds"), &BehaviorTreeView::set_update_interval_msec);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_update_interval_msec"), &BehaviorTreeView::get_update_interval_msec);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "update_interval_msec"), "set_update_interval_msec", "get_update_interval_msec");
|
||||||
}
|
}
|
||||||
|
|
||||||
BehaviorTreeView::BehaviorTreeView() {
|
BehaviorTreeView::BehaviorTreeView() {
|
||||||
|
|
|
@ -48,14 +48,23 @@ private:
|
||||||
Ref<Font> font_custom_name;
|
Ref<Font> font_custom_name;
|
||||||
} theme_cache;
|
} theme_cache;
|
||||||
|
|
||||||
Vector<int> collapsed_ids;
|
Vector<uint64_t> collapsed_ids;
|
||||||
|
uint64_t last_root_id = 0;
|
||||||
|
|
||||||
|
int last_update_msec = 0;
|
||||||
|
int update_interval_msec = 0;
|
||||||
|
Ref<BehaviorTreeData> update_data;
|
||||||
|
bool update_pending = false;
|
||||||
|
|
||||||
void _draw_success_status(Object *p_obj, Rect2 p_rect);
|
void _draw_success_status(Object *p_obj, Rect2 p_rect);
|
||||||
void _draw_running_status(Object *p_obj, Rect2 p_rect);
|
void _draw_running_status(Object *p_obj, Rect2 p_rect);
|
||||||
void _draw_failure_status(Object *p_obj, Rect2 p_rect);
|
void _draw_failure_status(Object *p_obj, Rect2 p_rect);
|
||||||
|
void _draw_fresh(Object *p_obj, Rect2 p_rect) {}
|
||||||
void _item_collapsed(Object *p_obj);
|
void _item_collapsed(Object *p_obj);
|
||||||
double _get_editor_scale() const;
|
double _get_editor_scale() const;
|
||||||
|
|
||||||
|
void _update_tree(const Ref<BehaviorTreeData> &p_data);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _do_update_theme_item_cache();
|
void _do_update_theme_item_cache();
|
||||||
|
|
||||||
|
@ -64,8 +73,11 @@ protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void update_tree(const Ref<BehaviorTreeData> &p_data);
|
|
||||||
void clear();
|
void clear();
|
||||||
|
void update_tree(const Ref<BehaviorTreeData> &p_data);
|
||||||
|
|
||||||
|
void set_update_interval_msec(int p_milliseconds) { update_interval_msec = p_milliseconds; }
|
||||||
|
int get_update_interval_msec() const { return update_interval_msec; }
|
||||||
|
|
||||||
BehaviorTreeView();
|
BehaviorTreeView();
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "../../bt/behavior_tree.h"
|
#include "../../bt/behavior_tree.h"
|
||||||
#include "../../editor/debugger/behavior_tree_data.h"
|
#include "../../editor/debugger/behavior_tree_data.h"
|
||||||
#include "../../editor/debugger/behavior_tree_view.h"
|
#include "../../editor/debugger/behavior_tree_view.h"
|
||||||
|
#include "../../util/limbo_compat.h"
|
||||||
#include "../../util/limbo_utility.h"
|
#include "../../util/limbo_utility.h"
|
||||||
#include "limbo_debugger.h"
|
#include "limbo_debugger.h"
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@
|
||||||
#include "core/string/ustring.h"
|
#include "core/string/ustring.h"
|
||||||
#include "core/variant/array.h"
|
#include "core/variant/array.h"
|
||||||
#include "editor/editor_interface.h"
|
#include "editor/editor_interface.h"
|
||||||
|
#include "editor/editor_paths.h"
|
||||||
#include "editor/editor_scale.h"
|
#include "editor/editor_scale.h"
|
||||||
#include "editor/filesystem_dock.h"
|
#include "editor/filesystem_dock.h"
|
||||||
#include "editor/plugins/editor_debugger_plugin.h"
|
#include "editor/plugins/editor_debugger_plugin.h"
|
||||||
|
@ -37,16 +39,20 @@
|
||||||
#include "scene/gui/item_list.h"
|
#include "scene/gui/item_list.h"
|
||||||
#include "scene/gui/label.h"
|
#include "scene/gui/label.h"
|
||||||
#include "scene/gui/line_edit.h"
|
#include "scene/gui/line_edit.h"
|
||||||
|
#include "scene/gui/separator.h"
|
||||||
#include "scene/gui/split_container.h"
|
#include "scene/gui/split_container.h"
|
||||||
#include "scene/gui/tab_container.h"
|
#include "scene/gui/tab_container.h"
|
||||||
#include "scene/gui/texture_rect.h"
|
#include "scene/gui/texture_rect.h"
|
||||||
#endif // LIMBOAI_MODULE
|
#endif // LIMBOAI_MODULE
|
||||||
|
|
||||||
#ifdef LIMBOAI_GDEXTENSION
|
#ifdef LIMBOAI_GDEXTENSION
|
||||||
|
#include <godot_cpp/classes/config_file.hpp>
|
||||||
#include <godot_cpp/classes/editor_interface.hpp>
|
#include <godot_cpp/classes/editor_interface.hpp>
|
||||||
|
#include <godot_cpp/classes/editor_paths.hpp>
|
||||||
#include <godot_cpp/classes/file_system_dock.hpp>
|
#include <godot_cpp/classes/file_system_dock.hpp>
|
||||||
#include <godot_cpp/classes/resource_loader.hpp>
|
#include <godot_cpp/classes/resource_loader.hpp>
|
||||||
#include <godot_cpp/classes/tab_container.hpp>
|
#include <godot_cpp/classes/tab_container.hpp>
|
||||||
|
#include <godot_cpp/classes/v_separator.hpp>
|
||||||
#endif // LIMBOAI_GDEXTENSION
|
#endif // LIMBOAI_GDEXTENSION
|
||||||
|
|
||||||
//**** LimboDebuggerTab
|
//**** LimboDebuggerTab
|
||||||
|
@ -180,6 +186,23 @@ void LimboDebuggerTab::_notification(int p_what) {
|
||||||
resource_header->connect(LW_NAME(pressed), callable_mp(this, &LimboDebuggerTab::_resource_header_pressed));
|
resource_header->connect(LW_NAME(pressed), callable_mp(this, &LimboDebuggerTab::_resource_header_pressed));
|
||||||
filter_players->connect(LW_NAME(text_changed), callable_mp(this, &LimboDebuggerTab::_filter_changed));
|
filter_players->connect(LW_NAME(text_changed), callable_mp(this, &LimboDebuggerTab::_filter_changed));
|
||||||
bt_player_list->connect(LW_NAME(item_selected), callable_mp(this, &LimboDebuggerTab::_bt_selected));
|
bt_player_list->connect(LW_NAME(item_selected), callable_mp(this, &LimboDebuggerTab::_bt_selected));
|
||||||
|
update_interval->connect("value_changed", callable_mp(bt_view, &BehaviorTreeView::set_update_interval_msec));
|
||||||
|
|
||||||
|
Ref<ConfigFile> cf;
|
||||||
|
cf.instantiate();
|
||||||
|
String conf_path = PROJECT_CONFIG_FILE();
|
||||||
|
if (cf->load(conf_path) == OK) {
|
||||||
|
Variant value = cf->get_value("debugger", "update_interval_msec", 0);
|
||||||
|
update_interval->set_value(value);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
|
Ref<ConfigFile> cf;
|
||||||
|
cf.instantiate();
|
||||||
|
String conf_path = PROJECT_CONFIG_FILE();
|
||||||
|
cf->load(conf_path);
|
||||||
|
cf->set_value("debugger", "update_interval_msec", update_interval->get_value());
|
||||||
|
cf->save(conf_path);
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_THEME_CHANGED: {
|
case NOTIFICATION_THEME_CHANGED: {
|
||||||
alert_icon->set_texture(get_theme_icon(LW_NAME(StatusWarning), LW_NAME(EditorIcons)));
|
alert_icon->set_texture(get_theme_icon(LW_NAME(StatusWarning), LW_NAME(EditorIcons)));
|
||||||
|
@ -195,7 +218,6 @@ void LimboDebuggerTab::setup(Ref<EditorDebuggerSession> p_session, CompatWindowW
|
||||||
if (p_wrapper->is_window_available()) {
|
if (p_wrapper->is_window_available()) {
|
||||||
make_floating = memnew(CompatScreenSelect);
|
make_floating = memnew(CompatScreenSelect);
|
||||||
make_floating->set_flat(true);
|
make_floating->set_flat(true);
|
||||||
make_floating->set_h_size_flags(Control::SIZE_EXPAND | Control::SIZE_SHRINK_END);
|
|
||||||
make_floating->set_tooltip_text(TTR("Make the LimboAI Debugger floating."));
|
make_floating->set_tooltip_text(TTR("Make the LimboAI Debugger floating."));
|
||||||
make_floating->connect(LW_NAME(request_open_in_screen), callable_mp(window_wrapper, &CompatWindowWrapper::enable_window_on_screen).bind(true));
|
make_floating->connect(LW_NAME(request_open_in_screen), callable_mp(window_wrapper, &CompatWindowWrapper::enable_window_on_screen).bind(true));
|
||||||
toolbar->add_child(make_floating);
|
toolbar->add_child(make_floating);
|
||||||
|
@ -221,6 +243,22 @@ LimboDebuggerTab::LimboDebuggerTab() {
|
||||||
resource_header->set_tooltip_text(TTR("Debugged BehaviorTree resource.\nClick to open."));
|
resource_header->set_tooltip_text(TTR("Debugged BehaviorTree resource.\nClick to open."));
|
||||||
resource_header->set_disabled(true);
|
resource_header->set_disabled(true);
|
||||||
|
|
||||||
|
Label *interval_label = memnew(Label);
|
||||||
|
toolbar->add_child(interval_label);
|
||||||
|
interval_label->set_text(TTR("Update Interval:"));
|
||||||
|
interval_label->set_h_size_flags(SIZE_EXPAND | SIZE_SHRINK_END);
|
||||||
|
|
||||||
|
update_interval = memnew(EditorSpinSlider);
|
||||||
|
toolbar->add_child(update_interval);
|
||||||
|
update_interval->set_min(0);
|
||||||
|
update_interval->set_max(1000);
|
||||||
|
update_interval->set_step(1.0);
|
||||||
|
update_interval->set_suffix("ms");
|
||||||
|
update_interval->set_custom_minimum_size(Vector2(100 * EDSCALE, 0));
|
||||||
|
|
||||||
|
VSeparator *sep = memnew(VSeparator);
|
||||||
|
toolbar->add_child(sep);
|
||||||
|
|
||||||
hsc = memnew(HSplitContainer);
|
hsc = memnew(HSplitContainer);
|
||||||
hsc->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
hsc->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||||
hsc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
hsc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "core/object/class_db.h"
|
#include "core/object/class_db.h"
|
||||||
#include "core/object/object.h"
|
#include "core/object/object.h"
|
||||||
#include "core/typedefs.h"
|
#include "core/typedefs.h"
|
||||||
|
#include "editor/gui/editor_spin_slider.h"
|
||||||
#include "editor/plugins/editor_debugger_plugin.h"
|
#include "editor/plugins/editor_debugger_plugin.h"
|
||||||
#include "editor/window_wrapper.h"
|
#include "editor/window_wrapper.h"
|
||||||
#include "scene/gui/box_container.h"
|
#include "scene/gui/box_container.h"
|
||||||
|
@ -35,6 +36,7 @@
|
||||||
#include <godot_cpp/classes/button.hpp>
|
#include <godot_cpp/classes/button.hpp>
|
||||||
#include <godot_cpp/classes/editor_debugger_plugin.hpp>
|
#include <godot_cpp/classes/editor_debugger_plugin.hpp>
|
||||||
#include <godot_cpp/classes/editor_debugger_session.hpp>
|
#include <godot_cpp/classes/editor_debugger_session.hpp>
|
||||||
|
#include <godot_cpp/classes/editor_spin_slider.hpp>
|
||||||
#include <godot_cpp/classes/h_box_container.hpp>
|
#include <godot_cpp/classes/h_box_container.hpp>
|
||||||
#include <godot_cpp/classes/h_split_container.hpp>
|
#include <godot_cpp/classes/h_split_container.hpp>
|
||||||
#include <godot_cpp/classes/item_list.hpp>
|
#include <godot_cpp/classes/item_list.hpp>
|
||||||
|
@ -64,6 +66,7 @@ private:
|
||||||
LineEdit *filter_players = nullptr;
|
LineEdit *filter_players = nullptr;
|
||||||
Button *resource_header = nullptr;
|
Button *resource_header = nullptr;
|
||||||
Button *make_floating = nullptr;
|
Button *make_floating = nullptr;
|
||||||
|
EditorSpinSlider *update_interval = nullptr;
|
||||||
CompatWindowWrapper *window_wrapper = nullptr;
|
CompatWindowWrapper *window_wrapper = nullptr;
|
||||||
|
|
||||||
void _reset_controls();
|
void _reset_controls();
|
||||||
|
|
|
@ -28,6 +28,7 @@ LimboStringNames *LimboStringNames::singleton = nullptr;
|
||||||
|
|
||||||
LimboStringNames::LimboStringNames() {
|
LimboStringNames::LimboStringNames() {
|
||||||
_draw_failure_status = SN("_draw_failure_status");
|
_draw_failure_status = SN("_draw_failure_status");
|
||||||
|
_draw_fresh = SN("_draw_fresh");
|
||||||
_draw_probability = SN("_draw_probability");
|
_draw_probability = SN("_draw_probability");
|
||||||
_draw_running_status = SN("_draw_running_status");
|
_draw_running_status = SN("_draw_running_status");
|
||||||
_draw_success_status = SN("_draw_success_status");
|
_draw_success_status = SN("_draw_success_status");
|
||||||
|
|
|
@ -42,6 +42,7 @@ public:
|
||||||
_FORCE_INLINE_ static LimboStringNames *get_singleton() { return singleton; }
|
_FORCE_INLINE_ static LimboStringNames *get_singleton() { return singleton; }
|
||||||
|
|
||||||
StringName _draw_failure_status;
|
StringName _draw_failure_status;
|
||||||
|
StringName _draw_fresh;
|
||||||
StringName _draw_probability;
|
StringName _draw_probability;
|
||||||
StringName _draw_running_status;
|
StringName _draw_running_status;
|
||||||
StringName _draw_success_status;
|
StringName _draw_success_status;
|
||||||
|
|
Loading…
Reference in New Issue