diff --git a/tools/blenvy/TODO.md b/tools/blenvy/TODO.md index f6b01df..6e48192 100644 --- a/tools/blenvy/TODO.md +++ b/tools/blenvy/TODO.md @@ -97,6 +97,8 @@ Components: - [x] add warning about hash colision (not much we can/ could do if it is the case ?) - [ ] double check weird collisions AND/OR reuse existing if applicable + - [x] annoying default path for registry, should be relative to the assets path + General things to solve: - [x] save settings diff --git a/tools/blenvy/add_ons/bevy_components/propGroups/process_component.py b/tools/blenvy/add_ons/bevy_components/propGroups/process_component.py index 7c6cc14..847ffa8 100644 --- a/tools/blenvy/add_ons/bevy_components/propGroups/process_component.py +++ b/tools/blenvy/add_ons/bevy_components/propGroups/process_component.py @@ -7,7 +7,7 @@ from . import process_enum from . import process_list from . import process_map -def process_component(registry, definition, update, extras=None, nesting = [], nesting_long_names = []): +def process_component(registry, definition, update, extras=None, nesting_long_names = []): long_name = definition['long_name'] short_name = definition["short_name"] type_info = definition["typeInfo"] if "typeInfo" in definition else None @@ -30,28 +30,32 @@ def process_component(registry, definition, update, extras=None, nesting = [], n with_list = False with_map = False + padding = " " * (len(nesting_long_names) + 1) + #print(f"{padding}process component", long_name, "nesting_long_names",nesting_long_names, "foo", has_properties, has_prefixItems, is_enum, is_list, is_map) if has_properties: - __annotations__ = __annotations__ | process_structs.process_structs(registry, definition, properties, update, nesting, nesting_long_names) + __annotations__ = __annotations__ | process_structs.process_structs(registry, definition, properties, update, nesting_long_names) with_properties = True tupple_or_struct = "struct" if has_prefixItems: - __annotations__ = __annotations__ | process_tupples.process_tupples(registry, definition, prefixItems, update, nesting, nesting_long_names) + __annotations__ = __annotations__ | process_tupples.process_tupples(registry, definition, prefixItems, update, nesting_long_names) with_items = True tupple_or_struct = "tupple" if is_enum: - __annotations__ = __annotations__ | process_enum.process_enum(registry, definition, update, nesting, nesting_long_names) + __annotations__ = __annotations__ | process_enum.process_enum(registry, definition, update, nesting_long_names) with_enum = True if is_list: - __annotations__ = __annotations__ | process_list.process_list(registry, definition, update, nesting, nesting_long_names) + __annotations__ = __annotations__ | process_list.process_list(registry, definition, update, nesting_long_names) with_list= True if is_map: - __annotations__ = __annotations__ | process_map.process_map(registry, definition, update, nesting, nesting_long_names) + __annotations__ = __annotations__ | process_map.process_map(registry, definition, update, nesting_long_names) with_map = True + + # print("AFTER PROCESS", nesting_long_names, long_name) field_names = [] for a in __annotations__: @@ -61,7 +65,10 @@ def process_component(registry, definition, update, extras=None, nesting = [], n extras = extras if extras is not None else { "long_name": long_name } + + nesting_long_names = nesting_long_names + [long_name] root_component = nesting_long_names[0] if len(nesting_long_names) > 0 else long_name + # print("") property_group_params = { **extras, @@ -78,7 +85,7 @@ def process_component(registry, definition, update, extras=None, nesting = [], n -BasicTest => the registration & update callback of this one overwrites the first "basicTest" have not found a cleaner workaround so far """ - property_group_name = registry.generate_propGroup_name(nesting, long_name) + property_group_name = registry.generate_propGroup_name(nesting_long_names) (property_group_pointer, property_group_class) = property_group_from_infos(property_group_name, property_group_params) # add our component propertyGroup to the registry registry.register_component_propertyGroup(property_group_name, property_group_pointer) diff --git a/tools/blenvy/add_ons/bevy_components/propGroups/process_enum.py b/tools/blenvy/add_ons/bevy_components/propGroups/process_enum.py index 2b5df03..1a71ea1 100644 --- a/tools/blenvy/add_ons/bevy_components/propGroups/process_enum.py +++ b/tools/blenvy/add_ons/bevy_components/propGroups/process_enum.py @@ -1,21 +1,19 @@ from bpy.props import (StringProperty) from . import process_component -def process_enum(registry, definition, update, nesting, nesting_long_names): +def process_enum(registry, definition, update, nesting_long_names): blender_property_mapping = registry.blender_property_mapping - short_name = definition["short_name"] long_name = definition["long_name"] type_def = definition["type"] if "type" in definition else None variants = definition["oneOf"] - nesting = nesting + [short_name] - nesting_long_names = nesting_long_names = [long_name] + nesting_long_names = nesting_long_names + [long_name] __annotations__ = {} original_type_name = "enum" - # print("processing enum", short_name, long_name, definition) + #print("processing enum", long_name)#, definition) if type_def == "object": labels = [] @@ -28,12 +26,12 @@ def process_enum(registry, definition, update, nesting, nesting_long_names): if "prefixItems" in variant: #print("tupple variant in enum", variant) registry.add_custom_type(variant_name, variant) - (sub_component_group, _) = process_component.process_component(registry, variant, update, {"nested": True}, nesting, nesting_long_names) + (sub_component_group, _) = process_component.process_component(registry, variant, update, {"nested": True}, nesting_long_names=nesting_long_names) additional_annotations[variant_prefixed_name] = sub_component_group elif "properties" in variant: #print("struct variant in enum", variant) registry.add_custom_type(variant_name, variant) - (sub_component_group, _) = process_component.process_component(registry, variant, update, {"nested": True}, nesting, nesting_long_names) + (sub_component_group, _) = process_component.process_component(registry, variant, update, {"nested": True}, nesting_long_names=nesting_long_names) additional_annotations[variant_prefixed_name] = sub_component_group else: # for the cases where it's neither a tupple nor a structs: FIXME: not 100% sure of this #print("other variant in enum") diff --git a/tools/blenvy/add_ons/bevy_components/propGroups/process_list.py b/tools/blenvy/add_ons/bevy_components/propGroups/process_list.py index bc48855..8c884e4 100644 --- a/tools/blenvy/add_ons/bevy_components/propGroups/process_list.py +++ b/tools/blenvy/add_ons/bevy_components/propGroups/process_list.py @@ -2,15 +2,13 @@ from bpy.props import (StringProperty, IntProperty, CollectionProperty) from .utils import generate_wrapper_propertyGroup from . import process_component -def process_list(registry, definition, update, nesting=[], nesting_long_names=[]): +def process_list(registry, definition, update, nesting_long_names=[]): value_types_defaults = registry.value_types_defaults type_infos = registry.type_infos - short_name = definition["short_name"] long_name = definition["long_name"] ref_name = definition["items"]["type"]["$ref"].replace("#/$defs/", "") - nesting = nesting+[short_name] nesting_long_names = nesting_long_names + [long_name] item_definition = type_infos[ref_name] @@ -20,9 +18,9 @@ def process_list(registry, definition, update, nesting=[], nesting_long_names=[] property_group_class = None #if the content of the list is a unit type, we need to generate a fake wrapper, otherwise we cannot use layout.prop(group, "propertyName") as there is no propertyName ! if is_item_value_type: - property_group_class = generate_wrapper_propertyGroup(long_name, item_long_name, definition["items"]["type"]["$ref"], registry, update) + property_group_class = generate_wrapper_propertyGroup(long_name, item_long_name, definition["items"]["type"]["$ref"], registry, update, nesting_long_names=nesting_long_names) else: - (_, list_content_group_class) = process_component.process_component(registry, item_definition, update, {"nested": True, "long_name": item_long_name}, nesting) + (_, list_content_group_class) = process_component.process_component(registry, item_definition, update, {"nested": True, "long_name": item_long_name}, nesting_long_names=nesting_long_names) property_group_class = list_content_group_class item_collection = CollectionProperty(type=property_group_class) diff --git a/tools/blenvy/add_ons/bevy_components/propGroups/process_map.py b/tools/blenvy/add_ons/bevy_components/propGroups/process_map.py index b1b2aab..bf16a7d 100644 --- a/tools/blenvy/add_ons/bevy_components/propGroups/process_map.py +++ b/tools/blenvy/add_ons/bevy_components/propGroups/process_map.py @@ -2,14 +2,12 @@ from bpy.props import (StringProperty, IntProperty, CollectionProperty, PointerP from .utils import generate_wrapper_propertyGroup from . import process_component -def process_map(registry, definition, update, nesting=[], nesting_long_names=[]): +def process_map(registry, definition, update, nesting_long_names=[]): value_types_defaults = registry.value_types_defaults type_infos = registry.type_infos - short_name = definition["short_name"] long_name = definition["long_name"] - nesting = nesting + [short_name] nesting_long_names = nesting_long_names + [long_name] value_ref_name = definition["valueType"]["type"]["$ref"].replace("#/$defs/", "") @@ -26,9 +24,9 @@ def process_map(registry, definition, update, nesting=[], nesting_long_names=[]) #if the content of the list is a unit type, we need to generate a fake wrapper, otherwise we cannot use layout.prop(group, "propertyName") as there is no propertyName ! if is_key_value_type: - keys_property_group_class = generate_wrapper_propertyGroup(f"{long_name}_keys", original_long_name, definition_link, registry, update) + keys_property_group_class = generate_wrapper_propertyGroup(f"{long_name}_keys", original_long_name, definition_link, registry, update, nesting_long_names=nesting_long_names) else: - (_, list_content_group_class) = process_component.process_component(registry, key_definition, update, {"nested": True, "long_name": original_long_name}, nesting, nesting_long_names) + (_, list_content_group_class) = process_component.process_component(registry, key_definition, update, {"nested": True, "long_name": original_long_name}, nesting_long_names=nesting_long_names) keys_property_group_class = list_content_group_class keys_collection = CollectionProperty(type=keys_property_group_class) @@ -45,9 +43,9 @@ def process_map(registry, definition, update, nesting=[], nesting_long_names=[]) #if the content of the list is a unit type, we need to generate a fake wrapper, otherwise we cannot use layout.prop(group, "propertyName") as there is no propertyName ! if is_value_value_type: - values_property_group_class = generate_wrapper_propertyGroup(f"{long_name}_values", original_long_name, definition_link, registry, update) + values_property_group_class = generate_wrapper_propertyGroup(f"{long_name}_values", original_long_name, definition_link, registry, update, nesting_long_names) else: - (_, list_content_group_class) = process_component.process_component(registry, value_definition, update, {"nested": True, "long_name": original_long_name}, nesting, nesting_long_names) + (_, list_content_group_class) = process_component.process_component(registry, value_definition, update, {"nested": True, "long_name": original_long_name}, nesting_long_names) values_property_group_class = list_content_group_class values_collection = CollectionProperty(type=values_property_group_class) diff --git a/tools/blenvy/add_ons/bevy_components/propGroups/process_structs.py b/tools/blenvy/add_ons/bevy_components/propGroups/process_structs.py index eff67d0..c3ec85b 100644 --- a/tools/blenvy/add_ons/bevy_components/propGroups/process_structs.py +++ b/tools/blenvy/add_ons/bevy_components/propGroups/process_structs.py @@ -1,16 +1,14 @@ from bpy.props import (StringProperty) from . import process_component -def process_structs(registry, definition, properties, update, nesting, nesting_long_names): +def process_structs(registry, definition, properties, update, nesting_long_names): value_types_defaults = registry.value_types_defaults blender_property_mapping = registry.blender_property_mapping type_infos = registry.type_infos long_name = definition["long_name"] - short_name = definition["short_name"] __annotations__ = {} default_values = {} - nesting = nesting + [short_name] nesting_long_names = nesting_long_names + [long_name] for property_name in properties.keys(): @@ -35,7 +33,7 @@ def process_structs(registry, definition, properties, update, nesting, nesting_l __annotations__[property_name] = blender_property else: original_long_name = original["long_name"] - (sub_component_group, _) = process_component.process_component(registry, original, update, {"nested": True, "long_name": original_long_name}, nesting, nesting_long_names) + (sub_component_group, _) = process_component.process_component(registry, original, update, {"nested": True, "long_name": original_long_name}, nesting_long_names) __annotations__[property_name] = sub_component_group # if there are sub fields, add an attribute "sub_fields" possibly a pointer property ? or add a standard field to the type , that is stored under "attributes" and not __annotations (better) else: diff --git a/tools/blenvy/add_ons/bevy_components/propGroups/process_tupples.py b/tools/blenvy/add_ons/bevy_components/propGroups/process_tupples.py index 8513875..acd6a00 100644 --- a/tools/blenvy/add_ons/bevy_components/propGroups/process_tupples.py +++ b/tools/blenvy/add_ons/bevy_components/propGroups/process_tupples.py @@ -1,14 +1,12 @@ from bpy.props import (StringProperty) from . import process_component -def process_tupples(registry, definition, prefixItems, update, nesting=[], nesting_long_names=[]): +def process_tupples(registry, definition, prefixItems, update, nesting_long_names=[]): value_types_defaults = registry.value_types_defaults blender_property_mapping = registry.blender_property_mapping type_infos = registry.type_infos long_name = definition["long_name"] - short_name = definition["short_name"] - nesting = nesting + [short_name] nesting_long_names = nesting_long_names + [long_name] __annotations__ = {} @@ -41,7 +39,7 @@ def process_tupples(registry, definition, prefixItems, update, nesting=[], nesti __annotations__[property_name] = blender_property else: original_long_name = original["long_name"] - (sub_component_group, _) = process_component.process_component(registry, original, update, {"nested": True, "long_name": original_long_name}, nesting) + (sub_component_group, _) = process_component.process_component(registry, original, update, {"nested": True, "long_name": original_long_name}, nesting_long_names=nesting_long_names) __annotations__[property_name] = sub_component_group else: # component not found in type_infos, generating placeholder diff --git a/tools/blenvy/add_ons/bevy_components/propGroups/prop_groups.py b/tools/blenvy/add_ons/bevy_components/propGroups/prop_groups.py index 6743893..d288acc 100644 --- a/tools/blenvy/add_ons/bevy_components/propGroups/prop_groups.py +++ b/tools/blenvy/add_ons/bevy_components/propGroups/prop_groups.py @@ -37,9 +37,9 @@ def generate_propertyGroups_for_components(): for component_name in type_infos: definition = type_infos[component_name] is_component = definition['isComponent'] if "isComponent" in definition else False - root_property_name = component_name if is_component else None - #print("root property", root_property_name) - process_component(registry, definition, update_calback_helper(definition, update_component, root_property_name), None, []) + root_property_name = component_name# if is_component else None + print("root property", component_name,f"({is_component})") + process_component(registry, definition, update_calback_helper(definition, update_component, root_property_name), extras=None, nesting_long_names=[]) # if we had to add any wrapper types on the fly, process them now registry.process_custom_types() \ No newline at end of file diff --git a/tools/blenvy/add_ons/bevy_components/propGroups/utils.py b/tools/blenvy/add_ons/bevy_components/propGroups/utils.py index 0b50dd4..9c0b928 100644 --- a/tools/blenvy/add_ons/bevy_components/propGroups/utils.py +++ b/tools/blenvy/add_ons/bevy_components/propGroups/utils.py @@ -8,12 +8,16 @@ from bpy_types import PropertyGroup # this helper creates a "fake"/wrapper property group that is NOT a real type in the registry # usefull for things like value types in list items etc -def generate_wrapper_propertyGroup(wrapped_type_long_name_name, item_long_name, definition_link, registry, update): +def generate_wrapper_propertyGroup(wrapped_type_long_name, item_long_name, definition_link, registry, update, nesting_long_names=[]): value_types_defaults = registry.value_types_defaults blender_property_mapping = registry.blender_property_mapping is_item_value_type = item_long_name in value_types_defaults - wrapper_name = "wrapper_" + wrapped_type_long_name_name + + wrapper_name = "wrapper_" + wrapped_type_long_name + + #nesting = nesting + [short_name] + nesting_long_names = nesting_long_names + [wrapper_name] wrapper_definition = { "isComponent": False, @@ -33,7 +37,7 @@ def generate_wrapper_propertyGroup(wrapped_type_long_name_name, item_long_name, } # we generate a very small 'hash' for the component name - property_group_name = registry.generate_propGroup_name(nesting=[], longName=wrapper_name) + property_group_name = registry.generate_propGroup_name(nesting=nesting_long_names) registry.add_custom_type(wrapper_name, wrapper_definition) diff --git a/tools/blenvy/add_ons/bevy_components/registry/registry.py b/tools/blenvy/add_ons/bevy_components/registry/registry.py index d3715d1..256ee4c 100644 --- a/tools/blenvy/add_ons/bevy_components/registry/registry.py +++ b/tools/blenvy/add_ons/bevy_components/registry/registry.py @@ -217,25 +217,27 @@ class ComponentsRegistry(PropertyGroup): long_names_to_propgroup_names = {} - # generate propGroup name from nesting level & longName: each longName + nesting is unique - def generate_propGroup_name(self, nesting, longName): + # generate propGroup name from nesting level: each longName + nesting is unique + def generate_propGroup_name(self, nesting): #print("gen propGroup name for", shortName, nesting) - key = str(nesting) + longName if len(nesting) > 0 else longName + key = str(nesting) propGroupHash = tiger_hash(key) propGroupName = propGroupHash + "_ui" # check for collision - #print("--computing hash for", nesting, longName) + padding = " " * (len(nesting) + 1) + + print(f"{padding}--computing hash for", nesting) if propGroupName in self.long_names_to_propgroup_names.values(): - print(" WARNING !! you have a collision between the hash of multiple component names: collision for", nesting, longName) + print(" WARNING !! you have a collision between the hash of multiple component names: collision for", nesting) self.long_names_to_propgroup_names[key] = propGroupName return propGroupName def get_propertyGroupName_from_longName(self, longName): - return self.long_names_to_propgroup_names.get(longName, None) + return self.long_names_to_propgroup_names.get(str([longName]), None) ########### diff --git a/tools/blenvy/add_ons/bevy_components/settings.py b/tools/blenvy/add_ons/bevy_components/settings.py index ce4a30c..7ba4660 100644 --- a/tools/blenvy/add_ons/bevy_components/settings.py +++ b/tools/blenvy/add_ons/bevy_components/settings.py @@ -62,15 +62,15 @@ class ComponentsSettings(PropertyGroup): schema_path: StringProperty( name="schema path", - description="path to the registry schema file", + description="path to the registry schema file (relative to the assets path)", default="registry.json", update=save_settings )# type: ignore schema_path_full: StringProperty( name="schema full path", - description="path to the registry schema file", - get=lambda self: os.path.abspath(os.path.join(os.path.dirname(bpy.data.filepath), self.schema_path)) + description="full path to the registry schema file", + get=lambda self: os.path.abspath(os.path.join(bpy.context.window_manager.blenvy.assets_path_full, self.schema_path)) ) # type: ignore watcher_enabled: BoolProperty(name="Watcher_enabled", default=True, update=toggle_watcher)# type: ignore