Integration of ECS pattern: Iteration 1

This commit is contained in:
Florian RICHER 2025-06-11 16:05:35 +02:00
parent fc81f65a27
commit 8ce620a74b
Signed by: florian.richer
GPG key ID: C73D37CBED7BFC77
13 changed files with 727 additions and 135 deletions

View file

@ -1,12 +1,20 @@
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::Scene;
pub struct SceneManager {
scenes: Vec<Box<dyn Scene>>,
scenes: Vec<(Box<dyn Scene>, World)>,
current_scene_index: Option<usize>,
window_context: Option<Rc<RefCell<WindowContext>>>,
}
impl SceneManager {
@ -14,26 +22,95 @@ impl SceneManager {
Self {
scenes: Vec::new(),
current_scene_index: None,
window_context: None,
}
}
pub fn load_scene(&mut self, scene: Box<dyn Scene>) {
self.scenes.push(scene);
pub fn set_window_context(&mut self, window_context: Rc<RefCell<WindowContext>>) {
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: Box<dyn Scene>, window_context: &WindowContext) {
let world = Self::create_world_with_resources(window_context);
self.scenes.push((scene, world));
self.current_scene_index = Some(self.scenes.len() - 1);
}
pub fn replace_current_scene(&mut self, scene: Box<dyn Scene>) {
pub fn replace_current_scene(&mut self, scene: Box<dyn Scene>, window_context: &WindowContext) {
if let Some(index) = self.current_scene_index {
if index < self.scenes.len() {
self.scenes[index].unload();
self.scenes[index] = scene;
self.scenes[index].0.unload();
let world = Self::create_world_with_resources(window_context);
self.scenes[index] = (scene, world);
}
} else {
self.load_scene(scene);
self.load_scene(scene, window_context);
}
}
pub fn current_scene(&self) -> Option<&Box<dyn Scene>> {
pub fn current_scene(&self) -> Option<&(Box<dyn Scene>, World)> {
if let Some(index) = self.current_scene_index {
self.scenes.get(index)
} else {
@ -41,7 +118,7 @@ impl SceneManager {
}
}
pub fn current_scene_mut(&mut self) -> Option<&mut Box<dyn Scene>> {
pub fn current_scene_mut(&mut self) -> Option<&mut (Box<dyn Scene>, World)> {
if let Some(index) = self.current_scene_index {
self.scenes.get_mut(index)
} else {
@ -51,11 +128,11 @@ impl SceneManager {
pub fn load_scene_if_not_loaded(
&mut self,
app_context: &mut WindowContext,
window_context: &mut WindowContext,
) -> Result<(), Box<dyn Error>> {
if let Some(scene) = self.current_scene_mut() {
if let Some((scene, world)) = self.current_scene_mut() {
if !scene.loaded() {
scene.load(app_context)?;
scene.load(world, window_context)?;
}
} else {
tracing::warn!("No scene found in SceneManager!");