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 sdl3::{
4    keyboard::{Keycode, Mod, Scancode},
5    mouse::{MouseButton, MouseState, MouseWheelDirection},
6};
7
8use crate::{audio::Audio, graphics::Graphics, resources::ResourceManager};
9
10/// Audio playback
11pub mod audio;
12/// Entity-component-system
13pub mod ecs;
14/// Handling keyboard, window, mouse and other events
15pub mod events;
16/// Rendering layer and all the related things
17pub mod graphics;
18/// Resource management
19pub mod resources;
20/// Tests
21mod tests;
22
23unsafe impl Send for Game {}
24unsafe impl Sync for Game {}
25
26/// Main game struct
27///
28/// Holds basic metadata and a reference to the graphics subsystem.
29/// User must create a [`Game`] in order to feed it to the EventHandler
30pub struct Game {
31    /// Human-readable game title.
32    pub name: String,
33    /// Author or owner of the game.
34    pub author: String,
35    /// Graphics subsystem used to render frames.
36    pub graphics: Graphics,
37    /// Audio subsystem
38    pub audio: Audio,
39    /// Resource management
40    pub resource_manager: ResourceManager,
41}
42
43impl Game {
44    /// Create a new [`Game`] instance.
45    ///
46    /// # Parameters
47    /// - `name`: title of the game
48    /// - `author`: author/owner name
49    /// - `graphics`: initialized graphics subsystem
50    ///
51    /// # Returns
52    /// A [`Game`] instance ready to be used by an [`EventHandler`].
53    pub fn new(name: String, author: String, graphics: Graphics) -> Game {
54        let audio = Audio::new();
55        Game {
56            name,
57            author,
58            graphics,
59            audio,
60            resource_manager: ResourceManager::new(),
61        }
62    }
63}
64
65/// Trait that must be implemented by user's game state struct
66/// - `update` is called to advance game state (physics, AI, input processing).
67/// - `draw` is called to render the current state using `game.graphics`.
68///
69/// Both return `anyhow::Result<()>`
70#[async_trait::async_trait]
71pub trait EventHandler {
72    /// Updates the game state.
73    ///
74    /// This method should contain the logic for updating the game state.
75    ///
76    /// # Arguments
77    ///
78    /// * `game` - A mutable reference to the game state.
79    ///
80    /// # Returns
81    ///
82    /// * `Result<()>` - `()` if everythings fine, otherwise you should return an error if
83    /// something failed in your logics
84    async fn update(&self, game: &mut Game) -> anyhow::Result<()>;
85
86    async fn draw(&self, game: &mut Game) -> anyhow::Result<()>;
87
88    fn key_down_event(
89        &self,
90        _game: &mut Game,
91        _timestamp: u64,
92        _window_id: u32,
93        _keycode: Option<Keycode>,
94        _scancode: Option<Scancode>,
95        _keymod: Mod,
96        _repeat: bool,
97        _which: u32,
98        _raw: u16,
99    ) -> anyhow::Result<()> {
100        Ok(())
101    }
102
103    fn key_up_event(
104        &self,
105        _game: &mut Game,
106        _timestamp: u64,
107        _window_id: u32,
108        _keycode: Option<Keycode>,
109        _scancode: Option<Scancode>,
110        _keymod: Mod,
111        _repeat: bool,
112        _which: u32,
113        _raw: u16,
114    ) -> anyhow::Result<()> {
115        Ok(())
116    }
117
118    fn mouse_motion_event(
119        &self,
120        _game: &mut Game,
121        _timestamp: u64,
122        _window_id: u32,
123        _which: u32,
124        _mousestate: MouseState,
125        _x: f32,
126        _y: f32,
127        _xrel: f32,
128        _yrel: f32,
129    ) -> anyhow::Result<()> {
130        Ok(())
131    }
132
133    fn mouse_button_down_event(
134        &self,
135        _game: &mut Game,
136        _timestamp: u64,
137        _window_id: u32,
138        _which: u32,
139        _mouse_btn: MouseButton,
140        _clicks: u8,
141        _x: f32,
142        _y: f32,
143    ) -> anyhow::Result<()> {
144        Ok(())
145    }
146
147    fn mouse_button_up_event(
148        &self,
149        _game: &mut Game,
150        _timestamp: u64,
151        _window_id: u32,
152        _which: u32,
153        _mouse_btn: MouseButton,
154        _clicks: u8,
155        _x: f32,
156        _y: f32,
157    ) -> anyhow::Result<()> {
158        Ok(())
159    }
160
161    fn mouse_wheel_event(
162        &self,
163        _game: &mut Game,
164        _timestamp: u64,
165        _window_id: u32,
166        _which: u32,
167        _x: f32,
168        _y: f32,
169        _direction: MouseWheelDirection,
170        _mouse_x: f32,
171        _mouse_y: f32,
172    ) -> anyhow::Result<()> {
173        Ok(())
174    }
175}