hello/
hello.rs

1use std::{
2    path::{Path, PathBuf},
3    sync::{Arc, Mutex},
4};
5
6use fennel_core::{events::{self, KeyboardEvent, WindowEventHandler}, graphics, resources::ResourceManager, Window};
7use sdl3::pixels::Color;
8use tokio::runtime::Handle;
9
10struct State;
11
12#[async_trait::async_trait]
13impl WindowEventHandler for State {
14    fn update(&self, _window: &mut Window) -> anyhow::Result<()> {
15        Ok(())
16    }
17
18    fn draw(&mut self, window: &mut Window) -> anyhow::Result<()> {
19        window.graphics.canvas.set_draw_color(Color::RGB(0, 0, 0));
20        window.graphics.canvas.clear();
21        window
22            .graphics
23            .draw_image("assets/example.png".to_string(), (0.0, 0.0))
24            .expect("failed to draw an image");
25        window.graphics.draw_text(
26            String::from("hi"),
27            (64.0, 64.0),
28            String::from("Terminus"),
29            Color::RGBA(255, 0, 0, 0),
30            16.0,
31        )?;
32        window.graphics.draw_text(
33            String::from("hi"),
34            (64.0, 64.0),
35            String::from("Terminus"),
36            Color::RGBA(255, 0, 0, 0),
37            64.0,
38        )?;
39        window.graphics.canvas.present();
40        Ok(())
41    }
42
43    fn key_down_event(&self, window: &mut Window, event: KeyboardEvent) -> anyhow::Result<()> {
44        println!("{:?}", event.keycode);
45        tokio::task::block_in_place(move || {
46            Handle::current().block_on(async move {
47                window
48                    .audio
49                    .play_audio(Path::new("assets/music.ogg"), false)
50                    .await
51                    .unwrap();
52            })
53        });
54        Ok(())
55    }
56}
57
58#[tokio::main]
59async fn main() {
60    let resource_manager = Arc::new(Mutex::new(ResourceManager::new()));
61    let graphics = graphics::GraphicsBuilder::new()
62        .window_name(String::from("game"))
63        .dimensions((500, 500))
64        .resource_manager(resource_manager.clone())
65        // we bulk load resources here because either we'll have to deal with
66        // ownership of `graphics` (the actual `let graphics`, not the closure
67        // argument)
68        // you may think of it like about just some initialization func
69        .initializer(|graphics| {
70            resource_manager.lock().unwrap().load_dir(PathBuf::from("assets"), graphics).unwrap();
71        })
72        .build();
73    let mut window = Window::new(graphics.unwrap(), resource_manager);
74
75    // because events::run takes a `&'static mut dyn WindowEventHandler` as a second argument we
76    // need to do this seemingly weird thing (while `app.rs` in fennel-engine has an ass solution
77    // with raw pointers lmfao) 
78    let handler: &'static mut dyn WindowEventHandler = {
79        let boxed = Box::new(State);
80        Box::leak(boxed) as &'static mut dyn WindowEventHandler
81    };
82    events::run(&mut window, handler).await;
83}