[gnome-shell] extensionSystem: Store extensions in a Map



commit 43cb3754d9b2f805422db65da03134ca6628ebe6
Author: Florian Müllner <fmuellner gnome org>
Date:   Mon Jul 8 00:01:11 2019 +0200

    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;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]