diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c6b7e7a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "[python]": { + "editor.defaultFormatter": "ms-python.black-formatter" + } +} \ No newline at end of file diff --git a/ecs.py b/ecs.py index 0129649..6b89957 100644 --- a/ecs.py +++ b/ecs.py @@ -15,7 +15,7 @@ class World: self._mapping: dict[type, set[Entity]] = {} self._to_apply_resources: list[tuple[type, object]] = [] self._resources: dict[type, object] = {} - + def create_entity(self, *components): """ Crée une entité avec les composants donnés en paramètres. @@ -28,7 +28,7 @@ class World: """ return Entity(self, *components) - def remove_entity(self, entity: 'Entity'): + def remove_entity(self, entity: "Entity"): """ Supprime une entité du monde. @@ -37,7 +37,7 @@ class World: """ entity._deleted = True self._to_apply.add(entity) - + def set(self, *resources): """ Définit les ressources données en paramètres. @@ -48,7 +48,7 @@ class World: """ 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. @@ -81,14 +81,16 @@ class World: entity._to_apply.clear() self._to_apply.clear() for resource_type, resource in self._to_apply_resources: - if resource is None: del self._resources[resource_type] - else: self._resources[resource_type] = resource + if resource is None: + del self._resources[resource_type] + else: + self._resources[resource_type] = resource self._to_apply_resources.clear() - - def query(self, *needed: type, without: tuple[type] = []) -> Iterator['Entity']: + + 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. @@ -103,10 +105,12 @@ class World: yield entity else: for entity in self._mapping.get(needed[0], set()): - if all(entity in self._mapping.get(component_type, set()) for component_type in needed[1:]) and \ - all(without_type not in entity for without_type in without): + if all( + entity in self._mapping.get(component_type, set()) + for component_type in needed[1:] + ) and all(without_type not in entity for without_type in without): yield entity - + def __getitem__(self, resource_type: type) -> object: """ Renvoie la ressource de type *resource_type. @@ -118,7 +122,7 @@ class World: 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. @@ -131,10 +135,12 @@ class World: """ 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. @@ -144,11 +150,13 @@ class Entity: *components: Les composants de l'entité. """ self._world = world - self._to_apply: list[tuple[type, object]] = [(type(component), component) for component in components] + self._to_apply: list[tuple[type, object]] = [ + (type(component), component) for component in components + ] self._components: dict[type, object] = {} self._deleted = False self._world._to_apply.add(self) - + def set(self, *components): """ Définit les composants de l'entité donnés en paramètres. @@ -159,7 +167,7 @@ class Entity: 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. @@ -171,7 +179,7 @@ class Entity: 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. @@ -194,4 +202,4 @@ class Entity: Retourne: Si le composant de type *component_type existe. """ - return component_type in self._components \ No newline at end of file + return component_type in self._components diff --git a/main.py b/main.py index 60c66fc..0eea953 100644 --- a/main.py +++ b/main.py @@ -1,8 +1,14 @@ from ecs import World + # Création de composants pouvant être ajouté a des entitées -class Name(str): pass -class Age(int): pass +class Name(str): + pass + + +class Age(int): + pass + # Création d'un monde world = World() @@ -50,8 +56,11 @@ for entity in world.query(): print(entity[Age], end=" ") print() + # Création d'une ressource pouvant être ajoutée a un monde -class Gravity(float): pass +class Gravity(float): + pass + # On peut aussi ajouter des ressources globales world.set(Gravity(9.81)) @@ -79,4 +88,3 @@ world.apply() print("On vérifie que la ressource Gravity n'existe plus") print(Gravity in world) - diff --git a/tasks.py b/tasks.py new file mode 100644 index 0000000..437e391 --- /dev/null +++ b/tasks.py @@ -0,0 +1,29 @@ +from typing import Callable +from ecs import World + + +class TaskManager: + """ + Contient des fonctions de logique s'appliquant sur un monde. + """ + + def __init__(self): + """ + Créer un gestionnaire de taches vide. + """ + self.tasks: dict[int, list[Callable[[World], None]]] = {} + + def add(self, priority: int, task: Callable[[World], None]): + """ + Ajoute une tache à un gestionnaire de taches. + """ + self.tasks.setdefault(priority, []).append(task) + + def run(self, world: World): + """ + Exécute toutes les taches. + """ + priorities = sorted(list(self.tasks.keys())) + for priority in priorities: + for task in self.tasks[priority]: + task(world)