Move World into dedicated Scene struct

This commit is contained in:
Florian RICHER 2025-06-11 22:24:28 +02:00
parent 8ce620a74b
commit c494574389
Signed by: florian.richer
GPG key ID: C73D37CBED7BFC77
6 changed files with 73 additions and 28 deletions

View file

@ -186,7 +186,7 @@ impl ApplicationHandler<UserEvent> for App {
if let Some(scene) = scene_manager.current_scene_mut() { if let Some(scene) = scene_manager.current_scene_mut() {
{ {
let _update_span = tracing::debug_span!("scene_update").entered(); let _update_span = tracing::debug_span!("scene_update").entered();
scene.0.update(&mut scene.1, &context).unwrap(); scene.update(&context).unwrap();
} }
let acquire_future = { let acquire_future = {
@ -198,10 +198,7 @@ impl ApplicationHandler<UserEvent> for App {
let acquire_future = { let acquire_future = {
let _render_span = tracing::debug_span!("scene_render").entered(); let _render_span = tracing::debug_span!("scene_render").entered();
scene scene.render(acquire_future, &mut context).unwrap()
.0
.render(acquire_future, &mut scene.1, &mut context)
.unwrap()
}; };
{ {
@ -245,7 +242,7 @@ impl ApplicationHandler<UserEvent> for App {
if let Some(scene_manager) = self.scene_manager.get_mut(&window_id) { if let Some(scene_manager) = self.scene_manager.get_mut(&window_id) {
if let Some(app_context) = self.app_contexts.get(&window_id) { if let Some(app_context) = self.app_contexts.get(&window_id) {
let context = app_context.borrow(); let context = app_context.borrow();
scene_manager.load_scene(scene, &context); scene_manager.replace_current_scene(scene, &context);
} }
} }
} }

View file

@ -1,11 +1,11 @@
use winit::window::{CursorGrabMode, WindowId}; use winit::window::{CursorGrabMode, WindowId};
use crate::core::scene::Scene; use crate::core::scene::AsScene;
pub enum UserEvent { pub enum UserEvent {
CursorGrabMode(WindowId, CursorGrabMode), CursorGrabMode(WindowId, CursorGrabMode),
CursorVisible(WindowId, bool), CursorVisible(WindowId, bool),
ChangeScene(WindowId, Box<dyn Scene>), ChangeScene(WindowId, Box<dyn AsScene>),
ChangeResolution(WindowId, f32, f32), ChangeResolution(WindowId, f32, f32),
Exit(WindowId), Exit(WindowId),
} }

View file

@ -9,10 +9,10 @@ use crate::core::render::primitives::vulkan_resource::{
}; };
use bevy_ecs::world::World; use bevy_ecs::world::World;
use super::Scene; use super::{AsScene, Scene};
pub struct SceneManager { pub struct SceneManager {
scenes: Vec<(Box<dyn Scene>, World)>, scenes: Vec<Scene>,
current_scene_index: Option<usize>, current_scene_index: Option<usize>,
window_context: Option<Rc<RefCell<WindowContext>>>, window_context: Option<Rc<RefCell<WindowContext>>>,
} }
@ -92,25 +92,30 @@ impl SceneManager {
world world
} }
pub fn load_scene(&mut self, scene: Box<dyn Scene>, window_context: &WindowContext) { pub fn load_scene(&mut self, scene_impl: Box<dyn AsScene>, window_context: &WindowContext) {
let world = Self::create_world_with_resources(window_context); let world = Self::create_world_with_resources(window_context);
self.scenes.push((scene, world)); let scene = Scene::new(scene_impl, world);
self.scenes.push(scene);
self.current_scene_index = Some(self.scenes.len() - 1); self.current_scene_index = Some(self.scenes.len() - 1);
} }
pub fn replace_current_scene(&mut self, scene: Box<dyn Scene>, window_context: &WindowContext) { pub fn replace_current_scene(
&mut self,
scene_impl: Box<dyn AsScene>,
window_context: &WindowContext,
) {
if let Some(index) = self.current_scene_index { if let Some(index) = self.current_scene_index {
if index < self.scenes.len() { if index < self.scenes.len() {
self.scenes[index].0.unload(); self.scenes[index].unload();
let world = Self::create_world_with_resources(window_context); let world = Self::create_world_with_resources(window_context);
self.scenes[index] = (scene, world); self.scenes[index] = Scene::new(scene_impl, world);
} }
} else { } else {
self.load_scene(scene, window_context); self.load_scene(scene_impl, window_context);
} }
} }
pub fn current_scene(&self) -> Option<&(Box<dyn Scene>, World)> { pub fn current_scene(&self) -> Option<&Scene> {
if let Some(index) = self.current_scene_index { if let Some(index) = self.current_scene_index {
self.scenes.get(index) self.scenes.get(index)
} else { } else {
@ -118,7 +123,7 @@ impl SceneManager {
} }
} }
pub fn current_scene_mut(&mut self) -> Option<&mut (Box<dyn Scene>, World)> { pub fn current_scene_mut(&mut self) -> Option<&mut Scene> {
if let Some(index) = self.current_scene_index { if let Some(index) = self.current_scene_index {
self.scenes.get_mut(index) self.scenes.get_mut(index)
} else { } else {
@ -130,9 +135,9 @@ impl SceneManager {
&mut self, &mut self,
window_context: &mut WindowContext, window_context: &mut WindowContext,
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
if let Some((scene, world)) = self.current_scene_mut() { if let Some(scene) = self.current_scene_mut() {
if !scene.loaded() { if !scene.loaded() {
scene.load(world, window_context)?; scene.load(window_context)?;
} }
} else { } else {
tracing::warn!("No scene found in SceneManager!"); tracing::warn!("No scene found in SceneManager!");

View file

@ -7,7 +7,48 @@ use crate::core::app::context::WindowContext;
pub mod manager; pub mod manager;
pub trait Scene { /// Structure Scene qui contient le world et l'implémentation AsScene
pub struct Scene {
pub world: World,
pub implementation: Box<dyn AsScene>,
}
impl Scene {
pub fn new(implementation: Box<dyn AsScene>, world: World) -> Self {
Self {
world,
implementation,
}
}
pub fn loaded(&self) -> bool {
self.implementation.loaded()
}
pub fn load(&mut self, window_context: &mut WindowContext) -> Result<(), Box<dyn Error>> {
self.implementation.load(&mut self.world, window_context)
}
pub fn update(&mut self, window_context: &WindowContext) -> Result<(), Box<dyn Error>> {
self.implementation.update(&mut self.world, window_context)
}
pub fn render(
&mut self,
acquire_future: Box<dyn GpuFuture>,
window_context: &mut WindowContext,
) -> Result<Box<dyn GpuFuture>, Box<dyn Error>> {
self.implementation
.render(acquire_future, &mut self.world, window_context)
}
pub fn unload(&mut self) {
self.implementation.unload()
}
}
/// Trait pour les implémentations de scènes
pub trait AsScene {
fn loaded(&self) -> bool; fn loaded(&self) -> bool;
fn load( fn load(
&mut self, &mut self,

View file

@ -16,7 +16,7 @@ use crate::core::render::render_pass_manager::{RenderPassConfig, RenderPassManag
use crate::core::render::resources::meshes::{ObjMesh, SquareMesh}; use crate::core::render::resources::meshes::{ObjMesh, SquareMesh};
use crate::core::render::resources::pipeline::PipelineLoader; use crate::core::render::resources::pipeline::PipelineLoader;
use crate::core::render::resources::texture::{TextureLoadInfo, TextureLoader, TextureSourceKind}; use crate::core::render::resources::texture::{TextureLoadInfo, TextureLoader, TextureSourceKind};
use crate::core::scene::Scene; use crate::core::scene::AsScene;
use crate::game::assets::pipelines::simple::SimplePipeline; use crate::game::assets::pipelines::simple::SimplePipeline;
use bevy_ecs::world::World; use bevy_ecs::world::World;
use egui_winit_vulkano::egui; use egui_winit_vulkano::egui;
@ -47,7 +47,7 @@ pub struct MainScene {
state: Option<MainSceneState>, state: Option<MainSceneState>,
} }
impl Scene for MainScene { impl AsScene for MainScene {
fn loaded(&self) -> bool { fn loaded(&self) -> bool {
self.state.is_some() self.state.is_some()
} }
@ -393,7 +393,7 @@ impl Scene for MainScene {
gui.draw_on_image(render_future, swapchain_image_view.clone()) gui.draw_on_image(render_future, swapchain_image_view.clone())
}); });
Ok(render_future) Ok(Box::new(render_future))
} }
fn unload(&mut self) { fn unload(&mut self) {

View file

@ -7,7 +7,7 @@ use crate::core::render::primitives::vulkan_resource::{
VulkanCommandBufferAllocator, VulkanGraphicsQueue, VulkanCommandBufferAllocator, VulkanGraphicsQueue,
}; };
use crate::core::render::render_pass_manager::{RenderPassConfig, RenderPassManager}; use crate::core::render::render_pass_manager::{RenderPassConfig, RenderPassManager};
use crate::core::scene::Scene; use crate::core::scene::AsScene;
use bevy_ecs::world::World; use bevy_ecs::world::World;
use egui_winit_vulkano::egui; use egui_winit_vulkano::egui;
use vulkano::{ use vulkano::{
@ -26,7 +26,7 @@ pub struct SettingsScene {
state: Option<SettingsSceneState>, state: Option<SettingsSceneState>,
} }
impl Scene for SettingsScene { impl AsScene for SettingsScene {
fn loaded(&self) -> bool { fn loaded(&self) -> bool {
self.state.is_some() self.state.is_some()
} }
@ -144,8 +144,10 @@ impl Scene for SettingsScene {
gui.draw_on_image(render_future, swapchain_image_view.clone()) gui.draw_on_image(render_future, swapchain_image_view.clone())
}); });
Ok(render_future) Ok(Box::new(render_future))
} }
fn unload(&mut self) {} fn unload(&mut self) {
self.state = None;
}
} }