diff options
author | Marco Trevisan (TreviƱo) <mail@3v1n0.net> | 2022-06-09 05:07:15 +0200 |
---|---|---|
committer | Philip Chimento <philip.chimento@gmail.com> | 2022-11-16 21:41:21 -0800 |
commit | 58269399ff3ffded19db3821786f14c9e34e84db (patch) | |
tree | ff5a4b04274363ca3c16e4efd7f00b3d541909f0 /modules | |
parent | 9437fd81e22bd4a12b24ce8c54ac9682c8b68586 (diff) | |
download | gjs-58269399ff3ffded19db3821786f14c9e34e84db.tar.gz |
signals: Use a Dict to associate connection IDs to objects
We often reference connection IDs, so now we can use a more optimized
native way to handle connections without having to iterate them all the
times.
This could have been implemented using the newer Map() object, but sadly
it's still way slower than using normal objects.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/core/_signals.js | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/modules/core/_signals.js b/modules/core/_signals.js index e0449706..286fdb8a 100644 --- a/modules/core/_signals.js +++ b/modules/core/_signals.js @@ -20,44 +20,43 @@ function _connect(name, callback) { // we instantiate the "signal machinery" only on-demand if anything // gets connected. if (this._signalConnections === undefined) { - this._signalConnections = []; + this._signalConnections = Object.create(null); this._nextConnectionId = 1; } const id = this._nextConnectionId; this._nextConnectionId += 1; - // this makes it O(n) in total connections to emit, but I think - // it's right to optimize for low memory and reentrancy-safety - // rather than speed - this._signalConnections.push({ - id, + this._signalConnections[id] = { name, callback, - }); + }; return id; } function _disconnect(id) { - const connectionIdx = this._signalConnections?.findIndex(c => c.id === id); + const connection = this._signalConnections?.[id]; - if (connectionIdx === undefined || connectionIdx === -1) + if (!connection) throw new Error(`No signal connection ${id} found`); - const connection = this._signalConnections[connectionIdx]; if (connection.disconnected) throw new Error(`Signal handler id ${id} already disconnected`); connection.disconnected = true; - this._signalConnections.splice(connectionIdx, 1); + delete this._signalConnections[id]; } function _signalHandlerIsConnected(id) { - return !!this._signalConnections?.some(c => c.id === id && !c.disconnected); + const connection = this._signalConnections?.[id]; + return !!connection && !connection.disconnected; } function _disconnectAll() { - this._signalConnections?.forEach(c => (c.disconnected = true)); + if (!this._signalConnections) + return; + + Object.values(this._signalConnections).forEach(c => (c.disconnected = true)); delete this._signalConnections; } @@ -70,7 +69,8 @@ function _emit(name, ...args) { // emitting), we copy out a list of what was connected // at emission start; and just before invoking each // handler we check its disconnected flag. - const handlers = this._signalConnections.filter(c => c.name === name); + const handlers = Object.values(this._signalConnections).filter( + c => c.name === name); // create arg array which is emitter + everything passed in except // signal name. Would be more convenient not to pass emitter to |