vulkano_test/src/core/app/context.rs

135 lines
3.9 KiB
Rust

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<VulkanContext>,
pub event_loop_proxy: EventLoopProxy<UserEvent>,
pub window_id: WindowId,
// Données mutables partagées avec Arc<Mutex<>>
pub vulkano_windows: Rc<RefCell<VulkanoWindows>>,
pub input_manager: Arc<RwLock<InputManager>>,
pub gui: Rc<RefCell<Gui>>,
}
impl WindowContext {
pub fn new(
vulkan_context: Arc<VulkanContext>,
vulkano_windows: Rc<RefCell<VulkanoWindows>>,
input_manager: Arc<RwLock<InputManager>>,
gui: Rc<RefCell<Gui>>,
event_loop_proxy: EventLoopProxy<UserEvent>,
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<T, F>(&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<T, F>(&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<T, F>(&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<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Gui) -> T,
{
let mut gui = self.gui.borrow_mut();
f(&mut gui)
}
}