Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delayed Automatic Transition Priorities #148

Open
laurentsenta opened this issue Oct 8, 2024 · 1 comment
Open

Delayed Automatic Transition Priorities #148

laurentsenta opened this issue Oct 8, 2024 · 1 comment
Labels
bug Something isn't working question Further information is requested

Comments

@laurentsenta
Copy link

Hi there, thanks for maintaining the library,

I'm confused how to deal with delayed automatic transitions,

A behavior I'm trying to implement:
CleanShot 2024-10-08 at 16 01 48@2x

My main issue is with the Explore state and transition:

on_target_reached is a transition with event: target_reached and delay: 4.0s
on_timeout_think_again is a transition with no event and delay: 8.0s

My expectation:

  • when we enter the Explore state, the timeout is scheduled, and taken after 8.0s if nothing happens.
  • if we receive the target_reached signal after a second (for example), we schedule that transition and take it after 4.0s. That transition is supposed to "complete" earlier.

What happens (0.17.0):

  • When we enter the Explore state, the timeout is scheduled and taken regardless of target_reached events.

It seems like a bug, doc says:

If a transition has a time delay, it will be marked as pending and executed after the time delay has elapsed but only if the state to which the transition belongs is still active at this time and was not left temporarily. Only one transition can ever be active or pending for any given state. So if another transition is executed for a state while one is pending, the pending transition will be discarded.

Would it be possible to configure/fix this behavior?

@derkork
Copy link
Owner

derkork commented Oct 9, 2024

Your expectations are correct here, whenever a new transition is taken while another one is pending this new transition should replace the pending one.

However I can't seem to reproduce the behaviour you have observed. I have written a test to check for this:

extends StateChartTestBase

# Checks that multiple delayed transitions work.
# https://github.com/derkork/godot-statecharts/issues/148
func test_multiple_delayed_transitions_work():
	var root := compound_state("root")
	
	var think := atomic_state("think", root)
	var explore := atomic_state("explore", root)
	var inspect := atomic_state("inspect", root)
	
	transition(think, explore, "pick_destination")
	transition( explore, inspect, "target_reached", "1.0")
	transition( explore, think, "", "2.0")
	
	await finish_setup()
	
	assert_active(think)	

	# when I pick a destination
	send_event("pick_destination")
	
	# then I should be exploring
	assert_active(explore)
	
	# when I now reach the target
	await wait_seconds(1.1, "wait for target reached")
	send_event("target_reached")
	
	# then after 1 second I should be inspecting
	await wait_seconds(1.1, "wait for inspect")
	assert_active(inspect)

and the test works with 0.17.0. So I also re-built the setup manually with some buttons to trigger the events and there it also works as expected.

2024-10-09_12-12-13.mp4

Could you check the history tab in the state chart debugger? This tab shows all incoming events and reactions to them, so maybe you can see there what causes your problem. My guess would be a typo in the event name for on_target_reached.

@derkork derkork added bug Something isn't working question Further information is requested labels Oct 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants