diff options
author | Lukas Toenne <lukas.toenne@googlemail.com> | 2013-08-28 10:36:54 +0400 |
---|---|---|
committer | Lukas Toenne <lukas.toenne@googlemail.com> | 2013-08-28 10:36:54 +0400 |
commit | 771906bc09317e3dc77be2319b44bc59081eff93 (patch) | |
tree | 2b6386aa5cdadfd52bc3b036feee3b00b6c87793 /release | |
parent | f75711db7fd3565925880f8a2ea89088334c35bf (diff) |
Fix for #36387, User Preferences "Addons" panel bogs down the whole interface.
The addons panel draw function calls addon_utils.modules() which in turn retrieves a list of fake modules from the script paths every time. This can become costly when network paths are included for
addons. Solution is to put the scanning process into a dedicated "refresh" function and disable it in frequently called draw and filter functions, i.e. in these cases the cached addons_fake_modules list
will be used instead.
Note that this may lead to invalid addon lists if script paths are changed (which is not working 100% without restart anyway according to Campbell). For this there is now a "Refresh" operator button in
the addons preferences. If necessary and feasible such forced refreshes can be added later too.
Diffstat (limited to 'release')
-rw-r--r-- | release/scripts/modules/addon_utils.py | 11 | ||||
-rw-r--r-- | release/scripts/modules/bl_i18n_utils/utils.py | 2 | ||||
-rw-r--r-- | release/scripts/startup/bl_operators/wm.py | 21 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/__init__.py | 2 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/space_userpref.py | 5 |
5 files changed, 31 insertions, 10 deletions
diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index 3aa4eef6392..2ac7d4c85aa 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -35,7 +35,6 @@ error_duplicates = False error_encoding = False addons_fake_modules = {} - def paths(): # RELEASE SCRIPTS: official scripts distributed in Blender releases addon_paths = _bpy.utils.script_paths("addons") @@ -51,7 +50,7 @@ def paths(): return addon_paths -def modules(module_cache): +def modules_refresh(module_cache=addons_fake_modules): global error_duplicates global error_encoding import os @@ -184,6 +183,11 @@ def modules(module_cache): del module_cache[mod_stale] del modules_stale + +def modules(module_cache=addons_fake_modules, refresh=True): + if refresh: + modules_refresh(module_cache) + mod_list = list(module_cache.values()) mod_list.sort(key=lambda mod: (mod.bl_info["category"], mod.bl_info["name"], @@ -370,6 +374,9 @@ def reset_all(reload_scripts=False): """ import sys + # initializes addons_fake_modules + modules_refresh() + # RELEASE SCRIPTS: official scripts distributed in Blender releases paths_list = paths() diff --git a/release/scripts/modules/bl_i18n_utils/utils.py b/release/scripts/modules/bl_i18n_utils/utils.py index 636e9a4a148..1b6d65d89d0 100644 --- a/release/scripts/modules/bl_i18n_utils/utils.py +++ b/release/scripts/modules/bl_i18n_utils/utils.py @@ -172,7 +172,7 @@ def enable_addons(addons={}, support={}, disable=False, check_only=False): userpref = bpy.context.user_preferences used_ext = {ext.module for ext in userpref.addons} - ret = [mod for mod in addon_utils.modules(addon_utils.addons_fake_modules) + ret = [mod for mod in addon_utils.modules() if ((addons and mod.__name__ in addons) or (not addons and addon_utils.module_bl_info(mod)["support"] in support))] diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 5095bfdd9d2..c575b6dfdaf 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1693,6 +1693,19 @@ class WM_OT_theme_install(Operator): return {'RUNNING_MODAL'} +class WM_OT_addon_refresh(Operator): + "Scan addon directories for new modules" + bl_idname = "wm.addon_refresh" + bl_label = "Refresh" + + def execute(self, context): + import addon_utils + + addon_utils.modules_refresh() + + return {'FINISHED'} + + class WM_OT_addon_install(Operator): "Install an addon" bl_idname = "wm.addon_install" @@ -1782,7 +1795,7 @@ class WM_OT_addon_install(Operator): del pyfile_dir # done checking for exceptional case - addons_old = {mod.__name__ for mod in addon_utils.modules(addon_utils.addons_fake_modules)} + addons_old = {mod.__name__ for mod in addon_utils.modules()} #check to see if the file is in compressed format (.zip) if zipfile.is_zipfile(pyfile): @@ -1825,7 +1838,7 @@ class WM_OT_addon_install(Operator): traceback.print_exc() return {'CANCELLED'} - addons_new = {mod.__name__ for mod in addon_utils.modules(addon_utils.addons_fake_modules)} - addons_old + addons_new = {mod.__name__ for mod in addon_utils.modules()} - addons_old addons_new.discard("modules") # disable any addons we may have enabled previously and removed. @@ -1835,7 +1848,7 @@ class WM_OT_addon_install(Operator): # possible the zip contains multiple addons, we could disallow this # but for now just use the first - for mod in addon_utils.modules(addon_utils.addons_fake_modules): + for mod in addon_utils.modules(refresh=False): if mod.__name__ in addons_new: info = addon_utils.module_bl_info(mod) @@ -1875,7 +1888,7 @@ class WM_OT_addon_remove(Operator): import os import addon_utils - for mod in addon_utils.modules(addon_utils.addons_fake_modules): + for mod in addon_utils.modules(): if mod.__name__ == module: filepath = mod.__file__ if os.path.exists(filepath): diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index b9f2e8406c6..df6247f65f5 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -105,7 +105,7 @@ def register(): items_unique = set() - for mod in addon_utils.modules(addon_utils.addons_fake_modules): + for mod in addon_utils.modules(refresh=False): info = addon_utils.module_bl_info(mod) items_unique.add(info["category"]) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index c2825d0641e..0418434c92b 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -1142,11 +1142,12 @@ class USERPREF_PT_addons(Panel): scripts_addons_folder = bpy.utils.user_resource('SCRIPTS', "addons") # collect the categories that can be filtered on - addons = [(mod, addon_utils.module_bl_info(mod)) for mod in addon_utils.modules(addon_utils.addons_fake_modules)] + addons = [(mod, addon_utils.module_bl_info(mod)) for mod in addon_utils.modules(refresh=False)] split = layout.split(percentage=0.2) col = split.column() col.prop(context.window_manager, "addon_search", text="", icon='VIEWZOOM') + col.operator("wm.addon_refresh", icon='FILE_REFRESH') col.label(text="Supported Level") col.prop(context.window_manager, "addon_support", expand=True) @@ -1156,7 +1157,7 @@ class USERPREF_PT_addons(Panel): col = split.column() - # set in addon_utils.modules(...) + # set in addon_utils.modules_refresh() if addon_utils.error_duplicates: self.draw_error(col, "Multiple addons using the same name found!\n" |