diff --git a/docs/ARCHI_RENDU.md b/docs/ARCHI_RENDU.md new file mode 100644 index 0000000..a9d6bc1 --- /dev/null +++ b/docs/ARCHI_RENDU.md @@ -0,0 +1,47 @@ +# Architecture de Rendu : Cycle Update/Render et Gestion des Données + +Ce document définit la stratégie de gestion de la mutabilité et des données du moteur wsg_lib, conçue pour maximiser la performance et garantir la sécurité mémoire via Rust. + +## 1. La Dichotomie Update / Render + +Pour éviter les conflits de données et optimiser le pipeline GPU, le moteur sépare strictement le cycle de vie de la frame en deux phases : + +### Phase Update (Mutabilité Totale) + +- L'utilisateur peut modifier librement l'état de la Scene (transformations, propriétés des matériaux, ajout/suppression d'entités). +- C'est l'unique zone de mutation autorisée. Le système est en "lecture-écriture". + +### Phase Render (Lecture et Orchestration) + +- La Scene est considérée comme immuable vis-à-vis du rendu. +- Le moteur itère automatiquement sur les entités pour soumettre les commandes au GPU. +- L'utilisateur dispose d'une "trappe" via `AppHandler::render()` pour injecter du code de rendu personnalisé, mais sans modifier l'état métier des objets. + +## 2. Gestion des Données : Indirection par ID (Handle) + +Pour contourner les limitations du Borrow Checker de Rust lors de l'accès aux ressources, le moteur utilise une approche par **Indirection (Handles/IDs)**. + +- **HashMaps et Vecs indexés** : Les ressources (`Mesh`, `Material`) ne sont pas stockées sous forme de références directes (`&Mesh`) dans les entités. Elles sont stockées dans des conteneurs centralisés dans la Scene. +- **Identifiants (Handles)** : Chaque entité possède un `MeshId` ou `MaterialId`. +- **Avantage** : Cela élimine les problèmes de durées de vie (lifetimes) complexes. Vous pouvez passer des IDs partout sans bloquer la mutabilité des conteneurs parents. +- **Performance** : Cette approche permet au moteur de trier les entités par `MaterialId` avant le rendu, réduisant drastiquement les changements d'état GPU (**State Change Overhead**). + +## 3. Points d'Attention du Borrow Checker + +Bien que cette architecture facilite la gestion de la mémoire, des règles strictes s'appliquent à `App` : + +- **Conflit de Mutabilité** : App contient à la fois la Scene et le Renderer. Il est interdit d'emprunter `&mut scene` et `&mut renderer` simultanément. +- **Solution** : Dans la boucle de rendu interne (`App::run`), le moteur doit être structuré pour séquencer les accès : `let scene = &app.scene;` suivi de `let renderer = &mut app.renderer;` puis `renderer.render_scene(scene);`. +- **Séparation des Responsabilités** : Le RenderLoop doit posséder la main sur l'ordonnancement pour éviter que l'utilisateur ne tente de muter la scène pendant que le renderer est en train de lire les données. + +## 4. Synthèse des Avantages + +- **Performance (Batching)** : Le rendu automatique par le moteur permet d'implémenter des stratégies de rendu optimales invisibles pour l'utilisateur. +- **Ergonomie** : L'utilisateur n'écrit pas de boucles de rendu complexes. Il se concentre sur sa logique métier dans `update()`. +- **Sécurité** : L'utilisation d'IDs évite les cycles de références et les références pendantes, rendant le code plus sûr et plus facile à maintenir. + +## 5. Guide de Développement pour l'Utilisateur + +> "Si vous devez changer la position d'un objet ou son matériau, faites-le dans `update()`. Si vous avez besoin d'afficher un élément de debug ou un rendu spécial, faites-le dans `render()`, mais traitez les objets de la scène comme des données en lecture seule." + +Cette structure permet au projet d'être extrêmement scalable. L'ajout futur de fonctionnalités (Lumières, Textures, Caméras) ne nécessitera que d'ajouter de nouveaux conteneurs dans la Scene et de mettre à jour le système de tri dans `Renderer::render_scene()`.