@makefully/platypus 4.1.19 → 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.19",
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": [
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--) {