fennel_engine/lib.rs
1//! A small 2D game framework I'm building just-for-fun and to learn Rust a little bit deeper
2
3use std::sync::{Arc, Mutex};
4
5use sdl3::{
6 keyboard::{Keycode, Mod, Scancode},
7 mouse::{MouseButton, MouseState, MouseWheelDirection},
8};
9
10use crate::{audio::Audio, graphics::Graphics, resources::ResourceManager};
11
12/// Audio playback
13pub mod audio;
14/// Entity-component-system
15pub mod ecs;
16/// Handling keyboard, window, mouse and other events
17pub mod events;
18/// Rendering layer and all the related things
19pub mod graphics;
20/// Resource management
21pub mod resources;
22/// Tests
23mod tests;
24
25unsafe impl Send for Game {}
26unsafe impl Sync for Game {}
27
28/// Main game struct
29///
30/// Holds basic metadata and a reference to the graphics subsystem.
31/// User must create a [`Game`] in order to feed it to the EventHandler
32pub struct Game {
33 /// Human-readable game title.
34 pub name: String,
35 /// Author or owner of the game.
36 pub author: String,
37 /// Graphics subsystem used to render frames.
38 pub graphics: Graphics,
39 /// Audio subsystem
40 pub audio: Audio,
41 /// Resource management
42 pub resource_manager: Arc<Mutex<ResourceManager>>,
43}
44
45impl Game {
46 /// Create a new [`Game`] instance.
47 ///
48 /// # Parameters
49 /// - `name`: title of the game
50 /// - `author`: author/owner name
51 /// - `graphics`: initialized graphics subsystem
52 ///
53 /// # Returns
54 /// A [`Game`] instance ready to be used by an [`EventHandler`].
55 pub fn new(
56 name: String,
57 author: String,
58 graphics: Graphics,
59 resource_manager: Arc<Mutex<ResourceManager>>,
60 ) -> Game {
61 let audio = Audio::new();
62 Game {
63 name,
64 author,
65 graphics,
66 audio,
67 resource_manager,
68 }
69 }
70}
71
72/// Trait that must be implemented by user's game state struct
73/// - `update` is called to advance game state (physics, AI, input processing).
74/// - `draw` is called to render the current state using `game.graphics`.
75#[async_trait::async_trait]
76pub trait EventHandler {
77 /// Updates the game state.
78 ///
79 /// This method should contain the logic for updating the game state.
80 ///
81 /// # Arguments
82 ///
83 /// - `game` - A mutable reference to the game state.
84 ///
85 /// # Returns
86 ///
87 /// - `Result<()>` - `()` if everythings fine, otherwise you should return an error if
88 /// something failed in your logics
89 async fn update(&self, game: &mut Game) -> anyhow::Result<()>;
90
91 /// Draws the game
92 ///
93 /// This method should contain the logic for drawing on the game's canvas
94 ///
95 /// # Arguments
96 ///
97 /// - `game` - A mutable reference to the game state.
98 ///
99 /// # Returns
100 ///
101 /// - `Result<()>` - `()` if everythings fine, otherwise you should return an error if
102 /// something failed in your logics
103 async fn draw(&self, game: &mut Game) -> anyhow::Result<()>;
104
105 /// Handles a key‑down event.
106 ///
107 /// # Parameters
108 /// - `game` – Mutable `Game` reference.
109 /// - `timestamp` – Event timestamp.
110 /// - `window_id` – Window identifier.
111 /// - `keycode` – Optional keycode of the pressed key.
112 /// - `scancode` – Optional scancode of the pressed key.
113 fn key_down_event(
114 &self,
115 _game: &mut Game,
116 _timestamp: u64,
117 _window_id: u32,
118 _keycode: Option<Keycode>,
119 _scancode: Option<Scancode>,
120 _keymod: Mod,
121 _repeat: bool,
122 _which: u32,
123 _raw: u16,
124 ) -> anyhow::Result<()> {
125 Ok(())
126 }
127
128 /// Handles a key‑up event. Parameters mirror `key_down_event`
129 fn key_up_event(
130 &self,
131 _game: &mut Game,
132 _timestamp: u64,
133 _window_id: u32,
134 _keycode: Option<Keycode>,
135 _scancode: Option<Scancode>,
136 _keymod: Mod,
137 _repeat: bool,
138 _which: u32,
139 _raw: u16,
140 ) -> anyhow::Result<()> {
141 Ok(())
142 }
143
144 /// Handles mouse‑motion events.
145 ///
146 /// # Parameters
147 /// - `game` – Mutable `Game` reference.
148 /// - `timestamp` – Event timestamp.
149 /// - `window_id` – Window identifier.
150 /// - `x`, `y` – Absolute cursor coordinates.
151 /// - `xrel`, `yrel` – Relative motion since the previous event.
152 fn mouse_motion_event(
153 &self,
154 _game: &mut Game,
155 _timestamp: u64,
156 _window_id: u32,
157 _which: u32,
158 _mousestate: MouseState,
159 _x: f32,
160 _y: f32,
161 _xrel: f32,
162 _yrel: f32,
163 ) -> anyhow::Result<()> {
164 Ok(())
165 }
166
167 /// Handles a mouse‑button‑down event.
168 ///
169 /// # Parameters
170 /// - `game` – Mutable `Game` reference.
171 /// - `timestamp` – Event timestamp.
172 /// - `window_id` – Window identifier.
173 /// - `mouse_btn` – Button that was pressed.
174 /// - `clicks` – Number of consecutive clicks.
175 /// - `x`, `y` – Cursor position at the time of the press.
176 fn mouse_button_down_event(
177 &self,
178 _game: &mut Game,
179 _timestamp: u64,
180 _window_id: u32,
181 _which: u32,
182 _mouse_btn: MouseButton,
183 _clicks: u8,
184 _x: f32,
185 _y: f32,
186 ) -> anyhow::Result<()> {
187 Ok(())
188 }
189
190 /// Handles a mouse‑button‑up event. Parameters mirror
191 /// `mouse_button_down_event`
192 fn mouse_button_up_event(
193 &self,
194 _game: &mut Game,
195 _timestamp: u64,
196 _window_id: u32,
197 _which: u32,
198 _mouse_btn: MouseButton,
199 _clicks: u8,
200 _x: f32,
201 _y: f32,
202 ) -> anyhow::Result<()> {
203 Ok(())
204 }
205
206 /// Handles a mouse‑wheel (scroll) event.
207 ///
208 /// # Parameters
209 /// - `game` – Mutable `Game` reference.
210 /// - `timestamp` – Event timestamp.
211 /// - `window_id` – Window identifier.
212 /// - `x`, `y` – Scroll amount along each axis.
213 /// - `direction` – Scroll direction probably i don't know.
214 /// - `mouse_x`, `mouse_y` – Cursor position when the wheel event occurred.
215 fn mouse_wheel_event(
216 &self,
217 _game: &mut Game,
218 _timestamp: u64,
219 _window_id: u32,
220 _which: u32,
221 _x: f32,
222 _y: f32,
223 _direction: MouseWheelDirection,
224 _mouse_x: f32,
225 _mouse_y: f32,
226 ) -> anyhow::Result<()> {
227 Ok(())
228 }
229}