From dc6131d121ddeefe685c53b35e94b3310c2ac0b4 Mon Sep 17 00:00:00 2001 From: ChrisLR Date: Sat, 19 Mar 2022 19:10:51 -0400 Subject: [PATCH] Added TagField for components --- .../base_systems/components/__init__.py | 2 +- .../base_systems/components/component.py | 5 +++ .../base_systems/components/dbfield.py | 43 +++++++++++++++++++ .../contrib/base_systems/components/holder.py | 14 ++++++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/evennia/contrib/base_systems/components/__init__.py b/evennia/contrib/base_systems/components/__init__.py index 705e9ee411..1aa94a1df1 100644 --- a/evennia/contrib/base_systems/components/__init__.py +++ b/evennia/contrib/base_systems/components/__init__.py @@ -9,7 +9,7 @@ See the docs for more information. """ from evennia.contrib.base_systems.components.component import Component -from evennia.contrib.base_systems.components.dbfield import DBField, NDBField +from evennia.contrib.base_systems.components.dbfield import DBField, NDBField, TagField from evennia.contrib.base_systems.components.holder import ComponentHolderMixin, ComponentProperty diff --git a/evennia/contrib/base_systems/components/component.py b/evennia/contrib/base_systems/components/component.py index f260610e54..4b1697da38 100644 --- a/evennia/contrib/base_systems/components/component.py +++ b/evennia/contrib/base_systems/components/component.py @@ -144,6 +144,11 @@ class Component: ndb_fields = getattr(self, "_ndb_fields", {}) return ndb_fields.keys() + @property + def tag_field_names(self): + tag_fields = getattr(self, "_tag_fields", {}) + return tag_fields.keys() + class ComponentRegisterError(Exception): pass diff --git a/evennia/contrib/base_systems/components/dbfield.py b/evennia/contrib/base_systems/components/dbfield.py index 8e4f63b5da..c63ab1bebc 100644 --- a/evennia/contrib/base_systems/components/dbfield.py +++ b/evennia/contrib/base_systems/components/dbfield.py @@ -52,3 +52,46 @@ class NDBField(NAttributeProperty): ndb_fields = {} setattr(owner, '_ndb_fields', ndb_fields) ndb_fields[name] = self + + +class TagField: + """ + Component Descriptor to add a tag to the host. + """ + def __init__(self, default=None, enforce_single=False): + self._category_key = None + self._default = default + self._enforce_single = enforce_single + + def __set_name__(self, owner, name): + """ + Called when descriptor is first assigned to the class. It is called with + the name of the field. + + """ + self._category_key = f"{owner.name}__{name}" + tag_fields = getattr(owner, "_tag_fields", None) + if tag_fields is None: + tag_fields = {} + setattr(owner, '_tag_fields', tag_fields) + tag_fields[name] = self + + def __get__(self, instance, owner): + tag_value = instance.host.tags.get( + default=self._default, + category=self._category_key, + ) + return tag_value + + def __set__(self, instance, value): + tag_handler = instance.host.tags + if self._enforce_single: + tag_handler.clear(category=self._category_key) + + tag_handler.add( + key=self._key, + category=self._category_key, + ) + + def __delete__(self, instance): + instance.host.tags.clear(category=self._category_key) diff --git a/evennia/contrib/base_systems/components/holder.py b/evennia/contrib/base_systems/components/holder.py index ef0be1a242..651ae5840a 100644 --- a/evennia/contrib/base_systems/components/holder.py +++ b/evennia/contrib/base_systems/components/holder.py @@ -66,6 +66,10 @@ class ComponentHandler: self.db_names.append(component.name) self.host.tags.add(component.name, category="components") component.at_added(self.host) + for tag_field_name in component.tag_field_names: + default_tag = type(component).__dict__[tag_field_name]._default + if default_tag: + setattr(component, tag_field_name, default_tag) def add_default(self, name): """ @@ -87,6 +91,10 @@ class ComponentHandler: self.db_names.append(name) self.host.tags.add(name, category="components") new_component.at_added(self.host) + for tag_field_name in component.tag_field_names: + default_tag = type(component).__dict__[tag_field_name]._default + if default_tag: + setattr(component, tag_field_name, default_tag) def remove(self, component): """ @@ -103,6 +111,8 @@ class ComponentHandler: component.at_removed(self.host) self.db_names.remove(component_name) self.host.tags.remove(component_name, category="components") + for tag_field_name in component.tag_field_names: + self.host.tags.remove() del self._loaded_components[component_name] else: message = f"Cannot remove {component_name} from {self.host.name} as it is not registered." @@ -217,6 +227,10 @@ class ComponentHolderMixin(object): component = component_class.create(self, **values) component_names.append(component_name) self.components._loaded_components[component_name] = component + for tag_field_name in component.tag_field_names: + default_tag = type(component).__dict__[tag_field_name]._default + if default_tag: + setattr(component, tag_field_name, default_tag) self.db.component_names = component_names