]> gitweb.factorcode.org Git - factor.git/blob - extra/game-loop/game-loop.factor
Merge branch 'master' of git://factorcode.org/git/factor
[factor.git] / extra / game-loop / game-loop.factor
1 USING: accessors destructors kernel math math.order namespaces
2 system threads ;
3 IN: game-loop
4
5 TUPLE: game-loop
6     { tick-length integer read-only }
7     delegate
8     { last-tick integer }
9     thread 
10     { running? boolean }
11     { tick-number integer }
12     { frame-number integer }
13     { benchmark-time integer }
14     { benchmark-tick-number integer }
15     { benchmark-frame-number integer } ;
16
17 GENERIC: tick* ( delegate -- )
18 GENERIC: draw* ( tick-slice delegate -- )
19
20 SYMBOL: game-loop
21
22 : since-last-tick ( loop -- milliseconds )
23     last-tick>> millis swap - ;
24
25 : tick-slice ( loop -- slice )
26     [ since-last-tick ] [ tick-length>> ] bi /f 1.0 min ;
27
28 CONSTANT: MAX-FRAMES-TO-SKIP 5
29
30 <PRIVATE
31
32 : redraw ( loop -- )
33     [ 1+ ] change-frame-number
34     [ tick-slice ] [ delegate>> ] bi draw* ;
35
36 : tick ( loop -- )
37     delegate>> tick* ;
38
39 : increment-tick ( loop -- )
40     [ 1+ ] change-tick-number
41     dup tick-length>> [ + ] curry change-last-tick
42     drop ;
43
44 : ?tick ( loop count -- )
45     dup zero? [ drop millis >>last-tick drop ] [
46         over [ since-last-tick ] [ tick-length>> ] bi >=
47         [ [ drop increment-tick ] [ drop tick ] [ 1- ?tick ] 2tri ]
48         [ 2drop ] if
49     ] if ;
50
51 : (run-loop) ( loop -- )
52     dup running?>>
53     [ [ MAX-FRAMES-TO-SKIP ?tick ] [ redraw ] [ yield (run-loop) ] tri ]
54     [ drop ] if ;
55
56 : run-loop ( loop -- )
57     dup game-loop [ (run-loop) ] with-variable ;
58
59 : benchmark-millis ( loop -- millis )
60     millis swap benchmark-time>> - ;
61
62 PRIVATE>
63
64 : reset-loop-benchmark ( loop -- )
65     millis >>benchmark-time
66     dup tick-number>> >>benchmark-tick-number
67     dup frame-number>> >>benchmark-frame-number
68     drop ;
69
70 : benchmark-ticks-per-second ( loop -- n )
71     [ tick-number>> ] [ benchmark-tick-number>> - ] [ benchmark-millis ] tri /f ;
72 : benchmark-frames-per-second ( loop -- n )
73     [ frame-number>> ] [ benchmark-frame-number>> - ] [ benchmark-millis ] tri /f ;
74
75 : start-loop ( loop -- )
76     millis >>last-tick
77     t >>running?
78     [ reset-loop-benchmark ]
79     [ [ run-loop ] curry "game loop" spawn ]
80     [ (>>thread) ] tri ;
81
82 : stop-loop ( loop -- )
83     f >>running?
84     f >>thread
85     drop ;
86
87 : <game-loop> ( tick-length delegate -- loop )
88     millis f f 0 0 millis 0 0
89     game-loop boa ;
90
91 M: game-loop dispose
92     stop-loop ;
93