11namespace user_interface_base {
2- /** TODO: Make an assert, since these priorities must be multiples of 10: */
3- const PRIORITY_DELTA = 10
4- const INPUT_PRIORITY = 10
5- const UPDATE_PRIORITY = 20
6- const RENDER_PRIORITY = 10
7- const SCREEN_PRIORITY = 100
8- const PRIORITIES = [ INPUT_PRIORITY , UPDATE_PRIORITY , RENDER_PRIORITY , SCREEN_PRIORITY ]
9-
10- /**
11- * Top-level abstraction drawn to the screen.
12- * Extended by CursorScene when you want to have a GUI with Button support.
13- * Useful if you: don't want buttons, aren't making a GUI, or to make a more complex GUI.
14- * CursorScene overwrites a number of these abstract methods.
15- */
16- export abstract class Scene implements IComponent {
17- private xfrm_ : Affine
18- private color_ : number
19- private backgroundCaptured_ = false
20-
21- //% blockCombine block="xfrm" callInDebugger
22- public get xfrm ( ) {
23- return this . xfrm_
24- }
25- //% blockCombine block="color" callInDebugger
26- public get backgroundColor ( ) {
27- return this . color_
28- }
29- public set backgroundColor ( v ) {
30- this . color_ = v
31- }
2+ const INPUT_PRIORITY = 10
3+ const UPDATE_PRIORITY = 20
4+ const RENDER_PRIORITY = 30
5+ const SCREEN_PRIORITY = 100
326
33- constructor ( public app ?: AppInterface , public name ?: string ) {
34- this . xfrm_ = new Affine ( )
35- this . color_ = 12
36- }
7+ /**
8+ * Top-level abstraction drawn to the screen.
9+ * Extended by CursorScene when you want to have a GUI with Button support.
10+ * Useful if you: don't want buttons, aren't making a GUI, or to make a more complex GUI.
11+ * CursorScene overwrites a number of these abstract methods.
12+ */
13+ export abstract class Scene implements IComponent {
14+ private xfrm_ : Affine
15+ private color_ : number
16+ private backgroundCaptured_ = false
17+
18+ //% blockCombine block="xfrm" callInDebugger
19+ public get xfrm ( ) {
20+ return this . xfrm_
21+ }
22+ //% blockCombine block="color" callInDebugger
23+ public get backgroundColor ( ) {
24+ return this . color_
25+ }
26+ public set backgroundColor ( v ) {
27+ this . color_ = v
28+ }
29+
30+ constructor ( public app ?: AppInterface , public name ?: string ) {
31+ this . xfrm_ = new Affine ( )
32+ this . color_ = 12
33+ }
3734
3835 /* abstract */ startup ( ) {
39- if ( Options . menuProfiling ) {
40- context . onEvent (
41- ControllerButtonEvent . Pressed ,
42- controller . menu . id ,
43- ( ) => {
44- control . heapSnapshot ( )
45- }
46- )
47- }
48- }
36+ if ( Options . menuProfiling ) {
37+ context . onEvent (
38+ ControllerButtonEvent . Pressed ,
39+ controller . menu . id ,
40+ ( ) => {
41+ control . heapSnapshot ( )
42+ }
43+ )
44+ }
45+ }
4946
5047 /* abstract */ shutdown ( ) { }
5148
5249 /* override */ activate ( ) {
53- profile ( )
54- }
50+ profile ( )
51+ }
5552
5653 /* override */ deactivate ( ) {
57- profile ( )
58- }
54+ profile ( )
55+ }
5956
6057 /* abstract */ update ( ) { }
6158
6259 /* abstract */ draw ( ) { }
6360
64- protected handleClick ( x : number , y : number ) { }
61+ protected handleClick ( x : number , y : number ) { }
6562
66- protected handleMove ( x : number , y : number ) { }
63+ protected handleMove ( x : number , y : number ) { }
6764
68- protected handleWheel ( dx : number , dy : number ) { }
65+ protected handleWheel ( dx : number , dy : number ) { }
6966
70- get backgroundCaptured ( ) {
71- return ! ! this . backgroundCaptured_
72- }
73-
74- /**
75- * Captures the current screen image as background image. You must call releaseBackground to resume usual rendering.
76- */
77- captureBackground ( ) {
78- this . backgroundCaptured_ = true
79- }
80-
81- releaseBackground ( ) {
82- this . backgroundCaptured_ = false
83- }
84-
85- __init ( ) {
86- let TIME : number = 0 ;
87- const MIN_PRIORITY : number = PRIORITIES . reduce ( ( a , b ) => Math . min ( a , b ) , PRIORITIES [ 0 ] ) ;
88- const MAX_PRIORITY : number = PRIORITIES . reduce ( ( a , b ) => Math . max ( a , b ) , PRIORITIES [ 0 ] ) ;
89-
90- control . enablePerfCounter ( )
91- context . eventContext ( ) . registerFrameHandler ( MIN_PRIORITY , ( ) => {
92- if ( TIME % INPUT_PRIORITY === 0 ) {
93- const dtms = ( context . eventContext ( ) . deltaTime * 1000 ) | 0
94- controller . left . __update ( dtms )
95- controller . right . __update ( dtms )
96- controller . up . __update ( dtms )
97- controller . down . __update ( dtms )
67+ get backgroundCaptured ( ) {
68+ return ! ! this . backgroundCaptured_
9869 }
9970
100- if ( TIME % UPDATE_PRIORITY === 0 ) {
101- this . update ( )
71+ /**
72+ * Captures the current screen image as background image. You must call releaseBackground to resume usual rendering.
73+ */
74+ captureBackground ( ) {
75+ this . backgroundCaptured_ = true
10276 }
10377
104- if ( TIME % RENDER_PRIORITY === 0 ) {
105- // perf: render directly on the background image buffer
106- this . draw ( )
107- if ( Options . fps )
108- Screen . image . print ( context . EventContext . lastStats , 1 , 1 , 15 )
109- if ( screen ( ) !== Screen . image )
110- screen ( ) . drawBitmap ( Screen . image , 0 , 0 )
111-
112- // control.__screen.update(); // not neccessary?
78+ releaseBackground ( ) {
79+ this . backgroundCaptured_ = false
11380 }
11481
115- TIME = ( TIME + PRIORITY_DELTA ) % ( MAX_PRIORITY ) ;
116- } )
117- }
118- }
119-
120-
121- /**
122- * This is an wrapper around a stack of scenes.
123- * You can .push() and .pop() scenes to navigator your application.
124- * In a microbit App this SceneManager is setup in app.ts,
125- * which has a wrapper around SceneManager methods.
126- * The app object is normally passed as a reference between scenes,
127- * so that they can access this SceneManager.
128- */
129- export class SceneManager {
130- private scenes : Scene [ ]
131-
132- constructor ( ) {
133- this . scenes = [ ]
82+ __init ( ) {
83+ context . eventContext ( ) . registerFrameHandler ( INPUT_PRIORITY , ( ) => {
84+ control . enablePerfCounter ( )
85+ const dtms = ( context . eventContext ( ) . deltaTime * 1000 ) | 0
86+ controller . left . __update ( dtms )
87+ controller . right . __update ( dtms )
88+ controller . up . __update ( dtms )
89+ controller . down . __update ( dtms )
90+ } )
91+ // Setup frame callbacks.
92+ context . eventContext ( ) . registerFrameHandler ( UPDATE_PRIORITY , ( ) => {
93+ control . enablePerfCounter ( )
94+ this . update ( )
95+ } )
96+ context . eventContext ( ) . registerFrameHandler ( RENDER_PRIORITY , ( ) => {
97+ control . enablePerfCounter ( )
98+ // perf: render directly on the background image buffer
99+ this . draw ( )
100+ if ( Options . fps )
101+ Screen . image . print ( context . EventContext . lastStats , 1 , 1 , 15 )
102+ if ( screen ( ) !== Screen . image )
103+ screen ( ) . drawBitmap ( Screen . image , 0 , 0 )
104+ } )
105+ context . eventContext ( ) . registerFrameHandler ( SCREEN_PRIORITY , ( ) => {
106+ control . enablePerfCounter ( )
107+ control . __screen . stop ( )
108+ control . __screen . update ( )
109+ } )
110+ }
134111 }
135112
136- public pushScene ( scene : Scene ) {
137- const currScene = this . currScene ( )
138- if ( currScene ) {
139- currScene . deactivate ( )
140- }
141- context . pushEventContext ( )
142- this . scenes . push ( scene )
143- scene . startup ( )
144- scene . activate ( )
145- scene . __init ( )
146- }
113+ /**
114+ * This is an wrapper around a stack of scenes.
115+ * You can .push() and .pop() scenes to navigator your application.
116+ * In a microbit App this SceneManager is setup in app.ts,
117+ * which has a wrapper around SceneManager methods.
118+ * The app object is normally passed as a reference between scenes,
119+ * so that they can access this SceneManager.
120+ */
121+ export class SceneManager {
122+ scenes : Scene [ ]
123+
124+ constructor ( ) {
125+ this . scenes = [ ]
126+ }
147127
148- public popScene ( ) {
149- const prevScene = this . scenes . pop ( )
150- if ( prevScene ) {
151- prevScene . deactivate ( )
152- prevScene . shutdown ( )
153- context . popEventContext ( )
154- }
155- const currScene = this . currScene ( )
156- if ( currScene ) {
157- currScene . activate ( )
158- }
159- }
128+ public pushScene ( scene : Scene ) {
129+ const currScene = this . currScene ( )
130+ if ( currScene ) {
131+ currScene . deactivate ( )
132+ }
133+ context . pushEventContext ( )
134+ this . scenes . push ( scene )
135+ scene . startup ( )
136+ scene . activate ( )
137+ scene . __init ( )
138+ }
160139
161- private currScene ( ) : Scene {
162- if ( this . scenes . length ) {
163- return this . scenes [ this . scenes . length - 1 ]
140+ public popScene ( ) {
141+ const prevScene = this . scenes . pop ( )
142+ if ( prevScene ) {
143+ prevScene . deactivate ( )
144+ prevScene . shutdown ( )
145+ context . popEventContext ( )
146+ }
147+ const currScene = this . currScene ( )
148+ if ( currScene ) {
149+ currScene . activate ( )
150+ }
151+ }
152+
153+ private currScene ( ) : Scene {
154+ if ( this . scenes . length ) {
155+ return this . scenes [ this . scenes . length - 1 ]
156+ }
157+ return undefined
158+ }
164159 }
165- return undefined
166- }
167- }
168- }
160+ }
0 commit comments