Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions addons/beehave/nodes/decorators/cooldown.gd
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ func tick(actor: Node, blackboard: Blackboard) -> int:
running_child = c
if c is ActionLeaf:
blackboard.set_value("running_action", c, str(actor.get_instance_id()))

if response != RUNNING:
else:
c.after_run(actor, blackboard)
blackboard.set_value(cache_key, wait_time, str(actor.get_instance_id()))

return response
9 changes: 5 additions & 4 deletions addons/beehave/nodes/decorators/delayer.gd
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@ func tick(actor: Node, blackboard: Blackboard) -> int:
blackboard.set_value("last_condition", c, str(actor.get_instance_id()))
blackboard.set_value("last_condition_status", response, str(actor.get_instance_id()))

if response == RUNNING and c is ActionLeaf:
if response == RUNNING:
running_child = c
blackboard.set_value("running_action", c, str(actor.get_instance_id()))

if response != RUNNING:
if c is ActionLeaf:
blackboard.set_value("running_action", c, str(actor.get_instance_id()))
else:
c.after_run(actor, blackboard)
blackboard.set_value(cache_key, 0.0, str(actor.get_instance_id()))

return response
2 changes: 2 additions & 0 deletions addons/beehave/nodes/decorators/until_fail.gd
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ func tick(actor: Node, blackboard: Blackboard) -> int:
blackboard.set_value("running_action", c, str(actor.get_instance_id()))
return RUNNING
if response == SUCCESS:
c.after_run(actor, blackboard)
return RUNNING

c.after_run(actor, blackboard)
return SUCCESS
3 changes: 3 additions & 0 deletions test/actions/mock_action.gd
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ signal stopped_running(actor, blackboard)
signal interrupted(actor, blackboard)

var tick_count: int = 0
var after_run_called: bool = false


func before_run(actor: Node, blackboard: Blackboard) -> void:
tick_count = 0
after_run_called = false
started_running.emit(actor, blackboard)


Expand All @@ -30,4 +32,5 @@ func interrupt(actor: Node, blackboard: Blackboard) -> void:

func after_run(actor: Node, blackboard: Blackboard) -> void:
tick_count = 0
after_run_called = true
stopped_running.emit(actor, blackboard)
48 changes: 47 additions & 1 deletion test/nodes/decorators/cooldown_test.gd
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,50 @@ func test_interrupt_propagates_when_composite() -> void:

func _on_interrupted(_actor, blackboard):
var started = blackboard.get_value("interrupted", 0)
blackboard.set_value("interrupted", started + 1)
blackboard.set_value("interrupted", started + 1)

func test_after_run_called_on_success() -> void:
cooldown.wait_time = 1.0
action.final_result = BeehaveNode.SUCCESS

# First tick should execute child and call after_run
assert_that(tree.tick()).is_equal(BeehaveNode.SUCCESS)
assert_bool(action.after_run_called).is_true()

# Reset after_run_called flag since before_run will be called on next tick
action.after_run_called = false

# Second tick should be in cooldown and not call after_run
assert_that(tree.tick()).is_equal(BeehaveNode.FAILURE)
assert_bool(action.after_run_called).is_false()

func test_after_run_called_on_failure() -> void:
cooldown.wait_time = 1.0
action.final_result = BeehaveNode.FAILURE

# First tick should execute child and call after_run
assert_that(tree.tick()).is_equal(BeehaveNode.FAILURE)
assert_bool(action.after_run_called).is_true()

# Reset after_run_called flag since before_run will be called on next tick
action.after_run_called = false

# Second tick should be in cooldown and not call after_run
assert_that(tree.tick()).is_equal(BeehaveNode.FAILURE)
assert_bool(action.after_run_called).is_false()

func test_after_run_not_called_during_cooldown() -> void:
cooldown.wait_time = 1.0
action.final_result = BeehaveNode.SUCCESS

# First tick should execute child and call after_run
assert_that(tree.tick()).is_equal(BeehaveNode.SUCCESS)
assert_bool(action.after_run_called).is_true()

# Reset after_run_called flag since before_run will be called on next tick
action.after_run_called = false

# Wait a bit but not enough to complete cooldown
await runner.simulate_frames(1, 500)
assert_that(tree.tick()).is_equal(BeehaveNode.FAILURE)
assert_bool(action.after_run_called).is_false() # Should not call after_run during cooldown
51 changes: 44 additions & 7 deletions test/nodes/decorators/delayer_test.gd
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ extends GdUnitTestSuite

# TestSuite generated from
const __source = "res://addons/beehave/nodes/decorators/delayer.gd"
const __action = "res://test/actions/count_up_action.gd"
const __action = "res://test/actions/mock_action.gd"
const __tree = "res://addons/beehave/nodes/beehave_tree.gd"
const __blackboard = "res://addons/beehave/blackboard.gd"

var tree: BeehaveTree
var action: ActionLeaf
var action: MockAction
var delayer: DelayDecorator
var runner: GdUnitSceneRunner

Expand All @@ -34,7 +34,7 @@ func before_test() -> void:

func test_return_success_after_delay() -> void:
delayer.wait_time = get_physics_process_delta_time()
action.status = BeehaveNode.SUCCESS
action.final_result = BeehaveNode.SUCCESS
assert_that(tree.tick()).is_equal(BeehaveNode.RUNNING)
assert_that(tree.tick()).is_equal(BeehaveNode.SUCCESS)
# Assure that the delayer properly resets
Expand All @@ -44,16 +44,53 @@ func test_return_success_after_delay() -> void:

func test_return_running_after_delay() -> void:
delayer.wait_time = 1.0
action.status = BeehaveNode.RUNNING
action.final_result = BeehaveNode.RUNNING
assert_that(tree.tick()).is_equal(BeehaveNode.RUNNING)
await runner.simulate_frames(1, 1000)
assert_that(tree.tick()).is_equal(BeehaveNode.RUNNING)
action.status = BeehaveNode.SUCCESS
action.final_result = BeehaveNode.SUCCESS
assert_that(tree.tick()).is_equal(BeehaveNode.SUCCESS)
# Assure that the delayer properly resets
action.status = BeehaveNode.RUNNING
action.final_result = BeehaveNode.RUNNING
assert_that(tree.tick()).is_equal(BeehaveNode.RUNNING)
await runner.simulate_frames(1, 1000)
assert_that(tree.tick()).is_equal(BeehaveNode.RUNNING)
action.status = BeehaveNode.SUCCESS
action.final_result = BeehaveNode.SUCCESS
assert_that(tree.tick()).is_equal(BeehaveNode.SUCCESS)

func test_after_run_called_on_success() -> void:
delayer.wait_time = get_physics_process_delta_time()
action.final_result = BeehaveNode.SUCCESS

# First tick should be in delay
assert_that(tree.tick()).is_equal(BeehaveNode.RUNNING)
assert_bool(action.after_run_called).is_false()

# Second tick should execute child and call after_run
assert_that(tree.tick()).is_equal(BeehaveNode.SUCCESS)
assert_bool(action.after_run_called).is_true()

func test_after_run_called_on_failure() -> void:
delayer.wait_time = get_physics_process_delta_time()
action.final_result = BeehaveNode.FAILURE

# First tick should be in delay
assert_that(tree.tick()).is_equal(BeehaveNode.RUNNING)
assert_bool(action.after_run_called).is_false()

# Second tick should execute child and call after_run
assert_that(tree.tick()).is_equal(BeehaveNode.FAILURE)
assert_bool(action.after_run_called).is_true()

func test_after_run_not_called_during_delay() -> void:
delayer.wait_time = 1.0
action.final_result = BeehaveNode.SUCCESS

# First tick should be in delay
assert_that(tree.tick()).is_equal(BeehaveNode.RUNNING)
assert_bool(action.after_run_called).is_false()

# Wait a bit but not enough to complete delay
await runner.simulate_frames(1, 500)
assert_that(tree.tick()).is_equal(BeehaveNode.RUNNING)
assert_bool(action.after_run_called).is_false()
36 changes: 31 additions & 5 deletions test/nodes/decorators/until_fail_test.gd
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ extends GdUnitTestSuite

# TestSuite generated from
const __source = "res://addons/beehave/nodes/decorators/until_fail.gd"
const __action = "res://test/actions/count_up_action.gd"
const __action = "res://test/actions/mock_action.gd"
const __tree = "res://addons/beehave/nodes/beehave_tree.gd"
const __blackboard = "res://addons/beehave/blackboard.gd"

var tree: BeehaveTree
var action: ActionLeaf
var action: MockAction
var until_fail: UntilFailDecorator


Expand All @@ -31,15 +31,41 @@ func before_test() -> void:


func test_failure() -> void:
action.status = BeehaveNode.RUNNING
action.final_result = BeehaveNode.RUNNING

for i in range(100):
assert_that(tree.tick()).is_equal(BeehaveNode.RUNNING)

action.status = BeehaveNode.SUCCESS
action.final_result = BeehaveNode.SUCCESS

for i in range(100):
assert_that(tree.tick()).is_equal(BeehaveNode.RUNNING)

action.status = BeehaveNode.FAILURE
action.final_result = BeehaveNode.FAILURE
assert_that(tree.tick()).is_equal(BeehaveNode.SUCCESS)

func test_after_run_called_on_success() -> void:
action.final_result = BeehaveNode.SUCCESS

# Child succeeds, decorator returns RUNNING
assert_that(tree.tick()).is_equal(BeehaveNode.RUNNING)
assert_bool(action.after_run_called).is_true()

func test_after_run_called_on_failure() -> void:
action.final_result = BeehaveNode.FAILURE

# Child fails, decorator returns SUCCESS
assert_that(tree.tick()).is_equal(BeehaveNode.SUCCESS)
assert_bool(action.after_run_called).is_true()

func test_after_run_not_called_during_running() -> void:
action.final_result = BeehaveNode.RUNNING

# Child is running, decorator returns RUNNING
assert_that(tree.tick()).is_equal(BeehaveNode.RUNNING)
assert_bool(action.after_run_called).is_false()

# Change to success, should call after_run
action.final_result = BeehaveNode.SUCCESS
assert_that(tree.tick()).is_equal(BeehaveNode.RUNNING)
assert_bool(action.after_run_called).is_true()