photonic_effects/attrs/
switch.rs1use anyhow::Result;
2
3use photonic::attr::{Bounded, Bounds};
4use photonic::{scene, Attr, AttrBuilder, AttrValue, BoundAttrDecl, FreeAttrDecl};
5
6pub struct SwitchAttr<V, I>
7where
8 V: AttrValue,
9 I: Attr<bool>,
10{
11 value_released: V,
12 value_pressed: V,
13
14 pressed: I,
15}
16
17impl<V, I> Attr<V> for SwitchAttr<V, I>
18where
19 V: AttrValue,
20 I: Attr<bool>,
21{
22 fn update(&mut self, ctx: &scene::RenderContext) -> V {
23 let pressed = self.pressed.update(ctx);
24 return match pressed {
25 true => self.value_pressed,
26 false => self.value_released,
27 };
28 }
29}
30
31pub struct Switch<V, I>
32where V: AttrValue
33{
34 pub value_release: V,
35 pub value_pressed: V,
36
37 pub pressed: I,
38}
39
40impl<V, I> BoundAttrDecl<V> for Switch<V, I>
41where
42 V: AttrValue + Bounded,
43 I: FreeAttrDecl<bool>,
44{
45 const KIND: &'static str = "button";
46
47 type Attr = SwitchAttr<V, I::Attr>;
48
49 fn materialize(self, bounds: Bounds<V>, builder: &mut AttrBuilder) -> Result<Self::Attr> {
50 return Ok(SwitchAttr {
51 value_released: bounds.ensure(self.value_release)?,
52 value_pressed: bounds.ensure(self.value_pressed)?,
53 pressed: builder.unbound_attr("pressed", self.pressed)?,
54 });
55 }
56}
57
58impl<V, I> FreeAttrDecl<V> for Switch<V, I>
59where
60 V: AttrValue,
61 I: FreeAttrDecl<bool>,
62{
63 const KIND: &'static str = "button";
64
65 type Attr = SwitchAttr<V, I::Attr>;
66
67 fn materialize(self, builder: &mut AttrBuilder) -> Result<Self::Attr> {
68 return Ok(SwitchAttr {
69 value_released: self.value_release,
70 value_pressed: self.value_pressed,
71 pressed: builder.unbound_attr("input", self.pressed)?,
72 });
73 }
74}
75
76#[cfg(feature = "dynamic")]
77pub mod dynamic {
78 use serde::de::DeserializeOwned;
79 use serde::Deserialize;
80
81 use photonic::boxed::{BoxedFreeAttrDecl, DynBoundAttrDecl, DynFreeAttrDecl};
82 use photonic_dynamic::factory::Producible;
83 use photonic_dynamic::registry::Registry;
84 use photonic_dynamic::{builder, config};
85
86 use super::*;
87
88 #[derive(Deserialize, Debug)]
89 pub struct Config<V: AttrValue> {
90 #[serde(bound(deserialize = "V: Deserialize<'de>"))]
91 pub value_release: V,
92 #[serde(bound(deserialize = "V: Deserialize<'de>"))]
93 pub value_pressed: V,
94
95 pub pressed: config::Attr<bool>,
96 }
97
98 impl<V> Producible<dyn DynFreeAttrDecl<V>> for Config<V>
99 where V: AttrValue + DeserializeOwned
100 {
101 type Product = Switch<V, BoxedFreeAttrDecl<bool>>;
102
103 fn produce<Reg: Registry>(config: Self, mut builder: builder::AttrBuilder<'_, Reg>) -> Result<Self::Product> {
104 return Ok(Switch {
105 value_release: config.value_release,
106 value_pressed: config.value_pressed,
107 pressed: builder.free_attr("pressed", config.pressed)?,
108 });
109 }
110 }
111
112 impl<V> Producible<dyn DynBoundAttrDecl<V>> for Config<V>
113 where V: AttrValue + DeserializeOwned + Bounded
114 {
115 type Product = Switch<V, BoxedFreeAttrDecl<bool>>;
116
117 fn produce<Reg: Registry>(config: Self, mut builder: builder::AttrBuilder<'_, Reg>) -> Result<Self::Product> {
118 return Ok(Switch {
119 value_release: config.value_release,
120 value_pressed: config.value_pressed,
121 pressed: builder.free_attr("pressed", config.pressed)?,
122 });
123 }
124 }
125}