Skip to content

Commit 133933b

Browse files
committed
X.on now always allocates an array - tidies up code (fix espruino#2559)
1 parent b88a4d1 commit 133933b

File tree

3 files changed

+26
-26
lines changed

3 files changed

+26
-26
lines changed

ChangeLog

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
Network: enable parsing of 'https' URL and TLS flag even even TLS not built in (#2410)
3838
removeListener while executing events no longer stops subsequent listeners from executing (#2151)
3939
jsvObjectIterator is now safe even if not called on something iterable
40+
X.on now always allocates an array - tidies up code (fix #2559)
4041

4142
2v24 : Bangle.js2: Add 'Bangle.touchRd()', 'Bangle.touchWr()'
4243
Bangle.js2: After Bangle.showTestScreen, put Bangle.js into a hard off state (not soft off)

src/jswrap_object.c

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "jswrapper.h"
2020
#include "jswrap_stream.h"
2121
#include "jswrap_functions.h"
22+
#include "jswrap_array.h" // for splice
2223
#ifdef __MINGW32__
2324
#include "malloc.h" // needed for alloca
2425
#endif//__MINGW32__
@@ -889,23 +890,22 @@ void jswrap_object_on_X(JsVar *parent, JsVar *event, JsVar *listener, bool addFi
889890
JsVar *eventList = jsvFindChildFromVar(parent, eventName, true);
890891
jsvUnLock(eventName);
891892
JsVar *eventListeners = jsvSkipName(eventList);
893+
// if no array, add it
892894
if (jsvIsUndefined(eventListeners)) {
893-
// just add the one handler on its own
894-
jsvSetValueOfName(eventList, listener);
895-
} else {
896-
// we already have an array and we just add to it
897-
// OR it's not an array but we need to make it an array
898-
JsVar *arr = jsvNewEmptyArray();
899-
if (addFirst) jsvArrayPush(arr, listener);
900-
if (jsvIsArray(eventListeners))
901-
jsvArrayPushAll(arr, eventListeners, false);
902-
else
903-
jsvArrayPush(arr, eventListeners);
904-
if (!addFirst) jsvArrayPush(arr, listener);
905-
jsvSetValueOfName(eventList, arr);
906-
jsvUnLock(arr);
895+
eventListeners = jsvNewEmptyArray();
896+
jsvSetValueOfName(eventList, eventListeners);
897+
}
898+
jsvUnLock(eventList);
899+
if (!eventListeners) return; // out of memory
900+
// now have an array and we just add to it
901+
if (addFirst) { // add it first?
902+
JsVar *elements = jsvNewArray(&listener, 1);
903+
jswrap_array_unshift(eventListeners, elements);
904+
jsvUnLock(elements);
905+
} else { // or add it at the end
906+
jsvArrayPush(eventListeners, listener);
907907
}
908-
jsvUnLock2(eventListeners, eventList);
908+
jsvUnLock(eventListeners);
909909
/* Special case if we're a data listener and data has already arrived then
910910
* we queue an event immediately. */
911911
if (jsvIsStringEqual(event, "data")) {
@@ -1033,16 +1033,12 @@ void jswrap_object_removeListener(JsVar *parent, JsVar *event, JsVar *callback)
10331033
jsvUnLock(eventName);
10341034
JsVar *eventList = jsvSkipName(eventListName);
10351035
if (eventList) {
1036-
if (eventList == callback) {
1037-
// there's no array, it was a single item
1038-
jsvRemoveChild(parent, eventListName);
1039-
} else if (jsvIsArray(eventList)) {
1036+
if (jsvIsArray(eventList)) {
10401037
// it's an array, search for the index
10411038
JsVar *idx = jsvGetIndexOf(eventList, callback, true);
1042-
if (idx) {
1039+
if (idx)
10431040
jsvRemoveChildAndUnLock(eventList, idx);
1044-
}
1045-
}
1041+
} // otherwise something is wrong, but lets just ignore it
10461042
jsvUnLock(eventList);
10471043
}
10481044
jsvUnLock(eventListName);

tests/test_eventemitter_removeListener.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ var a = {}; // should be EventEmitter, but currently all objects have it
88

99
a.on("data", foo);
1010
a.emit("data", 8);
11-
a.removeListener("data", foo);
12-
a.emit("data", 9);
13-
11+
// we need a delay, because events are processed in the next idle loop
12+
// and if we remove the listener before then, it won't get the event
1413
setTimeout(function() {
15-
result = x==42;
14+
a.removeListener("data", foo);
15+
a.emit("data", 9);
1616
}, 1);
17+
setTimeout(function() {
18+
result = x==42;
19+
}, 2);

0 commit comments

Comments
 (0)