summaryrefslogtreecommitdiff
path: root/src/componentwrapper.rs
diff options
context:
space:
mode:
authortroido <troido@protonmail.com>2020-03-06 16:43:15 +0100
committertroido <troido@protonmail.com>2020-03-06 16:43:15 +0100
commita1f45d1b40b23cb7e9f0b277f24ad66880b0bc56 (patch)
tree35b920c90fcb99e94f5b89f781e7434756edfa41 /src/componentwrapper.rs
parenta431234ab0c54ea87563a8e977c19fa3f1a5b400 (diff)
saved a few characters in componentwrapper definition but at macro cost
Diffstat (limited to 'src/componentwrapper.rs')
-rw-r--r--src/componentwrapper.rs74
1 files changed, 60 insertions, 14 deletions
diff --git a/src/componentwrapper.rs b/src/componentwrapper.rs
index e8dbba4..a49ac79 100644
--- a/src/componentwrapper.rs
+++ b/src/componentwrapper.rs
@@ -17,9 +17,8 @@ use crate::{
};
-
macro_rules! components {
- ($($comp: ident ($($paramname: ident : $paramtype: ident),*) $creation: expr);*;) => {
+ (post: $($comp: ident ($($paramname: ident : $paramtype: ident, $extraction: expr),*) $creation: expr);*;) => {
#[derive(Clone)]
pub enum ComponentWrapper{
$(
@@ -82,7 +81,54 @@ macro_rules! components {
}
}
}
- }
+
+ use specs::{World, Entity, WorldExt};
+ pub fn extract_parameter(typ: ComponentType, parameter: &str, world: World, ent: Entity) -> Option<Parameter> {
+ match typ {
+ $(
+
+ #[allow(path_statements)]
+ ComponentType::$comp => {
+ None::<Parameter>
+ $(
+ ;
+ if parameter == stringify!($paramname) {
+ #[allow(unreachable_code, non_snake_case)]
+ Some(Parameter::$paramtype({
+ let components = world.read_component::<crate::components::$comp>();
+ #[allow(unused_variables)]
+ let $comp = components.get(ent)?;
+ $extraction
+ }))
+ } else {
+ None
+ }
+ )*
+ }
+ )*
+ }
+ }
+ };
+ // no parameters: make unit struct
+ (pre: ($($done: tt)*) $comp: ident; $($tail:tt)*) => {
+ components!(pre: ($($done)* $comp () {$comp};) $($tail)*);
+ };
+ // struct is just parameters
+ (pre: ($($done: tt)*) $comp: ident ($($paramname: ident : $paramtype: ident),*);$($tail:tt)*) => {
+ components!(pre: ($($done)* $comp ($($paramname : $paramtype, {$comp.$paramname.clone()}),*) {$comp{$($paramname,)*}};) $($tail)*);
+ };
+ // full definition minus variable exraction
+ (pre: ($($done: tt)*) $comp: ident ($($paramname: ident : $paramtype: ident),*) $creation: expr; $($tail:tt)*) => {
+ components!(pre: ($($done)* $comp ($($paramname : $paramtype, {panic!(format!("can not extract {} for {}", stringify!($paramname), stringify!($comp)))}),*) $creation;) $($tail)*);
+ };
+ // full definition
+ (pre: ($($done: tt)*) $comp: ident ($($paramname: ident : $paramtype: ident ($extraction: expr)),*) $creation: expr; $($tail:tt)*) => {
+ components!(pre: ($($done)* $comp ($($paramname : $paramtype, $extraction),*) $creation;) $($tail)*);
+ };
+ (pre: ($($done: tt)*)) => {
+ components!(post: $($done)*);
+ };
+ ($($all: tt)*) => {components!(pre: () $($all)*);};
}
components!(
@@ -93,14 +139,14 @@ components!(
name
}
};
- Movable (cooldown: Int) {Movable {cooldown}};
- Blocking () {Blocking};
- Floor () {Floor};
+ Movable (cooldown: Int);
+ Blocking;
+ Floor;
Player (name: String) {Player::new(PlayerId{name})};
- Item (ent: Template, name: String, action: Action) {Item{ent, name, action}};
+ Item (ent: Template, name: String, action: Action);
Inventory () {panic!("inventory from parameters not implemented")};
- Health (health: Int, maxhealth: Int) {Health{health, maxhealth}};
- Serialise (template: Template) {Serialise{template}};
+ Health (health: Int, maxhealth: Int);
+ Serialise (template: Template);
RoomExit (destination: String, dest_pos: String) {
RoomExit {
destination: RoomId::from_str(&destination),
@@ -116,8 +162,8 @@ components!(
Healing (delay: Int, health: Int) {Healing{delay, health, next_heal: None}};
Volatile (delay: Int) {Volatile{delay, end_time: None}};
Autofight () {Autofight::default()};
- MonsterAI (move_chance: Float, homesickness: Float, view_distance: Int) {MonsterAI{move_chance, homesickness, view_distance}};
- Mortal () {Mortal};
+ MonsterAI (move_chance: Float, homesickness: Float, view_distance: Int);
+ Mortal;
Spawner (amount: Int, delay: Int, clan: String, template: Template, initial_spawn: Bool) {
Spawner{
amount: amount as usize,
@@ -133,11 +179,11 @@ components!(
last_spawn: if initial_spawn {Some(Timestamp(-delay))} else {None}
}
};
- Clan (name: String) Clan{name};
- Home (home: Pos) Home{home};
+ Clan (name: String);
+ Home (home: Pos);
Faction (faction: String) {Faction::from_str(faction.as_str())?};
Interactable (action: String) {Interactable::from_str(action.as_str())?};
- Loot (loot: LootList) {Loot{loot}};
+ Loot (loot: LootList);
Grow (delay: Int, into: Template) {Grow{delay, into, target_time: None}};
Equipment () {panic!("equipment from parameters not implemented")};
);