193 lines
6.3 KiB
Python
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()
|
|
|
|
|