diff --git a/tools/bevy_components/TODO.md b/tools/bevy_components/TODO.md index c006fce..6efab50 100644 --- a/tools/bevy_components/TODO.md +++ b/tools/bevy_components/TODO.md @@ -206,4 +206,11 @@ UI: - [x] delete => remove - [x] clean up reloading of registry settings -- [x] clean up file watcher \ No newline at end of file +- [x] clean up file watcher + + +========================================= +Restructuring of storage of components +- [x] marking of invalid root propgroups/components should be based on long name +- [ ] overhaul & check each prop group type's use of short names => long names + - [ ] lists \ No newline at end of file diff --git a/tools/bevy_components/__init__.py b/tools/bevy_components/__init__.py index 48effb9..66dc951 100644 --- a/tools/bevy_components/__init__.py +++ b/tools/bevy_components/__init__.py @@ -22,8 +22,7 @@ from .registry.registry import ComponentsRegistry,MissingBevyType from .registry.operators import (COMPONENTS_OT_REFRESH_CUSTOM_PROPERTIES_ALL, COMPONENTS_OT_REFRESH_CUSTOM_PROPERTIES_CURRENT, COMPONENTS_OT_REFRESH_PROPGROUPS_FROM_CUSTOM_PROPERTIES_ALL, COMPONENTS_OT_REFRESH_PROPGROUPS_FROM_CUSTOM_PROPERTIES_CURRENT, OT_select_component_name_to_replace, OT_select_object, ReloadRegistryOperator, OT_OpenFilebrowser) from .registry.ui import (BEVY_COMPONENTS_PT_Configuration, BEVY_COMPONENTS_PT_AdvancedToolsPanel, BEVY_COMPONENTS_PT_MissingTypesPanel, MISSING_TYPES_UL_List) -from .components.metadata import (ComponentMetadata, ComponentsMeta, ensure_metadata_for_all_objects) -from .propGroups.prop_groups import (generate_propertyGroups_for_components) +from .components.metadata import (ComponentMetadata, ComponentsMeta) from .components.lists import GENERIC_LIST_OT_actions, Generic_LIST_OT_AddItem, Generic_LIST_OT_RemoveItem, Generic_LIST_OT_SelectItem from .components.definitions_list import (ComponentDefinitionsList, ClearComponentDefinitionsList) from .components.ui import (BEVY_COMPONENTS_PT_ComponentsPanel) diff --git a/tools/bevy_components/components/definitions_list.py b/tools/bevy_components/components/definitions_list.py index 51659e7..ca953e6 100644 --- a/tools/bevy_components/components/definitions_list.py +++ b/tools/bevy_components/components/definitions_list.py @@ -47,12 +47,12 @@ class ComponentDefinitionsList(bpy.types.PropertyGroup): description="list", # items argument required to initialize, just filled with empty values items = add_component_to_ui_list, - ) + ) # type: ignore filter: StringProperty( name="component filter", description="filter for the components list", options={'TEXTEDIT_UPDATE'} - ) + ) # type: ignore class ClearComponentDefinitionsList(bpy.types.Operator): diff --git a/tools/bevy_components/components/lists.py b/tools/bevy_components/components/lists.py index f16421d..a613a83 100644 --- a/tools/bevy_components/components/lists.py +++ b/tools/bevy_components/components/lists.py @@ -10,19 +10,19 @@ class Generic_LIST_OT_AddItem(Operator): property_group_path: StringProperty( name="property group path", description="", - ) + ) # type: ignore component_name: StringProperty( name="component name", description="", - ) + ) # type: ignore def execute(self, context): print("") object = context.object # information is stored in component meta components_in_object = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == self.component_name, components_in_object), None) + component_meta = next(filter(lambda component: component["long_name"] == self.component_name, components_in_object), None) propertyGroup = component_meta for path_item in json.loads(self.property_group_path): @@ -47,19 +47,19 @@ class Generic_LIST_OT_RemoveItem(Operator): property_group_path: StringProperty( name="property group path", description="", - ) + ) # type: ignore component_name: StringProperty( name="component name", description="", - ) + ) # type: ignore def execute(self, context): print("remove from list", context.object) object = context.object # information is stored in component meta components_in_object = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == self.component_name, components_in_object), None) + component_meta = next(filter(lambda component: component["long_name"] == self.component_name, components_in_object), None) propertyGroup = component_meta for path_item in json.loads(self.property_group_path): @@ -81,14 +81,14 @@ class Generic_LIST_OT_SelectItem(Operator): property_group_path: StringProperty( name="property group path", description="", - ) + ) # type: ignore component_name: StringProperty( name="component name", description="", - ) + ) # type: ignore - selection_index: IntProperty() + selection_index: IntProperty() # type: ignore def execute(self, context): print("select in list", context.object) @@ -96,7 +96,7 @@ class Generic_LIST_OT_SelectItem(Operator): object = context.object # information is stored in component meta components_in_object = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == self.component_name, components_in_object), None) + component_meta = next(filter(lambda component: component["long_name"] == self.component_name, components_in_object), None) propertyGroup = component_meta for path_item in json.loads(self.property_group_path): @@ -121,23 +121,23 @@ class GENERIC_LIST_OT_actions(Operator): ('UP', "Up", ""), ('DOWN', "Down", ""), ('REMOVE', "Remove", ""), - ('ADD', "Add", ""))) + ('ADD', "Add", ""))) # type: ignore property_group_path: StringProperty( name="property group path", description="", - ) + ) # type: ignore component_name: StringProperty( name="component name", description="", - ) + ) # type: ignore def invoke(self, context, event): object = context.object # information is stored in component meta components_in_object = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == self.component_name, components_in_object), None) + component_meta = next(filter(lambda component: component["long_name"] == self.component_name, components_in_object), None) propertyGroup = component_meta for path_item in json.loads(self.property_group_path): diff --git a/tools/bevy_components/components/metadata.py b/tools/bevy_components/components/metadata.py index f792cf7..bbb2ae0 100644 --- a/tools/bevy_components/components/metadata.py +++ b/tools/bevy_components/components/metadata.py @@ -10,51 +10,51 @@ class ComponentMetadata(bpy.types.PropertyGroup): name : bpy.props.StringProperty( name = "name", default = "" - ) + ) # type: ignore long_name : bpy.props.StringProperty( name = "long name", default = "" - ) + ) # type: ignore type_name : bpy.props.StringProperty( name = "Type", default = "" - ) + ) # type: ignore values: bpy.props.StringProperty( name = "Value", default = "" - ) + ) # type: ignore enabled: BoolProperty( name="enabled", description="component enabled", default=True - ) + ) # type: ignore invalid: BoolProperty( name="invalid", description="component is invalid, because of missing registration/ other issues", default=False - ) + ) # type: ignore invalid_details: StringProperty( name="invalid details", description="detailed information about why the component is invalid", default="" - ) + ) # type: ignore visible: BoolProperty( # REALLY dislike doing this for UI control, but ok hack for now default=True - ) + ) # type: ignore class ComponentsMeta(PropertyGroup): infos_per_component: StringProperty( name="infos per component", description="component" - ) - components: bpy.props.CollectionProperty(type = ComponentMetadata) + ) # type: ignore + components: bpy.props.CollectionProperty(type = ComponentMetadata) # type: ignore @classmethod def register(cls): @@ -72,7 +72,9 @@ def get_component_metadata_by_short_name(object, short_name): # remove no longer valid metadata from object def cleanup_invalid_metadata(object): - bevy_components = json.loads(object['bevy_components']) if 'bevy_components' in object else {} + bevy_components = get_bevy_components(object) + if len(bevy_components.keys()) == 0: # no components, bail out + return components_metadata = object.components_meta.components to_remove = [] for index, component_meta in enumerate(components_metadata): @@ -93,6 +95,10 @@ def find_component_definition_from_short_name(short_name): return registry.type_infos.get(long_name, None) return None +def find_component_definition_from_long_name(long_name): + registry = bpy.context.window_manager.components_registry + return registry.type_infos.get(long_name, None) + # FIXME: feels a bit heavy duty, should only be done # if the components panel is active ? def ensure_metadata_for_all_objects(): @@ -123,31 +129,45 @@ def do_object_custom_properties_have_missing_metadata(object): return missing_metadata -# adds metadata to object only if it is missing -def add_metadata_to_components_without_metadata(object): - registry = bpy.context.window_manager.components_registry - - for component_name in dict(object) : - if component_name == "components_meta": - continue - upsert_component_in_object(object, component_name, registry) - - import json -def inject_component(object, long_name, value): +def upsert_bevy_component(object, long_name, value): if not 'bevy_components' in object: object['bevy_components'] = '{}' - previous = json.loads(object['bevy_components']) - previous[long_name] = value - object['bevy_components'] = json.dumps(previous) + bevy_components = json.loads(object['bevy_components']) + bevy_components[long_name] = value + object['bevy_components'] = json.dumps(bevy_components) #object['bevy_components'][long_name] = value # Sigh, this does not work, hits Blender's 63 char length limit -def bla_component(object, long_name): +def remove_bevy_component(object, long_name): if 'bevy_components' in object: current = json.loads(object['bevy_components']) del current[long_name] object['bevy_components'] = json.dumps(current) +def get_bevy_components(object): + if 'bevy_components' in object: + bevy_components = json.loads(object['bevy_components']) + return bevy_components + return {} + +def get_bevy_component_value_by_long_name(object, long_name): + bevy_components = get_bevy_components(object) + if len(bevy_components.keys()) == 0 : + return None + return bevy_components.get(long_name, None) + +def is_bevy_component_in_object(object, long_name): + return get_bevy_component_value_by_long_name(object, long_name) is not None + +# adds metadata to object only if it is missing +def add_metadata_to_components_without_metadata(object): + registry = bpy.context.window_manager.components_registry + + for component_name in get_bevy_components(object) : + if component_name == "components_meta": + continue + upsert_component_in_object(object, component_name, registry) + # adds a component to an object (including metadata) using the provided component definition & optional value def add_component_to_object(object, component_definition, value=None): cleanup_invalid_metadata(object) @@ -158,7 +178,6 @@ def add_component_to_object(object, component_definition, value=None): if not registry.has_type_infos(): raise Exception('registry type infos have not been loaded yet or are missing !') definition = registry.type_infos[long_name] - print("HEAAAY", value) # now we use our pre_generated property groups to set the initial value of our custom property (_, propertyGroup) = upsert_component_in_object(object, long_name=long_name, registry=registry) if value == None: @@ -170,7 +189,7 @@ def add_component_to_object(object, component_definition, value=None): # object[short_name] = value print("ADDING VAALUEEE", value) - inject_component(object, long_name, value) + upsert_bevy_component(object, long_name, value) #ping_depsgraph_update(object) @@ -226,14 +245,14 @@ def copy_propertyGroup_values_to_another_object(source_object, target_object, co if source_object == None or target_object == None or component_name == None: raise Exception('missing input data, cannot copy component propertryGroup') - component_definition = find_component_definition_from_short_name(component_name) - short_name = component_definition["short_name"] - property_group_name = registry.get_propertyGroupName_from_shortName(short_name) + component_definition = find_component_definition_from_long_name(component_name) + long_name = component_name + property_group_name = registry.get_propertyGroupName_from_longName(long_name) registry = bpy.context.window_manager.components_registry source_components_metadata = source_object.components_meta.components - source_componentMeta = next(filter(lambda component: component["name"] == short_name, source_components_metadata), None) + source_componentMeta = next(filter(lambda component: component["long_name"] == long_name, source_components_metadata), None) # matching component means we already have this type of component source_propertyGroup = getattr(source_componentMeta, property_group_name) @@ -241,28 +260,27 @@ def copy_propertyGroup_values_to_another_object(source_object, target_object, co (_, target_propertyGroup) = upsert_component_in_object(target_object, component_name, registry) # add to object value = property_group_value_to_custom_property_value(target_propertyGroup, component_definition, registry, None) - target_object[short_name] = value + upsert_bevy_component(target_object, long_name, value) # copy the values over for field_name in source_propertyGroup.field_names: if field_name in source_propertyGroup: target_propertyGroup[field_name] = source_propertyGroup[field_name] apply_propertyGroup_values_to_object_customProperties(target_object) - ping_depsgraph_update(object) # TODO: move to propgroups ? def apply_propertyGroup_values_to_object_customProperties(object): cleanup_invalid_metadata(object) registry = bpy.context.window_manager.components_registry - for component_name in dict(object) : - if component_name == "components_meta": - continue + for component_name in get_bevy_components(object) : + """if component_name == "components_meta": + continue""" (_, propertyGroup) = upsert_component_in_object(object, component_name, registry) - component_definition = find_component_definition_from_short_name(component_name) + component_definition = find_component_definition_from_long_name(component_name) if component_definition != None: value = property_group_value_to_custom_property_value(propertyGroup, component_definition, registry, None) - object[component_name] = value + upsert_bevy_component(object=object, long_name=component_name, value=value) # apply component value(s) to custom property of a single component def apply_propertyGroup_values_to_object_customProperties_for_component(object, component_name): @@ -304,7 +322,7 @@ def apply_customProperty_values_to_object_propertyGroups(object): # removes the given component from the object: removes both the custom property and the matching metadata from the object def remove_component_from_object(object, component_name): - bla_component(object, component_name) + remove_bevy_component(object, component_name) components_metadata = getattr(object, "components_meta", None) if components_metadata == None: @@ -319,16 +337,14 @@ def remove_component_from_object(object, component_name): break for index in to_remove: components_metadata.remove(index) - ping_depsgraph_update(object) return True def add_component_from_custom_property(object): add_metadata_to_components_without_metadata(object) apply_customProperty_values_to_object_propertyGroups(object) - ping_depsgraph_update(object) def toggle_component(object, component_name): components_in_object = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == component_name, components_in_object), None) + component_meta = next(filter(lambda component: component["long_name"] == component_name, components_in_object), None) if component_meta != None: component_meta.visible = not component_meta.visible diff --git a/tools/bevy_components/components/operators.py b/tools/bevy_components/components/operators.py index 873c16a..a8b0419 100644 --- a/tools/bevy_components/components/operators.py +++ b/tools/bevy_components/components/operators.py @@ -4,7 +4,7 @@ import bpy from bpy_types import Operator from bpy.props import (StringProperty) -from .metadata import add_component_from_custom_property, add_component_to_object, add_metadata_to_components_without_metadata, apply_customProperty_values_to_object_propertyGroups, apply_propertyGroup_values_to_object_customProperties_for_component, copy_propertyGroup_values_to_another_object, find_component_definition_from_short_name, remove_component_from_object, toggle_component +from .metadata import add_component_from_custom_property, add_component_to_object, add_metadata_to_components_without_metadata, apply_customProperty_values_to_object_propertyGroups, apply_propertyGroup_values_to_object_customProperties_for_component, copy_propertyGroup_values_to_another_object, find_component_definition_from_short_name, get_bevy_component_value_by_long_name, get_bevy_components, is_bevy_component_in_object, remove_component_from_object, toggle_component class AddComponentOperator(Operator): """Add Bevy component to object""" @@ -36,7 +36,7 @@ class CopyComponentOperator(Operator): bl_options = {"UNDO"} source_component_name: StringProperty( - name="source component_name", + name="source component_name (long)", description="name of the component to copy", ) # type: ignore @@ -80,10 +80,10 @@ class PasteComponentOperator(Operator): self.report({"ERROR"}, "The source object to copy a component from does not exist") else: component_name = context.window_manager.copied_source_component_name - if not component_name in source_object: + component_value = get_bevy_component_value_by_long_name(source_object, component_name) + if component_value is None: self.report({"ERROR"}, "The source component to copy from does not exist") else: - component_value = source_object[component_name] print("pasting component to object: component name:", str(component_name), "component value:" + str(component_value)) print (context.object) registry = context.window_manager.components_registry @@ -114,10 +114,15 @@ class RemoveComponentOperator(Operator): else: object = bpy.data.objects[self.object_name] print("removing component ", self.component_name, "from object '"+object.name+"'") - if object is not None and 'bevy_components' in object and self.component_name in object['bevy_components']: - remove_component_from_object(object, self.component_name) + + if object is not None and 'bevy_components' in object : + component_value = get_bevy_component_value_by_long_name(object, self.component_name) + if component_value is not None: + remove_component_from_object(object, self.component_name) + else : + self.report({"ERROR"}, "The component to remove ("+ self.component_name +") does not exist") else: - self.report({"ERROR"}, "The object/ component to remove ("+ self.component_name +") does not exist") + self.report({"ERROR"}, "The object to remove ("+ self.component_name +") from does not exist") return {'FINISHED'} @@ -145,7 +150,7 @@ class RemoveComponentFromAllObjectsOperator(Operator): total = len(bpy.data.objects) for index, object in enumerate(bpy.data.objects): if len(object.keys()) > 0: - if object is not None and self.component_name in object: + if object is not None and is_bevy_component_in_object(object, self.component_name): remove_component_from_object(object, self.component_name) progress = index / total @@ -222,7 +227,7 @@ class OT_rename_component(Operator): components_metadata = getattr(object, "components_meta", None) if components_metadata: components_metadata = components_metadata.components - component_meta = next(filter(lambda component: component["name"] == new_name, components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == new_name, components_metadata), None) if component_meta: component_meta.invalid = True component_meta.invalid_details = "unknow issue when renaming/transforming component, please remove it & add it back again" @@ -240,7 +245,7 @@ class OT_rename_component(Operator): components_metadata = getattr(object, "components_meta", None) if components_metadata: components_metadata = components_metadata.components - component_meta = next(filter(lambda component: component["name"] == new_name, components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == new_name, components_metadata), None) if component_meta: component_meta.invalid = True component_meta.invalid_details = "wrong custom property value, overwrite them by changing the values in the ui or change them & regenerate" diff --git a/tools/bevy_components/components/ui.py b/tools/bevy_components/components/ui.py index c5ed979..d9f883f 100644 --- a/tools/bevy_components/components/ui.py +++ b/tools/bevy_components/components/ui.py @@ -178,12 +178,12 @@ class BEVY_COMPONENTS_PT_ComponentsPanel(bpy.types.Panel): # we fetch the matching ui property group root_propertyGroup_name = registry.get_propertyGroupName_from_longName(component_name) - print("root_propertyGroup_name", root_propertyGroup_name) - print("component_meta", component_meta, component_invalid) + """print("root_propertyGroup_name", root_propertyGroup_name) + print("component_meta", component_meta, component_invalid)""" if root_propertyGroup_name: propertyGroup = getattr(component_meta, root_propertyGroup_name, None) - print("propertyGroup", propertyGroup) + """print("propertyGroup", propertyGroup)""" if propertyGroup: # if the component has only 0 or 1 field names, display inline, otherwise change layout single_field = len(propertyGroup.field_names) < 2 diff --git a/tools/bevy_components/propGroups/process_component.py b/tools/bevy_components/propGroups/process_component.py index 21521a3..6887fba 100644 --- a/tools/bevy_components/propGroups/process_component.py +++ b/tools/bevy_components/propGroups/process_component.py @@ -6,7 +6,7 @@ from . import process_tupples from . import process_enum from . import process_list -def process_component(registry, definition, update, extras=None, nesting = []): +def process_component(registry, definition, update, extras=None, nesting = [], nesting_long_names = []): component_name = definition['title'] short_name = definition["short_name"] type_info = definition["typeInfo"] if "typeInfo" in definition else None @@ -31,21 +31,21 @@ def process_component(registry, definition, update, extras=None, nesting = []): if has_properties: - __annotations__ = __annotations__ | process_structs.process_structs(registry, definition, properties, update, nesting) + __annotations__ = __annotations__ | process_structs.process_structs(registry, definition, properties, update, nesting, nesting_long_names) with_properties = True tupple_or_struct = "struct" if has_prefixItems: - __annotations__ = __annotations__ | process_tupples.process_tupples(registry, definition, prefixItems, update, nesting) + __annotations__ = __annotations__ | process_tupples.process_tupples(registry, definition, prefixItems, update, nesting, nesting_long_names) with_items = True tupple_or_struct = "tupple" if is_enum: - __annotations__ = __annotations__ | process_enum.process_enum(registry, definition, update, nesting) + __annotations__ = __annotations__ | process_enum.process_enum(registry, definition, update, nesting, nesting_long_names) with_enum = True if is_list: - __annotations__ = __annotations__ | process_list.process_list(registry, definition, update, nesting) + __annotations__ = __annotations__ | process_list.process_list(registry, definition, update, nesting, nesting_long_names) with_list= True field_names = [] @@ -56,7 +56,7 @@ def process_component(registry, definition, update, extras=None, nesting = []): extras = extras if extras is not None else { "type_name": component_name } - root_component = nesting[0] if len(nesting) > 0 else component_name + root_component = nesting_long_names[0] if len(nesting_long_names) > 0 else component_name # print("DONE:",short_name,"__annotations__", __annotations__) # print("") property_group_params = { diff --git a/tools/bevy_components/propGroups/process_enum.py b/tools/bevy_components/propGroups/process_enum.py index e7a1e24..48ca16c 100644 --- a/tools/bevy_components/propGroups/process_enum.py +++ b/tools/bevy_components/propGroups/process_enum.py @@ -1,13 +1,17 @@ from bpy.props import (StringProperty) from . import process_component -def process_enum(registry, definition, update, nesting): +def process_enum(registry, definition, update, nesting, nesting_long_names): blender_property_mapping = registry.blender_property_mapping short_name = definition["short_name"] + long_name = definition["title"] + type_def = definition["type"] if "type" in definition else None values = definition["oneOf"] nesting = nesting + [short_name] + nesting_long_names = nesting_long_names = [long_name] + __annotations__ = {} original_type_name = "enum" @@ -25,12 +29,12 @@ def process_enum(registry, definition, update, nesting): if "prefixItems" in item: #print("tupple variant in enum", short_name, item) registry.add_custom_type(item_short_name, item) - (sub_component_group, _) = process_component.process_component(registry, item, update, {"nested": True}, nesting) + (sub_component_group, _) = process_component.process_component(registry, item, update, {"nested": True}, nesting, nesting_long_names) additional_annotations[variant_name] = sub_component_group elif "properties" in item: #print("struct variant in enum", short_name, item) registry.add_custom_type(item_short_name, item) - (sub_component_group, _) = process_component.process_component(registry, item, update, {"nested": True}, nesting) + (sub_component_group, _) = process_component.process_component(registry, item, update, {"nested": True}, nesting, nesting_long_names) additional_annotations[variant_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", short_name) diff --git a/tools/bevy_components/propGroups/process_list.py b/tools/bevy_components/propGroups/process_list.py index 0d9fc73..16fb8bc 100644 --- a/tools/bevy_components/propGroups/process_list.py +++ b/tools/bevy_components/propGroups/process_list.py @@ -2,11 +2,12 @@ from bpy.props import (StringProperty, IntProperty, CollectionProperty) from .utils import generate_wrapper_propertyGroup from . import process_component -def process_list(registry, definition, update, nesting=[]): +def process_list(registry, definition, update, nesting=[], nesting_long_names=[]): value_types_defaults = registry.value_types_defaults type_infos = registry.type_infos short_name = definition["short_name"] + long_name = definition["title"] ref_name = definition["items"]["type"]["$ref"].replace("#/$defs/", "") item_definition = type_infos[ref_name] @@ -23,6 +24,8 @@ def process_list(registry, definition, update, nesting=[]): property_group_class = list_content_group_class nesting = nesting+[short_name] + nesting_long_names = nesting_long_names + [long_name] + item_collection = CollectionProperty(type=property_group_class) item_short_name = item_short_name if not is_item_value_type else "wrapper_" + item_short_name diff --git a/tools/bevy_components/propGroups/process_structs.py b/tools/bevy_components/propGroups/process_structs.py index 89ac7e7..8183d40 100644 --- a/tools/bevy_components/propGroups/process_structs.py +++ b/tools/bevy_components/propGroups/process_structs.py @@ -1,15 +1,17 @@ from bpy.props import (StringProperty) from . import process_component -def process_structs(registry, definition, properties, update, nesting): +def process_structs(registry, definition, properties, update, nesting, 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["title"] 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(): ref_name = properties[property_name]["type"]["$ref"].replace("#/$defs/", "") @@ -33,7 +35,7 @@ def process_structs(registry, definition, properties, update, nesting): __annotations__[property_name] = blender_property else: original_long_name = original["title"] - (sub_component_group, _) = process_component.process_component(registry, original, update, {"nested": True, "type_name": original_long_name}, nesting) + (sub_component_group, _) = process_component.process_component(registry, original, update, {"nested": True, "type_name": original_long_name}, nesting, 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: @@ -41,6 +43,6 @@ def process_structs(registry, definition, properties, update, nesting): __annotations__[property_name] = StringProperty(default="N/A") registry.add_missing_typeInfo(ref_name) # the root component also becomes invalid (in practice it is not always a component, but good enough) - registry.add_invalid_component(nesting[0]) + registry.add_invalid_component(nesting_long_names[0]) return __annotations__ diff --git a/tools/bevy_components/propGroups/process_tupples.py b/tools/bevy_components/propGroups/process_tupples.py index feafcc2..c7af472 100644 --- a/tools/bevy_components/propGroups/process_tupples.py +++ b/tools/bevy_components/propGroups/process_tupples.py @@ -1,13 +1,15 @@ from bpy.props import (StringProperty) from . import process_component -def process_tupples(registry, definition, prefixItems, update, nesting=[]): +def process_tupples(registry, definition, prefixItems, update, nesting=[], 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["title"] short_name = definition["short_name"] nesting = nesting+[short_name] + nesting_long_names = nesting_long_names + [long_name] __annotations__ = {} default_values = [] @@ -46,7 +48,7 @@ def process_tupples(registry, definition, prefixItems, update, nesting=[]): __annotations__[property_name] = StringProperty(default="N/A") registry.add_missing_typeInfo(ref_name) # the root component also becomes invalid (in practice it is not always a component, but good enough) - registry.add_invalid_component(nesting[0]) + registry.add_invalid_component(nesting_long_names[0]) return __annotations__ diff --git a/tools/bevy_components/propGroups/prop_groups.py b/tools/bevy_components/propGroups/prop_groups.py index 8ac1a1b..9f60981 100644 --- a/tools/bevy_components/propGroups/prop_groups.py +++ b/tools/bevy_components/propGroups/prop_groups.py @@ -3,6 +3,7 @@ from .conversions_from_prop_group import property_group_value_to_custom_property from .process_component import process_component from .utils import update_calback_helper +import json ## main callback function, fired whenever any property changes, no matter the nesting level def update_component(self, context, definition, component_name): registry = bpy.context.window_manager.components_registry @@ -14,12 +15,17 @@ def update_component(self, context, definition, component_name): print("") print("update in component", component_name, self, "current_object", current_object.name) components_in_object = current_object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == component_name, components_in_object), None) + component_meta = next(filter(lambda component: component["long_name"] == component_name, components_in_object), None) + print("component_meta", component_meta) + if component_meta != None: - property_group_name = registry.get_propertyGroupName_from_shortName(component_name) - self = getattr(component_meta, property_group_name) + property_group_name = registry.get_propertyGroupName_from_longName(component_name) + property_group = getattr(component_meta, property_group_name) # we use our helper to set the values - context.object[component_name] = property_group_value_to_custom_property_value(self, definition, registry, None) + object = context.object + previous = json.loads(object['bevy_components']) + previous[component_name] = property_group_value_to_custom_property_value(property_group, definition, registry, None) + object['bevy_components'] = json.dumps(previous) def generate_propertyGroups_for_components(): @@ -31,9 +37,8 @@ def generate_propertyGroups_for_components(): for component_name in type_infos: definition = type_infos[component_name] - short_name = definition["short_name"] is_component = definition['isComponent'] if "isComponent" in definition else False - root_property_name = short_name if is_component else None + root_property_name = component_name if is_component else None process_component(registry, definition, update_calback_helper(definition, update_component, root_property_name), None, []) # if we had to add any wrapper types on the fly, process them now diff --git a/tools/bevy_components/propGroups/utils.py b/tools/bevy_components/propGroups/utils.py index b784962..975339f 100644 --- a/tools/bevy_components/propGroups/utils.py +++ b/tools/bevy_components/propGroups/utils.py @@ -52,7 +52,6 @@ def generate_wrapper_propertyGroup(short_name, item_long_name, definition, regis 'tupple_or_struct': "tupple", 'field_names': ['0'], **dict(with_properties = False, with_items= True, with_enum= False, with_list= False, short_name= wrapper_name, type_name=wrapper_name), - #'root_component': root_component } property_group_class = type(wrapper_name, (PropertyGroup,), property_group_params) bpy.utils.register_class(property_group_class) diff --git a/tools/bevy_components/registry/registry.py b/tools/bevy_components/registry/registry.py index 8298d50..0a5e603 100644 --- a/tools/bevy_components/registry/registry.py +++ b/tools/bevy_components/registry/registry.py @@ -317,6 +317,7 @@ class ComponentsRegistry(PropertyGroup): self.type_infos[type_name] = self.custom_types_to_add[type_name] self.custom_types_to_add.clear() + # add an invalid component to the list (long name) def add_invalid_component(self, component_name): self.invalid_components.append(component_name) @@ -350,7 +351,7 @@ class ComponentsRegistry(PropertyGroup): self.short_names_to_propgroup_names[key] = propGroupName""" # FIXME: key = str(nesting) + longName if len(nesting) > 0 else longName - self.long_names_to_propgroup_names[longName] = propGroupName + self.long_names_to_propgroup_names[key] = propGroupName return propGroupName def get_propertyGroupName_from_shortName(self, shortName): diff --git a/tools/bevy_components/tests/test_components.py b/tools/bevy_components/tests/test_components.py index 42e5656..9709ace 100644 --- a/tools/bevy_components/tests/test_components.py +++ b/tools/bevy_components/tests/test_components.py @@ -39,7 +39,7 @@ def test_components_should_generate_correct_custom_properties(setup_data): property_group_name = registry.get_propertyGroupName_from_shortName(short_name) target_components_metadata = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None) propertyGroup = getattr(component_meta, property_group_name, None) added_components.append(component_type) custom_property_values[short_name] = object[short_name] @@ -87,7 +87,7 @@ def test_components_should_generate_correct_custom_properties_with_randomized_va property_group_name = registry.get_propertyGroupName_from_shortName(short_name) target_components_metadata = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None) propertyGroup = getattr(component_meta, property_group_name, None) component_values_shuffler(seed= 10, property_group=propertyGroup, definition=definition, registry=registry) @@ -136,7 +136,7 @@ def test_components_should_generate_correct_propertyGroup_values_from_custom_pro property_group_name = registry.get_propertyGroupName_from_shortName(short_name) target_components_metadata = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None) propertyGroup = getattr(component_meta, property_group_name, None) added_components.append(component_type) # randomise values @@ -195,7 +195,7 @@ def test_remove_components(setup_data): object = bpy.context.object target_components_metadata = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None) propertyGroup = getattr(component_meta, property_group_name, None) # print("propertyGroup", propertyGroup, propertyGroup.field_names) added_components.append(component_type) @@ -231,7 +231,7 @@ def test_copy_paste_components(setup_data): object = context.object target_components_metadata = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None) propertyGroup = getattr(component_meta, property_group_name, None) setattr(propertyGroup, propertyGroup.field_names[0], 25.0) @@ -246,7 +246,7 @@ def test_copy_paste_components(setup_data): # change name new_cube.name = "TargetCube" target_components_metadata = new_cube.components_meta.components - component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None) # first check that there is no component currently assert component_meta == None @@ -255,7 +255,7 @@ def test_copy_paste_components(setup_data): paste_component_operator() target_components_metadata = new_cube.components_meta.components - component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None) # now after pasting to the new object, it should have component meta assert component_meta != None diff --git a/tools/bevy_components/tests/test_registry.py b/tools/bevy_components/tests/test_registry.py index e13bb10..8dcd34c 100644 --- a/tools/bevy_components/tests/test_registry.py +++ b/tools/bevy_components/tests/test_registry.py @@ -16,7 +16,7 @@ def test_blend(setup_data): object = bpy.context.object target_components_metadata = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None) propertyGroup = getattr(component_meta, property_group_name, None) diff --git a/tools/bevy_components/tests/test_rename_components.py b/tools/bevy_components/tests/test_rename_components.py index 13efed6..adbecc8 100644 --- a/tools/bevy_components/tests/test_rename_components.py +++ b/tools/bevy_components/tests/test_rename_components.py @@ -9,7 +9,7 @@ from .setup_data import setup_data # small helpers def get_component_metadata(object, component_name): target_components_metadata = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == component_name, target_components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == component_name, target_components_metadata), None) return component_meta def get_component_propGroup(registry, component_name, component_meta): diff --git a/tools/bevy_components/tests/test_shuffler.py b/tools/bevy_components/tests/test_shuffler.py index 20ade74..0dbd0ed 100644 --- a/tools/bevy_components/tests/test_shuffler.py +++ b/tools/bevy_components/tests/test_shuffler.py @@ -19,7 +19,7 @@ def test_shuffler(setup_data): property_group_name = registry.get_propertyGroupName_from_shortName(short_name) target_components_metadata = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None) propertyGroup = getattr(component_meta, property_group_name, None) definition = type_infos[component_type] @@ -38,7 +38,7 @@ def test_shuffler(setup_data): property_group_name = registry.get_propertyGroupName_from_shortName(short_name) target_components_metadata = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None) propertyGroup = getattr(component_meta, property_group_name, None) definition = type_infos[component_type] @@ -57,7 +57,7 @@ def test_shuffler(setup_data): property_group_name = registry.get_propertyGroupName_from_shortName(short_name) target_components_metadata = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None) propertyGroup = getattr(component_meta, property_group_name, None) definition = type_infos[component_type] @@ -75,7 +75,7 @@ def test_shuffler(setup_data): property_group_name = registry.get_propertyGroupName_from_shortName(short_name) target_components_metadata = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None) propertyGroup = getattr(component_meta, property_group_name, None) definition = type_infos[component_type] @@ -95,7 +95,7 @@ def test_shuffler(setup_data): property_group_name = registry.get_propertyGroupName_from_shortName(short_name) target_components_metadata = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None) propertyGroup = getattr(component_meta, property_group_name, None) definition = type_infos[component_type] @@ -113,7 +113,7 @@ def test_shuffler(setup_data): property_group_name = registry.get_propertyGroupName_from_shortName(short_name) target_components_metadata = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None) propertyGroup = getattr(component_meta, property_group_name, None) definition = type_infos[component_type] @@ -130,7 +130,7 @@ def test_shuffler(setup_data): property_group_name = registry.get_propertyGroupName_from_shortName(short_name) target_components_metadata = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None) propertyGroup = getattr(component_meta, property_group_name, None) definition = type_infos[component_type] @@ -148,7 +148,7 @@ def test_shuffler(setup_data): property_group_name = registry.get_propertyGroupName_from_shortName(short_name) target_components_metadata = object.components_meta.components - component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None) propertyGroup = getattr(component_meta, property_group_name, None) definition = type_infos[component_type]