Implement guard func
This commit is contained in:
parent
b7ea9145df
commit
eecf27fdf5
|
@ -129,10 +129,21 @@ bool LimboHSM::dispatch(const String &p_event, const Variant &p_cargo) {
|
||||||
uint64_t key = _get_transition_key(active_state, p_event);
|
uint64_t key = _get_transition_key(active_state, p_event);
|
||||||
if (transitions.has(key)) {
|
if (transitions.has(key)) {
|
||||||
LimboState *to_state = transitions[key];
|
LimboState *to_state = transitions[key];
|
||||||
|
bool permitted = true;
|
||||||
|
if (to_state->guard.obj != nullptr) {
|
||||||
|
Variant result = to_state->guard.obj->callv(to_state->guard.func, to_state->guard.binds);
|
||||||
|
if (unlikely(result.get_type() != Variant::BOOL)) {
|
||||||
|
ERR_PRINT_ONCE(vformat("State guard func \"%s()\" returned non-boolean value (%s).", to_state->guard.func, to_state));
|
||||||
|
} else {
|
||||||
|
permitted = bool(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (permitted) {
|
||||||
_change_state(to_state);
|
_change_state(to_state);
|
||||||
event_consumed = true;
|
event_consumed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!event_consumed && p_event == EVENT_FINISHED && !(get_parent()->is_class("LimboState"))) {
|
if (!event_consumed && p_event == EVENT_FINISHED && !(get_parent()->is_class("LimboState"))) {
|
||||||
_exit();
|
_exit();
|
||||||
|
|
|
@ -109,6 +109,21 @@ LimboState *LimboState::call_on_update(Object *p_object, const StringName &p_met
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LimboState::set_guard_func(Object *p_object, const StringName &p_func, const Array &p_binds) {
|
||||||
|
ERR_FAIL_COND(p_object == nullptr);
|
||||||
|
ERR_FAIL_COND(!p_object->has_method(p_func));
|
||||||
|
|
||||||
|
guard.obj = p_object;
|
||||||
|
guard.func = p_func;
|
||||||
|
guard.binds = p_binds;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LimboState::clear_guard_func() {
|
||||||
|
guard.obj = nullptr;
|
||||||
|
guard.func = "";
|
||||||
|
guard.binds.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void LimboState::_notification(int p_what) {
|
void LimboState::_notification(int p_what) {
|
||||||
switch (p_what) {
|
switch (p_what) {
|
||||||
case NOTIFICATION_EXIT_TREE: {
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
|
@ -134,6 +149,8 @@ void LimboState::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("call_on_enter", "p_object", "p_method"), &LimboState::call_on_enter);
|
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_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);
|
ClassDB::bind_method(D_METHOD("call_on_update", "p_object", "p_method"), &LimboState::call_on_update);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_guard_func", "p_object", "p_func", "p_binds"), &LimboState::set_guard_func, Array());
|
||||||
|
ClassDB::bind_method(D_METHOD("clear_guard_func"), &LimboState::clear_guard_func);
|
||||||
|
|
||||||
BIND_VMETHOD(MethodInfo("_setup"));
|
BIND_VMETHOD(MethodInfo("_setup"));
|
||||||
BIND_VMETHOD(MethodInfo("_enter"));
|
BIND_VMETHOD(MethodInfo("_enter"));
|
||||||
|
@ -150,6 +167,8 @@ LimboState::LimboState() {
|
||||||
agent = nullptr;
|
agent = nullptr;
|
||||||
active = false;
|
active = false;
|
||||||
|
|
||||||
|
guard.obj = nullptr;
|
||||||
|
|
||||||
set_process(false);
|
set_process(false);
|
||||||
set_physics_process(false);
|
set_physics_process(false);
|
||||||
set_process_input(false);
|
set_process_input(false);
|
||||||
|
|
|
@ -4,22 +4,29 @@
|
||||||
#define LIMBO_STATE_H
|
#define LIMBO_STATE_H
|
||||||
|
|
||||||
#include "blackboard.h"
|
#include "blackboard.h"
|
||||||
|
#include "core/class_db.h"
|
||||||
|
#include "core/object.h"
|
||||||
#include "core/string_name.h"
|
#include "core/string_name.h"
|
||||||
#include "core/ustring.h"
|
#include "core/ustring.h"
|
||||||
#include "core/variant.h"
|
#include "core/variant.h"
|
||||||
#include "scene/main/node.h"
|
#include "scene/main/node.h"
|
||||||
|
|
||||||
// TODO Implement guards
|
|
||||||
class LimboHSM;
|
class LimboHSM;
|
||||||
|
|
||||||
class LimboState : public Node {
|
class LimboState : public Node {
|
||||||
GDCLASS(LimboState, Node);
|
GDCLASS(LimboState, Node);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct GuardCallback {
|
||||||
|
Object *obj = nullptr;
|
||||||
|
StringName func;
|
||||||
|
Array binds;
|
||||||
|
};
|
||||||
|
|
||||||
Object *agent;
|
Object *agent;
|
||||||
Ref<Blackboard> blackboard;
|
Ref<Blackboard> blackboard;
|
||||||
Map<String, StringName> handlers;
|
Map<String, StringName> handlers;
|
||||||
// Guard *guard;
|
GuardCallback guard;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend LimboHSM;
|
friend LimboHSM;
|
||||||
|
@ -51,7 +58,9 @@ public:
|
||||||
String event_finished() const { return EVENT_FINISHED; }
|
String event_finished() const { return EVENT_FINISHED; }
|
||||||
LimboState *get_root() const;
|
LimboState *get_root() const;
|
||||||
bool is_active() const { return active; }
|
bool is_active() const { return active; }
|
||||||
uint32_t hash() const;
|
|
||||||
|
void set_guard_func(Object *p_object, const StringName &p_func, const Array &p_binds = Array());
|
||||||
|
void clear_guard_func();
|
||||||
|
|
||||||
LimboState();
|
LimboState();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue