mirror of
https://github.com/evennia/evennia.git
synced 2026-03-30 12:37:16 +02:00
Merge remote-tracking branch 'fork/components-refactoring' into components-refactoring
This commit is contained in:
commit
1bfb3643ad
4 changed files with 80 additions and 9 deletions
|
|
@ -30,12 +30,20 @@ class Character(ComponentHolderMixin, DefaultCharacter):
|
|||
# ...
|
||||
```
|
||||
|
||||
Components need to inherit the Component class directly and require a name.
|
||||
Components need to inherit the Component class and require a unique name.
|
||||
Components may inherit from other components but must specify another name.
|
||||
You can assign the same 'slot' to both components to have alternative implementations.
|
||||
```python
|
||||
from evennia.contrib.base_systems.components import Component
|
||||
|
||||
|
||||
class Health(Component):
|
||||
name = "health"
|
||||
|
||||
|
||||
class ItemHealth(Health):
|
||||
name = "item_health"
|
||||
slot = "health"
|
||||
```
|
||||
|
||||
Components may define DBFields or NDBFields at the class level.
|
||||
|
|
@ -103,7 +111,10 @@ character.components.add(vampirism)
|
|||
|
||||
...
|
||||
|
||||
vampirism_from_elsewhere = character.components.get("vampirism")
|
||||
vampirism = character.components.get("vampirism")
|
||||
|
||||
# Alternatively
|
||||
vampirism = character.cmp.vampirism
|
||||
```
|
||||
|
||||
Keep in mind that all components must be imported to be visible in the listing.
|
||||
|
|
@ -128,6 +139,14 @@ from typeclasses.components import health
|
|||
```
|
||||
Both of the above examples will work.
|
||||
|
||||
## Known Issues
|
||||
|
||||
Assigning mutable default values such as a list to a DBField will share it across instances.
|
||||
To avoid this, you must set autocreate=True on the field, like this.
|
||||
```python
|
||||
health = DBField(default=[], autocreate=True)
|
||||
```
|
||||
|
||||
## Full Example
|
||||
```python
|
||||
from evennia.contrib.base_systems import components
|
||||
|
|
|
|||
|
|
@ -9,8 +9,17 @@ from evennia.contrib.base_systems.components import COMPONENT_LISTING, exception
|
|||
|
||||
|
||||
class BaseComponent(type):
|
||||
"""
|
||||
This is the metaclass for components,
|
||||
responsible for registering components to the listing.
|
||||
"""
|
||||
@classmethod
|
||||
def __new__(cls, *args):
|
||||
"""
|
||||
Every class that uses this metaclass will be registered
|
||||
as a component in the Component Listing using its name.
|
||||
All of them require a unique name.
|
||||
"""
|
||||
new_type = super().__new__(*args)
|
||||
if new_type.__base__ == object:
|
||||
return new_type
|
||||
|
|
|
|||
|
|
@ -26,17 +26,31 @@ class DBField(AttributeProperty):
|
|||
Called when descriptor is first assigned to the class.
|
||||
|
||||
Args:
|
||||
owner (object): The component classF on which this is set
|
||||
owner (Component): The component classF on which this is set
|
||||
name (str): The name that was used to set the DBField.
|
||||
"""
|
||||
self._key = f"{owner.slot or owner.name}::{name}"
|
||||
owner.add_field(name, self)
|
||||
|
||||
def at_added(self, component):
|
||||
"""
|
||||
Called when the parent component is added to a host.
|
||||
|
||||
Args:
|
||||
component (Component): The component instance being added.
|
||||
"""
|
||||
|
||||
if self._autocreate:
|
||||
self.__get__(component, type(component))
|
||||
|
||||
def at_removed(self, component):
|
||||
"""
|
||||
Called when the parent component is removed from a host.
|
||||
|
||||
Args:
|
||||
component (Component): The component instance being removed.
|
||||
"""
|
||||
|
||||
self.__delete__(component)
|
||||
|
||||
|
||||
|
|
@ -52,18 +66,30 @@ class NDBField(NAttributeProperty):
|
|||
Called when descriptor is first assigned to the class.
|
||||
|
||||
Args:
|
||||
owner (object): The component class on which this is set
|
||||
owner (Component): The component class on which this is set
|
||||
name (str): The name that was used to set the DBField.
|
||||
"""
|
||||
self._key = f"{owner.slot or owner.name}::{name}"
|
||||
owner.add_field(name, self)
|
||||
|
||||
def at_added(self, instance):
|
||||
if self._autocreate:
|
||||
self.__set__(instance, self._default)
|
||||
def at_added(self, component):
|
||||
"""
|
||||
Called when the parent component is added to a host.
|
||||
|
||||
def at_removed(self, instance):
|
||||
self.__delete__(instance)
|
||||
Args:
|
||||
component (Component): The component instance being added.
|
||||
"""
|
||||
if self._autocreate:
|
||||
self.__set__(component, self._default)
|
||||
|
||||
def at_removed(self, component):
|
||||
"""
|
||||
Called when the parent component is removed from a host.
|
||||
|
||||
Args:
|
||||
component (Component): The component instance being removed.
|
||||
"""
|
||||
self.__delete__(component)
|
||||
|
||||
|
||||
class TagField:
|
||||
|
|
@ -124,8 +150,20 @@ class TagField:
|
|||
instance.host.tags.clear(category=self._category_key)
|
||||
|
||||
def at_added(self, component):
|
||||
"""
|
||||
Called when the parent component is added to a host.
|
||||
|
||||
Args:
|
||||
component (Component): The component instance being added.
|
||||
"""
|
||||
if self._default:
|
||||
self.__set__(component, self._default)
|
||||
|
||||
def at_removed(self, component):
|
||||
"""
|
||||
Called when the parent component is removed from a host.
|
||||
|
||||
Args:
|
||||
component (Component): The component instance being removed.
|
||||
"""
|
||||
self.__delete__(component)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,11 @@ COMPONENT_LISTING = {}
|
|||
|
||||
|
||||
def get_component_class(name):
|
||||
"""
|
||||
Retrieves a component from the listing using a name
|
||||
Args:
|
||||
name (str): The unique name of the component
|
||||
"""
|
||||
component_class = COMPONENT_LISTING.get(name)
|
||||
if component_class is None:
|
||||
message = (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue