Skip to content

Instantly share code, notes, and snippets.

@firebelley
Created August 27, 2024 21:18
Show Gist options
  • Select an option

  • Save firebelley/96f2f82e3feaa2756fe647d8b9843174 to your computer and use it in GitHub Desktop.

Select an option

Save firebelley/96f2f82e3feaa2756fe647d8b9843174 to your computer and use it in GitHub Desktop.
class_name CallableStateMachine
var state_dictionary = {}
var current_state: String
func add_states(
normal_state_callable: Callable,
enter_state_callable: Callable,
leave_state_callable: Callable
):
state_dictionary[normal_state_callable.get_method()] = {
"normal": normal_state_callable,
"enter": enter_state_callable,
"leave": leave_state_callable
}
func set_initial_state(state_callable: Callable):
var state_name = state_callable.get_method()
if state_dictionary.has(state_name):
_set_state(state_name)
else:
push_warning("No state with name " + state_name)
func update():
if current_state != null:
(state_dictionary[current_state].normal as Callable).call()
func change_state(state_callable: Callable):
var state_name = state_callable.get_method()
if state_dictionary.has(state_name):
_set_state.call_deferred(state_name)
else:
push_warning("No state with name " + state_name)
func _set_state(state_name: String):
if current_state:
var leave_callable = state_dictionary[current_state].leave as Callable
if !leave_callable.is_null():
leave_callable.call()
current_state = state_name
var enter_callable = state_dictionary[current_state].enter as Callable
if !enter_callable.is_null():
enter_callable.call()
@qaptoR

qaptoR commented Jun 7, 2026

Copy link
Copy Markdown

I really don't like to duplicate code. I tested this on a small setup (just a ready function that calls them both) and it works

func set_initial_state(state_callable: Callable):
    change_state(state_callable, _set_state)


func change_state(state_callable: Callable, caller_ :Callable = _set_state.call_deferred):
    var state_name = state_callable.get_method()
    if state_dictionary.has(state_name):
        caller_.call(state_name)
    else:
        push_warning("No state with name " + state_name)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment