nightshade 0.14.0

A cross-platform data-oriented game engine.
Documentation
//! Helpers that reduce the ceremony of adding a new widget kind.
//!
//! The retained UI registers each widget kind across roughly seven sites
//! (component struct in components, freecs ecs! macro registration in world.rs,
//! WidgetData impl, query loop in widget_systems.rs, handler module, builder
//! method, scope wrapper, optional UiEvent variant). The macros below batch
//! the data definition pieces so adding a new widget is closer to two sites
//! (the macro invocation and the handler).
//!
//! The freecs ecs! macro and the widget_systems.rs dispatch loops still need
//! manual registration, but those are mechanical edits in fixed locations.

/// Defines a widget data struct with `Default`, `Clone`, `Debug` derived and
/// a [`WidgetData`](crate::ecs::ui::components::WidgetData) impl, removing the
/// `impl_widget_data!` line that would otherwise be needed.
///
/// Usage:
/// ```ignore
/// widget_data! {
///     UiFooData {
///         pub bar: f32,
///         pub baz: bool,
///     }
///     get: get_ui_foo,
///     get_mut: get_ui_foo_mut,
///     set: set_ui_foo,
/// }
/// ```
///
/// You still need to add a corresponding line to the `freecs::ecs!` macro in
/// `crates/nightshade/src/ecs/world.rs` like:
/// `ui_foo: crate::ecs::ui::components::UiFooData => UI_FOO,`
#[macro_export]
macro_rules! widget_data {
    (
        $name:ident {
            $($(#[$field_attr:meta])* $vis:vis $field:ident : $field_ty:ty),* $(,)?
        }
        get: $get:ident,
        get_mut: $get_mut:ident,
        set: $set:ident,
    ) => {
        #[derive(Clone, Debug, Default)]
        pub struct $name {
            $($(#[$field_attr])* $vis $field : $field_ty,)*
        }

        impl $crate::ecs::ui::components::WidgetData for $name {
            fn get(world: &$crate::ecs::world::World, entity: freecs::Entity) -> Option<&Self> {
                world.ui.$get(entity)
            }
            fn get_mut(
                world: &mut $crate::ecs::world::World,
                entity: freecs::Entity,
            ) -> Option<&mut Self> {
                world.ui.$get_mut(entity)
            }
            fn set(world: &mut $crate::ecs::world::World, entity: freecs::Entity, data: Self) {
                world.ui.$set(entity, data);
            }
        }
    };
}