Add LimboState
This commit is contained in:
parent
3f47f2bf76
commit
c62ecc9084
|
@ -0,0 +1,158 @@
|
||||||
|
/* limbo_state.cpp */
|
||||||
|
|
||||||
|
#include "limbo_state.h"
|
||||||
|
#include "core/array.h"
|
||||||
|
#include "core/class_db.h"
|
||||||
|
#include "core/error_macros.h"
|
||||||
|
#include "core/object.h"
|
||||||
|
#include "core/variant.h"
|
||||||
|
#include "limbo_string_names.h"
|
||||||
|
|
||||||
|
const String LimboState::EVENT_FINISHED = "finished";
|
||||||
|
|
||||||
|
LimboState *LimboState::get_root() const {
|
||||||
|
const LimboState *state = this;
|
||||||
|
while (get_parent() && get_parent()->is_class("LimboState")) {
|
||||||
|
state = Object::cast_to<LimboState>(get_parent());
|
||||||
|
}
|
||||||
|
return const_cast<LimboState *>(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
LimboState *LimboState::named(String p_name) {
|
||||||
|
set_name(p_name);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
void LimboState::_setup() {
|
||||||
|
if (get_script_instance() &&
|
||||||
|
get_script_instance()->has_method(LimboStringNames::get_singleton()->_setup)) {
|
||||||
|
get_script_instance()->call(LimboStringNames::get_singleton()->_setup);
|
||||||
|
}
|
||||||
|
emit_signal(LimboStringNames::get_singleton()->setup);
|
||||||
|
};
|
||||||
|
|
||||||
|
void LimboState::_enter() {
|
||||||
|
active = true;
|
||||||
|
if (get_script_instance() &&
|
||||||
|
get_script_instance()->has_method(LimboStringNames::get_singleton()->_enter)) {
|
||||||
|
get_script_instance()->call(LimboStringNames::get_singleton()->_enter);
|
||||||
|
}
|
||||||
|
emit_signal(LimboStringNames::get_singleton()->entered);
|
||||||
|
};
|
||||||
|
|
||||||
|
void LimboState::_exit() {
|
||||||
|
if (get_script_instance() &&
|
||||||
|
get_script_instance()->has_method(LimboStringNames::get_singleton()->_exit)) {
|
||||||
|
get_script_instance()->call(LimboStringNames::get_singleton()->_exit);
|
||||||
|
}
|
||||||
|
emit_signal(LimboStringNames::get_singleton()->exited);
|
||||||
|
active = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
void LimboState::_update(float p_delta) {
|
||||||
|
if (get_script_instance() &&
|
||||||
|
get_script_instance()->has_method(LimboStringNames::get_singleton()->_update)) {
|
||||||
|
get_script_instance()->call(LimboStringNames::get_singleton()->_update, p_delta);
|
||||||
|
}
|
||||||
|
emit_signal(LimboStringNames::get_singleton()->updated, p_delta);
|
||||||
|
};
|
||||||
|
|
||||||
|
void LimboState::initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard) {
|
||||||
|
ERR_FAIL_COND(p_agent == nullptr);
|
||||||
|
ERR_FAIL_COND(!p_blackboard.is_valid());
|
||||||
|
agent = p_agent;
|
||||||
|
blackboard = p_blackboard;
|
||||||
|
for (int i = 0; i < get_child_count(); i++) {
|
||||||
|
LimboState *c = Object::cast_to<LimboState>(get_child(i));
|
||||||
|
if (c) {
|
||||||
|
c->initialize(p_agent, p_blackboard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_setup();
|
||||||
|
};
|
||||||
|
|
||||||
|
bool LimboState::dispatch(const String &p_event, const Variant &p_cargo) {
|
||||||
|
ERR_FAIL_COND_V(p_event.empty(), false);
|
||||||
|
bool result = false;
|
||||||
|
if (handlers.size() > 0 && handlers.has(p_event)) {
|
||||||
|
if (p_cargo.get_type() == Variant::NIL) {
|
||||||
|
result = call(handlers[p_event]);
|
||||||
|
} else {
|
||||||
|
result = call(handlers[p_event], p_cargo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LimboState::add_event_handler(const String &p_event, const StringName &p_method) {
|
||||||
|
ERR_FAIL_COND(p_event.empty());
|
||||||
|
ERR_FAIL_COND(!has_method(p_method));
|
||||||
|
handlers.insert(p_event, p_method);
|
||||||
|
}
|
||||||
|
|
||||||
|
LimboState *LimboState::call_on_enter(Object *p_object, const StringName &p_method) {
|
||||||
|
ERR_FAIL_COND_V(p_object == nullptr, this);
|
||||||
|
ERR_FAIL_COND_V(!p_object->has_method(p_method), this);
|
||||||
|
connect(LimboStringNames::get_singleton()->entered, p_object, p_method);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
LimboState *LimboState::call_on_exit(Object *p_object, const StringName &p_method) {
|
||||||
|
ERR_FAIL_COND_V(p_object == nullptr, this);
|
||||||
|
ERR_FAIL_COND_V(!p_object->has_method(p_method), this);
|
||||||
|
connect(LimboStringNames::get_singleton()->exited, p_object, p_method);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
LimboState *LimboState::call_on_update(Object *p_object, const StringName &p_method) {
|
||||||
|
ERR_FAIL_COND_V(p_object == nullptr, this);
|
||||||
|
ERR_FAIL_COND_V(!p_object->has_method(p_method), this);
|
||||||
|
connect(LimboStringNames::get_singleton()->updated, p_object, p_method);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LimboState::_notification(int p_what) {
|
||||||
|
switch (p_what) {
|
||||||
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
|
if (active) {
|
||||||
|
_exit();
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LimboState::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("get_root"), &LimboState::get_root);
|
||||||
|
ClassDB::bind_method(D_METHOD("event_finished"), &LimboState::event_finished);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_active"), &LimboState::is_active);
|
||||||
|
ClassDB::bind_method(D_METHOD("_setup"), &LimboState::_setup);
|
||||||
|
ClassDB::bind_method(D_METHOD("_enter"), &LimboState::_enter);
|
||||||
|
ClassDB::bind_method(D_METHOD("_exit"), &LimboState::_exit);
|
||||||
|
ClassDB::bind_method(D_METHOD("_update", "p_delta"), &LimboState::_update);
|
||||||
|
ClassDB::bind_method(D_METHOD("initialize", "p_agent", "p_blackboard"), &LimboState::initialize);
|
||||||
|
ClassDB::bind_method(D_METHOD("dispatch", "p_event", "p_cargo"), &LimboState::dispatch, Variant());
|
||||||
|
ClassDB::bind_method(D_METHOD("named", "p_name"), &LimboState::named);
|
||||||
|
ClassDB::bind_method(D_METHOD("add_event_handler", "p_event", "p_method"), &LimboState::add_event_handler);
|
||||||
|
ClassDB::bind_method(D_METHOD("call_on_enter", "p_object", "p_method"), &LimboState::call_on_enter);
|
||||||
|
ClassDB::bind_method(D_METHOD("call_on_exit", "p_object", "p_method"), &LimboState::call_on_exit);
|
||||||
|
ClassDB::bind_method(D_METHOD("call_on_update", "p_object", "p_method"), &LimboState::call_on_update);
|
||||||
|
|
||||||
|
BIND_VMETHOD(MethodInfo("_setup"));
|
||||||
|
BIND_VMETHOD(MethodInfo("_enter"));
|
||||||
|
BIND_VMETHOD(MethodInfo("_exit"));
|
||||||
|
BIND_VMETHOD(MethodInfo("_update", PropertyInfo(Variant::REAL, "p_delta")));
|
||||||
|
|
||||||
|
ADD_SIGNAL(MethodInfo("setup"));
|
||||||
|
ADD_SIGNAL(MethodInfo("entered"));
|
||||||
|
ADD_SIGNAL(MethodInfo("exited"));
|
||||||
|
ADD_SIGNAL(MethodInfo("updated", PropertyInfo(Variant::REAL, "p_delta")));
|
||||||
|
};
|
||||||
|
|
||||||
|
LimboState::LimboState() {
|
||||||
|
agent = nullptr;
|
||||||
|
active = false;
|
||||||
|
|
||||||
|
set_process(false);
|
||||||
|
set_physics_process(false);
|
||||||
|
set_process_input(false);
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/* limbo_state.h */
|
||||||
|
|
||||||
|
#ifndef LIMBO_STATE_H
|
||||||
|
#define LIMBO_STATE_H
|
||||||
|
|
||||||
|
#include "blackboard.h"
|
||||||
|
#include "core/string_name.h"
|
||||||
|
#include "core/ustring.h"
|
||||||
|
#include "core/variant.h"
|
||||||
|
#include "scene/main/node.h"
|
||||||
|
|
||||||
|
// TODO Implement guards
|
||||||
|
|
||||||
|
class LimboState : public Node {
|
||||||
|
GDCLASS(LimboState, Node);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Object *agent;
|
||||||
|
Ref<Blackboard> blackboard;
|
||||||
|
Map<String, StringName> handlers;
|
||||||
|
bool active;
|
||||||
|
// Guard *guard;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void _bind_methods();
|
||||||
|
|
||||||
|
void _notification(int p_what);
|
||||||
|
|
||||||
|
virtual void _setup();
|
||||||
|
virtual void _enter();
|
||||||
|
virtual void _exit();
|
||||||
|
virtual void _update(float p_delta);
|
||||||
|
|
||||||
|
void add_event_handler(const String &p_event, const StringName &p_method);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const String EVENT_FINISHED;
|
||||||
|
|
||||||
|
virtual void initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard);
|
||||||
|
virtual bool dispatch(const String &p_event, const Variant &p_cargo);
|
||||||
|
|
||||||
|
LimboState *named(String p_name);
|
||||||
|
// LimboState *call_on_setup(Object *p_object, const StringName &p_method) {}
|
||||||
|
LimboState *call_on_enter(Object *p_object, const StringName &p_method);
|
||||||
|
LimboState *call_on_exit(Object *p_object, const StringName &p_method);
|
||||||
|
LimboState *call_on_update(Object *p_object, const StringName &p_method);
|
||||||
|
|
||||||
|
String event_finished() const { return EVENT_FINISHED; }
|
||||||
|
LimboState *get_root() const;
|
||||||
|
bool is_active() const { return active; }
|
||||||
|
|
||||||
|
LimboState();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LIMBO_STATE_H
|
|
@ -12,4 +12,9 @@ LimboStringNames::LimboStringNames() {
|
||||||
_exit = StaticCString::create("_exit");
|
_exit = StaticCString::create("_exit");
|
||||||
_tick = StaticCString::create("_tick");
|
_tick = StaticCString::create("_tick");
|
||||||
behavior_tree_finished = StaticCString::create("behavior_tree_finished");
|
behavior_tree_finished = StaticCString::create("behavior_tree_finished");
|
||||||
|
setup = StaticCString::create("setup");
|
||||||
|
entered = StaticCString::create("entered");
|
||||||
|
exited = StaticCString::create("exited");
|
||||||
|
updated = StaticCString::create("updated");
|
||||||
|
_update = StaticCString::create("_update");
|
||||||
}
|
}
|
|
@ -29,6 +29,11 @@ public:
|
||||||
StringName _exit;
|
StringName _exit;
|
||||||
StringName _tick;
|
StringName _tick;
|
||||||
StringName behavior_tree_finished;
|
StringName behavior_tree_finished;
|
||||||
|
StringName setup;
|
||||||
|
StringName entered;
|
||||||
|
StringName exited;
|
||||||
|
StringName updated;
|
||||||
|
StringName _update;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LIMBO_STRING_NAMES_H
|
#endif // LIMBO_STRING_NAMES_H
|
|
@ -39,6 +39,7 @@
|
||||||
#include "bt/decorators/bt_subtree.h"
|
#include "bt/decorators/bt_subtree.h"
|
||||||
#include "bt/decorators/bt_time_limit.h"
|
#include "bt/decorators/bt_time_limit.h"
|
||||||
#include "core/os/memory.h"
|
#include "core/os/memory.h"
|
||||||
|
#include "limbo_state.h"
|
||||||
#include "limbo_string_names.h"
|
#include "limbo_string_names.h"
|
||||||
#include "limbo_utility.h"
|
#include "limbo_utility.h"
|
||||||
|
|
||||||
|
@ -50,6 +51,9 @@ static LimboUtility *_limbo_utility = nullptr;
|
||||||
|
|
||||||
void register_limboai_types() {
|
void register_limboai_types() {
|
||||||
ClassDB::register_class<Blackboard>();
|
ClassDB::register_class<Blackboard>();
|
||||||
|
|
||||||
|
ClassDB::register_class<LimboState>();
|
||||||
|
|
||||||
ClassDB::register_class<BTTask>();
|
ClassDB::register_class<BTTask>();
|
||||||
ClassDB::register_class<BehaviorTree>();
|
ClassDB::register_class<BehaviorTree>();
|
||||||
ClassDB::register_class<BTPlayer>();
|
ClassDB::register_class<BTPlayer>();
|
||||||
|
|
Loading…
Reference in New Issue