Système d'entités et de composants #1
107
ecs.py
107
ecs.py
|
@ -2,7 +2,14 @@ from typing import Iterator
|
|||
|
||||
|
||||
class World:
|
||||
"""
|
||||
Un monde contenant des entités et des ressources.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Permet de créer un nouveau monde vide.
|
||||
"""
|
||||
self._to_apply: set[Entity] = set()
|
||||
self._entities: set[Entity] = set()
|
||||
self._mapping: dict[type, set[Entity]] = {}
|
||||
|
@ -10,22 +17,53 @@ class World:
|
|||
self._resources: dict[type, object] = {}
|
||||
|
||||
def create_entity(self, *components):
|
||||
"""
|
||||
Crée une entité avec les composants donnés en paramètres.
|
||||
|
||||
Paramètres:
|
||||
*components: Les composants de l'entité.
|
||||
|
||||
Retourne:
|
||||
L'entité crée.
|
||||
"""
|
||||
return Entity(self, *components)
|
||||
|
||||
def remove_entity(self, entity: 'Entity'):
|
||||
"""
|
||||
Supprime une entité du monde.
|
||||
|
||||
Paramètres:
|
||||
entity: L'entité a supprimer.
|
||||
"""
|
||||
entity._deleted = True
|
||||
self._to_apply.add(entity)
|
||||
|
||||
def set(self, *resources):
|
||||
"""
|
||||
Définit les ressources données en paramètres.
|
||||
Si les ressources existent deja, elles seront remplacées.
|
||||
|
||||
Paramètres:
|
||||
*resources: Les ressources a definir.
|
||||
"""
|
||||
for resource in resources:
|
||||
self._to_apply_resources.append((type(resource), resource))
|
||||
|
||||
def remove(self, *resource_types):
|
||||
"""
|
||||
Supprime les ressources données en paramètres.
|
||||
|
||||
Paramètres:
|
||||
*resource_types: Les types des ressources à supprimer.
|
||||
"""
|
||||
for resource_type in resource_types:
|
||||
if resource_type in self._resources:
|
||||
self._to_apply_resources.append((resource_type, None))
|
||||
|
||||
def apply(self):
|
||||
"""
|
||||
Applique les changements réaliser dans le monde.
|
||||
"""
|
||||
for entity in self._to_apply:
|
||||
if entity._deleted:
|
||||
self._entities.remove(entity)
|
||||
|
@ -48,6 +86,17 @@ class World:
|
|||
self._to_apply_resources.clear()
|
||||
|
||||
def query(self, *needed: type, without: tuple[type] = []) -> Iterator['Entity']:
|
||||
"""
|
||||
Renvoie les entités qui ont les composants de *needed et sans les composants de *without.
|
||||
|
||||
Paramètres:
|
||||
*needed: Le type de composants que les entités doivent avoir.
|
||||
*without: Les type de composants que les entités ne doivent pas avoir.
|
||||
|
||||
Retourne:
|
||||
Les entités qui ont les composants de *needed et sans les composants de *without.
|
||||
Si *needed est vide, on retourne toutes les entités qui ont les composants de *without.
|
||||
"""
|
||||
if not needed:
|
||||
for entity in self._entities:
|
||||
if all(without_type not in entity for without_type in without):
|
||||
|
@ -59,13 +108,41 @@ class World:
|
|||
yield entity
|
||||
|
||||
def __getitem__(self, resource_type: type) -> object:
|
||||
"""
|
||||
Renvoie la ressource de type *resource_type.
|
||||
|
||||
Paramètres:
|
||||
resource_type: Le type de ressource à récupérer.
|
||||
|
||||
Retourne:
|
||||
La ressource de type *resource_type.
|
||||
"""
|
||||
return self._resources[resource_type]
|
||||
|
||||
def __contains__(self, resource_type: type) -> bool:
|
||||
"""
|
||||
Renvoie si la ressource de type *resource_type existe.
|
||||
|
||||
Paramètres:
|
||||
resource_type: Le type de ressource à tester.
|
||||
|
||||
Retourne:
|
||||
Si la ressource de type *resource_type existe.
|
||||
"""
|
||||
return resource_type in self._resources
|
||||
|
||||
class Entity:
|
||||
"""
|
||||
Une entité du monde.
|
||||
"""
|
||||
def __init__(self, world: World, *components):
|
||||
"""
|
||||
Créer une entité avec les composants en paramètres et l'ajoute au monde.
|
||||
|
||||
Paramètres:
|
||||
world: Le monde auquel ajouter l'entité.
|
||||
*components: Les composants de l'entité.
|
||||
"""
|
||||
self._world = world
|
||||
self._to_apply: list[tuple[type, object]] = [(type(component), component) for component in components]
|
||||
self._components: dict[type, object] = {}
|
||||
|
@ -73,18 +150,48 @@ class Entity:
|
|||
self._world._to_apply.add(self)
|
||||
|
||||
def set(self, *components):
|
||||
"""
|
||||
Définit les composants de l'entité donnés en paramètres.
|
||||
|
||||
Paramètres:
|
||||
*components: Les composants a definir.
|
||||
"""
|
||||
for component in components:
|
||||
self._to_apply.append((type(component), component))
|
||||
self._world._to_apply.add(self)
|
||||
|
||||
def remove(self, *component_types: type):
|
||||
"""
|
||||
Supprime les composants de l'entité donnés en paramètres.
|
||||
|
||||
Paramètres:
|
||||
*component_types: Le type des composants à supprimer.
|
||||
"""
|
||||
for component_type in component_types:
|
||||
if component_type in self._components:
|
||||
self._to_apply.append((component_type, None))
|
||||
self._world._to_apply.add(self)
|
||||
|
||||
def __getitem__(self, component_type: type) -> object:
|
||||
"""
|
||||
Renvoie le composant de type *component_type.
|
||||
|
||||
Paramètres:
|
||||
component_type: Le type du composant à récupérer.
|
||||
|
||||
Retourne:
|
||||
Le composant de type *component_type.
|
||||
"""
|
||||
return self._components[component_type]
|
||||
|
||||
def __contains__(self, component_type: type) -> bool:
|
||||
"""
|
||||
Renvoie si le composant de type *component_type existe.
|
||||
|
||||
Paramètres:
|
||||
component_type: Le type du composant à tester.
|
||||
|
||||
Retourne:
|
||||
Si le composant de type *component_type existe.
|
||||
"""
|
||||
return component_type in self._components
|
Loading…
Reference in a new issue