123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- #[macro_export]
- macro_rules! system {
- ($name:ident ( $($pat:tt)* ) { $($rest:tt)* } ) => {
- pub struct $name;
- impl<'a> specs::System<'a> for $name {
- type SystemData = args_to_systemdata!(($($pat)*,));
- fn run(&mut self, args_to_fn_pat!(($($pat)*)): Self::SystemData) {
- for args_to_join_pat!(($($pat)*,)) in args_to_join!(($($pat)*,)).join() {
- $($rest)*
- }
- }
- }
- };
- ($name:ident $pat:tt { $($rest:tt)* } finally { $($finally:tt)* }) => {
- pub struct $name;
- impl<'a> specs::System<'a> for $name {
- type SystemData = args_to_systemdata!($pat);
- fn run(&mut self, args_to_fn_pat!($pat): Self::SystemData) {
- for args_to_join_pat!($pat) in args_to_join!($pat).join() {
- $($rest)*
- }
- $($finally)*
- }
- }
- };
- }
- #[macro_export]
- macro_rules! system_impl {
- ($name:ident ( $($pat:tt)* ) { $($rest:tt)* } ) => {
- pub struct $name;
- impl<'a> specs::System<'a> for $name {
- type SystemData = args_to_systemdata!(($($pat)*,));
- fn run(&mut self, args_to_fn_pat!(($($pat)*)): Self::SystemData) {
- use specs::join::Join;
- $($rest)*
- }
- }
- };
- }
- #[macro_export]
- macro_rules! args_to_systemdata {
- ( ( $name:ident : $ty:ty $(,)? ) ) => {
- ( specs::ReadStorage<'a, $ty> ,)
- };
- ( ( mut $name:ident : $ty:ty $(,)? ) ) => {
- ( specs::WriteStorage<'a, $ty> ,)
- };
- ( ( resource $name:ident : $ty:ty $(,)? ) ) => {
- compile_error!("Resources cannot come at the end of the argument block.")
- };
- ( ( resource mut $name:ident : $ty:ty $(,)? ) ) => {
- compile_error!("Resources cannot come at the end of the argument block.")
- };
- ( ( $name:ident : $ty:ty , $($tok:tt)* ) ) => {
- ( specs::ReadStorage<'a, $ty>, args_to_systemdata!( ( $( $tok )* ) ) )
- };
- ( ( mut $name:ident : $ty:ty , $( $tok:tt )* ) ) => {
- ( specs::WriteStorage<'a, $ty>, args_to_systemdata!( ( $( $tok )* ) ) )
- };
- ( ( resource $name:ident : $ty:ty , $( $tok:tt )* ) ) => {
- ( specs::ReadExpect<'a, $ty>, args_to_systemdata!( ( $( $tok )* ) ) )
- };
- ( ( resource mut $name:ident : $ty:ty , $( $tok:tt )* ) ) => {
- ( specs::WriteExpect<'a, $ty>, args_to_systemdata!( ( $( $tok )* ) ) )
- };
- }
- #[macro_export]
- macro_rules! args_to_fn_pat {
- ( ( $name:ident : $ty:ty $(,)? ) ) => {
- ( $name ,)
- };
- ( ( mut $name:ident : $ty:ty $(,)? ) ) => {
- ( mut $name ,)
- };
- ( ( resource $name:ident : $ty:ty $(,)? ) ) => {
- compile_error!("Resources cannot come at the end of the argument block.")
- };
- ( ( resource mut $name:ident : $ty:ty $(,)? ) ) => {
- compile_error!("Resources cannot come at the end of the argument block.")
- };
- ( ( $name:ident : $ty:ty , $($tok:tt)* ) ) => {
- ( $name, args_to_fn_pat!( ( $($tok)* ) ) )
- };
- ( ( mut $name:ident : $ty:ty , $($tok:tt)* ) ) => {
- ( mut $name, args_to_fn_pat!( ( $($tok)* ) ) )
- };
- ( ( resource $name:ident : $ty:ty , $($tok:tt)* ) ) => {
- ( $name, args_to_fn_pat!( ( $($tok)* ) ) )
- };
- ( ( resource mut $name:ident : $ty:ty , $($tok:tt)* ) ) => {
- ( mut $name, args_to_fn_pat!( ( $($tok)* ) ) )
- };
- }
- #[macro_export]
- macro_rules! args_to_join_pat {
- ( ( $name:ident : $ty:ty $(,)? ) ) => {
- ( $name ,)
- };
- ( ( mut $name:ident : $ty:ty $(,)? ) ) => {
- ( mut $name ,)
- };
- ( ( resource $name:ident : $ty:ty $(,)? ) ) => {
- compile_error!("Resources cannot come at the end of the argument block.")
- };
- ( ( resource mut $name:ident : $ty:ty $(,)? ) ) => {
- compile_error!("Resources cannot come at the end of the argument block.")
- };
- ( ( $name:ident : $ty:ty , $($tok:tt)* ) ) => {
- ( $name, args_to_join_pat!( ( $($tok)* ) ) )
- };
- ( ( mut $name:ident : $ty:ty , $($tok:tt)* ) ) => {
- ( mut $name, args_to_join_pat!( ( $($tok)* ) ) )
- };
- ( ( resource $name:ident : $ty:ty , $($tok:tt)* ) ) => {
- args_to_join_pat!( ( $($tok)* ) )
- };
- ( ( resource mut $name:ident : $ty:ty , $($tok:tt)* ) ) => {
- args_to_join_pat!( ( $($tok)* ) )
- };
- }
- #[macro_export]
- macro_rules! args_to_join {
- ( ( $name:ident : $ty:ty $(,)? ) ) => {
- ( & $name ,)
- };
- ( ( mut $name:ident : $ty:ty $(,)? ) ) => {
- ( &mut $name ,)
- };
- ( ( resource $name:ident : $ty:ty $(,)? ) ) => {
- compile_error!("Resources cannot come at the end of the argument block.")
- };
- ( ( resource mut $name:ident : $ty:ty $(,)? ) ) => {
- compile_error!("Resources cannot come at the end of the argument block.")
- };
- ( ( $name:ident : $ty:ty , $($tok:tt)* ) ) => {
- ( & $name, args_to_join!( ( $($tok)* ) ) )
- };
- ( ( mut $name:ident : $ty:ty , $($tok:tt)* ) ) => {
- ( &mut $name, args_to_join!( ( $($tok)* ) ) )
- };
- ( ( resource $name:ident : $ty:ty , $($tok:tt)* ) ) => {
- args_to_join!( ( $($tok)* ) )
- };
- ( ( resource mut $name:ident : $ty:ty , $($tok:tt)* ) ) => {
- args_to_join!( ( $($tok)* ) )
- };
- }
- #[cfg(test)]
- mod tests {
- use specs::join::Join;
- pub struct Pos {
- x: usize,
- }
- impl specs::Component for Pos {
- type Storage = specs::VecStorage<Pos>;
- }
- pub struct Mov;
- impl specs::Component for Mov {
- type Storage = specs::VecStorage<Mov>;
- }
- system! {
- Foo (_x: Mov, mut y: Pos) {
- y.x += 1;
- }
- }
- system_impl! {
- FooAlt (x: Mov, mut y: Pos) {
- for (_, mut y) in (&x, &mut y).join() {
- y.x += 1;
- }
- }
- }
- system! {
- Bar (_x: Mov, mut y: Pos) {
- y.x += 1;
- } finally {
- println!("Done!");
- }
- }
- system_impl! {
- BarAlt (x: Mov, mut y: Pos) {
- for (_, mut y) in (&x, &mut y).join() {
- y.x += 1;
- }
- println!("Done!");
- }
- }
- system! {
- Baz (resource n: usize, _x: Mov, mut y: Pos) {
- y.x += *n;
- }
- }
- system_impl! {
- BazAlt (resource n: usize, x: Mov, mut y: Pos) {
- for (_, mut y) in (&x, &mut y).join() {
- y.x += *n;
- }
- }
- }
- system! {
- Quux (resource mut n: usize, _x: Mov, mut y: Pos) {
- y.x += *n;
- *n += 1;
- } finally {
- *n += 1;
- }
- }
- system_impl! {
- QuuxAlt (resource mut n: usize, x: Mov, mut y: Pos) {
- for (_, mut y) in (&x, &mut y).join() {
- y.x += *n;
- }
- *n += 1;
- }
- }
- }
|