From 43cb3754d9b2f805422db65da03134ca6628ebe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Mon, 8 Jul 2019 00:01:11 +0200 Subject: [PATCH] extensionSystem: Store extensions in a Map After making the extensions map private to the ExtensionManager, we can switch it to a proper hash table which is more appropriate. https://bugzilla.gnome.org/show_bug.cgi?id=789852 --- js/misc/extensionUtils.js | 2 +- js/ui/extensionDownloader.js | 8 +++---- js/ui/extensionSystem.js | 42 ++++++++++++++++++++---------------- js/ui/lookingGlass.js | 5 +++-- js/ui/shellDBus.js | 10 ++++----- 5 files changed, 37 insertions(+), 30 deletions(-) diff --git a/js/misc/extensionUtils.js b/js/misc/extensionUtils.js index d17aee9fb..6887299bb 100644 --- a/js/misc/extensionUtils.js +++ b/js/misc/extensionUtils.js @@ -70,7 +70,7 @@ function getCurrentExtension() { // Walk up the directory tree, looking for an extension with // the same UUID as a directory name. while (file != null) { - let extension = extensionManager.extensions[file.get_basename()]; + let extension = extensionManager.lookup(file.get_basename()); if (extension !== undefined) return extension; file = file.get_parent(); diff --git a/js/ui/extensionDownloader.js b/js/ui/extensionDownloader.js index ca9de0e18..0c5bb396c 100644 --- a/js/ui/extensionDownloader.js +++ b/js/ui/extensionDownloader.js @@ -44,7 +44,7 @@ function installExtension(uuid, invocation) { } function uninstallExtension(uuid) { - let extension = Main.extensionManager.extensions[uuid]; + let extension = Main.extensionManager.lookup(uuid); if (!extension) return false; @@ -113,7 +113,7 @@ function updateExtension(uuid) { _httpSession.queue_message(message, (session, message) => { gotExtensionZipFile(session, message, uuid, newExtensionTmpDir, () => { - let oldExtension = Main.extensionManager.extensions[uuid]; + let oldExtension = Main.extensionManager.lookup(uuid); let extensionDir = oldExtension.dir; if (!Main.extensionManager.unloadExtension(oldExtension)) @@ -151,9 +151,9 @@ function updateExtension(uuid) { function checkForUpdates() { let metadatas = {}; - for (let uuid in Main.extensionManager.extensions) { + Main.extensionManager.getUuids().forEach(uuid => { metadatas[uuid] = Main.extensionManager.extensions[uuid].metadata; - } + }); let params = { shell_version: Config.PACKAGE_VERSION, installed: JSON.stringify(metadatas) }; diff --git a/js/ui/extensionSystem.js b/js/ui/extensionSystem.js index ba1d12a4e..1efb3f048 100644 --- a/js/ui/extensionSystem.js +++ b/js/ui/extensionSystem.js @@ -18,7 +18,7 @@ var ExtensionManager = class { this._initted = false; this._enabled = false; - this._extensions = {}; + this._extensions = new Map(); this._enabledExtensions = []; this._extensionOrder = []; @@ -29,12 +29,16 @@ var ExtensionManager = class { this._sessionUpdated(); } - get extensions() { - return this._extensions; + lookup(uuid) { + return this._extensions.get(uuid); + } + + getUuids() { + return [...this._extensions.keys()]; } _callExtensionDisable(uuid) { - let extension = this._extensions[uuid]; + let extension = this.lookup(uuid); if (!extension) return; @@ -56,7 +60,7 @@ var ExtensionManager = class { for (let i = 0; i < orderReversed.length; i++) { let uuid = orderReversed[i]; try { - this._extensions[uuid].stateObj.disable(); + this.lookup(uuid).stateObj.disable(); } catch (e) { this.logExtensionError(uuid, e); } @@ -77,7 +81,7 @@ var ExtensionManager = class { for (let i = 0; i < order.length; i++) { let uuid = order[i]; try { - this._extensions[uuid].stateObj.enable(); + this.lookup(uuid).stateObj.enable(); } catch (e) { this.logExtensionError(uuid, e); } @@ -92,7 +96,7 @@ var ExtensionManager = class { } _callExtensionEnable(uuid) { - let extension = this._extensions[uuid]; + let extension = this.lookup(uuid); if (!extension) return; @@ -136,7 +140,7 @@ var ExtensionManager = class { } enableExtension(uuid) { - if (!this._extensions[uuid]) + if (!this._extensions.has(uuid)) return false; let enabledExtensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY); @@ -149,7 +153,7 @@ var ExtensionManager = class { } disableExtension(uuid) { - if (!this._extensions[uuid]) + if (!this._extensions.has(uuid)) return false; let enabledExtensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY); @@ -162,7 +166,7 @@ var ExtensionManager = class { } logExtensionError(uuid, error) { - let extension = this._extensions[uuid]; + let extension = this.lookup(uuid); if (!extension) return; @@ -221,7 +225,7 @@ var ExtensionManager = class { hasPrefs: dir.get_child('prefs.js').query_exists(null), canChange: false }; - this._extensions[uuid] = extension; + this._extensions.set(uuid, extension); return extension; } @@ -259,7 +263,7 @@ var ExtensionManager = class { extension.state = ExtensionState.UNINSTALLED; this.emit('extension-state-changed', extension); - delete this._extensions[extension.uuid]; + this._extensions.delete(extension.uuid); return true; } @@ -284,7 +288,7 @@ var ExtensionManager = class { } _callExtensionInit(uuid) { - let extension = this._extensions[uuid]; + let extension = this.lookup(uuid); let dir = extension.dir; if (!extension) @@ -385,8 +389,7 @@ var ExtensionManager = class { } _onSettingsWritableChanged() { - for (let uuid in this._extensions) { - let extension = ExtensionUtils.extensions[uuid]; + for (let extension of this._extensions.values()) { this._updateCanChange(extension); this.emit('extension-state-changed', extension); } @@ -397,8 +400,11 @@ var ExtensionManager = class { // extensions when allowed by the sessionMode, so // temporarily disable them all this._enabledExtensions = []; - for (let uuid in this._extensions) - this.reloadExtension(this._extensions[uuid]); + + // The loop modifies the extensions map, so iterate over a copy + let extensions = [...this._extensions.values()]; + for (let extension of extensions) + this.reloadExtension(extension); this._enabledExtensions = this._getEnabledExtensions(); if (Main.sessionMode.allowExtensions) { @@ -426,7 +432,7 @@ var ExtensionManager = class { if (fileType != Gio.FileType.DIRECTORY) return; let uuid = info.get_name(); - let existing = this._extensions[uuid]; + let existing = this.lookup(uuid); if (existing) { log(`Extension ${uuid} already installed in ${existing.path}. ${dir.get_path()} will not be loaded`); return; diff --git a/js/ui/lookingGlass.js b/js/ui/lookingGlass.js index b99b701e1..4a6a80abd 100644 --- a/js/ui/lookingGlass.js +++ b/js/ui/lookingGlass.js @@ -624,15 +624,16 @@ var Extensions = class Extensions { this._extensionsList.add(this._noExtensions); this.actor.add(this._extensionsList); - for (let uuid in Main.extensionManager.extensions) + Main.extensionManager.getUuids().forEach(uuid => { this._loadExtension(null, uuid); + }); Main.extensionManager.connect('extension-loaded', this._loadExtension.bind(this)); } _loadExtension(o, uuid) { - let extension = Main.extensionManager.extensions[uuid]; + let extension = Main.extensionManager.lookup(uuid); // There can be cases where we create dummy extension metadata // that's not really a proper extension. Don't bother with these. if (!extension.metadata.name) diff --git a/js/ui/shellDBus.js b/js/ui/shellDBus.js index 2288d0cfd..59c569951 100644 --- a/js/ui/shellDBus.js +++ b/js/ui/shellDBus.js @@ -255,20 +255,20 @@ var GnomeShellExtensions = class { ListExtensions() { let out = {}; - for (let uuid in Main.extensionManager.extensions) { + Main.extensionManager.getUuids().forEach(uuid => { let dbusObj = this.GetExtensionInfo(uuid); out[uuid] = dbusObj; - } + }); return out; } GetExtensionInfo(uuid) { - let extension = Main.extensionManager.extensions[uuid] || {}; + let extension = Main.extensionManager.lookup(uuid) || {}; return ExtensionUtils.serializeExtension(extension); } GetExtensionErrors(uuid) { - let extension = Main.extensionManager.extensions[uuid]; + let extension = Main.extensionManager.lookup(uuid); if (!extension) return []; @@ -304,7 +304,7 @@ var GnomeShellExtensions = class { } ReloadExtension(uuid) { - let extension = Main.extensionManager.extensions[uuid]; + let extension = Main.extensionManager.lookup(uuid); if (!extension) return;