Refactor app context and render pass manager
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 9m10s
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 9m10s
This commit is contained in:
parent
f1ae54bc73
commit
2c169548b9
12 changed files with 846 additions and 466 deletions
230
src/core/app/context.rs
Normal file
230
src/core/app/context.rs
Normal file
|
@ -0,0 +1,230 @@
|
|||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use egui_winit_vulkano::Gui;
|
||||
use vulkano::{
|
||||
command_buffer::allocator::StandardCommandBufferAllocator,
|
||||
descriptor_set::allocator::StandardDescriptorSetAllocator,
|
||||
device::{Device, Queue},
|
||||
instance::Instance,
|
||||
memory::allocator::StandardMemoryAllocator,
|
||||
};
|
||||
use vulkano_util::{renderer::VulkanoWindowRenderer, window::VulkanoWindows};
|
||||
use winit::{
|
||||
event_loop::EventLoopProxy,
|
||||
window::{Window, WindowId},
|
||||
};
|
||||
|
||||
use crate::core::{input::InputManager, render::vulkan_context::VulkanContext, timer::Timer};
|
||||
|
||||
use super::user_event::UserEvent;
|
||||
|
||||
/// Contexte d'application unifié avec Arc<Mutex<>> pour la mutabilité partagée
|
||||
#[derive(Clone)]
|
||||
pub struct ApplicationContext {
|
||||
// Données Vulkan (immutables)
|
||||
pub vulkan_context: Arc<VulkanContext>,
|
||||
pub device: Arc<Device>,
|
||||
pub instance: Arc<Instance>,
|
||||
pub graphics_queue: Arc<Queue>,
|
||||
pub compute_queue: Arc<Queue>,
|
||||
pub transfer_queue: Option<Arc<Queue>>,
|
||||
pub memory_allocator: Arc<StandardMemoryAllocator>,
|
||||
pub command_buffer_allocator: Arc<StandardCommandBufferAllocator>,
|
||||
pub descriptor_set_allocator: Arc<StandardDescriptorSetAllocator>,
|
||||
pub event_loop_proxy: EventLoopProxy<UserEvent>,
|
||||
pub window_id: WindowId,
|
||||
|
||||
// Données mutables partagées avec Arc<Mutex<>>
|
||||
pub vulkano_windows: Arc<Mutex<VulkanoWindows>>,
|
||||
pub input_manager: Arc<Mutex<InputManager>>,
|
||||
pub timer: Arc<Mutex<Timer>>,
|
||||
pub gui: Arc<Mutex<Gui>>,
|
||||
}
|
||||
|
||||
impl ApplicationContext {
|
||||
pub fn new(
|
||||
vulkan_context: Arc<VulkanContext>,
|
||||
vulkano_windows: Arc<Mutex<VulkanoWindows>>,
|
||||
input_manager: Arc<Mutex<InputManager>>,
|
||||
timer: Arc<Mutex<Timer>>,
|
||||
gui: Arc<Mutex<Gui>>,
|
||||
event_loop_proxy: EventLoopProxy<UserEvent>,
|
||||
window_id: WindowId,
|
||||
) -> Self {
|
||||
let vulkano_context_inner = vulkan_context.vulkano_context();
|
||||
|
||||
Self {
|
||||
// Données Vulkan
|
||||
vulkan_context: vulkan_context.clone(),
|
||||
device: vulkano_context_inner.device().clone(),
|
||||
instance: vulkano_context_inner.instance().clone(),
|
||||
graphics_queue: vulkano_context_inner.graphics_queue().clone(),
|
||||
compute_queue: vulkano_context_inner.compute_queue().clone(),
|
||||
transfer_queue: vulkano_context_inner.transfer_queue().cloned(),
|
||||
memory_allocator: vulkano_context_inner.memory_allocator().clone(),
|
||||
command_buffer_allocator: vulkan_context.command_buffer_allocator().clone(),
|
||||
descriptor_set_allocator: vulkan_context.descriptor_set_allocator().clone(),
|
||||
event_loop_proxy,
|
||||
window_id,
|
||||
|
||||
// Données mutables partagées
|
||||
vulkano_windows,
|
||||
input_manager,
|
||||
timer,
|
||||
gui,
|
||||
}
|
||||
}
|
||||
|
||||
/// Récupère les résolutions disponibles du moniteur (méthode utilitaire statique)
|
||||
fn get_monitor_resolutions(window: &Window) -> Vec<(u32, u32)> {
|
||||
// Première tentative : moniteur actuel
|
||||
if let Some(monitor) = window.current_monitor() {
|
||||
let resolutions = Self::extract_resolutions_from_monitor(&monitor);
|
||||
if !resolutions.is_empty() {
|
||||
log::debug!(
|
||||
"Résolutions trouvées via moniteur actuel: {:?}",
|
||||
resolutions
|
||||
);
|
||||
return resolutions;
|
||||
}
|
||||
}
|
||||
|
||||
// Deuxième tentative : tous les moniteurs disponibles
|
||||
log::debug!("Tentative de récupération via tous les moniteurs disponibles...");
|
||||
let mut all_resolutions = Vec::new();
|
||||
|
||||
for monitor in window.available_monitors() {
|
||||
let resolutions = Self::extract_resolutions_from_monitor(&monitor);
|
||||
all_resolutions.extend(resolutions);
|
||||
}
|
||||
|
||||
if !all_resolutions.is_empty() {
|
||||
// Supprime les doublons et trie
|
||||
all_resolutions.sort_unstable();
|
||||
all_resolutions.dedup();
|
||||
all_resolutions.sort_by(|a, b| (b.0 * b.1).cmp(&(a.0 * a.1)));
|
||||
|
||||
log::debug!(
|
||||
"Résolutions trouvées via tous les moniteurs: {:?}",
|
||||
all_resolutions
|
||||
);
|
||||
return all_resolutions;
|
||||
}
|
||||
|
||||
// Aucune résolution détectée - retourne un vecteur vide
|
||||
log::warn!("Aucune résolution détectée pour cette fenêtre");
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
/// Extrait les résolutions d'un moniteur donné
|
||||
fn extract_resolutions_from_monitor(
|
||||
monitor: &winit::monitor::MonitorHandle,
|
||||
) -> Vec<(u32, u32)> {
|
||||
let video_modes: Vec<_> = monitor.video_modes().collect();
|
||||
|
||||
if video_modes.is_empty() {
|
||||
log::debug!(
|
||||
"Aucun mode vidéo trouvé pour le moniteur {:?}",
|
||||
monitor.name()
|
||||
);
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
let resolutions: Vec<(u32, u32)> = video_modes
|
||||
.into_iter()
|
||||
.map(|mode| {
|
||||
let size = mode.size();
|
||||
(size.width, size.height)
|
||||
})
|
||||
.collect();
|
||||
|
||||
log::debug!(
|
||||
"Modes vidéo trouvés pour {:?}: {:?}",
|
||||
monitor.name(),
|
||||
resolutions
|
||||
);
|
||||
resolutions
|
||||
}
|
||||
|
||||
/// Récupère les résolutions disponibles
|
||||
pub fn get_available_resolutions(&self) -> Vec<(u32, u32)> {
|
||||
self.with_renderer(|renderer| Self::get_monitor_resolutions(&renderer.window()))
|
||||
}
|
||||
|
||||
/// Récupère le delta time actuel depuis le timer
|
||||
pub fn get_delta_time(&self) -> f32 {
|
||||
self.with_timer(|timer| timer.delta_time())
|
||||
}
|
||||
|
||||
/// Récupère la taille de la fenêtre depuis le renderer
|
||||
pub fn get_window_size(&self) -> [f32; 2] {
|
||||
self.with_renderer(|renderer| renderer.window_size())
|
||||
}
|
||||
|
||||
/// Récupère l'aspect ratio depuis le renderer
|
||||
pub fn get_aspect_ratio(&self) -> f32 {
|
||||
self.with_renderer(|renderer| renderer.aspect_ratio())
|
||||
}
|
||||
|
||||
pub fn with_renderer<T, F>(&self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&VulkanoWindowRenderer) -> T,
|
||||
{
|
||||
let vulkano_windows = self
|
||||
.vulkano_windows
|
||||
.lock()
|
||||
.expect("Failed to lock vulkano_windows");
|
||||
let renderer = vulkano_windows
|
||||
.get_renderer(self.window_id)
|
||||
.expect("Failed to get renderer");
|
||||
f(&renderer)
|
||||
}
|
||||
|
||||
pub fn with_renderer_mut<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut VulkanoWindowRenderer) -> T,
|
||||
{
|
||||
let mut vulkano_windows = self
|
||||
.vulkano_windows
|
||||
.lock()
|
||||
.expect("Failed to lock vulkano_windows");
|
||||
let renderer = vulkano_windows
|
||||
.get_renderer_mut(self.window_id)
|
||||
.expect("Failed to get renderer");
|
||||
f(renderer)
|
||||
}
|
||||
|
||||
pub fn with_gui<T, F>(&self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&Gui) -> T,
|
||||
{
|
||||
let gui = self.gui.lock().unwrap();
|
||||
f(&gui)
|
||||
}
|
||||
|
||||
pub fn with_gui_mut<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Gui) -> T,
|
||||
{
|
||||
let mut gui = self.gui.lock().unwrap();
|
||||
f(&mut gui)
|
||||
}
|
||||
|
||||
/// Méthode utilitaire pour accéder à l'input manager de manière thread-safe
|
||||
pub fn with_input_manager<T, F>(&self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&InputManager) -> T,
|
||||
{
|
||||
let input_manager = self.input_manager.lock().unwrap();
|
||||
f(&input_manager)
|
||||
}
|
||||
|
||||
/// Méthode utilitaire pour accéder au timer de manière thread-safe
|
||||
pub fn with_timer<T, F>(&self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&Timer) -> T,
|
||||
{
|
||||
let timer = self.timer.lock().unwrap();
|
||||
f(&timer)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue