diff options
-rw-r--r-- | stockton-types/src/ent_map.rs | 35 | ||||
-rw-r--r-- | stockton-types/src/lib.rs | 2 | ||||
-rw-r--r-- | stockton-types/tests/ent_map.rs | 102 | ||||
-rw-r--r-- | stockton-types/tests/helpers.rs | 76 | ||||
-rw-r--r-- | stockton-types/tests/world.rs | 90 |
5 files changed, 236 insertions, 69 deletions
diff --git a/stockton-types/src/ent_map.rs b/stockton-types/src/ent_map.rs new file mode 100644 index 0000000..213e481 --- /dev/null +++ b/stockton-types/src/ent_map.rs @@ -0,0 +1,35 @@ +// Copyright (C) Oscar Shrimpton 2019 + +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. + +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with this program. If not, see <http://www.gnu.org/licenses/>. + +/// Convenience function for creating mappers for `World::new()`. +#[macro_export] +macro_rules! ent_map { + ( $ ( $name:expr => $type:ident [ $( $key:expr => $target:ident ),* ] ),* ) => { + { + use stockton_bsp::lumps::entities::Entity as BSPEntity; + use stockton_types::Entity; + |ent: &BSPEntity| -> Box<dyn Entity> { + $( + if ent.attributes["classname"] == $name { + return Box::new($type { + $( $target : ent.attributes[$key].into() ),* + }); + } + );* + panic!("Unrecognised Entity type: {:?}", ent); + } + } + } +}
\ No newline at end of file diff --git a/stockton-types/src/lib.rs b/stockton-types/src/lib.rs index 7e6c9ea..0adf8a5 100644 --- a/stockton-types/src/lib.rs +++ b/stockton-types/src/lib.rs @@ -25,6 +25,8 @@ pub use entity_store::{EntityStore, Entity}; pub mod world; pub use world::World; +pub mod ent_map; + /// Alias for convenience pub type Vector2 = na::base::Vector2<f32>; /// Alias for convenience diff --git a/stockton-types/tests/ent_map.rs b/stockton-types/tests/ent_map.rs new file mode 100644 index 0000000..107620d --- /dev/null +++ b/stockton-types/tests/ent_map.rs @@ -0,0 +1,102 @@ +// Copyright (C) Oscar Shrimpton 2019 + +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. + +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with this program. If not, see <http://www.gnu.org/licenses/>. + +#[macro_use] +extern crate stockton_types; +extern crate stockton_bsp; + +#[macro_use] +mod helpers; + +use stockton_bsp::lumps::entities::Entity as BSPEntity; + +use stockton_types::{Entity, Vector3}; + +#[derive(Debug, PartialEq)] +struct A; +impl Entity for A { + fn get_position(&self) -> Vector3 { + Vector3::new(0.0, 0.0, 0.0) + } +} + +#[derive(Debug, PartialEq)] +struct B { + data: String, +} +impl Entity for B { + fn get_position(&self) -> Vector3 { + Vector3::new(0.0, 0.0, 0.0) + } +} + +#[derive(Debug, PartialEq)] +struct CustomStruct { + one: i32, + two: i32, + three: i32 +} + +impl From<&str> for CustomStruct { + fn from(_: &str) -> CustomStruct { + CustomStruct { one: 1, two: 2, three: 3 } + } +} + +#[derive(Debug, PartialEq)] +struct C { + data2: String, + into: CustomStruct +} +impl Entity for C { + fn get_position(&self) -> Vector3 { + Vector3::new(0.0, 0.0, 0.0) + } +} + +#[test] +fn ent_map_macro() { + let map_func = ent_map![ + "A" => A [], + "B" => B [ + "data" => data + ], + "C" => C [ + "data" => data2, + "into" => into + ] + ]; + + assert_eq!(map_func(&BSPEntity { + attributes: map![ + "classname" => "A" + ] + }).downcast_ref::<A>().unwrap(), &A); + + assert_eq!(map_func(&BSPEntity { + attributes: map![ + "classname" => "B", + "data" => "foobar" + ] + }).downcast_ref::<B>().unwrap(), &B { data: "foobar".to_string() }); + + assert_eq!(map_func(&BSPEntity { + attributes: map![ + "classname" => "C", + "data" => "foobar", + "into" => "a b c" + ] + }).downcast_ref::<C>().unwrap(), &C { data2: "foobar".to_string(), into: CustomStruct { one: 1, two: 2, three: 3 } }); +}
\ No newline at end of file diff --git a/stockton-types/tests/helpers.rs b/stockton-types/tests/helpers.rs new file mode 100644 index 0000000..a0215cb --- /dev/null +++ b/stockton-types/tests/helpers.rs @@ -0,0 +1,76 @@ +// Copyright (C) Oscar Shrimpton 2019 + +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. + +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with this program. If not, see <http://www.gnu.org/licenses/>. +#![allow(dead_code, unused_macros)] + +extern crate stockton_bsp; + +use std::pin::Pin; + +use stockton_bsp::BSPFile; +use stockton_bsp::lumps::*; +use stockton_bsp::lumps::entities::Entity as BSPEntity; +use stockton_bsp::directory::{DirEntry, Header}; + +macro_rules! map( + { $($key:expr => $value:expr),* } => { + { + let mut m = ::std::collections::HashMap::new(); + $( + m.insert($key, $value); + )* + m + } + }; +); + + +pub fn dummy_bspfile(entities: Vec<BSPEntity<'static>>) -> Pin<Box<BSPFile<'static>>> { + Box::pin(BSPFile { + directory: Header { + version: 1, + dir_entries: [DirEntry { offset: 0, length: 0 }; 17] + }, + entities: EntitiesLump { + string: "dummy", + entities + }, + textures: TexturesLump { + textures: vec![].into_boxed_slice() + }, + planes: PlanesLump { + planes: vec![].into_boxed_slice() + }, + lightvols: LightVolsLump { + vols: vec![].into_boxed_slice() + }, + lightmaps: LightmapsLump { + maps: vec![].into_boxed_slice() + }, + meshverts: MeshVertsLump { + meshverts: vec![].into_boxed_slice() + }, + vertices: VerticesLump { + vertices: vec![].into_boxed_slice() + }, + effects: EffectsLump::empty(), + brushes: BrushesLump::empty(), + faces: FaceLump::empty(), + tree: BSPTree::empty(), + visdata: VisDataLump { + vecs: vec![].into_boxed_slice() + }, + models: ModelsLump::empty() + }) +}
\ No newline at end of file diff --git a/stockton-types/tests/world.rs b/stockton-types/tests/world.rs index 4ad68ea..83bb178 100644 --- a/stockton-types/tests/world.rs +++ b/stockton-types/tests/world.rs @@ -16,27 +16,14 @@ extern crate stockton_types; extern crate stockton_bsp; -use stockton_bsp::BSPFile; -use stockton_bsp::lumps::*; +#[macro_use] +mod helpers; +use crate::helpers::*; + use stockton_bsp::lumps::entities::Entity as BSPEntity; -use stockton_bsp::directory::{DirEntry, Header}; use stockton_types::{World, Entity, Vector3}; - -macro_rules! map( - { $($key:expr => $value:expr),+ } => { - { - let mut m = ::std::collections::HashMap::new(); - $( - m.insert($key, $value); - )+ - m - } - }; -); - - #[derive(Debug, PartialEq)] struct DummyEntity; @@ -50,58 +37,23 @@ impl Entity for DummyEntity { #[test] fn world_creation() { - let file = Box::pin(BSPFile { - directory: Header { - version: 1, - dir_entries: [DirEntry { offset: 0, length: 0 }; 17] - }, - entities: EntitiesLump { - string: "dummy", - entities: vec![ - BSPEntity { - attributes: map!( - "name" => "1" - ) - }, - BSPEntity { - attributes: map!( - "name" => "2" - ) - }, - BSPEntity { - attributes: map!( - "name" => "3" - ) - } - ] - }, - textures: TexturesLump { - textures: vec![].into_boxed_slice() - }, - planes: PlanesLump { - planes: vec![].into_boxed_slice() - }, - lightvols: LightVolsLump { - vols: vec![].into_boxed_slice() - }, - lightmaps: LightmapsLump { - maps: vec![].into_boxed_slice() - }, - meshverts: MeshVertsLump { - meshverts: vec![].into_boxed_slice() - }, - vertices: VerticesLump { - vertices: vec![].into_boxed_slice() - }, - effects: EffectsLump::empty(), - brushes: BrushesLump::empty(), - faces: FaceLump::empty(), - tree: BSPTree::empty(), - visdata: VisDataLump { - vecs: vec![].into_boxed_slice() - }, - models: ModelsLump::empty() - }); + let file = dummy_bspfile(vec![ + BSPEntity { + attributes: map!( + "name" => "1" + ) + }, + BSPEntity { + attributes: map!( + "name" => "2" + ) + }, + BSPEntity { + attributes: map!( + "name" => "3" + ) + } + ]); let mut called_times = 0; |