[Bf-extensions-cvs] [73784e78] master: Rigify: implement a new reload process to support Reload Scripts properly.

Alexander Gavrilov noreply at git.blender.org
Sun Sep 29 17:30:31 CEST 2019


Commit: 73784e78de99cb647870cbd93ef497f3e437a1a6
Author: Alexander Gavrilov
Date:   Sat Sep 28 12:51:33 2019 +0300
Branches: master
https://developer.blender.org/rBA73784e78de99cb647870cbd93ef497f3e437a1a6

Rigify: implement a new reload process to support Reload Scripts properly.

Due to dynamically loaded rig modules, Rigify has to implement
reload by purging all non-core modules from memory, or class
inheritance checks won't work right after reload.

===================================================================

M	rigify/__init__.py
M	rigify/metarig_menu.py
M	rigify/rig_lists.py
M	rigify/rigs/utils.py
M	rigify/ui.py
M	rigify/utils/__init__.py

===================================================================

diff --git a/rigify/__init__.py b/rigify/__init__.py
index d487f265..803c19c0 100644
--- a/rigify/__init__.py
+++ b/rigify/__init__.py
@@ -29,24 +29,97 @@ bl_info = {
                 "Scripts/Rigging/Rigify",
     "category": "Rigging"}
 
+import importlib
+import sys
+import bpy
+import os
 
-if "bpy" in locals():
-    import importlib
-    # Don't reload base_rig or base_generate, because it would break issubclass checks,
-    # unless _all_ modules with classes inheriting from BaseRig are also reloaded.
-    importlib.reload(utils)
-    importlib.reload(rig_ui_template)
-    importlib.reload(feature_set_list)
-    importlib.reload(rig_lists)
-    importlib.reload(generate)
-    importlib.reload(ui)
-    importlib.reload(metarig_menu)
+
+# The order in which core modules of the addon are loaded and reloaded.
+# Modules not in this list are removed from memory upon reload.
+# With the sole exception of 'utils', modules must be listed in the
+# correct dependency order.
+initial_load_order = [
+    'utils',
+    'utils.errors',
+    'utils.misc',
+    'utils.rig',
+    'utils.naming',
+    'utils.bones',
+    'utils.collections',
+    'utils.layers',
+    'utils.widgets',
+    'utils.widgets_basic',
+    'utils.widgets_special',
+    'utils.mechanism',
+    'utils.animation',
+    'utils.metaclass',
+    'feature_sets',
+    'rigs',
+    'rigs.utils',
+    'base_rig',
+    'base_generate',
+    'feature_set_list',
+    'rig_lists',
+    'metarig_menu',
+    'rig_ui_template',
+    'generate',
+    'rot_mode',
+    'ui',
+]
+
+
+def get_loaded_modules():
+    prefix = __name__ + '.'
+    return [name for name in sys.modules if name.startswith(prefix)]
+
+def reload_modules():
+    fixed_modules = set(reload_list)
+
+    for name in get_loaded_modules():
+        if name not in fixed_modules:
+            del sys.modules[name]
+
+    for name in reload_list:
+        importlib.reload(sys.modules[name])
+
+def load_initial_modules():
+    load_list = [ __name__ + '.' + name for name in initial_load_order ]
+
+    for i, name in enumerate(load_list):
+        importlib.import_module(name)
+
+        module_list = get_loaded_modules()
+        expected_list = load_list[0 : max(11, i+1)]
+
+        if module_list != expected_list:
+            print('!!! RIGIFY: initial load order mismatch after '+name+' - expected: \n', expected_list, '\nGot:\n', module_list)
+
+    return load_list
+
+def load_rigs():
+    if not legacy_loaded:
+        rig_lists.get_internal_rigs()
+        metarig_menu.init_metarig_menu()
+
+
+if "reload_list" in locals():
+    reload_modules()
 else:
-    from . import (utils, base_rig, base_generate, rig_ui_template, feature_set_list, rig_lists, generate, ui, metarig_menu)
+    legacy_loaded = False
+
+    load_list = load_initial_modules()
+
+    from . import (base_rig, base_generate, rig_ui_template, feature_set_list, rig_lists, generate, ui, metarig_menu)
+
+    reload_list = reload_list_init = get_loaded_modules()
+
+    if reload_list != load_list:
+        print('!!! RIGIFY: initial load order mismatch - expected: \n', load_list, '\nGot:\n', reload_list)
+
+load_rigs()
+
 
-import bpy
-import sys
-import os
 from bpy.types import AddonPreferences
 from bpy.props import (
     BoolProperty,
@@ -65,16 +138,14 @@ class RigifyPreferences(AddonPreferences):
     bl_idname = __name__
 
     def update_legacy(self, context):
-        if self.legacy_mode:
+        global legacy_loaded, reload_list
 
-            if 'ui' in globals() and 'legacy' in str(globals()['ui']):    # already in legacy mode. needed when rigify is reloaded
+        if self.legacy_mode:
+            if legacy_loaded:    # already in legacy mode. needed when rigify is reloaded
                 return
             else:
-                rigify_dir = os.path.dirname(os.path.realpath(__file__))
-                if rigify_dir not in sys.path:
-                    sys.path.append(rigify_dir)
-
                 unregister()
+                reload_modules()
 
                 globals().pop('utils')
                 globals().pop('rig_lists')
@@ -82,14 +153,13 @@ class RigifyPreferences(AddonPreferences):
                 globals().pop('ui')
                 globals().pop('metarig_menu')
 
-                import legacy.utils
-                import legacy.rig_lists
-                import legacy.generate
-                import legacy.ui
-                import legacy.metarig_menu
+                from .legacy import utils, rig_lists, generate, ui, metarig_menu
 
                 print("ENTERING RIGIFY LEGACY\r\n")
 
+                legacy_loaded = True
+                reload_list += [ m.__name__ for m in [ legacy, utils, rig_lists, generate, ui, metarig_menu ] ]
+
                 globals()['utils'] = legacy.utils
                 globals()['rig_lists'] = legacy.rig_lists
                 globals()['generate'] = legacy.generate
@@ -99,13 +169,6 @@ class RigifyPreferences(AddonPreferences):
                 register()
 
         else:
-
-            rigify_dir = os.path.dirname(os.path.realpath(__file__))
-
-            if rigify_dir in sys.path:
-                id = sys.path.index(rigify_dir)
-                sys.path.pop(id)
-
             unregister()
 
             globals().pop('utils')
@@ -114,11 +177,7 @@ class RigifyPreferences(AddonPreferences):
             globals().pop('ui')
             globals().pop('metarig_menu')
 
-            from . import utils
-            from . import rig_lists
-            from . import generate
-            from . import ui
-            from . import metarig_menu
+            from . import utils, rig_lists, generate, ui, metarig_menu
 
             print("EXIT RIGIFY LEGACY\r\n")
 
@@ -128,6 +187,12 @@ class RigifyPreferences(AddonPreferences):
             globals()['ui'] = ui
             globals()['metarig_menu'] = metarig_menu
 
+            legacy_loaded = False
+            reload_list = reload_list_init
+            reload_modules()
+
+            load_rigs()
+
             register()
 
     def update_external_rigs(self, force=False):
@@ -492,7 +557,7 @@ def register():
         description="Transfer selected bones only", default=True)
 
     # Update legacy on restart or reload.
-    if (ui and 'legacy' in str(ui)) or bpy.context.preferences.addons['rigify'].preferences.legacy_mode:
+    if legacy_loaded or bpy.context.preferences.addons['rigify'].preferences.legacy_mode:
         bpy.context.preferences.addons['rigify'].preferences.legacy_mode = True
 
     bpy.context.preferences.addons['rigify'].preferences.update_external_rigs()
diff --git a/rigify/metarig_menu.py b/rigify/metarig_menu.py
index dc583a67..48da1e89 100644
--- a/rigify/metarig_menu.py
+++ b/rigify/metarig_menu.py
@@ -26,7 +26,8 @@ from collections import defaultdict
 
 import bpy
 
-from . import utils
+from .utils.rig import METARIG_DIR, get_resource
+
 from . import feature_set_list
 
 
@@ -70,11 +71,11 @@ def get_metarigs(metarigs, base_dir, base_path, *, path=[], nested=False):
         elif f.endswith(".py"):
             # Check straight-up python files
             f = f[:-3]
-            module = utils.get_resource('.'.join([*base_path, *path, f]))
+            module = get_resource('.'.join([*base_path, *path, f]))
             if nested:
                 metarigs[f] = module
             else:
-                metarigs[utils.METARIG_DIR][f] = module
+                metarigs[METARIG_DIR][f] = module
 
 
 def make_metarig_add_execute(m):
@@ -120,7 +121,7 @@ def get_internal_metarigs():
     BASE_RIGIFY_DIR = os.path.dirname(__file__)
     BASE_RIGIFY_PATH = __name__.split('.')[:-1]
 
-    get_metarigs(metarigs, os.path.join(BASE_RIGIFY_DIR, utils.METARIG_DIR), [*BASE_RIGIFY_PATH, utils.METARIG_DIR])
+    get_metarigs(metarigs, os.path.join(BASE_RIGIFY_DIR, METARIG_DIR), [*BASE_RIGIFY_PATH, METARIG_DIR])
 
 def infinite_defaultdict():
     return defaultdict(infinite_defaultdict)
@@ -130,8 +131,6 @@ metarig_ops = {}
 armature_submenus = []
 menu_funcs = []
 
-get_internal_metarigs()
-
 def create_metarig_ops(dic=metarigs):
     """Create metarig add Operators"""
     for metarig_category in dic:
@@ -154,7 +153,7 @@ def create_metarig_ops(dic=metarigs):
 
 def create_menu_funcs():
     global menu_funcs
-    for mop, name in metarig_ops[utils.METARIG_DIR]:
+    for mop, name in metarig_ops[METARIG_DIR]:
         text = capwords(name.replace("_", " ")) + " (Meta-Rig)"
         menu_funcs += [make_metarig_menu_func(mop.bl_idname, text)]
 
@@ -167,7 +166,7 @@ def create_armature_submenus(dic=metarigs):
         if metarig_category == "external":
             create_armature_submenus(dic=metarigs["external"])
             continue
-        if metarig_category == utils.METARIG_DIR:
+        if metarig_category == METARIG_DIR:
             continue
 
         armature_submenus.append(type('Class_' + metarig_category + '_submenu', (ArmatureSubMenu,), {}))
@@ -180,10 +179,11 @@ def create_armature_submenus(dic=metarigs):
             arm_sub = next((e for e in armature_submenus if e.bl_label == metarig_category + ' (submenu)'), '')
             arm_sub.operators.append((mop.bl_idname, name,))
 
-create_metarig_ops()
-create_menu_funcs()
-create_armature_submenus()
-
+def init_metarig_menu():
+    get_internal_metarigs()
+    create_metarig_ops()
+    create_menu_funcs()
+    create_armature_submenus()
 
 ### Registering ###
 
@@ -224,7 +224,7 @@ def get_external_metarigs(set_list):
 
     for feature_set in set_list:
         try:
-            base_dir, base_path = feature_set_list.get_dir_path(feature_set, utils.METARIG_DIR)
+            base_dir, base_path = feature_set_list.get_dir_path(feature_set, METARIG_DIR)
 
             get_metarigs(metarigs['external'], base_dir, base_path)
         except Exception:
diff --git a/rigify/rig_lists.py b/rigify/rig_lists.py
index 018bbbac..49cc9545 100644
--- a/rigify/rig_lists.py
+++ b/rigify/rig_lists.py
@@ -20,7 +20,8 @@ import os
 import traceback
 import importlib
 
-from . import utils
+from .utils.rig import RIG_DIR
+
 from . import feature_set_list
 
 
@@ -76,15 +77,16 @@ def get_rigs(base_dir, base_path, *, path=[], feature_set=feature_set_list.DEFAU
 
 
 # Public variables
+rigs = {}
+implemen

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list