1use std::sync::{Arc, Mutex};
2
3use fennel_core::graphics::HasWindow;
4use specs::{Dispatcher, DispatcherBuilder, WorldExt};
5
6use crate::components::sprite::{RenderingSystem, Sprite};
7
8pub struct Runtime {
9 pub window: fennel_core::Window,
10 pub world: specs::World,
11 pub dispatcher: Dispatcher<'static, 'static>,
12}
13
14#[derive(Default, Debug)]
15pub struct RuntimeBuilder {
16 name: &'static str,
17 dimensions: (u32, u32),
18}
19
20impl HasWindow for Runtime {
21 fn window_mut(&mut self) -> &mut fennel_core::Window {
22 &mut self.window
23 }
24}
25
26impl Runtime {
27 pub async fn run<H>(&mut self, game_state: H) -> anyhow::Result<()>
28 where
29 H: fennel_common::events::WindowEventHandler<Host = Runtime> + Send + Sync + 'static,
30 {
31 fennel_core::events::run(self, game_state).await;
32 Ok(())
33 }
34}
35
36impl RuntimeBuilder {
37 pub fn new() -> RuntimeBuilder {
38 RuntimeBuilder {
39 name: "",
40 dimensions: (100, 100),
41 }
42 }
43
44 pub fn name(mut self, name: &'static str) -> RuntimeBuilder {
45 self.name = name;
46 self
47 }
48
49 pub fn dimensions(mut self, dimensions: (u32, u32)) -> RuntimeBuilder {
50 self.dimensions = dimensions;
51 self
52 }
53
54 pub fn build(&self) -> anyhow::Result<Runtime> {
55 let resource_manager = Arc::new(Mutex::new(fennel_core::resources::ResourceManager::new()));
56 let graphics = fennel_core::graphics::Graphics::new(
57 self.name.to_string(),
58 self.dimensions,
59 resource_manager.clone(),
60 );
61 let window = fennel_core::Window::new(
62 graphics.expect("failed to initialize graphics"),
63 resource_manager,
64 );
65 let mut world = specs::World::new();
66 let mut dispatcher = DispatcherBuilder::new()
67 .with(RenderingSystem, "rendering_system", &[])
68 .build();
69 dispatcher.setup(&mut world);
70 world.register::<Sprite>();
71
72 Ok(Runtime {
73 window,
74 world,
75 dispatcher,
76 })
77 }
78}