tinyecs 0.4.0__tar.gz → 0.5.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.
- {tinyecs-0.4.0 → tinyecs-0.5.0}/LICENSE +1 -1
- {tinyecs-0.4.0/src/tinyecs.egg-info → tinyecs-0.5.0}/PKG-INFO +14 -11
- {tinyecs-0.4.0 → tinyecs-0.5.0}/README.rst +0 -9
- {tinyecs-0.4.0 → tinyecs-0.5.0}/pyproject.toml +11 -7
- {tinyecs-0.4.0 → tinyecs-0.5.0}/src/tinyecs/__init__.py +86 -52
- {tinyecs-0.4.0 → tinyecs-0.5.0/src/tinyecs.egg-info}/PKG-INFO +14 -11
- tinyecs-0.5.0/src/tinyecs.egg-info/SOURCES.txt +11 -0
- tinyecs-0.5.0/src/tinyecs.egg-info/requires.txt +19 -0
- {tinyecs-0.4.0 → tinyecs-0.5.0}/tests/test_tinyecs.py +14 -8
- tinyecs-0.4.0/src/tinyecs/components.py +0 -1
- tinyecs-0.4.0/src/tinyecs/compsys.py +0 -399
- tinyecs-0.4.0/src/tinyecs/demo.py +0 -29
- tinyecs-0.4.0/src/tinyecs/demos/__init__.py +0 -0
- tinyecs-0.4.0/src/tinyecs/demos/background.py +0 -100
- tinyecs-0.4.0/src/tinyecs/demos/bouncing_sprites.py +0 -115
- tinyecs-0.4.0/src/tinyecs/demos/example.py +0 -117
- tinyecs-0.4.0/src/tinyecs/demos/homing-missiles.py +0 -234
- tinyecs-0.4.0/src/tinyecs/demos/marquee.py +0 -97
- tinyecs-0.4.0/src/tinyecs.egg-info/SOURCES.txt +0 -21
- tinyecs-0.4.0/src/tinyecs.egg-info/entry_points.txt +0 -2
- tinyecs-0.4.0/src/tinyecs.egg-info/requires.txt +0 -1
- {tinyecs-0.4.0 → tinyecs-0.5.0}/setup.cfg +0 -0
- {tinyecs-0.4.0 → tinyecs-0.5.0}/src/tinyecs/tutorial.py +0 -0
- {tinyecs-0.4.0 → tinyecs-0.5.0}/src/tinyecs.egg-info/dependency_links.txt +0 -0
- {tinyecs-0.4.0 → tinyecs-0.5.0}/src/tinyecs.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tinyecs
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: The teeniest, tiniest ECS system
|
|
5
5
|
Author-email: Michael Lamertz <michael.lamertz@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -13,7 +13,19 @@ Classifier: Topic :: Games/Entertainment
|
|
|
13
13
|
Classifier: Topic :: Software Development :: Libraries :: pygame
|
|
14
14
|
Description-Content-Type: text/x-rst
|
|
15
15
|
License-File: LICENSE
|
|
16
|
-
|
|
16
|
+
Provides-Extra: base
|
|
17
|
+
Requires-Dist: tinyecs-compsys-base; extra == "base"
|
|
18
|
+
Provides-Extra: dynamics
|
|
19
|
+
Requires-Dist: tinyecs-compsys-dynamics; extra == "dynamics"
|
|
20
|
+
Provides-Extra: patternengine
|
|
21
|
+
Requires-Dist: tinyecs-compsys-patternengine; extra == "patternengine"
|
|
22
|
+
Provides-Extra: sdl2
|
|
23
|
+
Requires-Dist: tinyecs-compsys-sdl2; extra == "sdl2"
|
|
24
|
+
Provides-Extra: demos
|
|
25
|
+
Requires-Dist: tinyecs[base,dynamics,sdl2]; extra == "demos"
|
|
26
|
+
Requires-Dist: tinyecs-demos; extra == "demos"
|
|
27
|
+
Provides-Extra: all
|
|
28
|
+
Requires-Dist: tinyecs[base,demos,dynamics,patternengine,sdl2]; extra == "all"
|
|
17
29
|
Dynamic: license-file
|
|
18
30
|
|
|
19
31
|
Introduction
|
|
@@ -73,15 +85,6 @@ Issues can be opened on `github issues`_
|
|
|
73
85
|
|
|
74
86
|
.. _github issues: https://github.com/dickerdackel/tinyecs/issues
|
|
75
87
|
|
|
76
|
-
Please respect, that I don't want any contributions done with the assistance
|
|
77
|
-
of AI. This is a hobby project with focus on the craft of programming. I
|
|
78
|
-
have experimentally used AI to audit parts of the code and documentation, and
|
|
79
|
-
while it found a lot of typos and 2 actual issues, without exception, the
|
|
80
|
-
provided solutions were often besides the point or plain wrong.
|
|
81
|
-
|
|
82
|
-
I have no possibility to enforce that request, the simple fact that I ask for
|
|
83
|
-
it should be sufficient.
|
|
84
|
-
|
|
85
88
|
License
|
|
86
89
|
=======
|
|
87
90
|
|
|
@@ -55,15 +55,6 @@ Issues can be opened on `github issues`_
|
|
|
55
55
|
|
|
56
56
|
.. _github issues: https://github.com/dickerdackel/tinyecs/issues
|
|
57
57
|
|
|
58
|
-
Please respect, that I don't want any contributions done with the assistance
|
|
59
|
-
of AI. This is a hobby project with focus on the craft of programming. I
|
|
60
|
-
have experimentally used AI to audit parts of the code and documentation, and
|
|
61
|
-
while it found a lot of typos and 2 actual issues, without exception, the
|
|
62
|
-
provided solutions were often besides the point or plain wrong.
|
|
63
|
-
|
|
64
|
-
I have no possibility to enforce that request, the simple fact that I ask for
|
|
65
|
-
it should be sufficient.
|
|
66
|
-
|
|
67
58
|
License
|
|
68
59
|
=======
|
|
69
60
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tinyecs"
|
|
3
3
|
description = "The teeniest, tiniest ECS system"
|
|
4
|
-
version = "0.
|
|
4
|
+
version = "0.5.0"
|
|
5
5
|
readme = "README.rst"
|
|
6
6
|
|
|
7
7
|
authors = [
|
|
@@ -18,14 +18,18 @@ classifiers = [
|
|
|
18
18
|
license = "MIT"
|
|
19
19
|
license-files = ["LICENSE"]
|
|
20
20
|
|
|
21
|
-
dependencies = [
|
|
22
|
-
"pgcooldown"
|
|
23
|
-
]
|
|
21
|
+
dependencies = [ ]
|
|
24
22
|
|
|
25
23
|
[project.optional-dependencies]
|
|
26
|
-
|
|
27
|
-
[
|
|
28
|
-
|
|
24
|
+
base = ["tinyecs-compsys-base"]
|
|
25
|
+
dynamics = ["tinyecs-compsys-dynamics"]
|
|
26
|
+
patternengine = ["tinyecs-compsys-patternengine"]
|
|
27
|
+
sdl2 = ["tinyecs-compsys-sdl2"]
|
|
28
|
+
demos = [
|
|
29
|
+
"tinyecs[base,dynamics,sdl2]",
|
|
30
|
+
"tinyecs-demos",
|
|
31
|
+
]
|
|
32
|
+
all = ["tinyecs[base,dynamics,sdl2,patternengine,demos]"]
|
|
29
33
|
|
|
30
34
|
[project.urls]
|
|
31
35
|
homepage = "https://github.com/dickerdackel/tinyecs"
|
|
@@ -3,20 +3,21 @@ from collections.abc import Hashable, Iterable
|
|
|
3
3
|
from typing import Any, Protocol
|
|
4
4
|
from uuid import uuid4
|
|
5
5
|
|
|
6
|
-
__all__ = ['Component', 'ComponentID', 'DomainID', 'EntityID',
|
|
7
|
-
'
|
|
8
|
-
'
|
|
9
|
-
'
|
|
10
|
-
'
|
|
11
|
-
'
|
|
12
|
-
'
|
|
13
|
-
'
|
|
14
|
-
'
|
|
15
|
-
'
|
|
16
|
-
'
|
|
17
|
-
'
|
|
18
|
-
'
|
|
19
|
-
'
|
|
6
|
+
__all__ = ['Component', 'ComponentID', 'DomainID', 'EntityID',
|
|
7
|
+
'EntityComponentsBundle', 'Property', 'RegistryError',
|
|
8
|
+
'SystemFunction', 'BulkSystemFunction', 'UnknownArchetypeError',
|
|
9
|
+
'UnknownComponentError', 'UnknownEntityError',
|
|
10
|
+
'UnknownSystemError', 'add_component', 'add_components',
|
|
11
|
+
'add_system', 'add_system_to_domain', 'add_to_archetype',
|
|
12
|
+
'cid_of_comp', 'cids_of_eid', 'clear_properties', 'comp_of_eid',
|
|
13
|
+
'comps_of_archetype', 'comps_of_eid', 'create_archetype',
|
|
14
|
+
'create_entity', 'eid_has', 'eid_of_comp', 'eids_by_cids',
|
|
15
|
+
'eids_by_property', 'has', 'has_property', 'healthcheck',
|
|
16
|
+
'purge_by_property', 'remove_archetype', 'remove_component',
|
|
17
|
+
'remove_entity', 'remove_from_archetype', 'remove_property',
|
|
18
|
+
'remove_system', 'remove_system_from_domain', 'reset',
|
|
19
|
+
'run_all_systems', 'run_bulk_system', 'run_domain', 'run_system',
|
|
20
|
+
'set_properties', 'set_property', 'update_component',]
|
|
20
21
|
|
|
21
22
|
type EntityID = Hashable
|
|
22
23
|
type ComponentID = Hashable
|
|
@@ -32,7 +33,11 @@ type _RunSystemResult = dict[EntityID, Any]
|
|
|
32
33
|
# The typehinting system can't work with functions using *args, **kwargs.
|
|
33
34
|
# This solution comes from https://docs.python.org/3/library/typing.html#annotating-callable-objects
|
|
34
35
|
class SystemFunction(Protocol):
|
|
35
|
-
def __call__(self, eid: EntityID, *cids: ComponentID, **kwargs: dict[str,
|
|
36
|
+
def __call__(self, eid: EntityID, *cids: ComponentID, **kwargs: dict[str, Any]) -> Any: ...
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class BulkSystemFunction(Protocol):
|
|
40
|
+
def __call__(self, call_list: list[tuple[EntityID, *tuple[Component, ...]]], **kwargs: dict[str, Any]) -> Any: ...
|
|
36
41
|
|
|
37
42
|
|
|
38
43
|
eidx = {} # entity index
|
|
@@ -71,14 +76,14 @@ class RegistryError(Exception):
|
|
|
71
76
|
:param eid: The entity ID of the defective registry entry
|
|
72
77
|
:param cid: The component ID of the defective registry entry
|
|
73
78
|
:param component: The component object of the defective registry entry
|
|
74
|
-
:param
|
|
79
|
+
:param other: Component in cidx when eidx and cidx mismatch
|
|
75
80
|
|
|
76
81
|
Contains an error message and the registry objects that have been
|
|
77
82
|
identified as inconsistent.
|
|
78
83
|
"""
|
|
79
84
|
|
|
80
85
|
def __init__(self, error, *, eid, cid=None, component=None, other=None, properties=None):
|
|
81
|
-
|
|
86
|
+
super().__init__(error)
|
|
82
87
|
self.eid = eid
|
|
83
88
|
self.cid = cid
|
|
84
89
|
self.component = component
|
|
@@ -149,7 +154,7 @@ def create_entity(tag: EntityID = None,
|
|
|
149
154
|
:return: The entity ID. Same as given if one is passed, otherwise a uuid4
|
|
150
155
|
"""
|
|
151
156
|
|
|
152
|
-
eid = tag if tag else str(uuid4())
|
|
157
|
+
eid = tag if tag is not None else str(uuid4())
|
|
153
158
|
if eid not in eidx:
|
|
154
159
|
eidx[eid] = {}
|
|
155
160
|
|
|
@@ -208,6 +213,11 @@ def add_component(eid: EntityID, cid: ComponentID, comp: Component) -> Component
|
|
|
208
213
|
.. note:: Technically, there is no reason a comp object couldn't
|
|
209
214
|
have methods, but by concept, functionality is reserved for the System
|
|
210
215
|
working on the components, not the component itself.
|
|
216
|
+
|
|
217
|
+
.. note:: This function is also aliased to `update_component` just to be
|
|
218
|
+
able to make it clear in the user code, that a component will be
|
|
219
|
+
replaced. Consider it semantic sugar.
|
|
220
|
+
|
|
211
221
|
"""
|
|
212
222
|
|
|
213
223
|
if eid not in eidx:
|
|
@@ -219,12 +229,16 @@ def add_component(eid: EntityID, cid: ComponentID, comp: Component) -> Component
|
|
|
219
229
|
# Make sure, when replacing a component, the the old one is removed from
|
|
220
230
|
# oidx for this entity.
|
|
221
231
|
try:
|
|
222
|
-
old_comp =
|
|
223
|
-
oidx[old_comp].discard(eid)
|
|
224
|
-
if not oidx[old_comp]:
|
|
225
|
-
del oidx[old_comp]
|
|
232
|
+
old_comp = eidx[eid][cid]
|
|
226
233
|
except KeyError:
|
|
227
234
|
pass
|
|
235
|
+
else:
|
|
236
|
+
old_comp_id = id(old_comp)
|
|
237
|
+
oidx[old_comp_id].discard(eid)
|
|
238
|
+
if not oidx[old_comp_id]:
|
|
239
|
+
del oidx[old_comp_id]
|
|
240
|
+
if hasattr(old_comp, 'shutdown_'):
|
|
241
|
+
old_comp.shutdown_()
|
|
228
242
|
|
|
229
243
|
cidx[cid][eid] = comp
|
|
230
244
|
eidx[eid][cid] = comp
|
|
@@ -242,7 +256,7 @@ def add_components(eid: EntityID, components: dict[ComponentID, Component]) -> l
|
|
|
242
256
|
"""A convenience wrapper around add_component.
|
|
243
257
|
|
|
244
258
|
:param components: A dict with component IDs as keys and components as values (see add_component)
|
|
245
|
-
:return:
|
|
259
|
+
:return: list of added component IDs
|
|
246
260
|
"""
|
|
247
261
|
|
|
248
262
|
return [add_component(eid, cid, comp) for cid, comp in components.items()]
|
|
@@ -255,8 +269,8 @@ def remove_component(eid: EntityID, *cids: ComponentID) -> None:
|
|
|
255
269
|
:param cids: The component ids to remove
|
|
256
270
|
:return: None
|
|
257
271
|
|
|
258
|
-
If the component has a shutdown\_ attribute, it is assumed to be a
|
|
259
|
-
zero parameter
|
|
272
|
+
If the component has a shutdown\_ attribute, it is assumed to be a
|
|
273
|
+
zero parameter function that is called after the component removal.
|
|
260
274
|
|
|
261
275
|
.. note:: If the entity no longer exists, the error is silently ignored.
|
|
262
276
|
|
|
@@ -291,11 +305,10 @@ def add_system(fn: SystemFunction, *cids: ComponentID) -> None:
|
|
|
291
305
|
|
|
292
306
|
The prototype for the function is::
|
|
293
307
|
|
|
294
|
-
fn(
|
|
308
|
+
fn(eid, *comps, **kwargs)
|
|
295
309
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
this specific entity.
|
|
310
|
+
eid is the id of the entity that matches, and \*comps are all requested
|
|
311
|
+
components for this specific entity.
|
|
299
312
|
|
|
300
313
|
This function is called for every entity that matches all specified
|
|
301
314
|
component ids.
|
|
@@ -340,10 +353,10 @@ def add_system_to_domain(domain: DomainID, system: SystemFunction) -> None:
|
|
|
340
353
|
.. important:: The system must first be registered with add_system.
|
|
341
354
|
"""
|
|
342
355
|
|
|
343
|
-
if domain not in didx:
|
|
344
|
-
didx[domain] = set()
|
|
345
356
|
if system not in sidx:
|
|
346
357
|
raise UnknownSystemError(f'system {system} is not registered')
|
|
358
|
+
if domain not in didx:
|
|
359
|
+
didx[domain] = set()
|
|
347
360
|
didx[domain].add(system)
|
|
348
361
|
|
|
349
362
|
|
|
@@ -387,9 +400,14 @@ def eid_has(eid: EntityID, *cids: ComponentID) -> bool:
|
|
|
387
400
|
|
|
388
401
|
:param cids: All component ids that need to match
|
|
389
402
|
:return: True if all given cids are available for the specified eid
|
|
403
|
+
:raises UnknownEntityError: If the entity is not registered (anymore).
|
|
390
404
|
"""
|
|
391
405
|
|
|
392
|
-
|
|
406
|
+
try:
|
|
407
|
+
e = eidx[eid]
|
|
408
|
+
except KeyError:
|
|
409
|
+
raise UnknownEntityError
|
|
410
|
+
|
|
393
411
|
for cid in cids:
|
|
394
412
|
if cid not in e:
|
|
395
413
|
return False
|
|
@@ -401,7 +419,7 @@ def eids_by_cids(*cids: ComponentID, has_properties: _OptionalProperties = None)
|
|
|
401
419
|
"""Get eids that match all specified cids.
|
|
402
420
|
|
|
403
421
|
:param cids: All component ids that need to match
|
|
404
|
-
:param
|
|
422
|
+
:param has_properties: Optional set/tuple/list of required properties
|
|
405
423
|
:return: A list of tuples of entity IDs and components
|
|
406
424
|
"""
|
|
407
425
|
|
|
@@ -454,7 +472,7 @@ def comps_of_eid(eid: EntityID, *cids: ComponentID) -> list[Component]:
|
|
|
454
472
|
While cids_of_eid gets component IDs, this function now gets the actual
|
|
455
473
|
components containing the data.
|
|
456
474
|
|
|
457
|
-
.. note:: If cids
|
|
475
|
+
.. note:: If no cids are given, returns all components of eid.
|
|
458
476
|
"""
|
|
459
477
|
|
|
460
478
|
if eid not in eidx:
|
|
@@ -484,10 +502,10 @@ def eid_of_comp(comp: Component) -> set[EntityID]:
|
|
|
484
502
|
"""Find the entity id for object comp.
|
|
485
503
|
|
|
486
504
|
:param comp: The component to find the entity of
|
|
487
|
-
:return:
|
|
505
|
+
:return: A set of all entity IDs that contain the given component.
|
|
488
506
|
"""
|
|
489
507
|
|
|
490
|
-
return oidx
|
|
508
|
+
return oidx.get(id(comp), set())
|
|
491
509
|
|
|
492
510
|
|
|
493
511
|
def cid_of_comp(eid: EntityID, comp: Component) -> ComponentID:
|
|
@@ -564,7 +582,7 @@ def run_system(fn: SystemFunction,
|
|
|
564
582
|
return {eid: fn(eid, *parms, **kwargs) for eid, *parms in call_list}
|
|
565
583
|
|
|
566
584
|
|
|
567
|
-
def run_bulk_system(fn:
|
|
585
|
+
def run_bulk_system(fn: BulkSystemFunction,
|
|
568
586
|
*cids: ComponentID,
|
|
569
587
|
has_properties: _OptionalProperties = None,
|
|
570
588
|
**kwargs: dict[str, Any]) -> Any:
|
|
@@ -573,18 +591,28 @@ def run_bulk_system(fn: SystemFunction,
|
|
|
573
591
|
:param fn: the actual system function
|
|
574
592
|
:param cids: the components to run on
|
|
575
593
|
:param has_properties: set of required properties
|
|
576
|
-
:return:
|
|
594
|
+
:return: Returns whatever the given callback returns or None if no
|
|
595
|
+
matching entities have been found
|
|
577
596
|
|
|
578
|
-
The fn is called with a list of
|
|
597
|
+
The fn is called with a list of `(eid, comp...)` tuples of all
|
|
579
598
|
entities that contain the listed components. The list can further be
|
|
580
599
|
narrowed down my filtering for given properties.
|
|
581
600
|
|
|
582
|
-
``fn`` is called given a list of ``(EntityID,
|
|
601
|
+
``fn`` is called given a list of ``(EntityID, components,...)``. In
|
|
583
602
|
contrast to ``run_system``, the user is responsible to loop over the list.
|
|
584
603
|
|
|
604
|
+
If no entities are found, `fn` is not called.
|
|
605
|
+
|
|
585
606
|
The prototype of ``fn`` is::
|
|
586
607
|
|
|
587
|
-
def callback(call_list: list[tuple[EntityID,
|
|
608
|
+
def callback(call_list: list[tuple[EntityID, *tuple[Component, ...]]], **kwargs) -> Any
|
|
609
|
+
|
|
610
|
+
Example::
|
|
611
|
+
|
|
612
|
+
def sys_bulk_render(entities_and_comps):
|
|
613
|
+
for eid, pos, sprite in entities_and_comps:
|
|
614
|
+
...
|
|
615
|
+
|
|
588
616
|
"""
|
|
589
617
|
|
|
590
618
|
call_list = _create_call_list(cids, has_properties)
|
|
@@ -654,20 +682,23 @@ def create_archetype(*cids: ComponentID) -> None:
|
|
|
654
682
|
|
|
655
683
|
|
|
656
684
|
def remove_archetype(cids: Iterable[ComponentID]) -> None:
|
|
657
|
-
"""Remove an archetype from the system. (See `
|
|
685
|
+
"""Remove an archetype from the system. (See `create_archetype`).
|
|
658
686
|
|
|
659
687
|
:param cids: The list of component IDs that construct the archetype.
|
|
660
688
|
:return: None
|
|
661
689
|
"""
|
|
662
690
|
|
|
663
691
|
at = tuple(cids)
|
|
664
|
-
|
|
692
|
+
try:
|
|
693
|
+
del archetype[at]
|
|
694
|
+
except KeyError:
|
|
695
|
+
pass
|
|
665
696
|
|
|
666
697
|
|
|
667
698
|
def add_to_archetype(eid: EntityID) -> None:
|
|
668
699
|
"""Make sure, eid is registered with all appropriate archetypes.
|
|
669
700
|
|
|
670
|
-
:param
|
|
701
|
+
:param eid: The entity ID to add to the archetype
|
|
671
702
|
|
|
672
703
|
There should be no need to call this function manually. It's called
|
|
673
704
|
internally, when a new component is added to an entity which makes this
|
|
@@ -687,7 +718,7 @@ def add_to_archetype(eid: EntityID) -> None:
|
|
|
687
718
|
def remove_from_archetype(eid: EntityID, cid: ComponentID | None = None) -> None:
|
|
688
719
|
"""Make sure, eid is only registered with appropriate archetypes.
|
|
689
720
|
|
|
690
|
-
:param
|
|
721
|
+
:param eid: The entity ID to remove from the archetype
|
|
691
722
|
:param cid: An optional component ID.
|
|
692
723
|
|
|
693
724
|
There should be no need to call this function manually. It's called
|
|
@@ -726,11 +757,11 @@ def comps_of_archetype(*cids: ComponentID, has_properties: _OptionalProperties =
|
|
|
726
757
|
return [(e, comps) for e, comps in archetype[at].items()]
|
|
727
758
|
|
|
728
759
|
|
|
729
|
-
def set_property(eid: EntityID,
|
|
760
|
+
def set_property(eid: EntityID, prop: Property) -> None:
|
|
730
761
|
"""Add a property to the given entity.
|
|
731
762
|
|
|
732
763
|
:param eid: The entity id to add the component to
|
|
733
|
-
:param
|
|
764
|
+
:param prop: A flag or tag that can be filtered, e.g. 'is_drawable'
|
|
734
765
|
:return: None
|
|
735
766
|
:raises UnknownEntityError: If the entity is not registered (anymore).
|
|
736
767
|
"""
|
|
@@ -738,14 +769,14 @@ def set_property(eid: EntityID, property: Property) -> None:
|
|
|
738
769
|
if eid not in eidx:
|
|
739
770
|
raise UnknownEntityError(f'Entity {eid} is not registered')
|
|
740
771
|
|
|
741
|
-
plist[eid].add(
|
|
772
|
+
plist[eid].add(prop)
|
|
742
773
|
|
|
743
774
|
|
|
744
775
|
def set_properties(eid: EntityID, properties: Iterable[Property]) -> None:
|
|
745
776
|
"""Add a list of properties to the given entity.
|
|
746
777
|
|
|
747
778
|
:param eid: The entity ID to add the properties to.
|
|
748
|
-
:param
|
|
779
|
+
:param properties: The list of properties to add.
|
|
749
780
|
|
|
750
781
|
This is just a convenience wrapper around `set_property`.
|
|
751
782
|
"""
|
|
@@ -757,7 +788,7 @@ def has_property(eid: EntityID, prop: Property) -> bool:
|
|
|
757
788
|
"""Checks if the given entity has that property.
|
|
758
789
|
|
|
759
790
|
:param eid: The entity id to add the component to
|
|
760
|
-
:param
|
|
791
|
+
:param prop: The property to check for
|
|
761
792
|
:return: True if the property is set for the given entity
|
|
762
793
|
:raises UnknownEntityError: If the entity is not registered (anymore).
|
|
763
794
|
"""
|
|
@@ -772,7 +803,7 @@ def remove_property(eid: EntityID, prop: Property) -> None:
|
|
|
772
803
|
"""Removes a property from the given entity.
|
|
773
804
|
|
|
774
805
|
:param eid: The entity id to add the component to
|
|
775
|
-
:param
|
|
806
|
+
:param prop: The property to remove
|
|
776
807
|
:return: None
|
|
777
808
|
:raises UnknownEntityError: If the entity is not registered (anymore).
|
|
778
809
|
"""
|
|
@@ -780,7 +811,10 @@ def remove_property(eid: EntityID, prop: Property) -> None:
|
|
|
780
811
|
if eid not in eidx:
|
|
781
812
|
raise UnknownEntityError(f'Entity {eid} is not registered')
|
|
782
813
|
|
|
783
|
-
|
|
814
|
+
try:
|
|
815
|
+
plist[eid].remove(prop)
|
|
816
|
+
except KeyError:
|
|
817
|
+
pass
|
|
784
818
|
|
|
785
819
|
|
|
786
820
|
def clear_properties(eid: EntityID) -> None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tinyecs
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: The teeniest, tiniest ECS system
|
|
5
5
|
Author-email: Michael Lamertz <michael.lamertz@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -13,7 +13,19 @@ Classifier: Topic :: Games/Entertainment
|
|
|
13
13
|
Classifier: Topic :: Software Development :: Libraries :: pygame
|
|
14
14
|
Description-Content-Type: text/x-rst
|
|
15
15
|
License-File: LICENSE
|
|
16
|
-
|
|
16
|
+
Provides-Extra: base
|
|
17
|
+
Requires-Dist: tinyecs-compsys-base; extra == "base"
|
|
18
|
+
Provides-Extra: dynamics
|
|
19
|
+
Requires-Dist: tinyecs-compsys-dynamics; extra == "dynamics"
|
|
20
|
+
Provides-Extra: patternengine
|
|
21
|
+
Requires-Dist: tinyecs-compsys-patternengine; extra == "patternengine"
|
|
22
|
+
Provides-Extra: sdl2
|
|
23
|
+
Requires-Dist: tinyecs-compsys-sdl2; extra == "sdl2"
|
|
24
|
+
Provides-Extra: demos
|
|
25
|
+
Requires-Dist: tinyecs[base,dynamics,sdl2]; extra == "demos"
|
|
26
|
+
Requires-Dist: tinyecs-demos; extra == "demos"
|
|
27
|
+
Provides-Extra: all
|
|
28
|
+
Requires-Dist: tinyecs[base,demos,dynamics,patternengine,sdl2]; extra == "all"
|
|
17
29
|
Dynamic: license-file
|
|
18
30
|
|
|
19
31
|
Introduction
|
|
@@ -73,15 +85,6 @@ Issues can be opened on `github issues`_
|
|
|
73
85
|
|
|
74
86
|
.. _github issues: https://github.com/dickerdackel/tinyecs/issues
|
|
75
87
|
|
|
76
|
-
Please respect, that I don't want any contributions done with the assistance
|
|
77
|
-
of AI. This is a hobby project with focus on the craft of programming. I
|
|
78
|
-
have experimentally used AI to audit parts of the code and documentation, and
|
|
79
|
-
while it found a lot of typos and 2 actual issues, without exception, the
|
|
80
|
-
provided solutions were often besides the point or plain wrong.
|
|
81
|
-
|
|
82
|
-
I have no possibility to enforce that request, the simple fact that I ask for
|
|
83
|
-
it should be sufficient.
|
|
84
|
-
|
|
85
88
|
License
|
|
86
89
|
=======
|
|
87
90
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.rst
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/tinyecs/__init__.py
|
|
5
|
+
src/tinyecs/tutorial.py
|
|
6
|
+
src/tinyecs.egg-info/PKG-INFO
|
|
7
|
+
src/tinyecs.egg-info/SOURCES.txt
|
|
8
|
+
src/tinyecs.egg-info/dependency_links.txt
|
|
9
|
+
src/tinyecs.egg-info/requires.txt
|
|
10
|
+
src/tinyecs.egg-info/top_level.txt
|
|
11
|
+
tests/test_tinyecs.py
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
[all]
|
|
3
|
+
tinyecs[base,demos,dynamics,patternengine,sdl2]
|
|
4
|
+
|
|
5
|
+
[base]
|
|
6
|
+
tinyecs-compsys-base
|
|
7
|
+
|
|
8
|
+
[demos]
|
|
9
|
+
tinyecs[base,dynamics,sdl2]
|
|
10
|
+
tinyecs-demos
|
|
11
|
+
|
|
12
|
+
[dynamics]
|
|
13
|
+
tinyecs-compsys-dynamics
|
|
14
|
+
|
|
15
|
+
[patternengine]
|
|
16
|
+
tinyecs-compsys-patternengine
|
|
17
|
+
|
|
18
|
+
[sdl2]
|
|
19
|
+
tinyecs-compsys-sdl2
|
|
@@ -338,17 +338,21 @@ def test_eid_has():
|
|
|
338
338
|
def test_shutdown():
|
|
339
339
|
ecs.reset()
|
|
340
340
|
|
|
341
|
-
|
|
341
|
+
class HasShutdown(Exception): ...
|
|
342
342
|
|
|
343
343
|
class ShutdownEntity():
|
|
344
344
|
def shutdown_(self):
|
|
345
|
-
|
|
346
|
-
shutdown_successful = True
|
|
345
|
+
raise HasShutdown()
|
|
347
346
|
|
|
348
|
-
|
|
349
|
-
ecs.add_component(
|
|
350
|
-
|
|
351
|
-
|
|
347
|
+
eid = ecs.create_entity()
|
|
348
|
+
ecs.add_component(eid, 'shutdown-test', ShutdownEntity())
|
|
349
|
+
with pytest.raises(HasShutdown) as e:
|
|
350
|
+
ecs.add_component(eid, 'shutdown-test', ShutdownEntity())
|
|
351
|
+
assert e.type == HasShutdown
|
|
352
|
+
|
|
353
|
+
with pytest.raises(HasShutdown) as e:
|
|
354
|
+
ecs.remove_entity(eid)
|
|
355
|
+
assert e.type == HasShutdown
|
|
352
356
|
|
|
353
357
|
|
|
354
358
|
def test_cid_of_comp():
|
|
@@ -536,6 +540,7 @@ if __name__ == '__main__':
|
|
|
536
540
|
test_cids_of_eid()
|
|
537
541
|
test_comps_of_eid()
|
|
538
542
|
test_run_system()
|
|
543
|
+
test_run_bulk_system()
|
|
539
544
|
test_run_all_systems()
|
|
540
545
|
test_remove_system()
|
|
541
546
|
test_remove_entity()
|
|
@@ -546,7 +551,6 @@ if __name__ == '__main__':
|
|
|
546
551
|
test_add_system_to_domain()
|
|
547
552
|
test_remove_system_from_domain()
|
|
548
553
|
test_run_domain()
|
|
549
|
-
test_is_eid()
|
|
550
554
|
test_eid_has()
|
|
551
555
|
test_shutdown()
|
|
552
556
|
test_cid_of_comp()
|
|
@@ -561,3 +565,5 @@ if __name__ == '__main__':
|
|
|
561
565
|
test_property_archetype()
|
|
562
566
|
test_property_find_entities()
|
|
563
567
|
test_property_clear()
|
|
568
|
+
test_property_purge()
|
|
569
|
+
test_property_eid_unknown()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from .compsys import *
|