tool class_name StateChart, "state_chart.svg" extends Node ## whether chart should propagate processing events every frame export var idle_frame_event: bool = false export var physics_frame_event: bool = false # root state of the state chart var _state: State = null # values available to expression guards var _guard_properties: Dictionary = {} func _ready() -> void: if Engine.editor_hint: return # make sure only one child exists if get_child_count() != 1: push_error("StateChart must have exactly one child") return # verify child is a State var child = get_child(0) if not child is State: push_error("StateChart's child must be a State") return # initialize states _state = child as State _state._state_init() # enter root state _state._state_enter() ## sends an event to be propagated through the states func send_event(event: String) -> void: if not is_instance_valid(_state): push_error("StateChart is not initialized properly") return _state._state_event(event) ## sets a property available to guard expressions in transitions func set_guard_property(property: String, value) -> void: _guard_properties[property] = value func _get_configuration_warning() -> String: if get_child_count() != 1: return "StateChart must have exactly one child" if not get_child(0) is State: return "StateChart's child must be a State" return "" # send frame events that transition can listen to if it should evaluate # its guard every frame func _process(delta: float) -> void: if idle_frame_event: send_event("idle_frame") func _physics_process(delta: float) -> void: if physics_frame_event: send_event("physics_frame")