Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 9m39s
233 lines
7.7 KiB
Rust
233 lines
7.7 KiB
Rust
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)
|
|
}
|
|
|
|
/// Méthode utilitaire pour accéder au renderer de manière thread-safe
|
|
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)
|
|
}
|
|
|
|
/// Méthode utilitaire pour accéder au gui de manière thread-safe
|
|
pub fn with_gui<T, F>(&self, f: F) -> T
|
|
where
|
|
F: FnOnce(&Gui) -> T,
|
|
{
|
|
let gui = self.gui.lock().unwrap();
|
|
f(&gui)
|
|
}
|
|
|
|
/// Méthode utilitaire pour accéder au gui de manière thread-safe
|
|
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)
|
|
}
|
|
}
|