[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [30969] trunk/blender/release/scripts: update userpref's addon code to support new register/unregister, now the modules are parsed rather then being imported since it become quite tricky to import once without registering the classes , then again in a way that registered the existing modules classes without a reload () - which had problems too.
Campbell Barton
ideasman42 at gmail.com
Mon Aug 2 09:50:59 CEST 2010
Revision: 30969
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=30969
Author: campbellbarton
Date: 2010-08-02 09:50:58 +0200 (Mon, 02 Aug 2010)
Log Message:
-----------
update userpref's addon code to support new register/unregister, now the modules are parsed rather then being imported since it become quite tricky to import once without registering the classes, then again in a way that registered the existing modules classes without a reload() - which had problems too.
Modified Paths:
--------------
trunk/blender/release/scripts/modules/bpy_types.py
trunk/blender/release/scripts/ui/space_userpref.py
Modified: trunk/blender/release/scripts/modules/bpy_types.py
===================================================================
--- trunk/blender/release/scripts/modules/bpy_types.py 2010-08-02 06:56:31 UTC (rev 30968)
+++ trunk/blender/release/scripts/modules/bpy_types.py 2010-08-02 07:50:58 UTC (rev 30969)
@@ -551,18 +551,18 @@
# registers moduals instantly.
_register_immediate = True
-def _unload_module(module):
+def _unload_module(module, free=True):
for t in TypeMap.get(module, ()):
bpy_types.unregister(t)
- if module in TypeMap:
+ if free == True and module in TypeMap:
del TypeMap[module]
for t in PropertiesMap.get(module, ()):
bpy_types.unregister(t)
- if module in PropertiesMap:
+ if free == True and module in PropertiesMap:
del PropertiesMap[module]
def _load_module(module, force=False):
Modified: trunk/blender/release/scripts/ui/space_userpref.py
===================================================================
--- trunk/blender/release/scripts/ui/space_userpref.py 2010-08-02 06:56:31 UTC (rev 30968)
+++ trunk/blender/release/scripts/ui/space_userpref.py 2010-08-02 07:50:58 UTC (rev 30969)
@@ -814,13 +814,20 @@
bl_label = "Addons"
bl_region_type = 'WINDOW'
bl_show_header = False
+
+ _addons_fake_modules = {}
def poll(self, context):
userpref = context.user_preferences
return (userpref.active_section == 'ADDONS')
@staticmethod
+ def module_get(mod_name):
+ return USERPREF_PT_addons._addons_fake_modules[mod_name]
+
+ @staticmethod
def _addon_list():
+ import os
import sys
import time
@@ -829,21 +836,99 @@
paths = bpy.utils.script_paths("addons")
# if folder addons_contrib/ exists, scripts in there will be loaded
paths += bpy.utils.script_paths("addons_contrib")
-
+
if bpy.app.debug:
t_main = time.time()
- # sys.path.insert(0, None)
- for path in paths:
- # sys.path[0] = path
- modules.extend(bpy.utils.modules_from_path(path, loaded_modules))
+ if 1:
+ # fake module importing
+ def fake_module(mod_name, mod_path):
+ import ast
+ ModuleType = type(ast)
+ data = open(mod_path, "r").read()
+ ast_data = ast.parse(data, filename=mod_path)
+ body_info = None
+ for body in ast_data.body:
+ if body.__class__ == ast.Assign:
+ if len(body.targets) == 1:
+ if body.targets[0].id == "bl_addon_info":
+ body_info = body
+ break
+
+ if body_info:
+ mod = ModuleType(mod_name)
+ mod.bl_addon_info = ast.literal_eval(body.value)
+ mod.__file__ = mod_path
+ mod.__time__ = os.path.getmtime(mod_path)
+ return mod
+ else:
+ return None
- if bpy.app.debug:
- print("Addon Script Load Time %.4f" % (time.time() - t_main))
- # del sys.path[0]
- return modules
+ modules_stale = set(USERPREF_PT_addons._addons_fake_modules.keys())
+ for path in paths:
+ for f in sorted(os.listdir(path)):
+ if f.endswith(".py"):
+ mod_name = f[0:-3]
+ mod_path = os.path.join(path, f)
+ elif ("." not in f) and (os.path.isfile(os.path.join(path, f, "__init__.py"))):
+ mod_name = f
+ mod_path = os.path.join(path, f, "__init__.py")
+ else:
+ mod_name = ""
+ mod_path = ""
+
+ if mod_name:
+ if mod_name in modules_stale:
+ modules_stale.remove(mod_name)
+ mod = USERPREF_PT_addons._addons_fake_modules.get(mod_name)
+ if mod:
+ if mod.__time__ != os.path.getmtime(mod_path):
+ print("Reloading", mod_name)
+ del USERPREF_PT_addons._addons_fake_modules[mod_name]
+ mod = None
+
+ if mod is None:
+ mod = fake_module(mod_name, mod_path)
+ if mod:
+ USERPREF_PT_addons._addons_fake_modules[mod_name] = mod
+
+
+ # just incase we get stale modules, not likely
+ for mod_stale in modules_stale:
+ del USERPREF_PT_addons._addons_fake_modules[mod_stale]
+ del modules_stale
+
+ return list(USERPREF_PT_addons._addons_fake_modules.values())
+
+ else:
+ # never run this!, before it used ast
+ pass
+ '''
+ # note, this still gets added to _bpy_types.TypeMap
+ import bpy_types as _bpy_types
+ _bpy_types._register_override = True
+
+ # sys.path.insert(0, None)
+ for path in paths:
+ # sys.path[0] = path
+ modules.extend(bpy.utils.modules_from_path(path, loaded_modules))
+
+ if bpy.app.debug:
+ print("Addon Script Load Time %.4f" % (time.time() - t_main))
+
+ _bpy_types._register_override = False
+
+ # del sys.path[0]
+ return modules
+ '''
+
+
+
+
+
+
def draw(self, context):
layout = self.layout
@@ -996,8 +1081,13 @@
def execute(self, context):
module_name = self.properties.module
+ # note, this still gets added to _bpy_types.TypeMap
+ import bpy_types as _bpy_types
+ _bpy_types._register_immediate = False
+
try:
mod = __import__(module_name)
+ bpy.utils._load_module(module_name)
mod.register()
except:
import traceback
@@ -1012,7 +1102,9 @@
if info.get("blender", (0, 0, 0)) > bpy.app.version:
self.report("WARNING','This script was written for a newer version of Blender and might not function (correctly).\nThe script is enabled though.")
-
+
+ _bpy_types._register_immediate = True
+
return {'FINISHED'}
@@ -1029,6 +1121,7 @@
try:
mod = __import__(module_name)
+ bpy.utils._unload_module(module_name, free=False) # dont free because we may want to enable again.
mod.unregister()
except:
traceback.print_exc()
@@ -1118,7 +1211,8 @@
# unlikely to fail, module should have already been imported
try:
- mod = __import__(module_name)
+ # mod = __import__(module_name)
+ mod = USERPREF_PT_addons.module_get(module_name)
except:
import traceback
traceback.print_exc()
More information about the Bf-blender-cvs
mailing list