tinyecs 0.3.6__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.3.6 → tinyecs-0.5.0}/LICENSE +1 -1
- {tinyecs-0.3.6/src/tinyecs.egg-info → tinyecs-0.5.0}/PKG-INFO +14 -11
- {tinyecs-0.3.6 → tinyecs-0.5.0}/README.rst +0 -9
- {tinyecs-0.3.6 → tinyecs-0.5.0}/pyproject.toml +11 -7
- {tinyecs-0.3.6 → tinyecs-0.5.0}/src/tinyecs/__init__.py +97 -69
- {tinyecs-0.3.6 → tinyecs-0.5.0}/src/tinyecs/tutorial.py +37 -36
- {tinyecs-0.3.6 → 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.3.6 → tinyecs-0.5.0}/tests/test_tinyecs.py +33 -27
- tinyecs-0.3.6/src/tinyecs/components.py +0 -1
- tinyecs-0.3.6/src/tinyecs/compsys.py +0 -399
- tinyecs-0.3.6/src/tinyecs/demo.py +0 -29
- tinyecs-0.3.6/src/tinyecs/demos/__init__.py +0 -0
- tinyecs-0.3.6/src/tinyecs/demos/background.py +0 -100
- tinyecs-0.3.6/src/tinyecs/demos/bouncing_sprites.py +0 -115
- tinyecs-0.3.6/src/tinyecs/demos/example.py +0 -117
- tinyecs-0.3.6/src/tinyecs/demos/homing-missiles.py +0 -234
- tinyecs-0.3.6/src/tinyecs/demos/marquee.py +0 -97
- tinyecs-0.3.6/src/tinyecs.egg-info/SOURCES.txt +0 -21
- tinyecs-0.3.6/src/tinyecs.egg-info/entry_points.txt +0 -2
- tinyecs-0.3.6/src/tinyecs.egg-info/requires.txt +0 -1
- {tinyecs-0.3.6 → tinyecs-0.5.0}/setup.cfg +0 -0
- {tinyecs-0.3.6 → tinyecs-0.5.0}/src/tinyecs.egg-info/dependency_links.txt +0 -0
- {tinyecs-0.3.6 → 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
|
|
@@ -24,7 +25,7 @@ type DomainID = Hashable
|
|
|
24
25
|
type Property = Hashable
|
|
25
26
|
type Component = object
|
|
26
27
|
|
|
27
|
-
type
|
|
28
|
+
type EntityComponentsBundle = tuple[EntityID, list[Component]]
|
|
28
29
|
type _OptionalProperties = Iterable[Property] | None
|
|
29
30
|
type _RunSystemResult = dict[EntityID, Any]
|
|
30
31
|
|
|
@@ -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,
|
|
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:
|
|
@@ -480,14 +498,14 @@ def comp_of_eid(eid: EntityID, cid: ComponentID) -> Component:
|
|
|
480
498
|
return comps_of_eid(eid, cid)[0]
|
|
481
499
|
|
|
482
500
|
|
|
483
|
-
def eid_of_comp(comp: Component) -> set
|
|
501
|
+
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:
|
|
@@ -538,14 +556,12 @@ def _create_call_list(cids: tuple[ComponentID],
|
|
|
538
556
|
return call_list
|
|
539
557
|
|
|
540
558
|
|
|
541
|
-
def run_system(
|
|
542
|
-
fn: SystemFunction,
|
|
559
|
+
def run_system(fn: SystemFunction,
|
|
543
560
|
*cids: ComponentID,
|
|
544
561
|
has_properties: _OptionalProperties = None,
|
|
545
562
|
**kwargs: dict[str, Any]) -> _RunSystemResult:
|
|
546
563
|
"""Run the system for the matching cids.
|
|
547
564
|
|
|
548
|
-
:param dt: delta time since the last frame (miliseconds)
|
|
549
565
|
:param fn: the actual system function
|
|
550
566
|
:param cids: the components to run on
|
|
551
567
|
:param has_properties: set of required properties
|
|
@@ -554,7 +570,7 @@ def run_system(dt: float,
|
|
|
554
570
|
For every entity that has all the listed components, ``fn`` is run. The
|
|
555
571
|
function prototype of ``fn`` is::
|
|
556
572
|
|
|
557
|
-
def callback(
|
|
573
|
+
def callback(eid: EntityID, *comps: Component) -> Any
|
|
558
574
|
|
|
559
575
|
The list can further be narrowed down my filtering for given properties.
|
|
560
576
|
|
|
@@ -563,56 +579,62 @@ def run_system(dt: float,
|
|
|
563
579
|
"""
|
|
564
580
|
|
|
565
581
|
call_list = _create_call_list(cids, has_properties)
|
|
566
|
-
return {eid: fn(
|
|
582
|
+
return {eid: fn(eid, *parms, **kwargs) for eid, *parms in call_list}
|
|
567
583
|
|
|
568
584
|
|
|
569
|
-
def run_bulk_system(
|
|
570
|
-
fn: SystemFunction,
|
|
585
|
+
def run_bulk_system(fn: BulkSystemFunction,
|
|
571
586
|
*cids: ComponentID,
|
|
572
587
|
has_properties: _OptionalProperties = None,
|
|
573
588
|
**kwargs: dict[str, Any]) -> Any:
|
|
574
589
|
"""Run the bulk system for all entities with matching cids.
|
|
575
590
|
|
|
576
|
-
:param dt: delta time since the last frame (miliseconds)
|
|
577
591
|
:param fn: the actual system function
|
|
578
592
|
:param cids: the components to run on
|
|
579
593
|
:param has_properties: set of required properties
|
|
580
|
-
:return:
|
|
594
|
+
:return: Returns whatever the given callback returns or None if no
|
|
595
|
+
matching entities have been found
|
|
581
596
|
|
|
582
|
-
The fn is called with a list of
|
|
597
|
+
The fn is called with a list of `(eid, comp...)` tuples of all
|
|
583
598
|
entities that contain the listed components. The list can further be
|
|
584
599
|
narrowed down my filtering for given properties.
|
|
585
600
|
|
|
586
|
-
``fn`` is called given a list of ``(EntityID,
|
|
601
|
+
``fn`` is called given a list of ``(EntityID, components,...)``. In
|
|
587
602
|
contrast to ``run_system``, the user is responsible to loop over the list.
|
|
588
603
|
|
|
604
|
+
If no entities are found, `fn` is not called.
|
|
605
|
+
|
|
589
606
|
The prototype of ``fn`` is::
|
|
590
607
|
|
|
591
|
-
def callback(
|
|
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
|
+
|
|
592
616
|
"""
|
|
593
617
|
|
|
594
618
|
call_list = _create_call_list(cids, has_properties)
|
|
595
|
-
return fn(
|
|
619
|
+
return fn(call_list, **kwargs) if call_list else None
|
|
596
620
|
|
|
597
621
|
|
|
598
|
-
def run_all_systems(
|
|
622
|
+
def run_all_systems(**kwargs) -> dict[SystemFunction, _RunSystemResult]:
|
|
599
623
|
"""Run all registered systems.
|
|
600
624
|
|
|
601
|
-
:param dt: Delta time
|
|
602
625
|
:return: A dict of function as key, and the result of run_system as value
|
|
603
626
|
|
|
604
627
|
This calls above run_system for all registered systems with their
|
|
605
628
|
appropriate components.
|
|
606
629
|
"""
|
|
607
630
|
|
|
608
|
-
return {fn: run_system(
|
|
631
|
+
return {fn: run_system(fn, *comps, **kwargs)
|
|
609
632
|
for fn, comps in sidx.items()}
|
|
610
633
|
|
|
611
634
|
|
|
612
|
-
def run_domain(
|
|
635
|
+
def run_domain(domain: DomainID, **kwargs) -> dict[SystemFunction, _RunSystemResult]:
|
|
613
636
|
"""Run all systems within domain.
|
|
614
637
|
|
|
615
|
-
:param dt: Delta time
|
|
616
638
|
:return: A dict of function as key, and the result of run_system as value
|
|
617
639
|
|
|
618
640
|
This is the same as run_all_systems, but limited to a specific domain.
|
|
@@ -621,7 +643,7 @@ def run_domain(dt: float, domain: DomainID) -> dict[SystemFunction, _RunSystemRe
|
|
|
621
643
|
if domain not in didx:
|
|
622
644
|
return {}
|
|
623
645
|
|
|
624
|
-
return {fn: run_system(
|
|
646
|
+
return {fn: run_system(fn, *sidx[fn], **kwargs)
|
|
625
647
|
for fn in didx[domain]}
|
|
626
648
|
|
|
627
649
|
|
|
@@ -660,20 +682,23 @@ def create_archetype(*cids: ComponentID) -> None:
|
|
|
660
682
|
|
|
661
683
|
|
|
662
684
|
def remove_archetype(cids: Iterable[ComponentID]) -> None:
|
|
663
|
-
"""Remove an archetype from the system. (See `
|
|
685
|
+
"""Remove an archetype from the system. (See `create_archetype`).
|
|
664
686
|
|
|
665
687
|
:param cids: The list of component IDs that construct the archetype.
|
|
666
688
|
:return: None
|
|
667
689
|
"""
|
|
668
690
|
|
|
669
691
|
at = tuple(cids)
|
|
670
|
-
|
|
692
|
+
try:
|
|
693
|
+
del archetype[at]
|
|
694
|
+
except KeyError:
|
|
695
|
+
pass
|
|
671
696
|
|
|
672
697
|
|
|
673
698
|
def add_to_archetype(eid: EntityID) -> None:
|
|
674
699
|
"""Make sure, eid is registered with all appropriate archetypes.
|
|
675
700
|
|
|
676
|
-
:param
|
|
701
|
+
:param eid: The entity ID to add to the archetype
|
|
677
702
|
|
|
678
703
|
There should be no need to call this function manually. It's called
|
|
679
704
|
internally, when a new component is added to an entity which makes this
|
|
@@ -693,7 +718,7 @@ def add_to_archetype(eid: EntityID) -> None:
|
|
|
693
718
|
def remove_from_archetype(eid: EntityID, cid: ComponentID | None = None) -> None:
|
|
694
719
|
"""Make sure, eid is only registered with appropriate archetypes.
|
|
695
720
|
|
|
696
|
-
:param
|
|
721
|
+
:param eid: The entity ID to remove from the archetype
|
|
697
722
|
:param cid: An optional component ID.
|
|
698
723
|
|
|
699
724
|
There should be no need to call this function manually. It's called
|
|
@@ -706,7 +731,7 @@ def remove_from_archetype(eid: EntityID, cid: ComponentID | None = None) -> None
|
|
|
706
731
|
del adict[eid]
|
|
707
732
|
|
|
708
733
|
|
|
709
|
-
def comps_of_archetype(*cids: ComponentID, has_properties: _OptionalProperties = None) -> list[
|
|
734
|
+
def comps_of_archetype(*cids: ComponentID, has_properties: _OptionalProperties = None) -> list[EntityComponentsBundle]:
|
|
710
735
|
"""Return the given archetype.
|
|
711
736
|
|
|
712
737
|
:param cids: The cids that define the archetype.
|
|
@@ -732,11 +757,11 @@ def comps_of_archetype(*cids: ComponentID, has_properties: _OptionalProperties =
|
|
|
732
757
|
return [(e, comps) for e, comps in archetype[at].items()]
|
|
733
758
|
|
|
734
759
|
|
|
735
|
-
def set_property(eid: EntityID,
|
|
760
|
+
def set_property(eid: EntityID, prop: Property) -> None:
|
|
736
761
|
"""Add a property to the given entity.
|
|
737
762
|
|
|
738
763
|
:param eid: The entity id to add the component to
|
|
739
|
-
:param
|
|
764
|
+
:param prop: A flag or tag that can be filtered, e.g. 'is_drawable'
|
|
740
765
|
:return: None
|
|
741
766
|
:raises UnknownEntityError: If the entity is not registered (anymore).
|
|
742
767
|
"""
|
|
@@ -744,14 +769,14 @@ def set_property(eid: EntityID, property: Property) -> None:
|
|
|
744
769
|
if eid not in eidx:
|
|
745
770
|
raise UnknownEntityError(f'Entity {eid} is not registered')
|
|
746
771
|
|
|
747
|
-
plist[eid].add(
|
|
772
|
+
plist[eid].add(prop)
|
|
748
773
|
|
|
749
774
|
|
|
750
775
|
def set_properties(eid: EntityID, properties: Iterable[Property]) -> None:
|
|
751
776
|
"""Add a list of properties to the given entity.
|
|
752
777
|
|
|
753
778
|
:param eid: The entity ID to add the properties to.
|
|
754
|
-
:param
|
|
779
|
+
:param properties: The list of properties to add.
|
|
755
780
|
|
|
756
781
|
This is just a convenience wrapper around `set_property`.
|
|
757
782
|
"""
|
|
@@ -763,7 +788,7 @@ def has_property(eid: EntityID, prop: Property) -> bool:
|
|
|
763
788
|
"""Checks if the given entity has that property.
|
|
764
789
|
|
|
765
790
|
:param eid: The entity id to add the component to
|
|
766
|
-
:param
|
|
791
|
+
:param prop: The property to check for
|
|
767
792
|
:return: True if the property is set for the given entity
|
|
768
793
|
:raises UnknownEntityError: If the entity is not registered (anymore).
|
|
769
794
|
"""
|
|
@@ -778,7 +803,7 @@ def remove_property(eid: EntityID, prop: Property) -> None:
|
|
|
778
803
|
"""Removes a property from the given entity.
|
|
779
804
|
|
|
780
805
|
:param eid: The entity id to add the component to
|
|
781
|
-
:param
|
|
806
|
+
:param prop: The property to remove
|
|
782
807
|
:return: None
|
|
783
808
|
:raises UnknownEntityError: If the entity is not registered (anymore).
|
|
784
809
|
"""
|
|
@@ -786,7 +811,10 @@ def remove_property(eid: EntityID, prop: Property) -> None:
|
|
|
786
811
|
if eid not in eidx:
|
|
787
812
|
raise UnknownEntityError(f'Entity {eid} is not registered')
|
|
788
813
|
|
|
789
|
-
|
|
814
|
+
try:
|
|
815
|
+
plist[eid].remove(prop)
|
|
816
|
+
except KeyError:
|
|
817
|
+
pass
|
|
790
818
|
|
|
791
819
|
|
|
792
820
|
def clear_properties(eid: EntityID) -> None:
|