Skip to content

Commit

Permalink
fix: support Blender's "Reload Scripts" operator
Browse files Browse the repository at this point in the history
Now all Sollumz modules are properly reloaded when "Reload Scripts" is
invoked, and no exceptions are raised. Now we can edit the source code
and test the changes without restarting Blender (finally).
  • Loading branch information
alexguirre committed Apr 22, 2024
1 parent 313344c commit b93aabd
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 20 deletions.
35 changes: 31 additions & 4 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from . import auto_load
from . import sollumz_debug
from . import sollumz_tool


bl_info = {
"name": "Sollumz",
Expand All @@ -28,6 +24,37 @@
}


def reload_sollumz_modules():
import sys

print("Reloading Sollumz modules")

# Remove the packages imported in this module from the scope, so they are loaded again when imported below
global auto_load, sollumz_tool, sollumz_debug
del sollumz_tool
del sollumz_debug
del auto_load

# Remove from `sys.modules` all Sollumz modules, so they are loaded again by auto_load
sz_module_prefix = f"{__package__}."
module_names = list(sys.modules.keys())
for name in module_names:
if name.startswith(sz_module_prefix):
del sys.modules[name]


if "auto_load" in locals():
# If an imported name already exists before imports, it means that the addon has been reloaded by Blender.
# Blender only reloads the main __init__.py file, so we reload all our modules now.
reload_sollumz_modules()


# These need to be here, not at the top of the file, to handle reload
from . import sollumz_tool # noqa: E402
from . import sollumz_debug # noqa: E402
from . import auto_load # noqa: E402


sollumz_debug.init_debug() # first in case we need to debug initialization code
auto_load.init()

Expand Down
23 changes: 7 additions & 16 deletions auto_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
"unregister",
)

blender_version = bpy.app.version

modules = None
ordered_classes = None

Expand All @@ -37,15 +35,15 @@ def register():


def unregister():
called = []
called = set()
for module in modules:
if module.__name__ == __name__:
continue
if hasattr(module, "unregister"):
# Check if unregister method has already been called
if not module.unregister in called:
if module.unregister not in called:
module.unregister()
called.append(module.unregister)
called.add(module.unregister)

for cls in reversed(ordered_classes):
bpy.utils.unregister_class(cls)
Expand Down Expand Up @@ -83,13 +81,11 @@ def get_ordered_classes_to_register(modules):

def get_register_deps_dict(modules):
my_classes = set(iter_my_classes(modules))
my_classes_by_idname = {
cls.bl_idname: cls for cls in my_classes if hasattr(cls, "bl_idname")}
my_classes_by_idname = {cls.bl_idname: cls for cls in my_classes if hasattr(cls, "bl_idname")}

deps_dict = {}
for cls in my_classes:
deps_dict[cls] = set(iter_my_register_deps(
cls, my_classes, my_classes_by_idname))
deps_dict[cls] = set(iter_my_register_deps(cls, my_classes, my_classes_by_idname))
return deps_dict


Expand All @@ -107,13 +103,8 @@ def iter_my_deps_from_annotations(cls, my_classes):


def get_dependency_from_annotation(value):
if blender_version >= (2, 93):
if isinstance(value, bpy.props._PropertyDeferred):
return value.keywords.get("type")
else:
if isinstance(value, tuple) and len(value) == 2:
if value[0] in (bpy.props.PointerProperty, bpy.props.CollectionProperty):
return value[1]["type"]
if isinstance(value, bpy.props._PropertyDeferred):
return value.keywords.get("type")
return None


Expand Down

0 comments on commit b93aabd

Please sign in to comment.