pxt-common-packages 12.2.13 → 12.2.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -356,6 +356,10 @@ declare namespace pxsim.browserEvents {
356
356
  interface BrowserEventsBoard extends CommonBoard {
357
357
  mouseState: MouseState;
358
358
  }
359
+ const INTERNAL_KEY_DOWN = 6870;
360
+ const INTERNAL_KEY_UP = 6871;
361
+ const INTERNAL_POINTER_DOWN = 6868;
362
+ const INTERNAL_POINTER_UP = 6869;
359
363
  type MouseEvent = "pointerdown" | "pointerup" | "pointermove" | "pointerleave" | "pointerenter" | "pointercancel" | "pointerover" | "pointerout";
360
364
  class MouseState {
361
365
  protected x: number;
@@ -843,10 +843,10 @@ var pxsim;
843
843
  browserEvents.onKeyboardEvent = onKeyboardEvent;
844
844
  function fireEvent(key, pressed) {
845
845
  if (pressed) {
846
- pxsim.board().bus.queue(6866, key);
846
+ pxsim.board().bus.queue(browserEvents.INTERNAL_KEY_DOWN, key);
847
847
  }
848
848
  else {
849
- pxsim.board().bus.queue(6867, key);
849
+ pxsim.board().bus.queue(browserEvents.INTERNAL_KEY_UP, key);
850
850
  }
851
851
  }
852
852
  function getValueForKey(event) {
@@ -1040,6 +1040,10 @@ var pxsim;
1040
1040
  var browserEvents;
1041
1041
  (function (browserEvents) {
1042
1042
  const THROTTLE_INTERVAL = 50;
1043
+ browserEvents.INTERNAL_KEY_DOWN = 6870;
1044
+ browserEvents.INTERNAL_KEY_UP = 6871;
1045
+ browserEvents.INTERNAL_POINTER_DOWN = 6868;
1046
+ browserEvents.INTERNAL_POINTER_UP = 6869;
1043
1047
  class MouseState {
1044
1048
  constructor() {
1045
1049
  this.onMove = pxsim.U.throttle(() => {
@@ -1062,9 +1066,16 @@ var pxsim;
1062
1066
  "pointerover",
1063
1067
  "pointerout",
1064
1068
  ];
1069
+ let eventId = 6857 + events.indexOf(event.type);
1070
+ if (event.type === "pointerdown") {
1071
+ eventId = browserEvents.INTERNAL_POINTER_DOWN;
1072
+ }
1073
+ else if (event.type === "pointerup") {
1074
+ eventId = browserEvents.INTERNAL_POINTER_UP;
1075
+ }
1065
1076
  // We add 1 to the button here because the left button is 0 and
1066
1077
  // that's used as a wildcard in our event bus
1067
- pxsim.board().bus.queue(6857 + events.indexOf(event.type), (event.button || 0) + 1);
1078
+ pxsim.board().bus.queue(eventId, (event.button || 0) + 1);
1068
1079
  }
1069
1080
  onWheelEvent(dx, dy, dz) {
1070
1081
  this.dx = dx;
@@ -48,40 +48,50 @@ namespace browserEvents {
48
48
  Released = Event.PointerUp,
49
49
  }
50
50
 
51
+ //% whenUsed
52
+ const INTERNAL_POINTER_DOWN = 6868;
53
+ //% whenUsed
54
+ const INTERNAL_POINTER_UP = 6869;
55
+
56
+ type MouseHandler = (x: number, y: number) => void;
57
+
51
58
  //% fixedInstances
52
59
  export class MouseButton {
53
60
  protected _pressed: boolean;
54
- protected pressHandler: (x: number, y: number) => void;
55
- protected pressListeners: ((x: number, y: number) => void)[];
56
- protected releaseHandler: (x: number, y: number) => void;
57
- protected releaseListeners: ((x: number, y: number) => void)[];
61
+
62
+ protected sceneStack: _SceneButtonHandlers<MouseHandler>[];
63
+
64
+ protected get state(): _SceneButtonHandlers<MouseHandler> {
65
+ return this.sceneStack[this.sceneStack.length - 1];
66
+ }
58
67
 
59
68
  constructor(public id: number) {
60
- control.internalOnEvent(Event.PointerDown, this.id, () => this.setPressed(true), 16);
61
- control.internalOnEvent(Event.PointerUp, this.id, () => this.setPressed(false), 16);
69
+ control.internalOnEvent(INTERNAL_POINTER_DOWN, this.id, () => this.setPressed(true), 16);
70
+ control.internalOnEvent(INTERNAL_POINTER_UP, this.id, () => this.setPressed(false), 16);
62
71
 
63
72
  this._pressed = false;
64
- this.pressListeners = [];
65
- this.releaseListeners = [];
73
+
74
+ this.sceneStack = [new _SceneButtonHandlers<MouseHandler>(id, invokeMouseHandler)];
75
+
76
+ game.addScenePushHandler(() => {
77
+ this.sceneStack.push(new _SceneButtonHandlers<MouseHandler>(id, invokeMouseHandler));
78
+ });
79
+ game.addScenePopHandler(() => {
80
+ this.sceneStack.pop();
81
+ if (this.sceneStack.length === 0) {
82
+ this.sceneStack = [new _SceneButtonHandlers<MouseHandler>(id, invokeMouseHandler)];
83
+ }
84
+ });
66
85
  }
67
86
 
68
87
  setPressed(pressed: boolean) {
69
88
  this._pressed = pressed;
89
+
70
90
  if (pressed) {
71
- if (this.pressHandler) {
72
- this.pressHandler(mouseX(), mouseY());
73
- }
74
- for (const handler of this.pressListeners) {
75
- handler(mouseX(), mouseY());
76
- }
91
+ control.raiseEvent(MouseButtonEvent.Pressed, this.id);
77
92
  }
78
93
  else {
79
- if (this.releaseHandler) {
80
- this.releaseHandler(mouseX(), mouseY());
81
- }
82
- for (const handler of this.releaseListeners) {
83
- handler(mouseX(), mouseY());
84
- }
94
+ control.raiseEvent(MouseButtonEvent.Released, this.id);
85
95
  }
86
96
  }
87
97
 
@@ -91,12 +101,7 @@ namespace browserEvents {
91
101
  //% group="Mouse"
92
102
  //% weight=50
93
103
  onEvent(event: MouseButtonEvent, handler: (x: number, y: number) => void) {
94
- if (event === MouseButtonEvent.Pressed) {
95
- this.pressHandler = handler;
96
- }
97
- else {
98
- this.releaseHandler = handler;
99
- }
104
+ this.state.onEvent(event, handler);
100
105
  }
101
106
 
102
107
  //% blockId=browserEvents_mouseButton_isPressed
@@ -116,24 +121,72 @@ namespace browserEvents {
116
121
  }
117
122
 
118
123
  addEventListener(event: MouseButtonEvent, handler: (x: number, y: number) => void) {
119
- if (event === MouseButtonEvent.Pressed) {
120
- this.pressListeners.push(handler);
121
- }
122
- else {
123
- this.releaseListeners.push(handler);
124
- }
124
+ this.state.addEventListener(event, handler);
125
125
  }
126
126
 
127
127
  removeEventListener(event: MouseButtonEvent, handler: (x: number, y: number) => void) {
128
- if (event === MouseButtonEvent.Pressed) {
129
- this.pressListeners = this.pressListeners.filter(p => p !== handler);
128
+ this.state.removeEventListener(event, handler);
129
+ }
130
+ }
131
+
132
+ export class _SceneButtonHandlers<U> {
133
+ protected handlers: ButtonHandler<U>[];
134
+
135
+ constructor(public id: number, protected invokeHandler: (handler: U) => void) {
136
+ this.handlers = [];
137
+ }
138
+
139
+ onEvent(event: number, handler: U) {
140
+ this.getHandler(event, true).handler = handler;
141
+ }
142
+
143
+ addEventListener(event: number, handler: U) {
144
+ this.getHandler(event, true).listeners.push(handler);
145
+ }
146
+
147
+ removeEventListener(event: number, handler: U) {
148
+ const eventHandler = this.getHandler(event);
149
+
150
+ if (eventHandler) {
151
+ eventHandler.listeners = eventHandler.listeners.filter(h => h !== handler);
130
152
  }
131
- else {
132
- this.releaseListeners = this.releaseListeners.filter(p => p !== handler);
153
+ }
154
+
155
+ protected getHandler(event: number, createIfMissing?: boolean) {
156
+ for (const handler of this.handlers) {
157
+ if (handler.event === event) return handler;
133
158
  }
159
+
160
+ if (createIfMissing) {
161
+ const newHandler = new ButtonHandler<U>(event, this.id, this.invokeHandler);
162
+ this.handlers.push(newHandler);
163
+ return newHandler;
164
+ }
165
+
166
+ return undefined;
134
167
  }
135
168
  }
136
169
 
170
+ class ButtonHandler<U> {
171
+ handler: U;
172
+ listeners: U[] = [];
173
+
174
+ constructor(public readonly event: number, id: number, invokeHandler: (handler: U) => void) {
175
+ control.onEvent(event, id, () => {
176
+ if (this.handler) {
177
+ invokeHandler(this.handler);
178
+ }
179
+ for (const listener of this.listeners) {
180
+ invokeHandler(listener);
181
+ }
182
+ });
183
+ }
184
+ }
185
+
186
+ function invokeMouseHandler(handler: MouseHandler) {
187
+ handler(mouseX(), mouseY());
188
+ }
189
+
137
190
  //% blockId=browserEvents_onEvent
138
191
  //% block="on browser event $event"
139
192
  //% draggableParameters="reporter"
@@ -73,13 +73,18 @@ namespace browserEvents {
73
73
 
74
74
  export enum KeyEvent {
75
75
  //% block="pressed"
76
- Pressed,
76
+ Pressed = 6872,
77
77
  //% block="released"
78
- Released,
78
+ Released = 6873,
79
79
  //% block="repeat"
80
- Repeat
80
+ Repeat = 6874
81
81
  }
82
82
 
83
+ //% whenUsed
84
+ const INTERNAL_KEY_DOWN = 6870;
85
+ //% whenUsed
86
+ const INTERNAL_KEY_UP = 6871;
87
+
83
88
  export function keyToString(key: Key) {
84
89
  switch (key) {
85
90
  case Key.Q:
@@ -229,83 +234,7 @@ namespace browserEvents {
229
234
  let defaultRepeatDelay = 500;
230
235
  let defaultRepeatInterval = 30;
231
236
 
232
- class KeySceneState {
233
- protected pressHandler: () => void;
234
- protected pressListeners: (() => void)[];
235
- protected releaseHandler: () => void;
236
- protected releaseListeners: (() => void)[];
237
- protected repeatHandler: () => void;
238
- protected repeatListeners: (() => void)[];
239
-
240
- constructor(public id: number) {
241
- this.pressListeners = [];
242
- this.releaseListeners = [];
243
- this.repeatListeners = [];
244
- }
245
-
246
- onEvent(event: KeyEvent, handler: () => void) {
247
- if (event === KeyEvent.Pressed) {
248
- this.pressHandler = handler;
249
- }
250
- else if (event === KeyEvent.Released) {
251
- this.releaseHandler = handler;
252
- }
253
- else {
254
- this.repeatHandler = handler;
255
- }
256
- }
257
-
258
- addEventListener(event: KeyEvent, handler: () => void) {
259
- if (event === KeyEvent.Pressed) {
260
- this.pressListeners.push(handler);
261
- }
262
- else if (event === KeyEvent.Released) {
263
- this.releaseListeners.push(handler);
264
- }
265
- else {
266
- this.repeatListeners.push(handler);
267
- }
268
- }
269
-
270
- removeEventListener(event: KeyEvent, handler: () => void) {
271
- if (event === KeyEvent.Pressed) {
272
- this.pressListeners = this.pressListeners.filter(p => p !== handler);
273
- }
274
- else if (event === KeyEvent.Released) {
275
- this.releaseListeners = this.releaseListeners.filter(p => p !== handler);;
276
- }
277
- else {
278
- this.repeatListeners = this.repeatListeners.filter(p => p !== handler);
279
- }
280
- }
281
-
282
- raiseButtonPressed() {
283
- if (this.pressHandler) {
284
- this.pressHandler();
285
- }
286
- for (const handler of this.pressListeners) {
287
- handler();
288
- }
289
- }
290
-
291
- raiseButtonReleased() {
292
- if (this.releaseHandler) {
293
- this.releaseHandler();
294
- }
295
- for (const handler of this.releaseListeners) {
296
- handler();
297
- }
298
- }
299
-
300
- raiseButtonRepeat() {
301
- if (this.repeatHandler) {
302
- this.repeatHandler();
303
- }
304
- for (const handler of this.repeatListeners) {
305
- handler();
306
- }
307
- }
308
- }
237
+ type KeyHandler = () => void;
309
238
 
310
239
  //% fixedInstances
311
240
  export class KeyButton {
@@ -315,16 +244,16 @@ namespace browserEvents {
315
244
  private _repeatCount: number;
316
245
  private _pressedElapsed: number;
317
246
 
318
- protected sceneStack: KeySceneState[];
247
+ protected sceneStack: _SceneButtonHandlers<KeyHandler>[];
319
248
 
320
- protected get state(): KeySceneState {
249
+ protected get state(): _SceneButtonHandlers<KeyHandler> {
321
250
  return this.sceneStack[this.sceneStack.length - 1];
322
251
  }
323
252
 
324
253
  constructor(public id: number) {
325
- // use internalOnEvent so that events fire regardless of the current scen
326
- control.internalOnEvent(Event.KeyUp, this.id, () => this.setPressed(false), 16);
327
- control.internalOnEvent(Event.KeyDown, this.id, () => this.setPressed(true), 16);
254
+ // use internalOnEvent so that events fire regardless of the current scene
255
+ control.internalOnEvent(INTERNAL_KEY_UP, this.id, () => this.setPressed(false), 16);
256
+ control.internalOnEvent(INTERNAL_KEY_DOWN, this.id, () => this.setPressed(true), 16);
328
257
  this._pressed = false;
329
258
 
330
259
  // this code may run before game/scene.ts, in which case calling this.__registerUpdate
@@ -347,16 +276,16 @@ namespace browserEvents {
347
276
  _buttonsPendingInit.push(this);
348
277
  }
349
278
 
350
- this.sceneStack = [new KeySceneState(id)];
279
+ this.sceneStack = [new _SceneButtonHandlers<KeyHandler>(id, invokeKeyHandler)];
351
280
 
352
281
  game.addScenePushHandler(() => {
353
- this.sceneStack.push(new KeySceneState(id));
282
+ this.sceneStack.push(new _SceneButtonHandlers<KeyHandler>(id, invokeKeyHandler));
354
283
  this.__registerUpdate();
355
284
  });
356
285
  game.addScenePopHandler(() => {
357
286
  this.sceneStack.pop();
358
287
  if (this.sceneStack.length === 0) {
359
- this.sceneStack = [new KeySceneState(id)];
288
+ this.sceneStack = [new _SceneButtonHandlers<KeyHandler>(id, invokeKeyHandler)];
360
289
  this.__registerUpdate();
361
290
  }
362
291
  });
@@ -369,10 +298,10 @@ namespace browserEvents {
369
298
  if (pressed) {
370
299
  this._repeatCount = 0;
371
300
  this._pressedElapsed = 0;
372
- this.state.raiseButtonPressed();
301
+ control.raiseEvent(KeyEvent.Pressed, this.id);
373
302
  }
374
303
  else {
375
- this.state.raiseButtonReleased();
304
+ control.raiseEvent(KeyEvent.Released, this.id);
376
305
  }
377
306
  }
378
307
 
@@ -422,7 +351,7 @@ namespace browserEvents {
422
351
  const count = Math.floor((this._pressedElapsed - delay - interval) / interval);
423
352
  if (count != this._repeatCount) {
424
353
  this._repeatCount = count;
425
- this.state.raiseButtonRepeat();
354
+ control.raiseEvent(KeyEvent.Repeat, this.id);
426
355
  }
427
356
  }
428
357
 
@@ -431,6 +360,10 @@ namespace browserEvents {
431
360
  }
432
361
  }
433
362
 
363
+ function invokeKeyHandler(handler: KeyHandler) {
364
+ handler();
365
+ }
366
+
434
367
  //% fixedInstance whenUsed
435
368
  export const A = new KeyButton(Key.A);
436
369
 
@@ -96,10 +96,10 @@ namespace pxsim.browserEvents {
96
96
 
97
97
  function fireEvent(key: Key, pressed: boolean) {
98
98
  if (pressed) {
99
- board().bus.queue(6866, key);
99
+ board().bus.queue(INTERNAL_KEY_DOWN, key);
100
100
  }
101
101
  else {
102
- board().bus.queue(6867, key);
102
+ board().bus.queue(INTERNAL_KEY_UP, key);
103
103
  }
104
104
  }
105
105
 
@@ -5,6 +5,11 @@ namespace pxsim.browserEvents {
5
5
 
6
6
  const THROTTLE_INTERVAL = 50;
7
7
 
8
+ export const INTERNAL_KEY_DOWN = 6870;
9
+ export const INTERNAL_KEY_UP = 6871;
10
+ export const INTERNAL_POINTER_DOWN = 6868;
11
+ export const INTERNAL_POINTER_UP = 6869;
12
+
8
13
  export type MouseEvent = "pointerdown" | "pointerup" | "pointermove" | "pointerleave" | "pointerenter" | "pointercancel" | "pointerover" | "pointerout";
9
14
  export class MouseState {
10
15
  protected x: number;
@@ -43,10 +48,19 @@ namespace pxsim.browserEvents {
43
48
  "pointerout",
44
49
  ];
45
50
 
51
+ let eventId = 6857 + events.indexOf(event.type);
52
+
53
+ if (event.type === "pointerdown") {
54
+ eventId = INTERNAL_POINTER_DOWN;
55
+ }
56
+ else if (event.type === "pointerup") {
57
+ eventId = INTERNAL_POINTER_UP;
58
+ }
59
+
46
60
  // We add 1 to the button here because the left button is 0 and
47
61
  // that's used as a wildcard in our event bus
48
62
  board().bus.queue(
49
- 6857 + events.indexOf(event.type),
63
+ eventId,
50
64
  (event.button || 0) + 1
51
65
  );
52
66
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pxt-common-packages",
3
- "version": "12.2.13",
3
+ "version": "12.2.14",
4
4
  "description": "Microsoft MakeCode (PXT) common packages",
5
5
  "keywords": [
6
6
  "MakeCode",