forked from team-sg/hero-mark-2
statecharts ehehehehehe
This commit is contained in:
parent
4d59717b88
commit
6eff1601a9
23 changed files with 895 additions and 2 deletions
126
addons/godot_state_charts/state.gd
Normal file
126
addons/godot_state_charts/state.gd
Normal file
|
@ -0,0 +1,126 @@
|
|||
tool
|
||||
class_name State
|
||||
extends Node
|
||||
|
||||
## called when state is entered
|
||||
signal state_entered()
|
||||
|
||||
## called when state is exited
|
||||
signal state_exited()
|
||||
|
||||
## called when state recieves an event while active
|
||||
signal event_received(event)
|
||||
|
||||
## called when the state is processing
|
||||
signal state_processing(delta)
|
||||
|
||||
## called when the state is physics_processing
|
||||
signal state_physics_processing(delta)
|
||||
|
||||
## processing mode
|
||||
enum ProcessMode {IDLE, PHYSICS}
|
||||
|
||||
## whether to process transition delays during physics or idle frames
|
||||
export (ProcessMode) var transition_process_mode: int = ProcessMode.PHYSICS
|
||||
|
||||
## whether the current state is active
|
||||
var active: bool setget _set_active
|
||||
func _set_active(value: bool):
|
||||
active = value
|
||||
set_process(value)
|
||||
set_physics_process(value)
|
||||
|
||||
## all of the state's transitions
|
||||
var _transitions: Array = []
|
||||
## queued transition to take
|
||||
var _queued_transition: Transition = null
|
||||
## time until queued transition is taken
|
||||
var _queued_transition_time: float = 0.0
|
||||
|
||||
## called when building the state chart
|
||||
func _state_init() -> void:
|
||||
_set_active(false)
|
||||
|
||||
# get references to transitions
|
||||
_transitions.clear()
|
||||
for child in get_children():
|
||||
if child is Transition:
|
||||
_transitions.append(child as Transition)
|
||||
|
||||
## called when state is entered
|
||||
func _state_enter() -> void:
|
||||
_set_active(true)
|
||||
emit_signal("state_entered")
|
||||
|
||||
# check eventless transitions
|
||||
for transition in _transitions:
|
||||
if not transition.has_event() and transition.evaluate_guard():
|
||||
# first match is taken
|
||||
_queue_transition(transition)
|
||||
|
||||
## called when state is exited
|
||||
func _state_exit() -> void:
|
||||
_set_active(false)
|
||||
emit_signal("state_exited")
|
||||
|
||||
## handles given event. returns true if it is consumed
|
||||
func _state_event(event: String) -> bool:
|
||||
if not active:
|
||||
return false
|
||||
|
||||
# emit event received signal
|
||||
emit_signal("event_received", event)
|
||||
|
||||
#check for transitions reacting to event
|
||||
for transition in _transitions:
|
||||
if transition.event == event and transition.evaluate_guard():
|
||||
# first match is taken
|
||||
_queue_transition(transition)
|
||||
return true
|
||||
return false
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if Engine.editor_hint:
|
||||
return
|
||||
|
||||
# emit processing signal
|
||||
emit_signal("state_processing")
|
||||
|
||||
# process transitions if mode is IDLE
|
||||
if transition_process_mode == ProcessMode.IDLE:
|
||||
_process_transition(delta)
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if Engine.editor_hint:
|
||||
return
|
||||
|
||||
# emit physics processing signal
|
||||
emit_signal("state_processing")
|
||||
|
||||
# process transitions if mode is PHYSICS
|
||||
if transition_process_mode == ProcessMode.PHYSICS:
|
||||
_process_transition(delta)
|
||||
|
||||
## queues a transition to be taken
|
||||
func _queue_transition(transition: Transition) -> void:
|
||||
_queued_transition = transition
|
||||
_queued_transition_time = transition.delay
|
||||
|
||||
## checks for and processes queued transition
|
||||
func _process_transition(delta: float) -> void:
|
||||
# check for queued transition
|
||||
if _queued_transition != null:
|
||||
_queued_transition_time -= delta
|
||||
# if ready, handle transition and clear queue
|
||||
if _queued_transition_time <= 0.0:
|
||||
var transition = _queued_transition
|
||||
_queued_transition = null
|
||||
_queued_transition_time = 0.0
|
||||
_handle_transition(transition, self)
|
||||
|
||||
## attempts to take transition
|
||||
func _handle_transition(transition: Transition, source: State) -> void:
|
||||
push_error("state %s cannot handle transitions" % name)
|
||||
|
||||
func _get_configuration_warning() -> String:
|
||||
return ""
|
Loading…
Add table
Add a link
Reference in a new issue