use std::error::Error; use crate::core::app::DEPTH_IMAGE_ID; use crate::core::app::context::WindowContext; use crate::core::input::InputManagerResource; use crate::core::render::primitives::vulkan_resource::{ VulkanCommandBufferAllocator, VulkanComputeQueue, VulkanDescriptorSetAllocator, VulkanDevice, VulkanGraphicsQueue, VulkanInstance, VulkanMemoryAllocator, VulkanTransferQueue, }; use crate::core::render::resources::pipeline::PipelineLoader; use crate::core::render::resources::texture::TextureLoader; use crate::core::scene::AsScene; use bevy_ecs::world::World; use super::Scene; #[derive(Default)] pub struct SceneManager { current_scene: Option, new_scene: Option>, } impl SceneManager { pub fn new() -> Self { Self { current_scene: None, new_scene: None, } } fn create_world_with_resources(window_context: &mut WindowContext) -> World { let mut world = World::new(); let depth_image_view = window_context.with_renderer_mut(|renderer| { renderer.get_additional_image_view(DEPTH_IMAGE_ID).clone() }); let swapchain_image_view = window_context.with_renderer(|renderer| renderer.swapchain_image_view().clone()); let vulkan_context = window_context.vulkan_context(); let vulkano_context = vulkan_context.vulkano_context(); let vulkan_instance = vulkano_context.instance(); let vulkan_device = vulkano_context.device(); let vulkan_graphics_queue = vulkano_context.graphics_queue(); let vulkan_compute_queue = vulkano_context.compute_queue(); let vulkan_transfer_queue = vulkano_context.transfer_queue(); let vulkan_memory_allocator = vulkano_context.memory_allocator(); let vulkan_command_buffer_allocator = vulkan_context.command_buffer_allocator(); let vulkan_descriptor_set_allocator = vulkan_context.descriptor_set_allocator(); let texture_loader = TextureLoader::new( vulkan_device.clone(), vulkan_command_buffer_allocator.clone(), vulkan_memory_allocator.clone(), TextureLoader::select_best_suitable_queue(vulkan_graphics_queue, vulkan_transfer_queue), ); let pipeline_loader = PipelineLoader::new( vulkan_device.clone(), swapchain_image_view.format(), depth_image_view.format(), ); world.insert_resource(VulkanInstance(vulkan_instance.clone())); world.insert_resource(VulkanDevice(vulkan_device.clone())); world.insert_resource(VulkanGraphicsQueue(vulkan_graphics_queue.clone())); world.insert_resource(VulkanComputeQueue(vulkan_compute_queue.clone())); world.insert_resource(VulkanTransferQueue(vulkan_transfer_queue.cloned())); world.insert_resource(VulkanMemoryAllocator(vulkan_memory_allocator.clone())); world.insert_resource(VulkanCommandBufferAllocator( vulkan_command_buffer_allocator.clone(), )); world.insert_resource(VulkanDescriptorSetAllocator( vulkan_descriptor_set_allocator.clone(), )); world.insert_resource(texture_loader); world.insert_resource(pipeline_loader); world.insert_resource(InputManagerResource(window_context.input_manager.clone())); world } pub fn set_new_scene(&mut self, scene_impl: Box) { self.new_scene = Some(scene_impl); } pub fn current_scene(&self) -> Option<&Scene> { self.current_scene.as_ref() } pub fn current_scene_mut(&mut self) -> Option<&mut Scene> { self.current_scene.as_mut() } pub fn load_scene_if_not_loaded( &mut self, window_context: &mut WindowContext, ) -> Result<(), Box> { if let Some(new_scene) = self.new_scene.take() { let world = Self::create_world_with_resources(window_context); let mut scene = Scene::new(new_scene, world); scene.load(window_context)?; if let Some(mut current_scene) = self.current_scene.take() { current_scene.unload(); } self.current_scene = Some(scene); } Ok(()) } }