use std::cell::RefCell; use std::error::Error; use std::rc::Rc; use crate::core::app::context::WindowContext; use crate::core::render::primitives::vulkan_resource::{ VulkanCommandBufferAllocator, VulkanComputeQueue, VulkanDescriptorSetAllocator, VulkanDevice, VulkanGraphicsQueue, VulkanInstance, VulkanMemoryAllocator, VulkanTransferQueue, }; use bevy_ecs::world::World; use super::{AsScene, Scene}; pub struct SceneManager { scenes: Vec, current_scene_index: Option, window_context: Option>>, } impl SceneManager { pub fn new() -> Self { Self { scenes: Vec::new(), current_scene_index: None, window_context: None, } } pub fn set_window_context(&mut self, window_context: Rc>) { self.window_context = Some(window_context); } fn create_world_with_resources(window_context: &WindowContext) -> World { let mut world = World::new(); // Add Vulkan resources world.insert_resource(VulkanInstance( window_context .vulkan_context() .vulkano_context() .instance() .clone(), )); world.insert_resource(VulkanDevice( window_context .vulkan_context() .vulkano_context() .device() .clone(), )); world.insert_resource(VulkanGraphicsQueue( window_context .vulkan_context() .vulkano_context() .graphics_queue() .clone(), )); world.insert_resource(VulkanComputeQueue( window_context .vulkan_context() .vulkano_context() .compute_queue() .clone(), )); world.insert_resource(VulkanTransferQueue( window_context .vulkan_context() .vulkano_context() .transfer_queue() .cloned(), )); world.insert_resource(VulkanMemoryAllocator( window_context .vulkan_context() .vulkano_context() .memory_allocator() .clone(), )); world.insert_resource(VulkanCommandBufferAllocator( window_context .vulkan_context() .command_buffer_allocator() .clone(), )); world.insert_resource(VulkanDescriptorSetAllocator( window_context .vulkan_context() .descriptor_set_allocator() .clone(), )); world } pub fn load_scene(&mut self, scene_impl: Box, window_context: &WindowContext) { let world = Self::create_world_with_resources(window_context); let scene = Scene::new(scene_impl, world); self.scenes.push(scene); self.current_scene_index = Some(self.scenes.len() - 1); } pub fn replace_current_scene( &mut self, scene_impl: Box, window_context: &WindowContext, ) { if let Some(index) = self.current_scene_index { if index < self.scenes.len() { self.scenes[index].unload(); let world = Self::create_world_with_resources(window_context); self.scenes[index] = Scene::new(scene_impl, world); } } else { self.load_scene(scene_impl, window_context); } } pub fn current_scene(&self) -> Option<&Scene> { if let Some(index) = self.current_scene_index { self.scenes.get(index) } else { None } } pub fn current_scene_mut(&mut self) -> Option<&mut Scene> { if let Some(index) = self.current_scene_index { self.scenes.get_mut(index) } else { None } } pub fn load_scene_if_not_loaded( &mut self, window_context: &mut WindowContext, ) -> Result<(), Box> { if let Some(scene) = self.current_scene_mut() { if !scene.loaded() { scene.load(window_context)?; } } else { tracing::warn!("No scene found in SceneManager!"); } Ok(()) } }