feat(app): added the prefab interface to the app struct

This commit is contained in:
lisk77 2025-07-14 01:58:49 +02:00
parent e1597e6fa4
commit 7cf9f5bd29
4 changed files with 256 additions and 227 deletions

0
crates/comet_app/Cargo.toml Normal file → Executable file
View file

77
crates/comet_app/src/app.rs Normal file → Executable file
View file

@ -1,22 +1,23 @@
use comet_colors::{Color as ColorTrait, LinearRgba};
use comet_ecs::{
Camera2D, Color, Component, Entity, Render2D, Scene, Text, Transform2D, Transform3D,
};
use comet_input::keyboard::Key;
use comet_log::*;
use comet_renderer::renderer::Renderer;
use std::any::{type_name, Any, TypeId}; use std::any::{type_name, Any, TypeId};
use std::sync::Arc; use std::sync::Arc;
use comet_ecs::{Camera2D, Color, Component, Entity, Render2D, Scene, Text, Transform2D, Transform3D}; use winit::dpi::LogicalSize;
use winit::{ use winit::{
event::*, event::*,
event_loop::EventLoop, event_loop::EventLoop,
window::{Icon, Window}, window::{Icon, Window},
}; };
use comet_colors::{Color as ColorTrait, LinearRgba};
use comet_log::*;
use winit::dpi::LogicalSize;
use winit_input_helper::WinitInputHelper as InputManager; use winit_input_helper::WinitInputHelper as InputManager;
use comet_input::keyboard::Key;
use comet_renderer::renderer::Renderer;
use comet_structs::ComponentSet;
pub enum ApplicationType { pub enum ApplicationType {
App2D, App2D,
App3D App3D,
} }
pub struct App { pub struct App {
@ -30,7 +31,7 @@ pub struct App {
game_state: Option<Box<dyn Any>>, game_state: Option<Box<dyn Any>>,
scene: Scene, scene: Scene,
fullscreen: bool, fullscreen: bool,
should_quit: bool should_quit: bool,
} }
impl App { impl App {
@ -46,7 +47,7 @@ impl App {
game_state: None, game_state: None,
scene: Scene::new(), scene: Scene::new(),
fullscreen: false, fullscreen: false,
should_quit: false should_quit: false,
} }
} }
@ -83,7 +84,7 @@ impl App {
self.scene.register_component::<Render2D>(); self.scene.register_component::<Render2D>();
self.scene.register_component::<Camera2D>(); self.scene.register_component::<Camera2D>();
self.scene.register_component::<Text>(); self.scene.register_component::<Text>();
}, }
ApplicationType::App3D => { ApplicationType::App3D => {
info!("Creating 3D app!"); info!("Creating 3D app!");
self.scene.register_component::<Transform3D>() self.scene.register_component::<Transform3D>()
@ -189,6 +190,18 @@ impl App {
self.scene.has::<C>(entity_id) self.scene.has::<C>(entity_id)
} }
pub fn register_prefab(&mut self, name: &str, factory: comet_ecs::PrefabFactory) {
self.scene.register_prefab(name, factory)
}
pub fn spawn_prefab(&mut self, name: &str) -> Option<usize> {
self.scene.spawn_prefab(name)
}
pub fn has_prefab(&self, name: &str) -> bool {
self.scene.has_prefab(name)
}
pub fn quit(&mut self) { pub fn quit(&mut self) {
self.should_quit = true; self.should_quit = true;
} }
@ -206,9 +219,13 @@ impl App {
self.update_timer = 1.0 / update_rate as f32; self.update_timer = 1.0 / update_rate as f32;
} }
fn create_window(app_title: String, app_icon: &Option<Icon>, window_size: &Option<LogicalSize<u32>>, event_loop: &EventLoop<()>) -> Window { fn create_window(
let winit_window = winit::window::WindowBuilder::new() app_title: String,
.with_title(app_title); app_icon: &Option<Icon>,
window_size: &Option<LogicalSize<u32>>,
event_loop: &EventLoop<()>,
) -> Window {
let winit_window = winit::window::WindowBuilder::new().with_title(app_title);
let winit_window = if let Some(icon) = app_icon.clone() { let winit_window = if let Some(icon) = app_icon.clone() {
winit_window.with_window_icon(Some(icon)) winit_window.with_window_icon(Some(icon))
@ -225,12 +242,21 @@ impl App {
winit_window.build(event_loop).unwrap() winit_window.build(event_loop).unwrap()
} }
pub fn run<R: Renderer>(mut self, setup: fn(&mut App, &mut R), update: fn(&mut App, &mut R, f32)) { pub fn run<R: Renderer>(
mut self,
setup: fn(&mut App, &mut R),
update: fn(&mut App, &mut R, f32),
) {
info!("Starting up {}!", self.title); info!("Starting up {}!", self.title);
pollster::block_on(async { pollster::block_on(async {
let event_loop = EventLoop::new().unwrap(); let event_loop = EventLoop::new().unwrap();
let window = Arc::new(Self::create_window(self.title.clone(), &self.icon, &self.size ,&event_loop)); let window = Arc::new(Self::create_window(
self.title.clone(),
&self.icon,
&self.size,
&event_loop,
));
let mut renderer = R::new(window.clone(), self.clear_color.clone()); let mut renderer = R::new(window.clone(), self.clear_color.clone());
info!("Renderer created! ({})", type_name::<R>()); info!("Renderer created! ({})", type_name::<R>());
@ -240,7 +266,8 @@ impl App {
let mut time_stack = 0.0; let mut time_stack = 0.0;
info!("Starting event loop!"); info!("Starting event loop!");
event_loop.run(|event, elwt| { event_loop
.run(|event, elwt| {
self.delta_time = renderer.update(); self.delta_time = renderer.update();
if self.should_quit { if self.should_quit {
@ -259,8 +286,10 @@ impl App {
} }
match event { match event {
Event::WindowEvent { ref event, window_id} => { Event::WindowEvent {
match event { ref event,
window_id,
} => match event {
WindowEvent::CloseRequested {} => elwt.exit(), WindowEvent::CloseRequested {} => elwt.exit(),
WindowEvent::Resized(physical_size) => { WindowEvent::Resized(physical_size) => {
renderer.resize(*physical_size); renderer.resize(*physical_size);
@ -268,16 +297,16 @@ impl App {
WindowEvent::RedrawRequested => { WindowEvent::RedrawRequested => {
window.request_redraw(); window.request_redraw();
match renderer.render() { match renderer.render() {
Ok(_) => {}, Ok(_) => {}
Err(e) => error!("Error rendering: {}", e) Err(e) => error!("Error rendering: {}", e),
} }
} }
_ => {} _ => {}
} },
}
_ => {} _ => {}
} }
}).unwrap() })
.unwrap()
}); });
info!("Shutting down {}!", self.title); info!("Shutting down {}!", self.title);

0
crates/comet_app/src/game_state.rs Normal file → Executable file
View file

0
crates/comet_app/src/lib.rs Normal file → Executable file
View file