sketchbook 0.0.2

Interactive visual applications in Rust
Documentation
/// Macro to create environment for testing a single aspect.
///
/// ```
/// use sketchbook::aspects::update;
///
/// use sketchbook::derive_sketch;
/// use macro_rules_attribute::apply;
/// use sketchbook::aspects::update::SketchExt;
/// mod single_aspect {
///     use sketchbook::aspects::update;
///     use sketchbook::aspects::update::*;
///     
///     sketchbook::env_for_aspect!(update);
///
///     sketchbook::compose! {
///         pub enum Events {
///             #[part]
///             Aspect(update::Event),
///         }
///     }
///
///     sketchbook::compose! {
///         #[derive(Default)]
///         pub struct Page {
///             #[part]
///             pub aspect: update::EnvData<EnvSpecificMarker>,
///         }
///     }
///
///     impl update::EnvSpecific for EnvSpecificMarker {
///         type Time = i16;
///         type Duration = i16;
///         type Num = f32;
///
///         fn default_update_rate() -> Self::Num {
///             30.0
///         }
///
///         fn zero_duration() -> Self::Duration {
///             0
///         }
///
///         fn duration_between(start: &Self::Time, end: &Self::Time) -> Self::Duration {
///             end - start
///         }
///     }
///
///     impl update::EnvPageExt<EnvSpecificMarker> for Page {
///         fn get_time(&mut self) -> update::TimeFor<EnvSpecificMarker> {
///             0
///         }
///     }
/// }
///
/// #[apply(derive_sketch)]
/// #[sketch(env=single_aspect, aspects=(update))]
/// struct App {
///     #[page]
///     page: single_aspect::Page,
/// }
///
/// impl update::Handlers for App {
///     fn update(&mut self, delta_t: i16) {
///         println!("Update state, time since last update: {}", delta_t);
///     }
/// }
/// ```
#[cfg(feature = "env-aspect-test")]
#[cfg_attr(docsrs, doc(cfg(feature = "env-aspect-test")))]
#[macro_export]
macro_rules! env_for_aspect {
    {
        $aspect:ident
    } => {
        pub struct Mill;

        pub struct Env(());

        pub struct EnvSpecificMarker;

        #[allow(unused_qualifications)]
        impl $aspect::AssociatedEnvSpecificMarker for Env {
            type EnvSpecificMarker = EnvSpecificMarker;
        }

        impl $crate::Environment for Env {
            type Mill = Mill;

            type Return = ();

            fn run<F, E>(self, _func: F)
            where
                F: FnMut(&mut Self::Mill) -> Result<$crate::Status, E>,
            {
                panic!("A single aspect environment does not allow running.")
            }
        }

        impl $crate::Mill for Mill {
            type Page = Page;

            fn new_page(&mut self) -> Self::Page {
                Page::default()
            }
        }

        impl $crate::Page for Page {
            type Event = Events;

            fn start_group(&mut self) {}

            fn end_group(&mut self) {}

            fn next_event_in_group(&mut self) -> Option<Self::Event> {
                None
            }

            fn before_event(&mut self, _event: &Self::Event) {}

            fn finish_event(&mut self, _event: Self::Event) {}

            fn status(&self) -> $crate::Status {
                $crate::Status::Stop
            }
        }
    };
}

#[cfg(feature = "env-aspect-test")]
pub use env_for_aspect;