tcod-ecs 5.3.0__tar.gz → 5.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tcod_ecs-5.3.0 → tcod_ecs-5.4.0}/PKG-INFO +2 -2
- {tcod_ecs-5.3.0 → tcod_ecs-5.4.0}/pyproject.toml +2 -1
- {tcod_ecs-5.3.0 → tcod_ecs-5.4.0}/tcod/ecs/_version.py +2 -2
- {tcod_ecs-5.3.0 → tcod_ecs-5.4.0}/tcod/ecs/entity.py +38 -27
- {tcod_ecs-5.3.0 → tcod_ecs-5.4.0}/tcod/ecs/query.py +2 -3
- {tcod_ecs-5.3.0 → tcod_ecs-5.4.0}/tcod/ecs/registry.py +7 -7
- {tcod_ecs-5.3.0 → tcod_ecs-5.4.0}/tcod/ecs/typing.py +1 -1
- {tcod_ecs-5.3.0 → tcod_ecs-5.4.0}/LICENSE +0 -0
- {tcod_ecs-5.3.0 → tcod_ecs-5.4.0}/README.md +0 -0
- {tcod_ecs-5.3.0 → tcod_ecs-5.4.0}/tcod/ecs/__init__.py +0 -0
- {tcod_ecs-5.3.0 → tcod_ecs-5.4.0}/tcod/ecs/_converter.py +0 -0
- {tcod_ecs-5.3.0 → tcod_ecs-5.4.0}/tcod/ecs/callbacks.py +0 -0
- {tcod_ecs-5.3.0 → tcod_ecs-5.4.0}/tcod/ecs/constants.py +0 -0
- {tcod_ecs-5.3.0 → tcod_ecs-5.4.0}/tcod/ecs/py.typed +0 -0
- {tcod_ecs-5.3.0 → tcod_ecs-5.4.0}/tcod/ecs/world.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tcod-ecs
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.4.0
|
|
4
4
|
Summary: A type-hinted Entity Component System based on Python dictionaries and sets.
|
|
5
5
|
Author-email: Kyle Benesch <4b796c65+github@gmail.com>
|
|
6
6
|
Requires-Python: >=3.8
|
|
@@ -16,7 +16,7 @@ License-File: LICENSE
|
|
|
16
16
|
Requires-Dist: attrs >=23.1.0
|
|
17
17
|
Requires-Dist: cattrs >=23.1.2
|
|
18
18
|
Requires-Dist: sentinel-value >=1.0.0
|
|
19
|
-
Requires-Dist: typing-extensions >=4.
|
|
19
|
+
Requires-Dist: typing-extensions >=4.9.0
|
|
20
20
|
Requires-Dist: attrs >=22.2.0 ; extra == "test"
|
|
21
21
|
Requires-Dist: pytest >=7.2.0 ; extra == "test"
|
|
22
22
|
Requires-Dist: pytest-cov >=4.0.0 ; extra == "test"
|
|
@@ -22,7 +22,7 @@ dependencies = [
|
|
|
22
22
|
"attrs >=23.1.0",
|
|
23
23
|
"cattrs >=23.1.2",
|
|
24
24
|
"sentinel-value >=1.0.0",
|
|
25
|
-
"typing-extensions >=4.
|
|
25
|
+
"typing-extensions >=4.9.0",
|
|
26
26
|
]
|
|
27
27
|
|
|
28
28
|
[tool.setuptools_scm]
|
|
@@ -89,6 +89,7 @@ line-length = 120
|
|
|
89
89
|
[tool.ruff.lint] # https://docs.astral.sh/ruff/rules/
|
|
90
90
|
select = ["ALL"]
|
|
91
91
|
ignore = [
|
|
92
|
+
"A005", # stdlib-module-shadowing, workaround VSCode treating all modules as local
|
|
92
93
|
"COM", # flake8-commas, handled by formatter
|
|
93
94
|
"E501", # line-too-long
|
|
94
95
|
"S101", # assert
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
import warnings
|
|
6
5
|
from typing import (
|
|
7
6
|
TYPE_CHECKING,
|
|
8
7
|
Any,
|
|
@@ -23,7 +22,7 @@ from weakref import WeakKeyDictionary, WeakValueDictionary
|
|
|
23
22
|
|
|
24
23
|
import attrs
|
|
25
24
|
from sentinel_value import sentinel
|
|
26
|
-
from typing_extensions import Self
|
|
25
|
+
from typing_extensions import Self, deprecated
|
|
27
26
|
|
|
28
27
|
import tcod.ecs.callbacks
|
|
29
28
|
import tcod.ecs.query
|
|
@@ -74,17 +73,16 @@ class Entity:
|
|
|
74
73
|
"""This entities unique identifier."""
|
|
75
74
|
|
|
76
75
|
@property
|
|
76
|
+
@deprecated("Use '.registry' instead of '.world'")
|
|
77
77
|
def world(self) -> Registry:
|
|
78
78
|
"""Deprecated alias for registry.
|
|
79
79
|
|
|
80
80
|
.. deprecated:: 5.1
|
|
81
81
|
Use :any:`registry` instead.
|
|
82
82
|
"""
|
|
83
|
-
if __debug__:
|
|
84
|
-
warnings.warn("Use '.registry' instead of '.world'", DeprecationWarning, stacklevel=2)
|
|
85
83
|
return self.registry
|
|
86
84
|
|
|
87
|
-
def __new__(cls, registry: Registry, uid: object = object) -> Entity:
|
|
85
|
+
def __new__(cls, registry: Registry, uid: object = object) -> Self | Entity:
|
|
88
86
|
"""Return a unique entity for the given `registry` and `uid`.
|
|
89
87
|
|
|
90
88
|
If an entity already exists with a matching `registry` and `uid` then that entity is returned.
|
|
@@ -126,10 +124,10 @@ class Entity:
|
|
|
126
124
|
|
|
127
125
|
.. versionadded:: 4.2.0
|
|
128
126
|
"""
|
|
129
|
-
self.components
|
|
130
|
-
self.tags
|
|
131
|
-
self.relation_tags_many
|
|
132
|
-
self.relation_components
|
|
127
|
+
self.components.clear()
|
|
128
|
+
self.tags.clear()
|
|
129
|
+
self.relation_tags_many.clear()
|
|
130
|
+
self.relation_components.clear()
|
|
133
131
|
|
|
134
132
|
def instantiate(self) -> Self:
|
|
135
133
|
"""Return a new entity which inherits the components, tags, and relations of this entity.
|
|
@@ -284,13 +282,13 @@ class Entity:
|
|
|
284
282
|
return EntityRelationsExclusive(self, (IsA,))
|
|
285
283
|
|
|
286
284
|
@property
|
|
285
|
+
@deprecated("The '.relation_tags' attribute has been renamed to '.relation_tag'", category=FutureWarning)
|
|
287
286
|
def relation_tags(self) -> EntityRelationsExclusive:
|
|
288
287
|
"""Access an entities exclusive relations.
|
|
289
288
|
|
|
290
289
|
.. deprecated:: 3.2
|
|
291
290
|
This attribute was renamed to :any:`relation_tag`.
|
|
292
291
|
"""
|
|
293
|
-
warnings.warn("The '.relation_tags' attribute has been renamed to '.relation_tag'", FutureWarning, stacklevel=2)
|
|
294
292
|
return EntityRelationsExclusive(self, (IsA,))
|
|
295
293
|
|
|
296
294
|
@property
|
|
@@ -303,12 +301,8 @@ class Entity:
|
|
|
303
301
|
"""
|
|
304
302
|
return EntityRelations(self, (IsA,))
|
|
305
303
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
"The name feature has been deprecated and will be removed.",
|
|
309
|
-
FutureWarning,
|
|
310
|
-
stacklevel=stacklevel + 1,
|
|
311
|
-
)
|
|
304
|
+
@deprecated("The name feature has been deprecated and will be removed.", category=FutureWarning)
|
|
305
|
+
def _set_name(self, value: object) -> None:
|
|
312
306
|
old_name = self.name
|
|
313
307
|
if old_name is not None: # Remove self from names
|
|
314
308
|
del self.registry._names_by_name[old_name]
|
|
@@ -333,8 +327,9 @@ class Entity:
|
|
|
333
327
|
return self.registry._names_by_entity.get(self)
|
|
334
328
|
|
|
335
329
|
@name.setter
|
|
330
|
+
@deprecated("The name feature has been deprecated and will be removed.", category=FutureWarning)
|
|
336
331
|
def name(self, value: object) -> None:
|
|
337
|
-
self._set_name(value
|
|
332
|
+
self._set_name(value)
|
|
338
333
|
|
|
339
334
|
def __repr__(self) -> str:
|
|
340
335
|
"""Return a representation of this entity.
|
|
@@ -410,17 +405,13 @@ class EntityComponents(MutableMapping[Union[Type[Any], Tuple[object, Type[Any]]]
|
|
|
410
405
|
"""
|
|
411
406
|
return self.__class__(self.entity, tuple(traverse))
|
|
412
407
|
|
|
413
|
-
|
|
408
|
+
@deprecated("Setting values without an explicit key has been deprecated.", category=FutureWarning)
|
|
409
|
+
def set(self, value: object) -> None:
|
|
414
410
|
"""Assign or overwrite a component, automatically deriving the key.
|
|
415
411
|
|
|
416
412
|
.. deprecated:: 3.1
|
|
417
413
|
Setting values without an explicit key has been deprecated.
|
|
418
414
|
"""
|
|
419
|
-
warnings.warn(
|
|
420
|
-
"Setting values without an explicit key has been deprecated.",
|
|
421
|
-
FutureWarning,
|
|
422
|
-
stacklevel=_stacklevel + 1,
|
|
423
|
-
)
|
|
424
415
|
key = value.__class__
|
|
425
416
|
self[key] = value
|
|
426
417
|
|
|
@@ -498,15 +489,17 @@ class EntityComponents(MutableMapping[Union[Type[Any], Tuple[object, Type[Any]]]
|
|
|
498
489
|
"""Return the number of components belonging to this entity."""
|
|
499
490
|
return len(self.keys())
|
|
500
491
|
|
|
501
|
-
|
|
492
|
+
@deprecated("Setting values without an explicit key has been deprecated.", category=FutureWarning)
|
|
493
|
+
def update_values(self, values: Iterable[object]) -> None:
|
|
502
494
|
"""Add or overwrite multiple components inplace, deriving the keys from the values.
|
|
503
495
|
|
|
504
496
|
.. deprecated:: 3.1
|
|
505
497
|
Setting values without an explicit key has been deprecated.
|
|
506
498
|
"""
|
|
507
499
|
for value in values:
|
|
508
|
-
self.set(value
|
|
500
|
+
self.set(value)
|
|
509
501
|
|
|
502
|
+
@deprecated("This method has been deprecated. Iterate over items instead.", category=FutureWarning)
|
|
510
503
|
def by_name_type(self, name_type: type[_T1], component_type: type[_T2]) -> Iterator[tuple[_T1, type[_T2]]]:
|
|
511
504
|
"""Iterate over all of an entities component keys with a specific (name_type, component_type) combination.
|
|
512
505
|
|
|
@@ -515,7 +508,6 @@ class EntityComponents(MutableMapping[Union[Type[Any], Tuple[object, Type[Any]]]
|
|
|
515
508
|
.. deprecated:: 3.1
|
|
516
509
|
This method has been deprecated. Iterate over items instead.
|
|
517
510
|
"""
|
|
518
|
-
warnings.warn("This method has been deprecated. Iterate over items instead.", FutureWarning, stacklevel=2)
|
|
519
511
|
# Naive implementation until I feel like optimizing it
|
|
520
512
|
for key in self:
|
|
521
513
|
if not isinstance(key, tuple):
|
|
@@ -561,7 +553,7 @@ class EntityComponents(MutableMapping[Union[Type[Any], Tuple[object, Type[Any]]]
|
|
|
561
553
|
return __default
|
|
562
554
|
|
|
563
555
|
@overload
|
|
564
|
-
def pop(self, __key: ComponentKey[T], /) -> T
|
|
556
|
+
def pop(self, __key: ComponentKey[T], /) -> T: ...
|
|
565
557
|
@overload
|
|
566
558
|
def pop(self, __key: ComponentKey[T], /, default: _T1) -> T | _T1: ...
|
|
567
559
|
|
|
@@ -602,6 +594,12 @@ class EntityComponents(MutableMapping[Union[Type[Any], Tuple[object, Type[Any]]]
|
|
|
602
594
|
del self[__key]
|
|
603
595
|
return value
|
|
604
596
|
|
|
597
|
+
def clear(self) -> None:
|
|
598
|
+
"""Remove any components stored directly in this entity."""
|
|
599
|
+
if self.traverse:
|
|
600
|
+
return self(traverse=()).clear()
|
|
601
|
+
return super().clear()
|
|
602
|
+
|
|
605
603
|
|
|
606
604
|
@attrs.define(eq=False, frozen=True, weakref_slot=False)
|
|
607
605
|
class EntityTags(MutableSet[Any]):
|
|
@@ -950,6 +948,13 @@ class EntityComponentRelationMapping(Generic[T], MutableMapping[Entity, T]):
|
|
|
950
948
|
"""Validate attributes."""
|
|
951
949
|
assert isinstance(self.entity, Entity), self.entity
|
|
952
950
|
|
|
951
|
+
def __call__(self, *, traverse: Iterable[object]) -> Self:
|
|
952
|
+
"""Update this view with alternative parameters, such as a specific traversal relation.
|
|
953
|
+
|
|
954
|
+
.. versionadded:: 5.4
|
|
955
|
+
"""
|
|
956
|
+
return self.__class__(self.entity, self.key, tuple(traverse))
|
|
957
|
+
|
|
953
958
|
def __getitem__(self, target: Entity) -> T:
|
|
954
959
|
"""Return the component related to a target entity."""
|
|
955
960
|
_relation_components_by_entity = self.entity.registry._relation_components_by_entity
|
|
@@ -1009,6 +1014,12 @@ class EntityComponentRelationMapping(Generic[T], MutableMapping[Entity, T]):
|
|
|
1009
1014
|
"""Return the count of targets for this component relation."""
|
|
1010
1015
|
return len(self.keys())
|
|
1011
1016
|
|
|
1017
|
+
def clear(self) -> None:
|
|
1018
|
+
"""Remove any components stored directly in this entity relation."""
|
|
1019
|
+
if self.traverse:
|
|
1020
|
+
return self(traverse=()).clear()
|
|
1021
|
+
return super().clear()
|
|
1022
|
+
|
|
1012
1023
|
|
|
1013
1024
|
@attrs.define(eq=False, frozen=True, weakref_slot=False)
|
|
1014
1025
|
class EntityComponentRelations(MutableMapping[ComponentKey[Any], EntityComponentRelationMapping[Any]]):
|
|
@@ -9,7 +9,7 @@ from typing import TYPE_CHECKING, Any, Iterable, Iterator, Protocol, TypeVar, ov
|
|
|
9
9
|
from weakref import WeakKeyDictionary, WeakSet
|
|
10
10
|
|
|
11
11
|
import attrs
|
|
12
|
-
from typing_extensions import Self
|
|
12
|
+
from typing_extensions import Self, deprecated
|
|
13
13
|
|
|
14
14
|
import tcod.ecs.entity
|
|
15
15
|
from tcod.ecs.constants import IsA
|
|
@@ -333,14 +333,13 @@ class BoundQuery:
|
|
|
333
333
|
_query: _Query = attrs.field(factory=_QueryLogicalAnd)
|
|
334
334
|
|
|
335
335
|
@property
|
|
336
|
+
@deprecated("Use '.registry' instead of '.world'")
|
|
336
337
|
def world(self) -> Registry:
|
|
337
338
|
"""Deprecated alias for registry.
|
|
338
339
|
|
|
339
340
|
.. deprecated:: 5.1
|
|
340
341
|
Use :any:`registry` instead.
|
|
341
342
|
"""
|
|
342
|
-
if __debug__:
|
|
343
|
-
warnings.warn("Use '.registry' instead of '.world'", DeprecationWarning, stacklevel=2)
|
|
344
343
|
return self.registry
|
|
345
344
|
|
|
346
345
|
def get_entities(self) -> AbstractSet[Entity]:
|
|
@@ -7,6 +7,7 @@ from collections import defaultdict
|
|
|
7
7
|
from typing import TYPE_CHECKING, Any, DefaultDict, Dict, Final, Iterable, Mapping, NoReturn, Set, TypeVar
|
|
8
8
|
|
|
9
9
|
import attrs
|
|
10
|
+
from typing_extensions import deprecated
|
|
10
11
|
|
|
11
12
|
import tcod.ecs._converter
|
|
12
13
|
import tcod.ecs.query
|
|
@@ -151,6 +152,10 @@ class Registry:
|
|
|
151
152
|
"""
|
|
152
153
|
|
|
153
154
|
@property
|
|
155
|
+
@deprecated(
|
|
156
|
+
"The 'registry.global_' attribute has been deprecated. Use 'registry[None]' to access this entity.",
|
|
157
|
+
category=FutureWarning,
|
|
158
|
+
)
|
|
154
159
|
def global_(self) -> Entity:
|
|
155
160
|
"""A unique globally accessible entity.
|
|
156
161
|
|
|
@@ -168,11 +173,6 @@ class Registry:
|
|
|
168
173
|
>>> registry[None].components[("turn", int)]
|
|
169
174
|
0
|
|
170
175
|
"""
|
|
171
|
-
warnings.warn(
|
|
172
|
-
"The 'registry.global_' attribute has been deprecated. Use 'registry[None]' to access this entity.",
|
|
173
|
-
FutureWarning,
|
|
174
|
-
stacklevel=2,
|
|
175
|
-
)
|
|
176
176
|
return Entity(self, None)
|
|
177
177
|
|
|
178
178
|
def __setstate__(self, state: dict[str, Any]) -> None:
|
|
@@ -300,12 +300,12 @@ class Registry:
|
|
|
300
300
|
if isinstance(components, Mapping):
|
|
301
301
|
entity.components.update(components)
|
|
302
302
|
elif components:
|
|
303
|
-
entity.components.update_values(components
|
|
303
|
+
entity.components.update_values(components)
|
|
304
304
|
entity_tags = entity.tags
|
|
305
305
|
for tag in tags:
|
|
306
306
|
entity_tags.add(tag)
|
|
307
307
|
if name is not None:
|
|
308
|
-
entity._set_name(name
|
|
308
|
+
entity._set_name(name)
|
|
309
309
|
return entity
|
|
310
310
|
|
|
311
311
|
@property
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|