Meilleur système de boucle #4

Merged
tipragot merged 1 commit from better-loop into main 2023-10-24 11:15:45 +00:00
2 changed files with 111 additions and 50 deletions
Showing only changes of commit 3846ebe0c8 - Show all commits

132
engine.py
View file

@ -235,63 +235,80 @@ class Game:
Créer une un jeu.
"""
self._running = False
self._startup_tasks: dict[int, list[Callable[[World], None]]] = {}
self._update_tasks: dict[int, list[Callable[[World], None]]] = {}
self._shutdown_tasks: dict[int, list[Callable[[World], None]]] = {}
self._startup_tasks: list[Callable[[World], None]] = []
self._pre_update_tasks: list[Callable[[World], None]] = []
self._update_tasks: list[Callable[[World], None]] = []
self._post_update_tasks: list[Callable[[World], None]] = []
self._render_tasks: list[Callable[[World], None]] = []
self._shutdown_tasks: list[Callable[[World], None]] = []
def add_startup_tasks(self, priority: int, *tasks: Callable[[World], None]) -> None:
def add_startup_tasks(self, *tasks: Callable[[World], None]) -> None:
"""
Ajoute des taches qui s'executeront au démarrage du jeu.
Paramètres:
priority: La priorité de la tache.
*tasks: Les taches à ajouter.
"""
if self._running:
raise RuntimeError("Cannot add startup task while the loop is running")
self._startup_tasks.setdefault(priority, []).extend(tasks)
raise RuntimeError("Cannot add a task while the loop is running")
self._startup_tasks.extend(tasks)
def add_tasks(self, priority: int, *tasks: Callable[[World], None]) -> None:
def add_pre_update_tasks(self, *tasks: Callable[[World], None]) -> None:
"""
Ajoute des taches qui s'executeront au debut de chaque mise à jour du jeu.
Paramètres:
*tasks: Les taches à ajouter.
"""
if self._running:
raise RuntimeError("Cannot add a task while the loop is running")
self._pre_update_tasks.extend(tasks)
def add_update_tasks(self, *tasks: Callable[[World], None]) -> None:
"""
Ajoute des taches qui s'executeront a chaque mise à jour du jeu.
Paramètres:
priority: La priorité de la tache.
*tasks: Les taches à ajouter.
"""
if self._running:
raise RuntimeError("Cannot add task while the loop is running")
self._update_tasks.setdefault(priority, []).extend(tasks)
raise RuntimeError("Cannot add a task while the loop is running")
self._update_tasks.extend(tasks)
def add_shutdown_tasks(
self, priority: int, *tasks: Callable[[World], None]
) -> None:
def add_post_update_tasks(self, *tasks: Callable[[World], None]) -> None:
"""
Ajoute des taches qui s'executeront à la fin de chaque mise à jour du jeu.
Paramètres:
*tasks: Les taches à ajouter.
"""
if self._running:
raise RuntimeError("Cannot add a task while the loop is running")
self._post_update_tasks.extend(tasks)
def add_render_tasks(self, *tasks: Callable[[World], None]) -> None:
"""
Ajoute des taches qui s'executeront après chaque mise à jour du jeu pour le rendu.
Paramètres:
*tasks: Les taches à ajouter.
"""
if self._running:
raise RuntimeError("Cannot add a task while the loop is running")
self._render_tasks.extend(tasks)
def add_shutdown_tasks(self, *tasks: Callable[[World], None]) -> None:
"""
Ajoute des taches qui s'executeront à la fin de la boucle de jeu.
Paramètres:
priority: La priorité de la tache.
*tasks: Les taches à ajouter.
"""
if self._running:
raise RuntimeError("Cannot add shutdown task while the loop is running")
self._shutdown_tasks.setdefault(priority, []).extend(tasks)
raise RuntimeError("Cannot add a task while the loop is running")
self._shutdown_tasks.extend(tasks)
def _run_tasks(
self, tasks: dict[int, list[Callable[[World], None]]], world: World
) -> None:
"""
Execute toutes les taches donnes en paramètres en respectant la priorité.
"""
priorities = sorted(list(tasks.keys()))
for priority in priorities:
for task in tasks[priority]:
try:
task(world)
except Exception as e:
error(f"Error in task: {e}")
def run(self) -> World:
def run(self, world: World = World()) -> World:
"""
Lance la boucle de jeu.
"""
@ -300,29 +317,56 @@ class Game:
self._running = True
# On initialize le monde
world: World = World()
world.set(self)
# On applique les moddifications pour l'ajout de la ressource
world.apply()
# On execute les taches d'initialisation du monde
self._run_tasks(self._startup_tasks, world)
# On applique les changements
for task in self._startup_tasks:
try:
task(world)
except Exception as e:
error(f"Error during startup task: {e}")
world.apply()
while self._running:
# On exécute les taches de mise a jour du monde
self._run_tasks(self._update_tasks, world)
# On execute les taches de pré mise à jour du monde
for task in self._pre_update_tasks:
try:
task(world)
except Exception as e:
error(f"Error during pre-update task: {e}")
world.apply()
# On applique les changements
# On exécute les taches de mise a jour du monde
for task in self._update_tasks:
try:
task(world)
except Exception as e:
error(f"Error during update task: {e}")
world.apply()
# On execute les taches de post mise à jour du monde
for task in self._post_update_tasks:
try:
task(world)
except Exception as e:
error(f"Error during post-update task: {e}")
world.apply()
# On execute les taches de rendu du jeu
for task in self._render_tasks:
try:
task(world)
except Exception as e:
error(f"Error during render task: {e}")
world.apply()
# On exécute les taches de fin du monde
self._run_tasks(self._shutdown_tasks, world)
# On applique les changements
for task in self._shutdown_tasks:
try:
task(world)
except Exception as e:
error(f"Error during shutdown task: {e}")
world.apply()
# On retourne le monde

29
main.py
View file

@ -6,11 +6,28 @@ Ceci est un exemple de comment l'on peut utiliser le moteur du jeu.
from engine import Game
# Initialisation
game = Game()
game.add_startup_tasks(1, lambda world: print("Hello 1"))
game.add_startup_tasks(-5, lambda world: print("Hello -5"))
game.add_startup_tasks(6, lambda world: print("Hello 6"))
game.add_startup_tasks(0, lambda world: print("Hello 0"))
game.add_tasks(0, lambda world: world[Game].stop())
game.add_shutdown_tasks(0, lambda world: print("Bye 0"))
# Ajout de tache au démarage (l'ordre d'ajout est important)
game.add_startup_tasks(lambda world: print("Hello first"))
game.add_startup_tasks(lambda world: print("Hello second"))
game.add_startup_tasks(lambda world: print("Hello third"))
game.add_startup_tasks(lambda world: print("Hello last"))
# Ajoute de tache au mise à jour (malgré le world[Game].stop(), la boucle termine les taches suivantes)
game.add_pre_update_tasks(lambda world: print("Pre Update"))
game.add_update_tasks(lambda world: world[Game].stop())
game.add_post_update_tasks(lambda world: print("Post Update"))
# Ajout de tache au rendu
game.add_render_tasks(lambda world: print("Render task 1"))
game.add_render_tasks(lambda world: print("Render task 2"))
game.add_render_tasks(lambda world: print("Render task 3"))
# Ajout de tache à la fin
game.add_shutdown_tasks(lambda world: print("Bye first"))
game.add_shutdown_tasks(lambda world: print("Bye second"))
# On lance la boucle
game.run()