Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'release/scripts/modules/bpy/utils.py')
-rw-r--r--release/scripts/modules/bpy/utils.py170
1 files changed, 130 insertions, 40 deletions
diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py
index 1792425268b..e3e93203235 100644
--- a/release/scripts/modules/bpy/utils.py
+++ b/release/scripts/modules/bpy/utils.py
@@ -23,12 +23,16 @@ This module contains utility functions specific to blender but
not assosiated with blenders internal data.
"""
-import bpy as _bpy
-import os as _os
-import sys as _sys
+from _bpy import register_class
+from _bpy import unregister_class
from _bpy import blend_paths
from _bpy import script_paths as _bpy_script_paths
+from _bpy import user_resource as _user_resource
+
+import bpy as _bpy
+import os as _os
+import sys as _sys
def _test_import(module_name, loaded_modules):
@@ -99,9 +103,6 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
import traceback
import time
- # must be set back to True on exits
- _bpy_types._register_immediate = False
-
t_main = time.time()
loaded_modules = set()
@@ -111,7 +112,6 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
if reload_scripts:
_bpy_types.TypeMap.clear()
- _bpy_types.PropertiesMap.clear()
# just unload, dont change user defaults, this means we can sync to reload.
# note that they will only actually reload of the modification time changes.
@@ -120,7 +120,6 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
addon_disable(module_name, default_set=False)
def register_module_call(mod):
- _bpy_types._register_module(mod.__name__)
register = getattr(mod, "register", None)
if register:
try:
@@ -131,7 +130,6 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
print("\nWarning! '%s' has no register function, this is now a requirement for registerable scripts." % mod.__file__)
def unregister_module_call(mod):
- _bpy_types._unregister_module(mod.__name__)
unregister = getattr(mod, "unregister", None)
if unregister:
try:
@@ -140,6 +138,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
traceback.print_exc()
def test_reload(mod):
+ import imp
# reloading this causes internal errors
# because the classes from this module are stored internally
# possibly to refresh internal references too but for now, best not to.
@@ -147,7 +146,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
return mod
try:
- return reload(mod)
+ return imp.reload(mod)
except:
traceback.print_exc()
@@ -197,18 +196,14 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
for mod in modules_from_path(path, loaded_modules):
test_register(mod)
- _bpy_types._register_immediate = True
-
# deal with addons seperately
- addon_reset_all()
-
+ addon_reset_all(reload_scripts)
# run the active integration preset
filepath = preset_find(_bpy.context.user_preferences.inputs.active_keyconfig, "keyconfig")
if filepath:
keyconfig_set(filepath)
-
if reload_scripts:
import gc
print("gc.collect() -> %d" % gc.collect())
@@ -339,7 +334,14 @@ def addon_check(module_name):
loaded_default = module_name in _bpy.context.user_preferences.addons
mod = _sys.modules.get(module_name)
- loaded_state = mod and getattr(mod, "__addon_enabled__")
+ loaded_state = mod and getattr(mod, "__addon_enabled__", Ellipsis)
+
+ if loaded_state is Ellipsis:
+ print("Warning: addon-module %r found module but without"
+ " __addon_enabled__ field, possible name collision from file: %r" %
+ (module_name, getattr(mod, "__file__", "<unknown>")))
+
+ loaded_state = False
return loaded_default, loaded_state
@@ -358,15 +360,11 @@ def addon_enable(module_name, default_set=True):
import os
import sys
import bpy_types as _bpy_types
-
-
- _bpy_types._register_immediate = False
+ import imp
def handle_error():
import traceback
traceback.print_exc()
- _bpy_types._register_immediate = True
-
# reload if the mtime changes
mod = sys.modules.get(module_name)
@@ -378,7 +376,7 @@ def addon_enable(module_name, default_set=True):
print("module changed on disk:", mod.__file__, "reloading...")
try:
- reload(mod)
+ imp.reload(mod)
except:
handle_error()
del sys.modules[module_name]
@@ -396,19 +394,13 @@ def addon_enable(module_name, default_set=True):
return None
# 2) try register collected modules
- try:
- _bpy_types._register_module(module_name)
- except:
- handle_error()
- del sys.modules[module_name]
- return None
+ # removed, addons need to handle own registration now.
# 3) try run the modules register function
try:
mod.register()
except:
handle_error()
- _bpy_types._unregister_module(module_name)
del sys.modules[module_name]
return None
@@ -419,12 +411,11 @@ def addon_enable(module_name, default_set=True):
if not ext:
ext = _bpy.context.user_preferences.addons.new()
ext.module = module_name
-
- _bpy_types._register_immediate = True
mod.__addon_enabled__ = True
- print("\tbpy.utils.addon_enable", mod.__name__)
+ if _bpy.app.debug:
+ print("\tbpy.utils.addon_enable", mod.__name__)
return mod
@@ -447,7 +438,6 @@ def addon_disable(module_name, default_set=True):
mod.__addon_enabled__ = False
try:
- _bpy_types._unregister_module(module_name, free=False) # dont free because we may want to enable again.
mod.unregister()
except:
traceback.print_exc()
@@ -462,21 +452,37 @@ def addon_disable(module_name, default_set=True):
addon = addons.get(module_name)
if addon:
addons.remove(addon)
-
- print("\tbpy.utils.addon_disable", module_name)
+
+ if _bpy.app.debug:
+ print("\tbpy.utils.addon_disable", module_name)
-def addon_reset_all():
+def addon_reset_all(reload_scripts=False):
"""
Sets the addon state based on the user preferences.
"""
+ import imp
- paths = script_paths("addons") + script_paths("addons_contrib")
+ # RELEASE SCRIPTS: official scripts distributed in Blender releases
+ paths = script_paths("addons")
+
+ # CONTRIB SCRIPTS: good for testing but not official scripts yet
+ paths += script_paths("addons_contrib")
+
+ # EXTERN SCRIPTS: external projects scripts
+ paths += script_paths("addons_extern")
for path in paths:
_sys_path_ensure(path)
for mod_name, mod_path in _bpy.path.module_names(path):
is_enabled, is_loaded = addon_check(mod_name)
+
+ # first check if reload is needed before changing state.
+ if reload_scripts:
+ mod = _sys.modules.get(mod_name)
+ if mod:
+ imp.reload(mod)
+
if is_enabled == is_loaded:
pass
elif is_enabled:
@@ -485,12 +491,13 @@ def addon_reset_all():
print("\taddon_reset_all unloading", mod_name)
addon_disable(mod_name)
+
def preset_find(name, preset_path, display_name=False):
if not name:
return None
-
+
for directory in preset_paths(preset_path):
-
+
if display_name:
filename = ""
for fn in _os.listdir(directory):
@@ -533,8 +540,91 @@ def keyconfig_set(filepath):
keyconfigs.remove(kc_dupe)
else:
break
-
+
kc_new.name = name
keyconfigs.active = kc_new
+def user_resource(type, path="", create=False):
+ """
+ Return a user resource path (normally from the users home directory).
+
+ :arg type: Resource type in ['DATAFILES', 'CONFIG', 'SCRIPTS', 'AUTOSAVE'].
+ :type type: string
+ :arg subdir: Optional subdirectory.
+ :type subdir: string
+ :arg create: Treat the path as a directory and create it if its not existing.
+ :type create: boolean
+ :return: a path.
+ :rtype: string
+ """
+
+ target_path = _user_resource(type, path)
+
+ if create:
+ # should always be true.
+ if target_path:
+ # create path if not existing.
+ if not _os.path.exists(target_path):
+ try:
+ _os.makedirs(target_path)
+ except:
+ import traceback
+ traceback.print_exc()
+ target_path = ""
+ elif not _os.path.isdir(target_path):
+ print("Path %r found but isn't a directory!" % target_path)
+ target_path = ""
+
+ return target_path
+
+
+def _bpy_module_classes(module, is_registered=False):
+ typemap_list = _bpy_types.TypeMap.get(module, ())
+ i = 0
+ while i < len(typemap_list):
+ cls_weakref, path, line = typemap_list[i]
+ cls = cls_weakref()
+
+ if cls is None:
+ del typemap_list[i]
+ else:
+ if is_registered == ("bl_rna" in cls.__dict__):
+ yield (cls, path, line)
+ i += 1
+
+
+def register_module(module, verbose=False):
+ import traceback
+ if verbose:
+ print("bpy.utils.register_module(%r): ..." % module)
+ for cls, path, line in _bpy_module_classes(module, is_registered=False):
+ if verbose:
+ print(" %s of %s:%s" % (cls, path, line))
+ try:
+ register_class(cls)
+ except:
+ print("bpy.utils.register_module(): failed to registering class '%s.%s'" % (cls.__module__, cls.__name__))
+ print("\t", path, "line", line)
+ traceback.print_exc()
+ if verbose:
+ print("done.\n")
+ if "cls" not in locals():
+ raise Exception("register_module(%r): defines no classes" % module)
+
+
+def unregister_module(module, verbose=False):
+ import traceback
+ if verbose:
+ print("bpy.utils.unregister_module(%r): ..." % module)
+ for cls, path, line in _bpy_module_classes(module, is_registered=True):
+ if verbose:
+ print(" %s of %s:%s" % (cls, path, line))
+ try:
+ unregister_class(cls)
+ except:
+ print("bpy.utils.unregister_module(): failed to unregistering class '%s.%s'" % (cls.__module__, cls.__name__))
+ print("\t", path, "line", line)
+ traceback.print_exc()
+ if verbose:
+ print("done.\n") \ No newline at end of file