#!#[rustfmt::skip]
#![allow(unused_variables)]
use std::marker::PhantomData;
use constructivism::*;
#[derive(Construct)]
pub struct Node {
hidden: bool,
position: (f32, f32),
}
pub struct TypeRef<C: Construct + 'static>(PhantomData<C>);
pub fn construct_node<F, P, const I: u8>(func: F) -> <<Node as Construct>::NestedSequence as Flattern>::Output
where
P: ExtractParams<
I, <Node as Construct>::MixedParams,
Value = <<Node as Construct>::MixedParams as Extractable>::Output,
Rest = <<<<Node as Construct>::Base as Construct>::ExpandedParams as Extractable>::Input as AsParams>::Defined
>,
F: FnOnce(
&<Node as Construct>::Params,
<<<Node as Construct>::ExpandedParams as Extractable>::Input as AsParams>::Undefined
) -> P
{
construct_inferred::<Node, F, P, I>(func)
}
fn construct_inferred<C: Construct + 'static, F, P, const I: u8>(func: F) -> <C::NestedSequence as Flattern>::Output
where
P: ExtractParams<
I, C::MixedParams,
Value = <C::MixedParams as Extractable>::Output,
Rest = <<<C::Base as Construct>::ExpandedParams as Extractable>::Input as AsParams>::Defined
>,
F: FnOnce(
&<C as Construct>::Params,
<<<C as Construct>::ExpandedParams as Extractable>::Input as AsParams>::Undefined
) -> P
{
let fields = <<C as Construct>::Params as Singleton>::instance();
let params = <<C as Construct>::ExpandedParams as Extractable>::as_params();
let defined = func(fields, params);
<C as Construct>::construct(defined).flattern()
}
fn create_node() {
let node = construct_node(|fields, params| {
let param: &::constructivism::Param<_, _> = &fields.position;
let field = param.field();
let value = params
.field(&field)
.define(param.value(((10., 10.)).into()));
let params = params + value;
let param: &::constructivism::Param<_, _> = &fields.hidden;
let field = param.field();
let value = params.field(&field).define(param.value((true).into()));
let params = params + value;
params.defined()
});
assert_eq!(node.position.0, 10.);
assert_eq!(node.hidden, true);
}
#[derive(Construct)]
#[construct(Rect -> Node)]
pub struct Rect {
size: (f32, f32),
}
fn create_sequence() {
let (rect, node ) = construct!(Rect {
.hidden, .position: (10., 10.),
.size: (10., 10.),
});
assert_eq!(rect.size.0, 10.);
assert_eq!(node.position.1, 10.);
assert_eq!(node.hidden, true);
}
#[derive(Construct)]
#[construct(Follow -> Node)]
pub struct Follow {
offset: (f32, f32),
#[param(required)] target: Entity,
#[param(default = Anchor::Center)] anchor: Anchor,
#[param(skip)] last_computed_distance: f32,
#[param(skip = FollowState::None)] state: FollowState,
}
#[derive(PartialEq, Debug, Copy, Clone)]
pub struct Entity;
pub enum Anchor {
Left,
Center,
Right,
}
pub enum FollowState {
None,
Initialized(f32),
}
fn create_elements() {
let (rect, node ) = construct!(Rect);
assert_eq!(node.hidden, false);
assert_eq!(rect.size.0, 0.);
let (follow, node) = construct!(Follow {
.target: Entity
});
assert_eq!(follow.offset.0, 0.);
assert_eq!(node.hidden, false);
let (follow, node) = construct!(Follow {
.hidden,
.target: Entity,
.offset: (10., 10.),
});
assert_eq!(follow.offset.0, 10.);
assert_eq!(node.hidden, true);
}
impl NodeDesign {
pub fn move_to(&self, entity: Entity, position: (f32, f32)) {}
}
impl RectDesign {
pub fn expand_to(&self, entity: Entity, size: (f32, f32)) {}
}
fn use_design() {
let rect_entity = Entity;
design!(Rect).expand_to(rect_entity, (10., 10.));
design!(Rect).move_to(rect_entity, (10., 10.)); }
#[derive(Segment)]
pub struct Input {
disabled: bool,
}
#[derive(Construct)]
#[construct(Button -> Input -> Rect)]
pub struct Button {
pressed: bool,
}
fn create_button() {
let (button, input, rect, node) = construct!(Button {
.disabled: true,
});
assert_eq!(button.pressed, false);
assert_eq!(input.disabled, true);
assert_eq!(rect.size.0, 0.);
assert_eq!(node.position.0, 0.);
}
impl<T> InputDesign<T> {
fn focus(&self, entity: Entity) {
}
}
fn focus_button() {
let btn = Entity;
design!(Button).focus(btn);
}
fn button_props() {
let (mut button, mut input, mut rect, mut node) = construct!(Button);
let pos = prop!(Button.position);
let size = prop!(Button.size);
let disabled = prop!(Button.disabled);
let pressed = prop!(Button.pressed);
let x = pos.get(&node).as_ref().0;
let w = size.get(&rect).as_ref().0;
let is_disabled = *disabled.get(&input).as_ref();
let is_pressed = *pressed.get(&button).as_ref();
assert_eq!(0., x);
assert_eq!(0., w);
assert_eq!(false, is_disabled);
assert_eq!(false, is_pressed);
pos.set(&mut node, (1., 1.));
size.set(&mut rect, (10., 10.));
disabled.set(&mut input, true);
pressed.set(&mut button, true);
assert_eq!(node.position.0, 1.);
assert_eq!(rect.size.0, 10.);
assert_eq!(input.disabled, true);
assert_eq!(button.pressed, true);
}
#[derive(Construct, Default)]
pub struct Vec2 {
x: f32,
y: f32,
}
#[derive(Construct)]
pub struct Node2d {
#[prop(construct)] position: Vec2,
}
fn modify_position_x() {
let mut node = construct!(Node2d);
assert_eq!(node.position.x, 0.);
assert_eq!(node.position.y, 0.);
let x = prop!(Node2d.position.x);
x.set(&mut node, 100.);
assert_eq!(node.position.x, 100.);
assert_eq!(node.position.y, 0.);
}
pub struct ProgressBar {
min: f32,
val: f32,
max: f32,
}
impl ProgressBar {
pub fn min(&self) -> f32 {
self.min
}
pub fn set_min(&mut self, min: f32) {
self.min = min;
if self.max < min {
self.max = min;
}
if self.val < min {
self.val = min;
}
}
pub fn max(&self) -> f32 {
self.max
}
pub fn set_max(&mut self, max: f32) {
self.max = max;
if self.min > max {
self.min = max;
}
if self.val > max {
self.val = max;
}
}
pub fn val(&self) -> f32 {
self.val
}
pub fn set_val(&mut self, val: f32) {
self.val = val.max(self.min).min(self.max)
}
}
derive_construct! {
seq => ProgressBar -> Rect;
construct => (min: f32 = 0., max: f32 = 1., val: f32 = 0.) -> {
if max < min {
max = min;
}
val = val.min(max).max(min);
Self { min, val, max }
};
props => {
min: f32 = [min, set_min];
max: f32 = [max, set_max];
val: f32 = [val, set_val];
};
}
fn create_progress_bar() {
let (pb, _, _) = construct!(ProgressBar { .val: 100. });
assert_eq!(pb.min, 0.);
assert_eq!(pb.max, 1.);
assert_eq!(pb.val, 1.);
}
fn modify_progress_bar() {
let (mut pb, _, _) = construct!(ProgressBar);
let min = prop!(ProgressBar.min);
let val = prop!(ProgressBar.val);
let max = prop!(ProgressBar.max);
assert_eq!(pb.val, 0.);
val.set(&mut pb, 2.);
assert_eq!(pb.val, 1.0);
min.set(&mut pb, 5.);
max.set(&mut pb, 10.);
assert_eq!(pb.min, 5.);
assert_eq!(pb.val, 5.);
assert_eq!(pb.max, 10.);
}
pub struct Range {
min: f32,
max: f32,
val: f32,
}
derive_segment! {
seg => Range;
construct => (min: f32 = 0., max: f32 = 1., val: f32 = 0.) -> {
if max < min {
max = min;
}
val = val.min(max).max(min);
Self { min, val, max }
};
props => {
min: f32 = value;
max: f32 = value;
val: f32 = value;
};
}
#[derive(Construct)]
#[construct(Slider -> Range -> Rect)]
pub struct Slider;
fn create_slider() {
let (slider, range, _, _) = construct!(Slider {
.val: 10.
});
assert_eq!(range.min, 0.0);
assert_eq!(range.max, 1.0);
assert_eq!(range.val, 1.0);
}
fn main() {
create_node();
create_elements();
create_sequence();
use_design();
create_button();
button_props();
modify_position_x();
focus_button();
create_progress_bar();
modify_progress_bar();
create_slider();
}