eaafd3bb69
- Added addon_preferences so we can save users preferences into a json file. - Made translation slightly simpler This mostly works just have to figure out why we can't update description on reload (There only update on blender restart).
116 lines
3.5 KiB
Python
116 lines
3.5 KiB
Python
import bpy
|
|
from typing import List, Type
|
|
|
|
# List to store the classes to register
|
|
__bl_classes = []
|
|
# List to store the ordered classes for registration
|
|
__bl_ordered_classes = []
|
|
# List to store props to register
|
|
__bl_props = []
|
|
|
|
def register_wrap(cls):
|
|
# Check if the class has a 'bl_rna' attribute (indicating it's a Blender class)
|
|
if hasattr(cls, 'bl_rna'):
|
|
# Add the class to the list of classes to register
|
|
__bl_classes.append(cls)
|
|
return cls
|
|
|
|
# Register all properties
|
|
def register_property(prop):
|
|
__bl_props.append(prop)
|
|
|
|
def register_properties():
|
|
for prop in __bl_props:
|
|
if isinstance(prop[2], bpy.props._PropertyDeferred):
|
|
setattr(prop[0], prop[1], prop[2])
|
|
else:
|
|
prop()
|
|
|
|
def unregister_properties():
|
|
for prop in reversed(__bl_props):
|
|
delattr(prop[0], prop[1])
|
|
|
|
#- @989onan had to add this from Cats. This is extremely important else you will be screamed at by register order issues!
|
|
# Find order to register to solve dependencies
|
|
|
|
#################################################
|
|
|
|
def toposort(deps_dict):
|
|
sorted_list = []
|
|
sorted_values = set()
|
|
while len(deps_dict) > 0:
|
|
unsorted = []
|
|
for value, deps in deps_dict.items():
|
|
if len(deps) == 0:
|
|
sorted_list.append(value)
|
|
sorted_values.add(value)
|
|
else:
|
|
unsorted.append(value)
|
|
deps_dict = {value : deps_dict[value] - sorted_values for value in unsorted}
|
|
|
|
sort_order(sorted_list) #to sort by 'bl_order' so we can choose how things may appear in the ui
|
|
return sorted_list
|
|
|
|
|
|
|
|
def order_classes():
|
|
deps_dict = {}
|
|
classes_to_register = set(iter_classes_to_register())
|
|
for class_obj in classes_to_register:
|
|
deps_dict[class_obj] = set(iter_own_register_deps(class_obj, classes_to_register))
|
|
|
|
__bl_ordered_classes.clear()
|
|
# Then put everything else sorted into the list
|
|
for class_obj in toposort(deps_dict):
|
|
__bl_ordered_classes.append(class_obj)
|
|
|
|
print(__bl_ordered_classes)
|
|
__bl_classes.clear()
|
|
|
|
|
|
def iter_classes_to_register():
|
|
for class_obj in __bl_classes:
|
|
yield class_obj
|
|
|
|
|
|
def iter_own_register_deps(class_obj, own_classes):
|
|
yield from (dep for dep in iter_register_deps(class_obj) if dep in own_classes)
|
|
|
|
|
|
def iter_register_deps(class_obj):
|
|
for value in typing.get_type_hints(class_obj, {}, {}, True).values():
|
|
dependency = get_dependency_from_annotation(value)
|
|
if dependency is not None:
|
|
yield dependency
|
|
if hasattr(class_obj, "bl_parent_id"):
|
|
if class_obj.bl_parent_id != "":
|
|
for dependency in __bl_classes:
|
|
if dependency.bl_idname == class_obj.bl_parent_id:
|
|
yield dependency
|
|
|
|
def get_dependency_from_annotation(value):
|
|
if isinstance(value, tuple) and len(value) == 2:
|
|
if value[0] in (bpy.props.PointerProperty, bpy.props.CollectionProperty):
|
|
return value[1]["type"]
|
|
return None
|
|
|
|
|
|
# Find order to register to solve dependencies
|
|
#################################################
|
|
|
|
def toposort(deps_dict):
|
|
sorted_list = []
|
|
sorted_values = set()
|
|
while len(deps_dict) > 0:
|
|
unsorted = []
|
|
for value, deps in deps_dict.items():
|
|
if len(deps) == 0:
|
|
sorted_list.append(value)
|
|
sorted_values.add(value)
|
|
else:
|
|
unsorted.append(value)
|
|
deps_dict = {value : deps_dict[value] - sorted_values for value in unsorted}
|
|
|
|
return sorted_list
|
|
|