Merge pull request #101 from limbonaut/unit-tests
Add tests for nested HSM flow, tests for dispatch() and get_root(), and fix BBParam saved_value initializing to null
This commit is contained in:
commit
69e921be31
|
@ -79,6 +79,9 @@ Variant BBParam::get_value(Object *p_agent, const Ref<Blackboard> &p_blackboard,
|
|||
ERR_FAIL_COND_V(!p_blackboard.is_valid(), p_default);
|
||||
|
||||
if (value_source == SAVED_VALUE) {
|
||||
if (saved_value == Variant()) {
|
||||
_assign_default_value();
|
||||
}
|
||||
return saved_value;
|
||||
} else {
|
||||
ERR_FAIL_COND_V_MSG(!p_blackboard->has_var(variable), p_default, vformat("BBParam: Blackboard variable \"%s\" doesn't exist.", variable));
|
||||
|
@ -114,6 +117,4 @@ void BBParam::_bind_methods() {
|
|||
|
||||
BBParam::BBParam() {
|
||||
value_source = SAVED_VALUE;
|
||||
|
||||
_assign_default_value();
|
||||
}
|
||||
|
|
|
@ -17,8 +17,14 @@
|
|||
#include "core/object/ref_counted.h"
|
||||
#include "core/string/node_path.h"
|
||||
#include "core/variant/variant.h"
|
||||
#include "modules/limboai/blackboard/bb_param/bb_bool.h"
|
||||
#include "modules/limboai/blackboard/bb_param/bb_float.h"
|
||||
#include "modules/limboai/blackboard/bb_param/bb_int.h"
|
||||
#include "modules/limboai/blackboard/bb_param/bb_node.h"
|
||||
#include "modules/limboai/blackboard/bb_param/bb_param.h"
|
||||
#include "modules/limboai/blackboard/bb_param/bb_string.h"
|
||||
#include "modules/limboai/blackboard/bb_param/bb_variant.h"
|
||||
#include "modules/limboai/blackboard/bb_param/bb_vector2.h"
|
||||
#include "modules/limboai/blackboard/blackboard.h"
|
||||
#include "modules/limboai/bt/tasks/bt_task.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
@ -122,6 +128,68 @@ TEST_CASE("[Modules][LimboAI] BBNode") {
|
|||
memdelete(dummy);
|
||||
}
|
||||
|
||||
TEST_CASE("[Modules][LimboAI] BBParam default values") {
|
||||
Node *dummy = memnew(Node);
|
||||
Ref<Blackboard> bb = memnew(Blackboard);
|
||||
|
||||
SUBCASE("Test default value for BBBool") {
|
||||
Ref<BBBool> param = memnew(BBBool);
|
||||
param->set_value_source(BBParam::SAVED_VALUE);
|
||||
CHECK_EQ(param->get_value(dummy, bb), Variant(false));
|
||||
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||
}
|
||||
SUBCASE("Test default value for BBInt") {
|
||||
Ref<BBInt> param = memnew(BBInt);
|
||||
param->set_value_source(BBParam::SAVED_VALUE);
|
||||
CHECK_EQ(param->get_value(dummy, bb), Variant(0));
|
||||
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||
}
|
||||
SUBCASE("Test default value for BBFloat") {
|
||||
Ref<BBFloat> param = memnew(BBFloat);
|
||||
param->set_value_source(BBParam::SAVED_VALUE);
|
||||
CHECK_EQ(param->get_value(dummy, bb), Variant(0.0));
|
||||
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||
}
|
||||
SUBCASE("Test default value for BBString") {
|
||||
Ref<BBString> param = memnew(BBString);
|
||||
param->set_value_source(BBParam::SAVED_VALUE);
|
||||
CHECK_EQ(param->get_value(dummy, bb), Variant(""));
|
||||
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||
}
|
||||
SUBCASE("Test default value for BBVector2") {
|
||||
Ref<BBVector2> param = memnew(BBVector2);
|
||||
param->set_value_source(BBParam::SAVED_VALUE);
|
||||
CHECK_EQ(param->get_value(dummy, bb), Variant(Vector2()));
|
||||
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||
}
|
||||
SUBCASE("Test default value for BBVariant") {
|
||||
Ref<BBVariant> param = memnew(BBVariant);
|
||||
CHECK_EQ(param->get_value(dummy, bb), Variant());
|
||||
param->set_value_source(BBParam::SAVED_VALUE);
|
||||
CHECK_EQ(param->get_value(dummy, bb), Variant());
|
||||
param->set_type(Variant::BOOL);
|
||||
CHECK_EQ(param->get_value(dummy, bb), Variant(false));
|
||||
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||
param->set_type(Variant::INT);
|
||||
CHECK_EQ(param->get_value(dummy, bb), Variant(0));
|
||||
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||
param->set_type(Variant::FLOAT);
|
||||
CHECK_EQ(param->get_value(dummy, bb), Variant(0.0));
|
||||
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||
param->set_type(Variant::STRING);
|
||||
CHECK_EQ(param->get_value(dummy, bb), Variant(""));
|
||||
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||
param->set_type(Variant::VECTOR2);
|
||||
CHECK_EQ(param->get_value(dummy, bb), Variant(Vector2()));
|
||||
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||
param->set_type(Variant::NODE_PATH);
|
||||
CHECK_EQ(param->get_value(dummy, bb), Variant(NodePath()));
|
||||
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||
}
|
||||
|
||||
memdelete(dummy);
|
||||
}
|
||||
|
||||
} //namespace TestBBParam
|
||||
|
||||
#endif // TEST_BB_PARAM_H
|
||||
|
|
|
@ -24,6 +24,12 @@
|
|||
|
||||
namespace TestHSM {
|
||||
|
||||
inline void wire_callbacks(LimboState *p_state, Ref<CallbackCounter> p_entries_counter, Ref<CallbackCounter> p_updates_counter, Ref<CallbackCounter> p_exits_counter) {
|
||||
p_state->call_on_enter(callable_mp(p_entries_counter.ptr(), &CallbackCounter::callback));
|
||||
p_state->call_on_update(callable_mp(p_updates_counter.ptr(), &CallbackCounter::callback_delta));
|
||||
p_state->call_on_exit(callable_mp(p_exits_counter.ptr(), &CallbackCounter::callback));
|
||||
}
|
||||
|
||||
class TestGuard : public RefCounted {
|
||||
GDCLASS(TestGuard, RefCounted);
|
||||
|
||||
|
@ -42,22 +48,38 @@ TEST_CASE("[Modules][LimboAI] HSM") {
|
|||
Ref<CallbackCounter> beta_entries = memnew(CallbackCounter);
|
||||
Ref<CallbackCounter> beta_exits = memnew(CallbackCounter);
|
||||
Ref<CallbackCounter> beta_updates = memnew(CallbackCounter);
|
||||
Ref<CallbackCounter> nested_entries = memnew(CallbackCounter);
|
||||
Ref<CallbackCounter> nested_exits = memnew(CallbackCounter);
|
||||
Ref<CallbackCounter> nested_updates = memnew(CallbackCounter);
|
||||
Ref<CallbackCounter> gamma_entries = memnew(CallbackCounter);
|
||||
Ref<CallbackCounter> gamma_exits = memnew(CallbackCounter);
|
||||
Ref<CallbackCounter> gamma_updates = memnew(CallbackCounter);
|
||||
Ref<CallbackCounter> delta_entries = memnew(CallbackCounter);
|
||||
Ref<CallbackCounter> delta_exits = memnew(CallbackCounter);
|
||||
Ref<CallbackCounter> delta_updates = memnew(CallbackCounter);
|
||||
|
||||
LimboState *state_alpha = memnew(LimboState);
|
||||
state_alpha->call_on_enter(callable_mp(alpha_entries.ptr(), &CallbackCounter::callback));
|
||||
state_alpha->call_on_update(callable_mp(alpha_updates.ptr(), &CallbackCounter::callback_delta));
|
||||
state_alpha->call_on_exit(callable_mp(alpha_exits.ptr(), &CallbackCounter::callback));
|
||||
|
||||
wire_callbacks(state_alpha, alpha_entries, alpha_updates, alpha_exits);
|
||||
LimboState *state_beta = memnew(LimboState);
|
||||
state_beta->call_on_enter(callable_mp(beta_entries.ptr(), &CallbackCounter::callback));
|
||||
state_beta->call_on_update(callable_mp(beta_updates.ptr(), &CallbackCounter::callback_delta));
|
||||
state_beta->call_on_exit(callable_mp(beta_exits.ptr(), &CallbackCounter::callback));
|
||||
wire_callbacks(state_beta, beta_entries, beta_updates, beta_exits);
|
||||
LimboHSM *nested_hsm = memnew(LimboHSM);
|
||||
wire_callbacks(nested_hsm, nested_entries, nested_updates, nested_exits);
|
||||
LimboState *state_gamma = memnew(LimboState);
|
||||
wire_callbacks(state_gamma, gamma_entries, gamma_updates, gamma_exits);
|
||||
LimboState *state_delta = memnew(LimboState);
|
||||
wire_callbacks(state_delta, delta_entries, delta_updates, delta_exits);
|
||||
|
||||
hsm->add_child(state_alpha);
|
||||
hsm->add_child(state_beta);
|
||||
hsm->add_child(nested_hsm);
|
||||
nested_hsm->add_child(state_gamma);
|
||||
nested_hsm->add_child(state_delta);
|
||||
|
||||
hsm->add_transition(state_alpha, state_beta, "event_one");
|
||||
hsm->add_transition(state_beta, state_alpha, "event_two");
|
||||
hsm->add_transition(hsm->anystate(), nested_hsm, "goto_nested");
|
||||
nested_hsm->add_transition(state_gamma, state_delta, "goto_delta");
|
||||
nested_hsm->add_transition(state_delta, state_gamma, "goto_gamma");
|
||||
|
||||
hsm->set_initial_state(state_alpha);
|
||||
Ref<Blackboard> parent_scope = memnew(Blackboard);
|
||||
|
@ -179,6 +201,57 @@ TEST_CASE("[Modules][LimboAI] HSM") {
|
|||
CHECK(state_beta->get_blackboard()->get_parent() == parent_scope);
|
||||
CHECK(state_alpha->get_blackboard()->get_var("parent_var", Variant()) == Variant(100));
|
||||
}
|
||||
SUBCASE("Test flow with a nested HSM, and test dispatch() from nested states") {
|
||||
state_gamma->dispatch("goto_nested");
|
||||
CHECK(hsm->get_leaf_state() == state_gamma);
|
||||
CHECK(nested_entries->num_callbacks == 1);
|
||||
CHECK(nested_updates->num_callbacks == 0);
|
||||
CHECK(nested_exits->num_callbacks == 0);
|
||||
CHECK(gamma_entries->num_callbacks == 1);
|
||||
CHECK(gamma_updates->num_callbacks == 0);
|
||||
CHECK(gamma_exits->num_callbacks == 0);
|
||||
|
||||
hsm->update(0.01666);
|
||||
CHECK(nested_entries->num_callbacks == 1);
|
||||
CHECK(nested_updates->num_callbacks == 1);
|
||||
CHECK(nested_exits->num_callbacks == 0);
|
||||
CHECK(gamma_entries->num_callbacks == 1);
|
||||
CHECK(gamma_updates->num_callbacks == 1);
|
||||
CHECK(gamma_exits->num_callbacks == 0);
|
||||
|
||||
state_gamma->dispatch("goto_delta");
|
||||
CHECK(hsm->get_leaf_state() == state_delta);
|
||||
CHECK(nested_entries->num_callbacks == 1);
|
||||
CHECK(nested_updates->num_callbacks == 1);
|
||||
CHECK(nested_exits->num_callbacks == 0);
|
||||
CHECK(gamma_entries->num_callbacks == 1);
|
||||
CHECK(gamma_updates->num_callbacks == 1);
|
||||
CHECK(gamma_exits->num_callbacks == 1);
|
||||
CHECK(delta_entries->num_callbacks == 1);
|
||||
CHECK(delta_updates->num_callbacks == 0);
|
||||
CHECK(delta_exits->num_callbacks == 0);
|
||||
|
||||
state_delta->dispatch(hsm->event_finished());
|
||||
CHECK(nested_entries->num_callbacks == 1);
|
||||
CHECK(nested_updates->num_callbacks == 1);
|
||||
CHECK(nested_exits->num_callbacks == 1);
|
||||
CHECK(gamma_entries->num_callbacks == 1);
|
||||
CHECK(gamma_updates->num_callbacks == 1);
|
||||
CHECK(gamma_exits->num_callbacks == 1);
|
||||
CHECK(delta_entries->num_callbacks == 1);
|
||||
CHECK(delta_updates->num_callbacks == 0);
|
||||
CHECK(delta_exits->num_callbacks == 1);
|
||||
CHECK(hsm->is_active() == false);
|
||||
CHECK(hsm->get_leaf_state() == hsm);
|
||||
}
|
||||
SUBCASE("Test get_root()") {
|
||||
CHECK(hsm->get_root() == hsm);
|
||||
CHECK(state_alpha->get_root() == hsm);
|
||||
CHECK(state_beta->get_root() == hsm);
|
||||
CHECK(nested_hsm->get_root() == hsm);
|
||||
CHECK(state_delta->get_root() == hsm);
|
||||
CHECK(state_gamma->get_root() == hsm);
|
||||
}
|
||||
|
||||
memdelete(agent);
|
||||
memdelete(hsm);
|
||||
|
|
Loading…
Reference in New Issue