186 lines
6 KiB
Rust
186 lines
6 KiB
Rust
use std::{
|
|
cell::RefCell,
|
|
rc::Rc,
|
|
sync::{Arc, RwLock},
|
|
};
|
|
|
|
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, monitor::MonitorHandle, 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 WindowContext {
|
|
// 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: Rc<RefCell<VulkanoWindows>>,
|
|
pub input_manager: Arc<RwLock<InputManager>>,
|
|
pub timer: Arc<RwLock<Timer>>,
|
|
pub gui: Rc<RefCell<Gui>>,
|
|
}
|
|
|
|
impl WindowContext {
|
|
pub fn new(
|
|
vulkan_context: Arc<VulkanContext>,
|
|
vulkano_windows: Rc<RefCell<VulkanoWindows>>,
|
|
input_manager: Arc<RwLock<InputManager>>,
|
|
timer: Arc<RwLock<Timer>>,
|
|
gui: Rc<RefCell<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,
|
|
}
|
|
}
|
|
|
|
/// 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 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.borrow_mut();
|
|
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)
|
|
}
|
|
|
|
/// 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
|
|
.read()
|
|
.expect("Failed to lock input_manager");
|
|
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.read().expect("Failed to lock timer");
|
|
f(&timer)
|
|
}
|
|
}
|