Files
wsg/docs/PLAN.md
T
Jérôme Bousquié 91007853d9 docs: note pour mémoire sur le couplage au runtime async (pollster)
La lib n'a qu'un seul point de couplage au runtime (block_on dans app.rs) ; on ne crée volontairement
pas d'abstraction à ce stade. Consigné dans PLAN.md et ARCHI_APP.md : isoler derrière un module-pivot
unique si la lib acquiert d'autres appels async. Corrige aussi l'item check-list pollster devenu faux
dev-dependencies -> dependencies depuis la migration winit 0.30.
2026-09-16 14:58:51 +02:00

105 lines
6.6 KiB
Markdown

---
type: Plan
title: Implementation Plan for wsg_lib Engine Consolidation and Finalization
description: Implementation plan defining priority steps to finalize the current architecture, making the API intuitive for standard users while maintaining power for advanced users
tags: [plan, implementation, roadmap, development, wsg-lib]
status: stable
generated: { by: human:jerome, at: 2026-07-31T00:00:00Z }
---
# Plan d'Implémentation : Consolidation et Finalisation du Moteur wsg_lib
Ce plan définit les étapes prioritaires pour finaliser l'architecture actuelle. L'objectif est de rendre l'API intuitive pour l'utilisateur standard tout en conservant la puissance de contrôle pour l'utilisateur avancé.
> **Statut réel (à jour au 2026-09-16).** Ce plan couvre la phase de *consolidation* passée ; la source
> de vérité sur l'état actuel est **README.md** et le code. Depuis la révision du 2026-09-14, l'étape
> **« Scene auto-render »** a été réalisée : le rendu de la `Scene` est **automatisé** en une seule
> passe groupée via `App::render_scene(frame.view())` (appelée par défaut dans `AppHandler::render`),
> et `simple.rs` (API `AppBuilder`, sans `winit`/`wgpu`) déclare un quad rendu automatiquement.
## Phase 1 : Finalisation et Nettoyage de l'Existant (Priorité Absolue)
Cette phase vise à supprimer la dette technique et à unifier les accès.
### Uniformisation des Modules
- [X] Vérifier que tous les traits (`AppHandler`) et structures (`App`, `Context`) sont explicitement marqués `pub` dans leurs fichiers sources.
- [X] Ré-exporter l'API dans `lib.rs` pour permettre des imports simplifiés (ex : `use wsg_lib::{App, AppHandler}`).
- [X] Nettoyer les accès internes pour que l'utilisateur n'ait pas à importer les modules système (`core`, `pipeline`) sauf besoin spécifique.
### Abstraction de la Boucle (`App::run`)
- [X] Déplacer la gestion de `winit::event_loop` et des `Frame` à l'intérieur de la méthode `run()` de `App`.
- [X] Garantir que le trait `AppHandler` reçoit une référence à `App` permettant d'appeler `app.renderer` ou `app.scene`.
- [X] Supprimer toute gestion de `Frame` ou `EventLoop` manuelle des exemples utilisateurs (`simple.rs`).
### Correction du Builder et Initialisation
- [X] Standardiser la création de `App` via un `AppBuilder` robuste.
- [X] Gérer les `dev-dependencies` dans `lib/Cargo.toml` (notamment `pollster` avec la feature `macro`) pour permettre la compilation des exemples sans polluer les dépendances finales de la librairie.
## Phase 2 : Structure de Rendu et Scène
Une fois la plomberie encapsulée, nous devons rendre l'assemblage des objets cohérent.
### Intégration de la Scene
- [X] Formaliser la structure `Scene` : un conteneur qui liste les Entities.
- [ ] Associer le `PipelineCache` à la Scene pour que la gestion des matériaux soit entièrement portée par la scène (actuellement le cache est porté par `App`, indépendant de la Scene — le rendu de la scène est, lui, déjà automatisé depuis 2026-09-16).
- [X] Implémenter la logique de rendu de la scène : `App::render_scene(view)` parcourt la scène,
récupère les matériaux et soumet tous les draw calls en **une seule passe groupée**
(`Renderer::render_scene`), appelée automatiquement chaque frame par l'implémentation par défaut
de `AppHandler::render` (Scene auto-render — réalisé 2026-09-16). Reste à brancher : associé au
`PipelineCache` porté par la `Scene` (cf. ligne précédente).
### Gestion des Matériaux et Shaders
- [ ] S'assurer que chaque Mesh possède une référence vers un Material (à l'heure actuelle le lien est porté par l'entité `(mesh_id, material_id)` de la Scene, pas par le Mesh lui-même).
- [ ] Implémenter le comportement par défaut : si aucun matériau n'est assigné, le moteur injecte automatiquement le `basic_shader` (non implémenté).
## Phase 3 : Documentation et Interface (API "User-Friendly")
### Refonte des Exemples
- [X] `simple.rs` doit devenir le modèle : **15 lignes** de code, pas de manipulation WGPU explicite (mis en conformité : `AppBuilder`, compile sans `winit`/`wgpu`).
- [X] `manual.rs` doit rester disponible en tant que tutoriel pour ceux qui veulent contourner l'abstraction App.
### Nettoyage du Code Interne
- [X] Vérifier les durées de vie (lifetimes) et les Arc pour s'assurer qu'aucune fuite mémoire ou accès concurrentiel invalide ne survient lors des changements de frame.
## Phase 4 : Nouvelles Fonctionnalités (Planification Future)
Une fois les phases 1 à 3 validées, nous pourrons introduire :
- [ ] **Système de Lumières** : Ajout de buffers d'uniformes dans le PipelineCache.
- [ ] **Textures** : Intégration d'un module de chargement d'images et de BindGroups.
- [ ] **Caméras** : Gestion des matrices de projection/vue dans la Scene.
## Check-list de Vérification pour le LLM d'Assistance
- [X] Est-ce que `simple.rs` compile sans importer `winit` ou `wgpu` ? (oui — modèle 15 lignes, API `AppBuilder`)
- [X] Est-ce que `App::run` gère bien le cycle update → render → present ? (oui — la vue de frame est
exposée via `Frame::view()`, `render()` dessine la scène automatiquement en une passe via
`App::render_scene(frame.view())`, la présentation est faite par `App::run`)
- [X] Les modules sont-ils bien exposés via `lib.rs` ?
- [X] `pollster` est-il uniquement en dev-dependencies ? — **obsolète** : depuis la migration
winit 0.30 (2026-09-16), `pollster` est en `dependencies` de la lib (le `block_on` d'init GPU
est désormais appelé dans le code de la lib, `app.rs`, cf. note pour mémoire ci-dessous).
## Note pour mémoire : couplage au runtime async (pollster)
Depuis la migration winit 0.30, la lib embarque un runtime async pour l'init GPU. Le point de
couplage actuel est **unique** : `pollster::block_on(Context::new(...))` dans `lib/src/app.rs`
(`resumed()`), plus le macro `#[pollster::main]` dans les exemples (crates séparées, hors lib).
À ce stade (un seul appel), **on ne crée volontairement PAS d'abstraction** : ce serait du
sur-engineering pour un seul point d'appel. Mais si la lib acquiert d'autres appels async
(chargements / uploads GPU, etc.), il faudra isoler le runtime derrière un **module-pivot unique**
(`lib/src/exec.rs`, une fonction `block_on`), seul fichier à modifier pour basculer de pollster
vers tokio/futures-executor — le reste du code appelant `crate::exec::block_on(...)`.
Rappel : pollster et tokio sont des runtimes indépendants qui coexistent sans conflit dans un
même binaire ; la seule contre-indication est de faire un `pollster::block_on` **à l'intérieur**
d'un contexte async tokio (blocage imbriqué / deadlock possible).