1use crate::{
26 engine::{Engine, Game, run_game},
27 window::WindowConfig,
28 entity::{EntityManager, Transform, Sprite, Velocity},
29 math::{Position, Size, Color},
30 resources::Resources,
31 systems::{System, SystemSet},
32 EngineResult,
33};
34use std::any::Any;
35use winit::event::WindowEvent;
36
37pub struct App {
38 resources: Resources,
39 startup_systems: Vec<Box<dyn System>>,
40 update_systems: Vec<Box<dyn System>>,
41 render_systems: Vec<Box<dyn System>>,
42 window_config: WindowConfig,
43}
44
45impl App {
46 pub fn new() -> AppBuilder {
47 AppBuilder::new()
48 }
49
50 pub fn run(self) -> EngineResult<()> {
51 let game = ShadowGame {
52 app: self,
53 initialized: false,
54 };
55 run_game(game.app.window_config.clone(), Box::new(game))
56 }
57}
58
59pub struct AppBuilder {
60 resources: Resources,
61 startup_systems: Vec<Box<dyn System>>,
62 update_systems: Vec<Box<dyn System>>,
63 render_systems: Vec<Box<dyn System>>,
64 window_config: WindowConfig,
65}
66
67impl AppBuilder {
68 pub fn new() -> Self {
69 Self {
70 resources: Resources::new(),
71 startup_systems: Vec::new(),
72 update_systems: Vec::new(),
73 render_systems: Vec::new(),
74 window_config: WindowConfig::default(),
75 }
76 }
77
78 pub fn set_window(mut self, config: WindowConfig) -> Self {
79 self.window_config = config;
80 self
81 }
82
83 pub fn insert_resource<T: 'static>(mut self, resource: T) -> Self {
84 self.resources.insert(resource);
85 self
86 }
87
88 pub fn add_startup_system<T: System + 'static>(mut self, system: T) -> Self {
89 self.startup_systems.push(Box::new(system));
90 self
91 }
92
93 pub fn add_system<T: System + 'static>(mut self, system: T) -> Self {
94 self.update_systems.push(Box::new(system));
95 self
96 }
97
98 pub fn add_system_set(mut self, system_set: SystemSet) -> Self {
99 match system_set {
100 SystemSet::Startup(systems) => {
101 self.startup_systems.extend(systems);
102 }
103 SystemSet::Update(systems) => {
104 self.update_systems.extend(systems);
105 }
106 SystemSet::Render(systems) => {
107 self.render_systems.extend(systems);
108 }
109 }
110 self
111 }
112
113 pub fn build(self) -> App {
114 App {
115 resources: self.resources,
116 startup_systems: self.startup_systems,
117 update_systems: self.update_systems,
118 render_systems: self.render_systems,
119 window_config: self.window_config,
120 }
121 }
122}
123
124struct ShadowGame {
125 app: App,
126 initialized: bool,
127}
128
129impl Game for ShadowGame {
130 fn init(&mut self, engine: &mut Engine) -> EngineResult<()> {
131
132 for system in &mut self.app.startup_systems {
133 system.run(engine, &mut self.app.resources)?;
134 }
135 self.initialized = true;
136 Ok(())
137 }
138
139 fn update(&mut self, engine: &mut Engine, delta_time: f32) -> EngineResult<()> {
140 if !self.initialized {
141 return Ok(());
142 }
143
144 if let Some(time) = self.app.resources.get_mut::<TimeResource>() {
145 time.update(delta_time);
146 }
147
148 for system in &mut self.app.update_systems {
149 system.run(engine, &mut self.app.resources)?;
150 }
151
152 Ok(())
153 }
154
155 fn render(&mut self, engine: &mut Engine) -> EngineResult<()> {
156 if !self.initialized {
157 return Ok(());
158 }
159
160 for system in &mut self.app.render_systems {
161 system.run(engine, &mut self.app.resources)?;
162 }
163
164 engine.render()?;
165 Ok(())
166 }
167
168 fn on_event(&mut self, engine: &mut Engine, event: &WindowEvent) -> EngineResult<()> {
169
170 if let Some(input) = self.app.resources.get_mut::<InputResource>() {
171 input.handle_event(event);
172 }
173 Ok(())
174 }
175}
176
177#[derive(Debug)]
178pub struct TimeResource {
179 pub delta_time: f32,
180 pub total_time: f32,
181}
182
183impl TimeResource {
184 pub fn new() -> Self {
185 Self {
186 delta_time: 0.0,
187 total_time: 0.0,
188 }
189 }
190
191 pub fn update(&mut self, delta_time: f32) {
192 self.delta_time = delta_time;
193 self.total_time += delta_time;
194 }
195}
196
197#[derive(Debug)]
198pub struct InputResource {
199
200}
201
202impl InputResource {
203 pub fn new() -> Self {
204 Self {}
205 }
206
207 pub fn handle_event(&mut self, _event: &WindowEvent) {
208
209 }
210}
211
212impl Default for AppBuilder {
213 fn default() -> Self {
214 Self::new()
215 }
216}