diff --git a/Cargo.lock b/Cargo.lock index d19cb63..fae4355 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,6 +14,14 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "component-macro" +version = "0.1.0" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -26,13 +34,32 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "proc-macro2" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +dependencies = [ + "unicode-ident", +] + [[package]] name = "pvp-game-dilapidation" version = "0.1.0" dependencies = [ + "component-macro", "sdl2", ] +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + [[package]] name = "sdl2" version = "0.36.0" @@ -56,6 +83,23 @@ dependencies = [ "version-compare", ] +[[package]] +name = "syn" +version = "2.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + [[package]] name = "version-compare" version = "0.1.1" diff --git a/Cargo.toml b/Cargo.toml index f2d76a3..d6fb392 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,4 @@ edition = "2021" [dependencies] sdl2 = { version = "0.36.0", features = ["ttf", "image", "mixer"] } +component-macro = { version = "0.1.0", path = "./component-macro" } diff --git a/type-id-test-rs/component-macro/Cargo.toml b/component-macro/Cargo.toml similarity index 100% rename from type-id-test-rs/component-macro/Cargo.toml rename to component-macro/Cargo.toml diff --git a/type-id-test-rs/component-macro/src/lib.rs b/component-macro/src/lib.rs similarity index 99% rename from type-id-test-rs/component-macro/src/lib.rs rename to component-macro/src/lib.rs index f8ef66b..116c490 100644 --- a/type-id-test-rs/component-macro/src/lib.rs +++ b/component-macro/src/lib.rs @@ -22,5 +22,3 @@ fn impl_derive_macro(ast: &syn::DeriveInput) -> TokenStream { }; gen.into() } - - diff --git a/src/engine.rs b/src/engine.rs index 8e529d8..fc43880 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1,3 +1,5 @@ +use std::any::{Any, TypeId}; +use std::collections::HashMap; use std::time::Duration; use sdl2::{ @@ -42,40 +44,49 @@ impl_from_T_for_Error!(String, WindowBuildError, IntegerOrSdlError); pub struct Entity(u64); -pub trait Component {} - -pub struct Sprite<'a> { - texture: Texture<'a>, +pub trait Component { + fn inner_type_id(&self) -> TypeId; + fn as_any(&mut self) -> &mut dyn Any; } -pub struct Context<'a> { - id_counter: &'a mut u64, - canvas: &'a mut Canvas, - texture_creator: &'a TextureCreator, - entities: &'a mut Vec, - components: &'a mut Vec<(u64, Box)>, - systems: &'a mut Vec>, +pub struct Sprite { + path: std::path::PathBuf, } -impl<'a> Context<'a> { - pub fn load_sprite<'b, P>(&self, path: P) -> Result, Error> +pub struct Context<'context, 'game> +where + 'game: 'context, +{ + id_counter: &'context mut u64, + canvas: &'context mut Canvas, + texture_creator: &'context TextureCreator, + entities: &'context mut Vec, + components: &'context mut Vec<(u64, Box)>, + systems: &'context mut Vec>, + textures: &'context mut HashMap>, +} + +impl<'context, 'game> Context<'context, 'game> { + pub fn load_sprite

(&mut self, path: P) -> Result where - 'a: 'b, P: AsRef, { - let texture = self.texture_creator.load_texture(path)?; - Ok(Sprite { texture }) + let path = path.as_ref().to_path_buf(); + let texture: Texture<'game> = self.texture_creator.load_texture(&path)?; + self.textures.insert(path.clone(), texture); + Ok(Sprite { path }) } - pub fn draw_sprite<'b>(&mut self, sprite: &Sprite<'b>, x: i32, y: i32) -> Result<(), Error> { + pub fn draw_sprite(&mut self, sprite: &Sprite, x: i32, y: i32) -> Result<(), Error> { + let texture = &self.textures[&sprite.path]; self.canvas.copy( - &sprite.texture, + texture, None, Rect::new( x * 4, y * 4, - sprite.texture.query().width * 4, - sprite.texture.query().height * 4, + texture.query().width * 4, + texture.query().height * 4, ), )?; Ok(()) @@ -100,7 +111,7 @@ pub trait System { fn on_update(&self, _ctx: &mut Context) {} } -pub struct Game { +pub struct Game<'a> { id_counter: u64, sdl_context: Sdl, video_subsystem: VideoSubsystem, @@ -111,9 +122,10 @@ pub struct Game { entities: Vec, components: Vec<(u64, Box)>, systems: Vec>, + textures: HashMap>, } -impl Game { +impl<'game> Game<'game> { pub fn new() -> Result { let sdl_context = sdl2::init()?; let video_subsystem = sdl_context.video()?; @@ -141,31 +153,35 @@ impl Game { entities: vec![], components: vec![], systems: vec![], + textures: HashMap::new(), }) } - pub fn run ()>(mut self, f: F) { - 'running: loop { - for event in self.event_pump.poll_iter() { - match event { - Event::Quit { .. } - | Event::KeyDown { - keycode: Some(Keycode::Escape), - .. - } => break 'running, - _ => {} - } - } - self.canvas.set_draw_color(Color::RGB(60, 180, 180)); - self.canvas.clear(); - f(&mut self.context()); - self.canvas.present(); - } - self.canvas.present(); - std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60)) + pub fn run ()>(&mut self, _f: F) { + // 'running: loop { + // for event in self.event_pump.poll_iter() { + // match event { + // Event::Quit { .. } + // | Event::KeyDown { + // keycode: Some(Keycode::Escape), + // .. + // } => break 'running, + // _ => {} + // } + // } + // self.canvas.set_draw_color(Color::RGB(60, 180, 180)); + // self.canvas.clear(); + // f(&mut self.context()); + // self.canvas.present(); + // } + // self.canvas.present(); + // std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60)) } - pub fn context<'a>(&'a mut self) -> Context<'a> { + pub fn context<'context>(&'context mut self) -> Context<'context, 'game> + where + 'game: 'context, + { Context { id_counter: &mut self.id_counter, canvas: &mut self.canvas, @@ -173,6 +189,7 @@ impl Game { entities: &mut self.entities, components: &mut self.components, systems: &mut self.systems, + textures: &mut self.textures, } } } diff --git a/src/main.rs b/src/main.rs index c2c5922..bbb4151 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,14 +1,16 @@ #![allow(dead_code)] +#![allow(unused_imports)] +use component_macro::Component; use engine::{Component, Sprite, System}; +use std::any::{Any, TypeId}; mod engine; -struct Player<'a> { - sprite: Option>, +#[derive(Component)] +struct Player { + sprite: Option, } -impl<'a> Component for Player<'a> {} - struct PlayerRenderer; impl System for PlayerRenderer { @@ -17,13 +19,16 @@ impl System for PlayerRenderer { fn on_update(&self, _ctx: &mut engine::Context) {} } +fn add_player<'borrow, 'game>(game: &'borrow mut engine::Game<'game>) { + let mut context = game.context(); + context.add_system(Box::new(PlayerRenderer)); + context.spawn(vec![Box::new(Player { sprite: None })]); +} + fn main() { let mut game = engine::Game::new().unwrap(); - { - let mut context = game.context(); - context.add_system(Box::new(PlayerRenderer)); - context.spawn(vec![Box::new(Player { sprite: None })]); + add_player(&mut game); } game.run(|context| { diff --git a/type-id-test-rs/Cargo.toml b/type-id-test-rs/Cargo.toml index 3a4316d..9bb1c3e 100644 --- a/type-id-test-rs/Cargo.toml +++ b/type-id-test-rs/Cargo.toml @@ -1,4 +1,3 @@ -workspace = { members = ["component-macro"] } [package] name = "type-id-test-rs" version = "0.1.0"