goud_engine/ffi/window/
state.rs1use crate::core::error::GoudError;
8use crate::ecs::InputManager;
9use crate::ffi::context::GoudContextId;
10use crate::libs::graphics::backend::opengl::OpenGLBackend;
11use crate::libs::graphics::backend::StateOps;
12use crate::libs::platform::glfw_platform::GlfwPlatform;
13use crate::libs::platform::PlatformBackend;
14use crate::sdk::debug_overlay::DebugOverlay;
15use std::cell::RefCell;
16
17pub struct WindowState {
27 pub(crate) platform: GlfwPlatform,
28
29 pub(crate) backend: OpenGLBackend,
31
32 delta_time: f32,
34
35 pub(crate) debug_overlay: DebugOverlay,
37}
38
39impl WindowState {
40 pub fn new(platform: GlfwPlatform, backend: OpenGLBackend) -> Self {
42 Self {
43 platform,
44 backend,
45 delta_time: 0.0,
46 debug_overlay: DebugOverlay::new(0.5),
47 }
48 }
49
50 pub fn should_close(&self) -> bool {
52 self.platform.should_close()
53 }
54
55 pub fn set_should_close(&mut self, should_close: bool) {
57 self.platform.set_should_close(should_close);
58 }
59
60 pub fn poll_events(&mut self, input: &mut InputManager) -> f32 {
62 let old_size = self.platform.get_size();
63 self.delta_time = self.platform.poll_events(input);
64 let new_size = self.platform.get_size();
65
66 if old_size != new_size {
67 self.backend.set_viewport(0, 0, new_size.0, new_size.1);
68 }
69
70 self.debug_overlay.update(self.delta_time);
71
72 self.delta_time
73 }
74
75 pub fn swap_buffers(&mut self) {
77 self.platform.swap_buffers();
78 }
79
80 pub fn get_size(&self) -> (u32, u32) {
82 self.platform.get_size()
83 }
84
85 pub fn get_framebuffer_size(&self) -> (u32, u32) {
87 self.platform.get_framebuffer_size()
88 }
89
90 pub fn backend_mut(&mut self) -> &mut OpenGLBackend {
92 &mut self.backend
93 }
94
95 pub fn delta_time(&self) -> f32 {
97 self.delta_time
98 }
99}
100
101thread_local! {
106 pub(super) static WINDOW_STATES: RefCell<Vec<Option<WindowState>>> = const { RefCell::new(Vec::new()) };
107}
108
109pub fn set_window_state(context_id: GoudContextId, state: WindowState) -> Result<(), GoudError> {
111 WINDOW_STATES.with(|cell| {
112 let mut states = cell.borrow_mut();
113 let index = context_id.index() as usize;
114
115 while states.len() <= index {
116 states.push(None);
117 }
118
119 states[index] = Some(state);
120 Ok(())
121 })
122}
123
124pub fn remove_window_state(context_id: GoudContextId) {
126 WINDOW_STATES.with(|cell| {
127 let mut states = cell.borrow_mut();
128 let index = context_id.index() as usize;
129 if index < states.len() {
130 states[index] = None;
131 }
132 });
133}
134
135pub fn with_window_state<F, R>(context_id: GoudContextId, f: F) -> Option<R>
141where
142 F: FnOnce(&mut WindowState) -> R,
143{
144 WINDOW_STATES.with(|cell| {
145 let mut states = cell.borrow_mut();
146 let index = context_id.index() as usize;
147 states.get_mut(index).and_then(|opt| opt.as_mut()).map(f)
148 })
149}