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}