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);
|
||||
if (transitions.has(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);
|
||||
event_consumed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!event_consumed && p_event == EVENT_FINISHED && !(get_parent()->is_class("LimboState"))) {
|
||||
_exit();
|
||||
|
|
|
@ -109,6 +109,21 @@ LimboState *LimboState::call_on_update(Object *p_object, const StringName &p_met
|
|||
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) {
|
||||
switch (p_what) {
|
||||
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_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("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("_enter"));
|
||||
|
@ -150,6 +167,8 @@ LimboState::LimboState() {
|
|||
agent = nullptr;
|
||||
active = false;
|
||||
|
||||
guard.obj = nullptr;
|
||||
|
||||
set_process(false);
|
||||
set_physics_process(false);
|
||||
set_process_input(false);
|
||||
|
|
|
@ -4,22 +4,29 @@
|
|||
#define LIMBO_STATE_H
|
||||
|
||||
#include "blackboard.h"
|
||||
#include "core/class_db.h"
|
||||
#include "core/object.h"
|
||||
#include "core/string_name.h"
|
||||
#include "core/ustring.h"
|
||||
#include "core/variant.h"
|
||||
#include "scene/main/node.h"
|
||||
|
||||
// TODO Implement guards
|
||||
class LimboHSM;
|
||||
|
||||
class LimboState : public Node {
|
||||
GDCLASS(LimboState, Node);
|
||||
|
||||
private:
|
||||
struct GuardCallback {
|
||||
Object *obj = nullptr;
|
||||
StringName func;
|
||||
Array binds;
|
||||
};
|
||||
|
||||
Object *agent;
|
||||
Ref<Blackboard> blackboard;
|
||||
Map<String, StringName> handlers;
|
||||
// Guard *guard;
|
||||
GuardCallback guard;
|
||||
|
||||
protected:
|
||||
friend LimboHSM;
|
||||
|
@ -51,7 +58,9 @@ public:
|
|||
String event_finished() const { return EVENT_FINISHED; }
|
||||
LimboState *get_root() const;
|
||||
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();
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue