MetaWhiz/scripts/ReloadModules.py
2025-04-17 13:00:39 +08:00

193 lines
6.3 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Tool - Module Reload Tool
Provides module reloading functionality for the plugin, supporting hot updates
"""
import sys
import importlib
import os
import traceback
from maya import cmds
def get_all_py_files(start_path):
"""
Recursively get all .py files in the specified directory
Returns: A list containing the paths of all .py files
"""
py_files = []
for root, dirs, files in os.walk(start_path):
# Skip __pycache__ directory
if '__pycache__' in dirs:
dirs.remove('__pycache__')
# Skip .git directory
if '.git' in dirs:
dirs.remove('.git')
for file in files:
if file.endswith('.py') and not file.startswith('__'):
full_path = os.path.join(root, file)
# Convert to module path format
rel_path = os.path.relpath(full_path, start_path)
module_path = os.path.splitext(rel_path)[0].replace(os.sep, '.')
# Ensure module path format is correct
if module_path.startswith("scripts."):
module_path = module_path[8:]
elif module_path.startswith("Scripts."):
module_path = module_path[8:]
py_files.append(module_path)
return py_files
def reload_Tool():
"""
Reload Tool and all its related modules
"""
try:
# Close existing Tool window
if cmds.workspaceControl("ToolWorkspaceControl", exists=True):
cmds.deleteUI("ToolWorkspaceControl", control=True)
# Get scripts root directory
SCRIPTS_PATH = os.path.dirname(os.path.dirname(__file__))
print(f"Reloading modules, path: {SCRIPTS_PATH}")
# List of priority modules to reload
priority_modules = [
"QtCompat", # First reload Qt compatibility module
"config", # Then reload configuration module
"utils", # Then reload utility modules
"ui" # Finally reload UI modules
]
# Get module paths for all .py files
modules_to_reload = get_all_py_files(SCRIPTS_PATH)
# Sort by module hierarchy, ensuring lower-level modules are reloaded first
# First sort by priority, then by module hierarchy
def module_sort_key(module_name):
# Check if module is in priority list
for i, prefix in enumerate(priority_modules):
if module_name == prefix or module_name.startswith(prefix + "."):
return (i, len(module_name.split('.')))
return (len(priority_modules), len(module_name.split('.')))
modules_to_reload.sort(key=module_sort_key)
print("Module reload order:")
for i, module in enumerate(modules_to_reload):
print(f"{i+1}. {module}")
print("\nStarting module reload...")
# Reload all modules
reloaded_modules = set()
for module_name in modules_to_reload:
try:
if module_name in sys.modules:
module = sys.modules[module_name]
# Save reference to original module object for recovery if reload fails
old_module = module
try:
importlib.reload(module)
reloaded_modules.add(module_name)
print(f"Module reloaded: {module_name}")
except Exception as e:
# Reload failed, restore original module
sys.modules[module_name] = old_module
print(f"Failed to reload module {module_name}: {str(e)}")
traceback.print_exc()
else:
try:
# Try to import unloaded module
__import__(module_name)
print(f"Module imported: {module_name}")
except Exception as e:
print(f"Failed to import module {module_name}: {str(e)}")
except Exception as e:
print(f"Error processing module {module_name}: {str(e)}")
traceback.print_exc()
print(f"\nSuccessfully reloaded {len(reloaded_modules)} modules")
# Reimport main module
try:
import Main
importlib.reload(Main)
# Show UI
Main.main()
print("Tool reloaded successfully!")
except Exception as e:
print(f"Error reloading main module: {str(e)}")
traceback.print_exc()
# Reload complete
except Exception as e:
error_msg = f"Error reloading Tool: {str(e)}"
print(error_msg)
cmds.warning(error_msg)
traceback.print_exc()
def reload_all():
"""
Execute reload and print separator lines
"""
print("\n" + "="*50)
print("Starting reload of Tool and all its modules")
print("="*50 + "\n")
reload_Tool()
print("\n" + "="*50)
print("Reload complete")
def reload_qt():
"""
Reload Qt compatibility module
"""
try:
# Reload QtCompat module
if "QtCompat" in sys.modules:
module = sys.modules["QtCompat"]
importlib.reload(module)
print("QtCompat module reloaded")
# Reinitialize Qt module
if hasattr(module, "init_qt"):
qt_version = module.init_qt()
print(f"Qt module reinitialized: {qt_version}")
return True
else:
try:
import QtCompat
print("QtCompat module imported")
return True
except Exception as e:
print(f"Import QtCompat module failed: {str(e)}")
return False
except Exception as e:
print(f"Reload Qt module failed: {str(e)}")
traceback.print_exc()
return False
# For backward compatibility, keep the original function name
def reload_Tool():
"""
Function kept for backward compatibility
"""
return reload_Tool()
print("="*50 + "\n")
# Execute reload
# if __name__ == "__main__":
# reload_all()