From cca93b032f82cb678cb47781ec0290a6e9ef3a83 Mon Sep 17 00:00:00 2001 From: ChrisLR Date: Sat, 24 Feb 2024 14:35:46 -0500 Subject: [PATCH] Revert "Refactor _get_class_components" This reverts commit c4ec977b9cf79c218574dfcdb30f20bfb1619a52. --- .../base_systems/components/exceptions.py | 4 -- .../contrib/base_systems/components/holder.py | 46 +++++++++++-------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/evennia/contrib/base_systems/components/exceptions.py b/evennia/contrib/base_systems/components/exceptions.py index c331e7a608..7a2254c631 100644 --- a/evennia/contrib/base_systems/components/exceptions.py +++ b/evennia/contrib/base_systems/components/exceptions.py @@ -8,7 +8,3 @@ class ComponentDoesNotExist(ValueError): class ComponentIsNotRegistered(ValueError): pass - - -class ComponentSlotRegisteredTwice(ValueError): - pass diff --git a/evennia/contrib/base_systems/components/holder.py b/evennia/contrib/base_systems/components/holder.py index 238cc6b35f..a09844f457 100644 --- a/evennia/contrib/base_systems/components/holder.py +++ b/evennia/contrib/base_systems/components/holder.py @@ -42,6 +42,14 @@ class ComponentProperty: def __set__(self, instance, value): raise Exception("Cannot set a class property") + def __set_name__(self, owner, name): + # Retrieve the class_components set on the direct class only + class_components = owner.__dict__.get("_class_components", []) + if not class_components: + setattr(owner, "_class_components", class_components) + + class_components.append((self.name, self.values)) + class ComponentHandler: """ @@ -262,29 +270,27 @@ class ComponentHolderMixin: return getattr(self, "_signal_handler", None) def _get_class_components(self): - self_class = type(self) - class_components = getattr(self_class, "_class_components", None) - if class_components is not None: - return class_components + class_components = {} - class_components_by_slot = {} - for att_name in dir(self_class): - if att_name.startswith("__"): - continue + def base_type_iterator(): + base_stack = [type(self)] + while base_stack: + _base_type = base_stack.pop() + yield _base_type + base_stack.extend(_base_type.__bases__) - att_obj = getattr(self_class, att_name, None) - if isinstance(att_obj, ComponentProperty): - cmp_name = att_obj.name + for base_type in base_type_iterator(): + base_class_components = getattr(base_type, "_class_components", ()) + for cmp_name, cmp_values in base_class_components: cmp_class = get_component_class(cmp_name) cmp_slot = cmp_class.get_component_slot() - if cmp_slot in class_components_by_slot: - raise exceptions.ComponentSlotRegisteredTwice( - f"Component slot={cmp_slot} is registered twice on class={self_class}" - ) + class_components[cmp_slot] = (cmp_name, cmp_values) - class_components_by_slot[cmp_slot] = (cmp_name, att_obj.values) + # TODO Is this necessary? + instance_components = getattr(self, "_class_components", ()) + for cmp_name, cmp_values in instance_components: + cmp_class = get_component_class(cmp_name) + cmp_slot = cmp_class.get_component_slot() + class_components[cmp_slot] = (cmp_name, cmp_values) - class_components = tuple(class_components_by_slot.values()) - setattr(self_class, "_class_components", class_components) - - return class_components + return tuple(class_components.values())