@makefully/platypus 4.1.17 → 4.1.20

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makefully/platypus",
3
- "version": "4.1.17",
3
+ "version": "4.1.20",
4
4
  "description": "2D tile-based HTML5 game engine with a component-based entity model",
5
5
  "license": "MIT",
6
6
  "contributors": [
@@ -82,7 +82,7 @@
82
82
  },
83
83
  "optionalDependencies": {
84
84
  "box2d3-wasm": "^4.2.0",
85
- "jsmediatags": "github:probityrules/jsmediatags",
85
+ "@probityrules/jsmediatags": "^4.0.4",
86
86
  "poly-decomp": "^0.3.0"
87
87
  },
88
88
  "engines": {
package/src/Component.js CHANGED
@@ -64,9 +64,15 @@ export default class Component {
64
64
  if (this.listener) {
65
65
  const
66
66
  publicMethods = this.publicMethods,
67
- keys = Object.keys(publicMethods);
67
+ keys = Object.keys(publicMethods),
68
+ // Detach first so re-entrant removeEventListener during teardown
69
+ // cannot read a recycled listener's deleted `events` array.
70
+ listener = this.listener,
71
+ {events, messages} = listener;
68
72
  let i = keys.length;
69
73
 
74
+ this.listener = null;
75
+
70
76
  // Handle component's destroy method before removing messaging and methods.
71
77
  if (this._destroy) {
72
78
  this._destroy();
@@ -77,12 +83,21 @@ export default class Component {
77
83
  this.removeMethod(keys[i]);
78
84
  }
79
85
  this.publicMethods.recycle();
80
-
81
- this.removeEventListeners();
82
- arrayCache.recycle(this.listener.events);
83
- arrayCache.recycle(this.listener.messages);
84
- this.listener.recycle();
85
- this.listener = null;
86
+
87
+ if (events && messages) {
88
+ const
89
+ {owner} = this,
90
+ {length} = events;
91
+
92
+ for (let j = 0; j < length; j++) {
93
+ owner.off(events[j], messages[j]);
94
+ }
95
+ events.length = 0;
96
+ messages.length = 0;
97
+ arrayCache.recycle(events);
98
+ arrayCache.recycle(messages);
99
+ }
100
+ listener.recycle();
86
101
  }
87
102
  }
88
103
 
@@ -96,7 +111,13 @@ export default class Component {
96
111
  removeEventListeners (listeners) {
97
112
  if (!listeners) {
98
113
  const
99
- {listener, owner} = this,
114
+ {listener, owner} = this;
115
+
116
+ if (!listener?.events || !listener.messages) {
117
+ return;
118
+ }
119
+
120
+ const
100
121
  {events, messages} = listener,
101
122
  {length} = events;
102
123
 
@@ -188,7 +209,13 @@ export default class Component {
188
209
  */
189
210
  removeEventListener (event, callback) {
190
211
  const
191
- {listener, owner} = this,
212
+ {listener, owner} = this;
213
+
214
+ if (!listener?.events || !listener.messages) {
215
+ return;
216
+ }
217
+
218
+ const
192
219
  {events, messages} = listener;
193
220
 
194
221
  for (let i = events.length - 1; i >= 0; i--) {
@@ -298,13 +298,15 @@ export default createComponentClass(/** @lends platypus.components.AudioSFX.prot
298
298
  const
299
299
  key = keys[i],
300
300
  sound = audioMap[key],
301
+ // Must match the resolved id stored on clips in playSound / stopAudio.
302
+ soundId = platypus.assetCache.getFileId(sound.sound ?? sound),
301
303
  playClip = playSound(sound);
302
304
 
303
305
  if (this.eventBased) {
304
306
  this.addEventListener(key, playClip);
305
307
  }
306
308
  if (this.stateBased) {
307
- this.addStateCheck(key, sound.sound ?? sound, playClip);
309
+ this.addStateCheck(key, soundId, playClip);
308
310
  }
309
311
  }
310
312
  }
@@ -623,7 +625,7 @@ export default createComponentClass(/** @lends platypus.components.AudioSFX.prot
623
625
  if (active) {
624
626
  play.call(this);
625
627
  } else {
626
- this.stopAudio(audioId, this.forcePlaythrough);
628
+ this.stopAudio(audioId, this.forcePlayThrough);
627
629
  }
628
630
  checkData.playing = active;
629
631
  }