use std::{ cell::RefCell, rc::Rc, sync::{Arc, RwLock}, }; use egui_winit_vulkano::Gui; use vulkano_util::{renderer::VulkanoWindowRenderer, window::VulkanoWindows}; use winit::{event_loop::EventLoopProxy, monitor::MonitorHandle, window::WindowId}; use crate::core::{input::InputManager, render::vulkan_context::VulkanContext}; use super::user_event::UserEvent; /// Contexte d'application unifié pour les fonctions liées à la fenêtre pub struct WindowContext { // Données Vulkan (immutables) pub vulkan_context: Arc, pub event_loop_proxy: EventLoopProxy, pub window_id: WindowId, // Données mutables partagées avec Arc> pub vulkano_windows: Rc>, pub input_manager: Arc>, pub gui: Rc>, } impl WindowContext { pub fn new( vulkan_context: Arc, vulkano_windows: Rc>, input_manager: Arc>, gui: Rc>, event_loop_proxy: EventLoopProxy, window_id: WindowId, ) -> Self { Self { // Données Vulkan vulkan_context, event_loop_proxy, window_id, // Données mutables partagées vulkano_windows, input_manager, gui, } } pub fn vulkan_context(&self) -> &VulkanContext { &self.vulkan_context } /// Extrait les résolutions d'un moniteur donné fn extract_resolutions_from_monitor(monitor: MonitorHandle) -> Vec<(u32, u32)> { let video_modes: Vec<_> = monitor.video_modes().collect(); let resolutions: Vec<(u32, u32)> = video_modes .into_iter() .map(|mode| { let size = mode.size(); (size.width, size.height) }) .collect(); tracing::trace!( "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| { renderer .window() .current_monitor() .map(Self::extract_resolutions_from_monitor) .unwrap_or_default() }) } /// 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(&self, f: F) -> T where F: FnOnce(&VulkanoWindowRenderer) -> T, { let vulkano_windows = self.vulkano_windows.borrow(); 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(&mut self, f: F) -> T where F: FnOnce(&mut VulkanoWindowRenderer) -> T, { let mut vulkano_windows = self.vulkano_windows.borrow_mut(); 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(&self, f: F) -> T where F: FnOnce(&Gui) -> T, { let gui = self.gui.borrow(); f(&gui) } /// Méthode utilitaire pour accéder au gui de manière thread-safe pub fn with_gui_mut(&mut self, f: F) -> T where F: FnOnce(&mut Gui) -> T, { let mut gui = self.gui.borrow_mut(); f(&mut gui) } }