[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59588] trunk/blender: Fix for #36387, User Preferences "Addons" panel bogs down the whole interface.
Lukas Toenne
lukas.toenne at googlemail.com
Wed Aug 28 08:36:54 CEST 2013
Revision: 59588
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59588
Author: lukastoenne
Date: 2013-08-28 06:36:54 +0000 (Wed, 28 Aug 2013)
Log Message:
-----------
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.
Modified Paths:
--------------
trunk/blender/intern/tools/bpy_introspect_ui.py
trunk/blender/release/scripts/modules/addon_utils.py
trunk/blender/release/scripts/modules/bl_i18n_utils/utils.py
trunk/blender/release/scripts/startup/bl_operators/wm.py
trunk/blender/release/scripts/startup/bl_ui/__init__.py
trunk/blender/release/scripts/startup/bl_ui/space_userpref.py
Modified: trunk/blender/intern/tools/bpy_introspect_ui.py
===================================================================
--- trunk/blender/intern/tools/bpy_introspect_ui.py 2013-08-28 05:03:02 UTC (rev 59587)
+++ trunk/blender/intern/tools/bpy_introspect_ui.py 2013-08-28 06:36:54 UTC (rev 59588)
@@ -310,7 +310,8 @@
bpy_extras.keyconfig_utils.keyconfig_merge = lambda a, b: ()
addon_utils = module_add("addon_utils")
- addon_utils.modules = lambda f: ()
+ addon_utils.modules = lambda f: []
+ addon_utils.modules_refresh = lambda f: None
addon_utils.module_bl_info = lambda f: None
addon_utils.addons_fake_modules = {}
addon_utils.error_duplicates = ()
Modified: trunk/blender/release/scripts/modules/addon_utils.py
===================================================================
--- trunk/blender/release/scripts/modules/addon_utils.py 2013-08-28 05:03:02 UTC (rev 59587)
+++ trunk/blender/release/scripts/modules/addon_utils.py 2013-08-28 06:36:54 UTC (rev 59588)
@@ -35,7 +35,6 @@
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 @@
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 @@
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 @@
"""
import sys
+ # initializes addons_fake_modules
+ modules_refresh()
+
# RELEASE SCRIPTS: official scripts distributed in Blender releases
paths_list = paths()
Modified: trunk/blender/release/scripts/modules/bl_i18n_utils/utils.py
===================================================================
--- trunk/blender/release/scripts/modules/bl_i18n_utils/utils.py 2013-08-28 05:03:02 UTC (rev 59587)
+++ trunk/blender/release/scripts/modules/bl_i18n_utils/utils.py 2013-08-28 06:36:54 UTC (rev 59588)
@@ -172,7 +172,7 @@
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))]
Modified: trunk/blender/release/scripts/startup/bl_operators/wm.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_operators/wm.py 2013-08-28 05:03:02 UTC (rev 59587)
+++ trunk/blender/release/scripts/startup/bl_operators/wm.py 2013-08-28 06:36:54 UTC (rev 59588)
@@ -1693,6 +1693,19 @@
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 @@
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 @@
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 @@
# 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 @@
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):
Modified: trunk/blender/release/scripts/startup/bl_ui/__init__.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/__init__.py 2013-08-28 05:03:02 UTC (rev 59587)
+++ trunk/blender/release/scripts/startup/bl_ui/__init__.py 2013-08-28 06:36:54 UTC (rev 59588)
@@ -105,7 +105,7 @@
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"])
Modified: trunk/blender/release/scripts/startup/bl_ui/space_userpref.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/space_userpref.py 2013-08-28 05:03:02 UTC (rev 59587)
+++ trunk/blender/release/scripts/startup/bl_ui/space_userpref.py 2013-08-28 06:36:54 UTC (rev 59588)
@@ -1142,11 +1142,12 @@
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 @@
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"
More information about the Bf-blender-cvs
mailing list