Created
September 27, 2015 07:30
-
-
Save paniq/fd441a08c083dd321557 to your computer and use it in GitHub Desktop.
test_fsm.n
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
none | |
import-from "none.libc" printf | |
syntax-import "liminal.machine" | |
; declares a new state machine struct; all routines are compiled to machine | |
; language and the machine operates exclusively using function pointer tables | |
machine Flow | |
; a static predicate that always returns true | |
method skipmenu (ctx) : | |
bool <- (&this-struct) | |
true | |
; a bunch of events to be sent from outside | |
enum Event | |
start | |
exit | |
pause | |
gameover | |
loaded | |
frame | |
; a list of all states of the state machine | |
; also generates a "States" enum | |
states | |
main | |
boot | |
menu | |
load | |
init | |
; any additional code will be executed when the | |
; state is entered | |
run | |
printf "step!\n" | |
paused | |
printf "paused.\n" | |
unpaused | |
printf "unpaused.\n" | |
end | |
unload | |
quit | |
; a list of all transitions | |
transitions | |
; a transition without predicates happens immediately | |
main => boot | |
boot => menu | |
; transitions with predicates override transitions without. | |
; this one depends on skipmenu being true, which we defined earlier | |
boot => load | |
(self.skipmenu) | |
; a predicate number is interpreted as an event ID to check against | |
menu => quit | |
Event.exit | |
menu => load | |
Event.start | |
load => init | |
Event.loaded | |
init => run | |
run => run | |
Event.frame | |
run => end | |
Event.exit | |
Event.gameover | |
run => paused | |
Event.pause | |
paused => unpaused | |
Event.pause | |
unpaused => run | |
Event.frame | |
end => unload | |
unload => menu | |
; debug handler for all state machine changes | |
###method on-enter (self state) : | |
void <- (&this-struct this-struct.StateId) | |
; | |
escape | |
function (state) | |
print "on-enter:" | |
this-struct.State # state | |
state | |
; a small test | |
do-if (main-module?) | |
print "testing machine..." | |
; create a new instance | |
const flow : Flow | |
flow.reset ; | |
; reset and run until the first state that depends on an event (load) | |
flow.send 0 | |
assert (flow.state == Flow.State.load) | |
; indicate that the game has been loaded; prints "step!" | |
flow.send Flow.Event.loaded | |
; we should now be in the run state | |
assert (flow.state == Flow.State.run) | |
; run a few frames; prints "step!" ten times | |
loop i (1 10) | |
flow.send Flow.Event.frame | |
; simulate pausing the game; prints "paused." | |
flow.send Flow.Event.pause | |
; we should now be in the paused state | |
assert (flow.state == Flow.State.paused) | |
; run a few frames; should print nothing | |
loop i (1 10) | |
flow.send Flow.Event.frame | |
; simulate unpausing the game; prints "unpaused." | |
flow.send Flow.Event.pause | |
; we should now be in the unpaused state, waiting for the next frame | |
assert (flow.state == Flow.State.unpaused) | |
; run a few frames; prints "step!" ten times | |
loop i (1 10) | |
flow.send Flow.Event.frame | |
assert (flow.state == Flow.State.run) | |
; exit the game; prints "unloaded." | |
flow.send Flow.Event.exit | |
; we should be back in the main menu | |
assert (flow.state == Flow.State.menu) | |
null |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment