1 ! (c)2009 Joe Groff bsd license
2 USING: accessors calendar continuations destructors kernel math
3 math.order namespaces system threads ui ui.gadgets.worlds
8 { tick-interval-micros integer read-only }
14 { tick-number integer }
15 { frame-number integer }
16 { benchmark-time integer }
17 { benchmark-tick-number integer }
18 { benchmark-frame-number integer } ;
20 GENERIC: tick* ( delegate -- )
21 GENERIC: draw* ( tick-slice delegate -- )
25 : since-last-tick ( loop -- microseconds )
26 last-tick>> system-micros swap - ;
28 : tick-slice ( loop -- slice )
29 [ since-last-tick ] [ tick-interval-micros>> ] bi /f 1.0 min ;
31 CONSTANT: MAX-FRAMES-TO-SKIP 5
35 TUPLE: game-loop-error game-loop error ;
37 : ?ui-error ( error -- )
38 ui-running? [ ui-error ] [ rethrow ] if ;
40 : game-loop-error ( game-loop error -- )
41 [ drop stop-loop ] [ \ game-loop-error boa ?ui-error ] 2bi ;
43 : fps ( fps -- micros )
44 1,000,000 swap /i ; inline
49 [ 1 + ] change-frame-number
50 [ tick-slice ] [ draw-delegate>> ] bi draw* ;
53 tick-delegate>> tick* ;
55 : increment-tick ( loop -- )
56 [ 1 + ] change-tick-number
57 dup tick-interval-micros>> [ + ] curry change-last-tick
60 : ?tick ( loop count -- )
61 [ system-micros >>last-tick drop ] [
62 over [ since-last-tick ] [ tick-interval-micros>> ] bi >=
63 [ [ drop increment-tick ] [ drop tick ] [ 1 - ?tick ] 2tri ]
67 : (run-loop) ( loop -- )
69 [ [ MAX-FRAMES-TO-SKIP ?tick ] [ redraw ] [ yield (run-loop) ] tri ]
72 : run-loop ( loop -- )
74 [ [ (run-loop) ] [ game-loop-error ] recover ]
77 : benchmark-micros ( loop -- micros )
78 system-micros swap benchmark-time>> - ;
82 : reset-loop-benchmark ( loop -- )
83 system-micros >>benchmark-time
84 dup tick-number>> >>benchmark-tick-number
85 dup frame-number>> >>benchmark-frame-number
88 : benchmark-ticks-per-second ( loop -- n )
89 [ tick-number>> ] [ benchmark-tick-number>> - ] [ benchmark-micros ] tri /f ;
90 : benchmark-frames-per-second ( loop -- n )
91 [ frame-number>> ] [ benchmark-frame-number>> - ] [ benchmark-micros ] tri /f ;
93 : start-loop ( loop -- )
94 system-micros >>last-tick
96 [ reset-loop-benchmark ]
97 [ [ run-loop ] curry "game loop" spawn ]
100 : stop-loop ( loop -- )
105 : <game-loop*> ( tick-interval-micros tick-delegate draw-delegate -- loop )
106 system-micros f f 0 0 system-micros 0 0
109 : <game-loop> ( tick-interval-micros delegate -- loop )
110 dup <game-loop*> ; inline
117 { "game.loop" "prettyprint" } "game.loop.prettyprint" require-when