tiny_game_framework/events/
main_loop.rs1extern crate glfw;
2
3use std::time::{self, Instant};
4
5use gl::{BlendFunc, Enable, Viewport, BLEND, DEPTH_TEST, ONE_MINUS_SRC_ALPHA, SRC_ALPHA};
6use glam::{vec2, Vec2};
7use glfw::{fail_on_errors, Glfw, GlfwReceiver, PWindow, Window, WindowEvent};
8use glfw::{Action, Context, Key};
9use imgui::Ui;
10
11use crate::{Camera, Imgui};
12
13use super::EventHandler;
14
15pub struct EventLoop {
16 pub event_handler: EventHandler,
17 pub window: PWindow,
18 pub ui: Imgui,
19 pub glfw: Glfw,
20 events: GlfwReceiver<(f64, WindowEvent)>,
21 pub now: Instant,
22 pub dt: f32,
23 pub time: f32,
24
25 pub timescale: f32,
26}
27
28impl EventLoop {
29 pub fn new(w: u32, h: u32) -> Self {
30 let mut glfw = glfw::init(fail_on_errors!()).unwrap();
31
32 glfw.window_hint(glfw::WindowHint::TransparentFramebuffer(true));
33
34 let (mut window, events) = glfw.create_window(w, h, "Hello this is window", glfw::WindowMode::Windowed)
35 .expect("Failed to create GLFW window.");
36
37 let ui = Imgui::new(&mut window);
38
39 window.make_current();
40 window.set_key_polling(true);
41 window.set_cursor_pos_polling(true);
42 window.set_framebuffer_size_polling(true);
43 window.set_mouse_button_polling(true);
44 window.set_scroll_polling(true);
45 gl::load_with(|s| window.get_proc_address(s) );
49
50 unsafe {
51 BlendFunc(SRC_ALPHA, ONE_MINUS_SRC_ALPHA);
52 Enable(BLEND | DEPTH_TEST);
53 }
54
55 let mut event_handler = EventHandler::new();
56 event_handler.on_window_resize(w as i32, h as i32);
57
58 Self {
59 event_handler,
60 window,
61 ui,
62 glfw,
63 events,
64 now: std::time::Instant::now(),
65 dt: 0.0,
66 time: 0.0,
67 timescale: 1.0,
68 }
69 }
70
71 pub fn size(&self) -> Vec2 {
72 vec2(self.window.get_size().0 as f32, self.window.get_size().1 as f32)
73 }
74
75 pub fn update(&mut self) {
76 self.dt = self.now.elapsed().as_secs_f32() * self.timescale;
77 self.time += self.dt;
78 self.now = std::time::Instant::now();
79
80
81 self.window.swap_buffers();
82
83 self.glfw.poll_events();
84
85 self.event_handler.update();
86
87 for (_, event) in glfw::flush_messages(&self.events) {
88 match event {
89 glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => {
90 self.window.set_should_close(true)
91 },
92 glfw::WindowEvent::Key(key, _, Action::Press, _ ) => {
93 self.event_handler.on_key_press(key);
94 }
95 glfw::WindowEvent::Key(key, _, Action::Release, _ ) => {
96 self.event_handler.on_key_release(key);
97 }
98
99 glfw::WindowEvent::CursorPos(x, y) => {
100 self.event_handler.on_mouse_move(x, y);
101 self.ui.on_mouse_move(x as f32, y as f32);
102 }
103
104 glfw::WindowEvent::MouseButton(button, Action::Press, _) => {
105 self.ui.on_mouse_click(button, Action::Press);
106
107 match button {
111 glfw::MouseButton::Button1 => {
112 self.event_handler.on_lmb_press();
116 },
117 glfw::MouseButton::Button2 => {
118 self.event_handler.on_rmb_press();
122 },
123 _ => ()
124 }
125 }
126
127 glfw::WindowEvent::MouseButton(button, Action::Release, _) => {
128 self.ui.on_mouse_click(button, Action::Release);
129 match button {
130 glfw::MouseButton::Button1 => {
131 self.event_handler.on_lmb_release();
132 },
133 glfw::MouseButton::Button2 => {
134 self.event_handler.on_rmb_release();
135 },
136
137 _ => ()
138 }
139 }
140
141 glfw::WindowEvent::Scroll(xoff, yoff) => {
142 self.event_handler.on_scroll_change(vec2(xoff as f32, yoff as f32));
143 self.ui.on_mouse_scroll(xoff as f32, yoff as f32);
144 }
145
146 glfw::WindowEvent::FramebufferSize(w, h) => {
147 self.event_handler.on_window_resize(w, h);
148 unsafe {
149 Viewport(0, 0, w, h);
150 }
151 }
152 _ => {},
153 }
154 }
155 }
156
157 pub fn is_key_down(&mut self, key: Key) -> bool {
158 if self.window.get_key(key) == Action::Press {
159 true
160 } else {
161 false
162 }
163 }
164
165 pub fn is_key_up(&mut self, key: Key) -> bool {
166 if self.window.get_key(key) == Action::Release {
167 true
168 } else {
169 false
170 }
171 }
172
173 pub fn set_fullscreen(&mut self, fullscreen: &bool) {
175 if self.event_handler.key_just_pressed(Key::F11) {
176 if !fullscreen {
177 self.glfw.with_primary_monitor(|_, monitor| {
178 let monitor = monitor.unwrap();
179 let mode = monitor.get_video_mode().unwrap();
180 self.window.set_monitor(
181 glfw::WindowMode::FullScreen(&monitor),
182 0,
183 0,
184 mode.width,
185 mode.height,
186 Some(mode.refresh_rate),
187 );
188 });
189 } else {
190 self.glfw.with_primary_monitor(|_, monitor| {
191 let monitor = monitor.unwrap();
192 let mode = monitor.get_video_mode().unwrap();
193 self.window.set_monitor(
194 glfw::WindowMode::Windowed,
195 200,
196 200,
197 800,
198 800,
199 Some(mode.refresh_rate),
200 );
201 });
202 }
203 }
204 }
205}