Port BTPlayer and LimboDebugger (game-side part)

This commit is contained in:
Serhii Snitsaruk 2024-01-07 02:40:51 +01:00
parent 4f97c1bd24
commit 0767c0eee1
9 changed files with 102 additions and 26 deletions

View File

@ -11,9 +11,10 @@
#include "bt_player.h" #include "bt_player.h"
#include "modules/limboai/blackboard/blackboard.h" #include "../editor/debugger/limbo_debugger.h"
#include "modules/limboai/editor/debugger/limbo_debugger.h" #include "../util/limbo_string_names.h"
#include "modules/limboai/util/limbo_string_names.h"
#ifdef LIMBOAI_MODULE
#include "core/config/engine.h" #include "core/config/engine.h"
#include "core/debugger/engine_debugger.h" #include "core/debugger/engine_debugger.h"
@ -25,11 +26,27 @@
#include "core/variant/variant.h" #include "core/variant/variant.h"
#include "main/performance.h" #include "main/performance.h"
#define IS_DEBUGGER_ACTIVE() (EngineDebugger::is_active())
#define GET_TICKS_USEC() (OS::get_singleton()->get_ticks_usec())
#endif // LIMBO_MODULE
#ifdef LIMBOAI_GDEXTENSION
#include <godot_cpp/classes/engine_debugger.hpp>
#include <godot_cpp/classes/performance.hpp>
#include <godot_cpp/classes/time.hpp>
#define IS_DEBUGGER_ACTIVE() (EngineDebugger::get_singleton()->is_active())
#define GET_TICKS_USEC() (Time::get_singleton()->get_ticks_usec())
#endif // LIMBOAI_GDEXTENSION
VARIANT_ENUM_CAST(BTPlayer::UpdateMode); VARIANT_ENUM_CAST(BTPlayer::UpdateMode);
void BTPlayer::_load_tree() { void BTPlayer::_load_tree() {
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
if (tree_instance.is_valid() && EngineDebugger::is_active()) { if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
LimboDebugger::get_singleton()->unregister_bt_instance(tree_instance, get_path()); LimboDebugger::get_singleton()->unregister_bt_instance(tree_instance, get_path());
} }
#endif #endif
@ -41,7 +58,7 @@ void BTPlayer::_load_tree() {
} }
tree_instance = behavior_tree->instantiate(get_owner(), blackboard); tree_instance = behavior_tree->instantiate(get_owner(), blackboard);
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
if (EngineDebugger::is_active()) { if (IS_DEBUGGER_ACTIVE()) {
LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path()); LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path());
} }
#endif #endif
@ -74,7 +91,7 @@ void BTPlayer::update(double p_delta) {
} }
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
double start = OS::get_singleton()->get_ticks_usec(); double start = GET_TICKS_USEC();
#endif #endif
if (active) { if (active) {
@ -86,7 +103,7 @@ void BTPlayer::update(double p_delta) {
} }
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
double end = OS::get_singleton()->get_ticks_usec(); double end = GET_TICKS_USEC();
update_time_acc += (end - start); update_time_acc += (end - start);
update_time_n += 1.0; update_time_n += 1.0;
#endif #endif
@ -113,7 +130,7 @@ void BTPlayer::_set_monitor_performance(bool p_monitor_performance) {
String(itos(get_instance_id())).md5_text().substr(0, 4)); String(itos(get_instance_id())).md5_text().substr(0, 4));
} }
if (!perf->has_custom_monitor(monitor_id)) { if (!perf->has_custom_monitor(monitor_id)) {
perf->add_custom_monitor(monitor_id, callable_mp(this, &BTPlayer::_get_mean_update_time_msec), Vector<Variant>()); perf->add_custom_monitor(monitor_id, callable_mp(this, &BTPlayer::_get_mean_update_time_msec));
} }
} else if (monitor_id != StringName() && perf->has_custom_monitor(monitor_id)) { } else if (monitor_id != StringName() && perf->has_custom_monitor(monitor_id)) {
perf->remove_custom_monitor(monitor_id); perf->remove_custom_monitor(monitor_id);
@ -155,12 +172,12 @@ void BTPlayer::_notification(int p_notification) {
} break; } break;
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
case NOTIFICATION_ENTER_TREE: { case NOTIFICATION_ENTER_TREE: {
if (tree_instance.is_valid() && EngineDebugger::is_active()) { if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path()); LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path());
} }
} break; } break;
case NOTIFICATION_EXIT_TREE: { case NOTIFICATION_EXIT_TREE: {
if (tree_instance.is_valid() && EngineDebugger::is_active()) { if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
LimboDebugger::get_singleton()->unregister_bt_instance(tree_instance, get_path()); LimboDebugger::get_singleton()->unregister_bt_instance(tree_instance, get_path());
} }
} break; } break;
@ -205,7 +222,7 @@ void BTPlayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_monitor_performance", "p_value"), &BTPlayer::_set_monitor_performance); ClassDB::bind_method(D_METHOD("_set_monitor_performance", "p_value"), &BTPlayer::_set_monitor_performance);
ClassDB::bind_method(D_METHOD("_get_monitor_performance"), &BTPlayer::_get_monitor_performance); ClassDB::bind_method(D_METHOD("_get_monitor_performance"), &BTPlayer::_get_monitor_performance);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitor_performance"), "_set_monitor_performance", "_get_monitor_performance"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitor_performance"), "_set_monitor_performance", "_get_monitor_performance");
ADD_PROPERTY_DEFAULT("monitor_performance", false); // ADD_PROPERTY_DEFAULT("monitor_performance", false);
#endif // DEBUG_ENABLED #endif // DEBUG_ENABLED
} }

View File

@ -12,10 +12,16 @@
#ifndef BT_PLAYER_H #ifndef BT_PLAYER_H
#define BT_PLAYER_H #define BT_PLAYER_H
#ifdef LIMBOAI_MODULE
#include "scene/main/node.h" #include "scene/main/node.h"
#endif
#ifdef LIMBOAI_GDEXTENSION
#include <godot_cpp/classes/node.hpp>
#endif
#include "../blackboard/blackboard.h"
#include "behavior_tree.h" #include "behavior_tree.h"
#include "modules/limboai/blackboard/blackboard.h"
#include "tasks/bt_task.h" #include "tasks/bt_task.h"
class BTPlayer : public Node { class BTPlayer : public Node {

View File

@ -11,8 +11,9 @@
#include "behavior_tree_data.h" #include "behavior_tree_data.h"
#include "core/object/script_language.h" #ifdef LIMBOAI_MODULE
#include "core/templates/list.h" #include "core/templates/list.h"
#endif
//// BehaviorTreeData //// BehaviorTreeData
@ -76,7 +77,7 @@ BehaviorTreeData::BehaviorTreeData(const Ref<BTTask> &p_instance, const NodePath
String script_path; String script_path;
if (task->get_script()) { if (task->get_script()) {
Ref<Script> script = task->get_script(); Ref<Resource> script = task->get_script();
script_path = script->get_path(); script_path = script->get_path();
} }

View File

@ -12,7 +12,7 @@
#ifndef BEHAVIOR_TREE_DATA_H #ifndef BEHAVIOR_TREE_DATA_H
#define BEHAVIOR_TREE_DATA_H #define BEHAVIOR_TREE_DATA_H
#include "modules/limboai/bt/tasks/bt_task.h" #include "../../bt/tasks/bt_task.h"
class BehaviorTreeData { class BehaviorTreeData {
public: public:

View File

@ -11,15 +11,23 @@
#include "limbo_debugger.h" #include "limbo_debugger.h"
#include "../../bt/tasks/bt_task.h"
#include "behavior_tree_data.h" #include "behavior_tree_data.h"
#include "modules/limboai/bt/tasks/bt_task.h"
#ifdef LIMBOAI_MODULE
#include "core/debugger/engine_debugger.h" #include "core/debugger/engine_debugger.h"
#include "core/error/error_macros.h" #include "core/error/error_macros.h"
#include "core/io/resource.h" #include "core/io/resource.h"
#include "core/string/node_path.h" #include "core/string/node_path.h"
#include "scene/main/scene_tree.h" #include "scene/main/scene_tree.h"
#include "scene/main/window.h" #include "scene/main/window.h"
#endif // LIMBOAI_MODULE
#ifdef LIMBOAI_GDEXTENSION
#include <godot_cpp/classes/engine_debugger.hpp>
#include <godot_cpp/classes/scene_tree.hpp>
#include <godot_cpp/classes/window.hpp>
#endif // LIMBOAI_GDEXTENSION
//// LimboDebugger //// LimboDebugger
@ -30,9 +38,12 @@ LimboDebugger *LimboDebugger::get_singleton() {
LimboDebugger::LimboDebugger() { LimboDebugger::LimboDebugger() {
singleton = this; singleton = this;
#ifdef DEBUG_ENABLED #if defined(DEBUG_ENABLED) && defined(LIMBOAI_MODULE)
EngineDebugger::register_message_capture("limboai", EngineDebugger::Capture(nullptr, LimboDebugger::parse_message)); EngineDebugger::register_message_capture("limboai", EngineDebugger::Capture(nullptr, LimboDebugger::parse_message));
#endif #endif
#if defined(DEBUG_ENABLED) && defined(LIMBOAI_GDEXTENSION)
// EngineDebugger::get_singleton()->register_message_capture("limboai", callable_mp(this, &LimboDebugger::parse_message));
#endif
} }
LimboDebugger::~LimboDebugger() { LimboDebugger::~LimboDebugger() {
@ -40,7 +51,7 @@ LimboDebugger::~LimboDebugger() {
} }
void LimboDebugger::initialize() { void LimboDebugger::initialize() {
if (EngineDebugger::is_active()) { if (IS_DEBUGGER_ACTIVE()) {
memnew(LimboDebugger); memnew(LimboDebugger);
} }
} }
@ -51,6 +62,14 @@ void LimboDebugger::deinitialize() {
} }
} }
void LimboDebugger::_bind_methods() {
#ifdef LIMBOAI_GDEXTENSION
ClassDB::bind_method(D_METHOD("parse_message_gdext"), &LimboDebugger::parse_message_gdext);
#endif
ClassDB::bind_method(D_METHOD("_on_bt_updated", "p_status", "p_path"), &LimboDebugger::_on_bt_updated);
ClassDB::bind_method(D_METHOD("_on_state_updated", "p_delta", "p_path"), &LimboDebugger::_on_state_updated);
}
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
Error LimboDebugger::parse_message(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured) { Error LimboDebugger::parse_message(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured) {
r_captured = true; r_captured = true;
@ -69,6 +88,12 @@ Error LimboDebugger::parse_message(void *p_user, const String &p_msg, const Arra
return OK; return OK;
} }
bool LimboDebugger::parse_message_gdext(const String &p_msg, const Array &p_args) {
bool ret;
LimboDebugger::parse_message(nullptr, p_msg, p_args, ret);
return ret;
}
void LimboDebugger::register_bt_instance(Ref<BTTask> p_instance, NodePath p_player_path) { void LimboDebugger::register_bt_instance(Ref<BTTask> p_instance, NodePath p_player_path) {
ERR_FAIL_COND(p_instance.is_null()); ERR_FAIL_COND(p_instance.is_null());
ERR_FAIL_COND(p_player_path.is_empty()); ERR_FAIL_COND(p_player_path.is_empty());
@ -104,13 +129,20 @@ void LimboDebugger::_track_tree(NodePath p_path) {
_untrack_tree(); _untrack_tree();
} }
Node *node = SceneTree::get_singleton()->get_root()->get_node(p_path); Node *node = GET_SCENE_TREE()->get_root()->get_node_or_null(p_path);
ERR_FAIL_COND(node == nullptr); ERR_FAIL_COND(node == nullptr);
tracked_player = p_path; tracked_player = p_path;
Ref<Resource> bt;
#ifdef LIMBOAI_MODULE
bool r_valid = false; bool r_valid = false;
Ref<Resource> bt = node->get(SNAME("behavior_tree"), &r_valid); bt = node->get(LSNAME(behavior_tree), &r_valid);
#endif
#ifdef LIMBOAI_GDEXTENSION
bt = node->get(LSNAME(behavior_tree));
#endif
if (bt.is_valid()) { if (bt.is_valid()) {
bt_resource_path = bt->get_path(); bt_resource_path = bt->get_path();
} else { } else {
@ -118,9 +150,9 @@ void LimboDebugger::_track_tree(NodePath p_path) {
} }
if (node->is_class("BTPlayer")) { if (node->is_class("BTPlayer")) {
node->connect(SNAME("updated"), callable_mp(this, &LimboDebugger::_on_bt_updated).bind(p_path)); node->connect(LSNAME(updated), callable_mp(this, &LimboDebugger::_on_bt_updated).bind(p_path));
} else if (node->is_class("BTState")) { } else if (node->is_class("BTState")) {
node->connect(SNAME("updated"), callable_mp(this, &LimboDebugger::_on_state_updated).bind(p_path)); node->connect(LSNAME(updated), callable_mp(this, &LimboDebugger::_on_state_updated).bind(p_path));
} }
} }
@ -132,13 +164,13 @@ void LimboDebugger::_untrack_tree() {
NodePath was_tracking = tracked_player; NodePath was_tracking = tracked_player;
tracked_player = NodePath(); tracked_player = NodePath();
Node *node = SceneTree::get_singleton()->get_root()->get_node(was_tracking); Node *node = GET_SCENE_TREE()->get_root()->get_node_or_null(was_tracking);
ERR_FAIL_COND(node == nullptr); ERR_FAIL_COND(node == nullptr);
if (node->is_class("BTPlayer")) { if (node->is_class("BTPlayer")) {
node->disconnect(SNAME("updated"), callable_mp(this, &LimboDebugger::_on_bt_updated)); node->disconnect(LSNAME(updated), callable_mp(this, &LimboDebugger::_on_bt_updated));
} else if (node->is_class("BTState")) { } else if (node->is_class("BTState")) {
node->disconnect(SNAME("updated"), callable_mp(this, &LimboDebugger::_on_state_updated)); node->disconnect(LSNAME(updated), callable_mp(this, &LimboDebugger::_on_state_updated));
} }
} }

View File

@ -12,11 +12,19 @@
#ifndef LIMBO_DEBUGGER_H #ifndef LIMBO_DEBUGGER_H
#define LIMBO_DEBUGGER_H #define LIMBO_DEBUGGER_H
#include "modules/limboai/bt/tasks/bt_task.h" #include "../../bt/tasks/bt_task.h"
#ifdef LIMBOAI_MODULE
#include "core/object/class_db.h" #include "core/object/class_db.h"
#include "core/object/object.h" #include "core/object/object.h"
#include "core/string/node_path.h" #include "core/string/node_path.h"
#endif // LIMBOAI_MODULE
#ifdef LIMBOAI_GDEXTENSION
#include <godot_cpp/classes/object.hpp>
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/variant/node_path.hpp>
#endif // LIMBOAI_GDEXTENSION
class LimboDebugger : public Object { class LimboDebugger : public Object {
GDCLASS(LimboDebugger, Object); GDCLASS(LimboDebugger, Object);
@ -33,6 +41,9 @@ public:
~LimboDebugger(); ~LimboDebugger();
protected:
static void _bind_methods();
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
private: private:
HashMap<NodePath, Ref<BTTask>> active_trees; HashMap<NodePath, Ref<BTTask>> active_trees;
@ -49,6 +60,9 @@ private:
public: public:
static Error parse_message(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured); static Error parse_message(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured);
#ifdef LIMBOAI_GDEXTENSION
bool parse_message_gdext(const String &p_msg, const Array &p_args);
#endif
void register_bt_instance(Ref<BTTask> p_instance, NodePath p_player_path); void register_bt_instance(Ref<BTTask> p_instance, NodePath p_player_path);
void unregister_bt_instance(Ref<BTTask> p_instance, NodePath p_player_path); void unregister_bt_instance(Ref<BTTask> p_instance, NodePath p_player_path);

View File

@ -17,6 +17,8 @@
#define RAND_RANGE(m_from, m_to) (Math::random(m_from, m_to)) #define RAND_RANGE(m_from, m_to) (Math::random(m_from, m_to))
#define RANDF() (Math::randf()) #define RANDF() (Math::randf())
#define PRINT_LINE(...) (print_line(__VA_ARGS__)) #define PRINT_LINE(...) (print_line(__VA_ARGS__))
#define IS_DEBUGGER_ACTIVE() (EngineDebugger::is_active())
#define GET_SCENE_TREE() (SceneTree::get_singleton())
#endif // LIMBOAI_MODULE #endif // LIMBOAI_MODULE
@ -28,5 +30,7 @@
#define RAND_RANGE(m_from, m_to) (UtilityFunctions::randf_range(m_from, m_to)) #define RAND_RANGE(m_from, m_to) (UtilityFunctions::randf_range(m_from, m_to))
#define RANDF() (UtilityFunctions::randf()) #define RANDF() (UtilityFunctions::randf())
#define PRINT_LINE(...) (UtilityFunctions::print(__VA_ARGS__)) #define PRINT_LINE(...) (UtilityFunctions::print(__VA_ARGS__))
#define IS_DEBUGGER_ACTIVE() (EngineDebugger::get_singleton()->is_active())
#define GET_SCENE_TREE() ((SceneTree *)(Engine::get_singleton()->get_main_loop()))
#endif // LIMBOAI_GDEXTENSION #endif // LIMBOAI_GDEXTENSION

View File

@ -32,6 +32,7 @@ LimboStringNames::LimboStringNames() {
changed = StringName("emit_changed"); changed = StringName("emit_changed");
_weight_ = StringName("_weight_"); _weight_ = StringName("_weight_");
error_value = StringName("error_value"); error_value = StringName("error_value");
behavior_tree = StringName("behavior_tree");
repeat_forever.parse_utf8("Repeat ∞"); repeat_forever.parse_utf8("Repeat ∞");
} }

View File

@ -57,6 +57,7 @@ public:
StringName emit_changed; StringName emit_changed;
StringName _weight_; StringName _weight_;
StringName error_value; StringName error_value;
StringName behavior_tree;
String repeat_forever; String repeat_forever;
}; };