From 31cfd22b8c0f6c6ae5d55a6311961073f037451e Mon Sep 17 00:00:00 2001 From: Steven Franklin Date: Sat, 9 Nov 2024 20:59:13 -0600 Subject: [PATCH] uses str enum - todo: just use strenum after we stop supporting 3.10 --- .../formats/bmssd.py | 47 +++++++++++-------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/src/mercury_engine_data_structures/formats/bmssd.py b/src/mercury_engine_data_structures/formats/bmssd.py index 5608af9..e171637 100644 --- a/src/mercury_engine_data_structures/formats/bmssd.py +++ b/src/mercury_engine_data_structures/formats/bmssd.py @@ -98,19 +98,29 @@ def crc_func(obj): return crc32 if obj._version == "1.12.0" else crc64 -class ItemType(Enum): - group_name: str +class ItemType(str, Enum): + group_index: int - SCENE_BLOCK = 0, "scene_blocks" - OBJECT = 1, "objects" - LIGHT = 2, "lights" + SCENE_BLOCK = "scene_blocks", 0 + OBJECT = "objects", 1 + LIGHT = "lights", 2 - def __new__(cls, value: int, group_name: str): - member = object.__new__(cls) - member._value_ = value - member.group_name = group_name + def __new__(cls, name: int, index: str): + member = str.__new__(cls, name) + member._value_ = name + member.group_index = index return member + @classmethod + def from_index(cls, val: int): + for it in cls: + if it.group_index == val: + return it + return ValueError(f"Value {val} is not a valid index of ItemType") + + def __format__(self, format_spec: str) -> str: + return self.value.__format__(format_spec) + class BmssdAdapter(Adapter): def _decode(self, obj, context, path): @@ -130,8 +140,7 @@ def _decode(self, obj, context, path): res.scene_groups[sg.sg_name] = construct.Container() for ig_value, items in sg.item_groups.items(): - group_type = ItemType(ig_value) - res.scene_groups[sg.sg_name][group_type] = construct.ListContainer() + group_type = ItemType.from_index(ig_value) # objects are indexed and not hashed if ig_value == 1: @@ -142,9 +151,7 @@ def _decode(self, obj, context, path): res.scene_groups[sg.sg_name][group_type] = construct.ListContainer( [ # use raw hash value instead of block value if it doesn't exist above - res[f"_{group_type.group_name}"][block] - if res[f"_{group_type.group_name}"].get(block, None) - else block + res[f"_{group_type}"][block] if res[f"_{group_type}"].get(block, None) else block for block in items ] ) @@ -199,9 +206,9 @@ def obj_to_tuple(o): item_count += len(items) if group_type == ItemType.OBJECT: - sg_cont.item_groups[group_type.value] = [object_order[obj_to_tuple(o)] for o in items] + sg_cont.item_groups[group_type.group_index] = [object_order[obj_to_tuple(o)] for o in items] else: - sg_cont.item_groups[group_type.value] = [ + sg_cont.item_groups[group_type.group_index] = [ # handle integers (unmatched crc's in decode) o if isinstance(o, int) else crc(o["model_name"]) for o in items @@ -223,13 +230,13 @@ def get_item(self, item_name_or_id: str | int, item_type: ItemType) -> construct if item_type == ItemType.OBJECT: return self.raw._objects[item_name_or_id] else: - return self.raw[f"_{item_type.group_name}"].get(item_name_or_id, None) + return self.raw[f"_{item_type}"].get(item_name_or_id, None) if item_type == ItemType.OBJECT: raise ValueError("If accessing an Object type item, must use the index!") crc = crc_func(self.raw) - return self.raw[f"_{item_type.group_name}"].get(crc(item_name_or_id), None) + return self.raw[f"_{item_type}"].get(crc(item_name_or_id), None) def get_scene_group(self, scene_group: str) -> construct.Container: return self.raw.scene_groups.get(scene_group, None) @@ -245,7 +252,7 @@ def add_item(self, item: construct.Container, item_type: ItemType, scene_groups: self.raw._objects.append(item) else: crc = crc_func(self.raw) - self.raw[f"_{item_type.group_name}"][crc(item["model_name"])] = item + self.raw[f"_{item_type}"][crc(item["model_name"])] = item for sg_name in scene_groups: self.get_scene_group(sg_name)[item_type].append(item) @@ -260,4 +267,4 @@ def remove_item(self, item: construct.Container, item_type: ItemType): for sg in groups: self.remove_item_from_group(item, item_type, sg) - self.raw[f"_{item_type.group_name}"].remove(item) + self.raw[f"_{item_type}"].remove(item)