aframe/entity/mod.rs
1//! Module for the instantiaion of entities and primitives.
2
3pub mod primitive;
4
5use std::borrow::Cow;
6use crate::{Attribute, ComponentVec, component::Component};
7
8/// Defines the high-level API for describing entities, with one form for
9/// describing general entities and another for defining specific primitives.
10
11/// Here's an example of a general entity definition:
12/// ```ignore
13/// entity!
14/// {
15/// attributes: ("id", "cube-rig"),
16/// components:
17/// ("position", component::Position{x: 0.0, y: 2.5, z: -2.0}),
18/// ("sound", component!
19/// {
20/// component::Sound,
21/// src: Cow::Borrowed("#ambient_music"),
22/// volume: 0.5
23/// }),
24/// ("play-sound-on-event", component!
25/// {
26/// component::PlaySoundOnEvent,
27/// mode: component::PlaySoundOnEventMode::ToggleStop,
28/// event: Cow::Borrowed("click")
29/// }),
30/// ("light", component!
31/// {
32/// component::Light,
33/// light_type: component::LightType::Point
34/// {
35/// decay: 1.0,
36/// distance: 50.0,
37/// shadow: component::OptionalLocalShadow::NoCast{},
38/// },
39/// intensity: 0.0
40/// }),
41/// ("animation__mouseenter", component!
42/// {
43/// component::Animation,
44/// property: Cow::Borrowed("light.intensity"),
45/// to: Cow::Borrowed("1.0"),
46/// start_events: component::List(Cow::Borrowed(&[Cow::Borrowed("mouseenter")])),
47/// dur: 250
48/// }),
49/// ("animation__mouseleave", component!
50/// {
51/// component::Animation,
52/// property: Cow::Borrowed("light.intensity"),
53/// to: Cow::Borrowed("0.0"),
54/// start_events: component::List(Cow::Borrowed(&[Cow::Borrowed("mouseleave")])),
55/// dur: 250
56/// }),
57/// children: entity!
58/// {
59/// primitive: primitive::A_BOX,
60/// attributes: ("id", "my-box"),
61/// components:
62/// }
63/// },
64/// ```
65/// and here's an example of a primitive definition:
66/// ```ignore
67/// entity!
68/// {
69/// // This can also jsut a be a string: "a-box"
70/// primitive: primitive::A_BOX,
71/// attributes: ("id", "my-box"),
72/// components:
73/// }
74/// ```
75#[macro_export]
76macro_rules! entity
77{
78 (
79 $(attributes: $(($attr_id:literal, $attr_value:expr)),*)? $(,)?
80 $(components: $(($cmp_id:literal, $cmp_value:expr)),*)? $(,)?
81 $(children: $($child:expr),*)?
82 ) =>
83 {
84 Entity::new
85 (
86 attributes_vec!
87 {
88 $($(($attr_id, $attr_value)),*)?
89 },
90 components_vec!
91 {
92 $($(($cmp_id, $cmp_value)),*)?
93 },
94 vec!
95 {
96 $($($child),*)?
97 }
98 )
99 };
100 (
101 primitive: $name:expr,
102 $(attributes: $(($attr_id:literal, $attr_value:expr)),*)? $(,)?
103 $(components: $(($cmp_id:literal, $cmp_value:expr)),*)? $(,)?
104 $(children: $($child:expr),*)?
105 ) =>
106 {
107 Entity::new_primitive
108 (
109 std::borrow::Cow::Borrowed($name),
110 attributes_vec!
111 {
112 $($(($attr_id, $attr_value)),*)?
113 },
114 components_vec!
115 {
116 $($(($cmp_id, $cmp_value)),*)?
117 },
118 vec!
119 {
120 $($($child),*)?
121 }
122 )
123 }
124}
125
126/// Mid-level macro to create a vector of attributes
127#[macro_export]
128macro_rules! attributes_vec
129{
130 (
131 $(($attr_id:literal, $attr_value:expr)),*
132 ) =>
133 {
134 vec![ $(Attribute::new($attr_id, $attr_value)),* ]
135 }
136}
137
138/// Mid-level macro to create a vector of components
139#[macro_export]
140macro_rules! components_vec
141{
142 (
143 $(($cmp_id:literal, $cmp_value:expr)),*
144 ) =>
145 {
146 vec![ $(($cmp_id.into(), Box::new($cmp_value))),* ]
147 }
148}
149
150/// Struct which represents an Aframe entity or primitive
151#[derive(Default, Debug, Clone, PartialEq)]
152pub struct Entity
153{
154 primitive: Option<Cow<'static, str>>,
155 attributes: Vec<Attribute>,
156 components: ComponentVec,
157 children: Vec<Entity>
158}
159
160impl Entity
161{
162 pub fn new(attributes: Vec<Attribute>, components: Vec<(Cow<'static, str>, Box<dyn Component>)>, children: Vec<Entity>) -> Self
163 {
164 Self { primitive: None, attributes, components: ComponentVec(components), children }
165 }
166
167 pub fn new_primitive(tag: Cow<'static, str>, attributes: Vec<Attribute>, components: Vec<(Cow<'static, str>, Box<dyn Component>)>, children: Vec<Entity>) -> Self
168 {
169 Self { primitive: Some(tag), attributes, components: ComponentVec(components), children }
170 }
171
172 pub fn with_components(components: Vec<(Cow<'static, str>, Box<dyn Component>)>) -> Self
173 {
174 Self { primitive: None, attributes: vec!(), components: ComponentVec(components), children: vec!() }
175 }
176
177 pub fn attributes(&self) -> &Vec<Attribute>
178 {
179 &self.attributes
180 }
181
182 pub fn attributes_mut(&mut self) -> &mut Vec<Attribute>
183 {
184 &mut self.attributes
185 }
186
187 pub fn components(&self) -> &Vec<(Cow<'static, str>, Box<dyn Component>)>
188 {
189 &self.components
190 }
191
192 pub fn components_mut(&mut self) -> &mut Vec<(Cow<'static, str>, Box<dyn Component>)>
193 {
194 &mut self.components
195 }
196
197 pub fn children(&self) -> &Vec<Entity>
198 {
199 &self.children
200 }
201
202 pub fn children_mut(&mut self) -> &mut Vec<Entity>
203 {
204 &mut self.children
205 }
206
207 pub fn tag(&self) -> Cow<'static, str>
208 {
209 match self.primitive
210 {
211 Some(ref tag) => tag.clone(),
212 None => self.tag().into()
213 }
214 }
215}