1use crate::{
24 core::{pool::Handle, reflect::prelude::*, visitor::prelude::*},
25 machine::{Parameter, ParameterContainer, State},
26 Animation, AnimationContainer, EntityId,
27};
28use fyrox_core::uuid::{uuid, Uuid};
29use fyrox_core::{NameProvider, TypeUuidProvider};
30use std::any::{type_name, Any, TypeId};
31use strum_macros::{AsRefStr, EnumString, VariantNames};
32
33macro_rules! define_two_args_node {
34 ($(#[$meta:meta])* $name:ident) => {
35 $(#[$meta])*
36 #[derive(Debug, Clone, PartialEq)]
37 pub struct $name <T:EntityId> {
38 pub lhs: Box<LogicNode<T>>,
40 pub rhs: Box<LogicNode<T>>,
42 }
43
44 impl<T:EntityId> Default for $name<T> {
45 fn default() -> Self {
46 Self {
47 lhs: Box::new(LogicNode::Parameter(Default::default())),
48 rhs: Box::new(LogicNode::Parameter(Default::default())),
49 }
50 }
51 }
52
53 impl<T:EntityId> Visit for $name<T> {
54 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
55 let mut guard = visitor.enter_region(name)?;
56
57 self.lhs.visit("Lhs", &mut guard)?;
58 self.rhs.visit("Rhs", &mut guard)?;
59
60 Ok(())
61 }
62 }
63
64 impl<T:EntityId> Reflect for $name<T> {
65 fn source_path() -> &'static str {
66 file!()
67 }
68
69 fn derived_types() -> &'static [TypeId] {
70 &[]
71 }
72
73 fn query_derived_types(&self) -> &'static [TypeId] {
74 Self::derived_types()
75 }
76
77 fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
78 Some(Box::new(self.clone()))
79 }
80
81 fn type_name(&self) -> &'static str {
82 type_name::<Self>()
83 }
84
85 fn doc(&self) -> &'static str {
86 ""
87 }
88
89 fn assembly_name(&self) -> &'static str {
90 env!("CARGO_PKG_NAME")
91 }
92
93 fn type_assembly_name() -> &'static str {
94 env!("CARGO_PKG_NAME")
95 }
96
97 fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
98 func(&[
99 {
100 static METADATA: FieldMetadata = FieldMetadata {
101 name: "Lhs",
102 display_name: "Lhs",
103 tag: "",
104 read_only: false,
105 immutable_collection: false,
106 min_value: None,
107 max_value: None,
108 step: None,
109 precision: None,
110 doc: "",
111 };
112
113 FieldRef {
114 metadata: &METADATA,
115 value: &*self.lhs,
116 }
117 },
118 {
119 static METADATA: FieldMetadata = FieldMetadata {
120 name: "Rhs",
121 display_name: "Rhs",
122 tag: "",
123 read_only: false,
124 immutable_collection: false,
125 min_value: None,
126 max_value: None,
127 step: None,
128 precision: None,doc: "",
129 };
130
131 FieldRef {
132 metadata: &METADATA,
133 value: &*self.rhs,
134 }
135 },
136 ])
137 }
138
139 fn fields_mut(&mut self, func: &mut dyn FnMut(&mut [FieldMut])) {
140 func(&mut [
141 {
142 static METADATA: FieldMetadata = FieldMetadata {
143 name: "Lhs",
144 display_name: "Lhs",
145 tag: "",
146 read_only: false,
147 immutable_collection: false,
148 min_value: None,
149 max_value: None,
150 step: None,
151 precision: None,
152 doc: "",
153 };
154
155 FieldMut {
156 metadata: &METADATA,
157 value: &mut *self.lhs,
158 }
159 },
160 {
161 static METADATA: FieldMetadata = FieldMetadata {
162 name: "Rhs",
163 display_name: "Rhs",
164 tag: "",
165 read_only: false,
166 immutable_collection: false,
167 min_value: None,
168 max_value: None,
169 step: None,
170 precision: None,doc: "",
171 };
172
173 FieldMut {
174 metadata: &METADATA,
175 value: &mut *self.rhs,
176 }
177 },
178 ])
179 }
180
181
182 fn into_any(self: Box<Self>) -> Box<dyn Any> {
183 self
184 }
185
186 fn as_any(&self, func: &mut dyn FnMut(&dyn ::core::any::Any)) {
187 func(self)
188 }
189
190 fn as_any_mut(&mut self, func: &mut dyn FnMut(&mut dyn ::core::any::Any)) {
191 func(self)
192 }
193
194 fn as_reflect(&self, func: &mut dyn FnMut(&dyn Reflect)) {
195 func(self)
196 }
197
198 fn as_reflect_mut(&mut self, func: &mut dyn FnMut(&mut dyn Reflect)) {
199 func(self)
200 }
201
202 fn set(
203 &mut self,
204 value: Box<dyn Reflect>,
205 ) -> Result<Box<dyn Reflect>, Box<dyn Reflect>> {
206 let this = std::mem::replace(self, value.take()?);
207 Ok(Box::new(this))
208 }
209 }
210 };
211}
212
213define_two_args_node!(
214 AndNode
216);
217define_two_args_node!(
218 OrNode
220);
221define_two_args_node!(
222 XorNode
224);
225
226#[derive(Debug, Clone, PartialEq)]
228pub struct NotNode<T: EntityId> {
229 pub lhs: Box<LogicNode<T>>,
231}
232
233impl<T: EntityId> Default for NotNode<T> {
234 fn default() -> Self {
235 Self {
236 lhs: Box::new(LogicNode::Parameter(Default::default())),
237 }
238 }
239}
240
241impl<T: EntityId> Visit for NotNode<T> {
242 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
243 let mut guard = visitor.enter_region(name)?;
244
245 self.lhs.visit("Lhs", &mut guard)?;
246
247 Ok(())
248 }
249}
250
251impl<T: EntityId> Reflect for NotNode<T> {
252 fn source_path() -> &'static str {
253 file!()
254 }
255
256 fn derived_types() -> &'static [TypeId] {
257 &[]
258 }
259
260 fn query_derived_types(&self) -> &'static [TypeId] {
261 Self::derived_types()
262 }
263
264 fn type_name(&self) -> &'static str {
265 type_name::<Self>()
266 }
267
268 fn doc(&self) -> &'static str {
269 ""
270 }
271
272 fn assembly_name(&self) -> &'static str {
273 env!("CARGO_PKG_NAME")
274 }
275
276 fn type_assembly_name() -> &'static str {
277 env!("CARGO_PKG_NAME")
278 }
279
280 fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
281 func(&[{
282 static METADATA: FieldMetadata = FieldMetadata {
283 name: "Lhs",
284 display_name: "Lhs",
285 tag: "",
286 read_only: false,
287 immutable_collection: false,
288 min_value: None,
289 max_value: None,
290 step: None,
291 precision: None,
292 doc: "",
293 };
294
295 FieldRef {
296 metadata: &METADATA,
297 value: &*self.lhs,
298 }
299 }])
300 }
301
302 fn fields_mut(&mut self, func: &mut dyn FnMut(&mut [FieldMut])) {
303 func(&mut [{
304 static METADATA: FieldMetadata = FieldMetadata {
305 name: "Lhs",
306 display_name: "Lhs",
307 tag: "",
308 read_only: false,
309 immutable_collection: false,
310 min_value: None,
311 max_value: None,
312 step: None,
313 precision: None,
314 doc: "",
315 };
316
317 FieldMut {
318 metadata: &METADATA,
319 value: &mut *self.lhs,
320 }
321 }])
322 }
323
324 fn into_any(self: Box<Self>) -> Box<dyn Any> {
325 self
326 }
327
328 fn as_any(&self, func: &mut dyn FnMut(&dyn ::core::any::Any)) {
329 func(self)
330 }
331
332 fn as_any_mut(&mut self, func: &mut dyn FnMut(&mut dyn ::core::any::Any)) {
333 func(self)
334 }
335
336 fn as_reflect(&self, func: &mut dyn FnMut(&dyn Reflect)) {
337 func(self)
338 }
339
340 fn as_reflect_mut(&mut self, func: &mut dyn FnMut(&mut dyn Reflect)) {
341 func(self)
342 }
343
344 fn set(&mut self, value: Box<dyn Reflect>) -> Result<Box<dyn Reflect>, Box<dyn Reflect>> {
345 let this = std::mem::replace(self, value.take()?);
346 Ok(Box::new(this))
347 }
348
349 fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
350 Some(Box::new(self.clone()))
351 }
352}
353
354#[derive(Debug, Visit, Clone, Reflect, PartialEq, AsRefStr, EnumString, VariantNames)]
381pub enum LogicNode<T: EntityId> {
382 Parameter(String),
384 And(AndNode<T>),
386 Or(OrNode<T>),
388 Xor(XorNode<T>),
390 Not(NotNode<T>),
392 IsAnimationEnded(Handle<Animation<T>>),
394}
395
396impl<T: EntityId> TypeUuidProvider for LogicNode<T> {
397 fn type_uuid() -> Uuid {
398 uuid!("98a5b767-5560-4ed7-ad40-1625a8868e39")
399 }
400}
401
402impl<T: EntityId> Default for LogicNode<T> {
403 fn default() -> Self {
404 Self::Parameter(Default::default())
405 }
406}
407
408impl<T: EntityId> LogicNode<T> {
409 pub fn calculate_value(
411 &self,
412 parameters: &ParameterContainer,
413 animations: &AnimationContainer<T>,
414 ) -> bool {
415 match self {
416 LogicNode::Parameter(rule_name) => parameters.get(rule_name).is_some_and(|p| {
417 if let Parameter::Rule(rule_value) = p {
418 *rule_value
419 } else {
420 false
421 }
422 }),
423 LogicNode::And(and) => {
424 let lhs_value = and.lhs.calculate_value(parameters, animations);
425 let rhs_value = and.rhs.calculate_value(parameters, animations);
426 lhs_value & rhs_value
427 }
428 LogicNode::Or(or) => {
429 let lhs_value = or.lhs.calculate_value(parameters, animations);
430 let rhs_value = or.rhs.calculate_value(parameters, animations);
431 lhs_value | rhs_value
432 }
433 LogicNode::Xor(or) => {
434 let lhs_value = or.lhs.calculate_value(parameters, animations);
435 let rhs_value = or.rhs.calculate_value(parameters, animations);
436 lhs_value ^ rhs_value
437 }
438 LogicNode::Not(node) => !node.lhs.calculate_value(parameters, animations),
439 LogicNode::IsAnimationEnded(animation) => animations
440 .try_get(*animation)
441 .ok()
442 .is_none_or(|a| a.has_ended()),
443 }
444 }
445}
446
447#[derive(Default, Debug, Clone, Reflect, PartialEq)]
449pub struct Transition<T: EntityId> {
450 pub(crate) name: String,
452
453 pub(crate) transition_time: f32,
455
456 pub(crate) elapsed_time: f32,
457
458 #[reflect(read_only)]
459 pub(crate) source: Handle<State<T>>,
460
461 #[reflect(read_only)]
462 pub(crate) dest: Handle<State<T>>,
463
464 pub(crate) condition: LogicNode<T>,
466
467 pub(crate) blend_factor: f32,
469}
470
471impl<T: EntityId> Visit for Transition<T> {
472 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
473 let mut guard = visitor.enter_region(name)?;
474
475 self.name.visit("Name", &mut guard)?;
476 self.transition_time.visit("TransitionTime", &mut guard)?;
477 self.source.visit("Source", &mut guard)?;
478 self.dest.visit("Dest", &mut guard)?;
479 self.blend_factor.visit("BlendFactor", &mut guard)?;
480
481 if guard.is_reading() {
482 if self.condition.visit("Condition", &mut guard).is_err() {
483 let mut invert_rule = false;
485 let mut rule: String = Default::default();
486
487 invert_rule.visit("InvertRule", &mut guard)?;
488 rule.visit("Rule", &mut guard)?;
489
490 if invert_rule {
491 self.condition = LogicNode::Not(NotNode {
492 lhs: Box::new(LogicNode::Parameter(rule)),
493 });
494 } else {
495 self.condition = LogicNode::Parameter(rule);
496 }
497 }
498 } else {
499 self.condition.visit("Condition", &mut guard)?;
500 }
501
502 Ok(())
503 }
504}
505
506impl<T: EntityId> NameProvider for Transition<T> {
507 fn name(&self) -> &str {
508 &self.name
509 }
510}
511
512impl<T: EntityId> Transition<T> {
513 pub fn new(
516 name: &str,
517 src: Handle<State<T>>,
518 dest: Handle<State<T>>,
519 time: f32,
520 rule: &str,
521 ) -> Transition<T> {
522 Self {
523 name: name.to_owned(),
524 transition_time: time,
525 elapsed_time: 0.0,
526 source: src,
527 dest,
528 blend_factor: 0.0,
529 condition: LogicNode::Parameter(rule.to_owned()),
530 }
531 }
532
533 #[inline]
535 pub fn name(&self) -> &str {
536 self.name.as_str()
537 }
538
539 #[inline]
541 pub fn transition_time(&self) -> f32 {
542 self.transition_time
543 }
544
545 #[inline]
547 pub fn source(&self) -> Handle<State<T>> {
548 self.source
549 }
550
551 #[inline]
553 pub fn dest(&self) -> Handle<State<T>> {
554 self.dest
555 }
556
557 pub fn set_condition(&mut self, condition: LogicNode<T>) {
559 self.condition = condition;
560 }
561
562 pub fn condition(&self) -> &LogicNode<T> {
564 &self.condition
565 }
566
567 #[inline]
569 pub fn is_done(&self) -> bool {
570 (self.transition_time - self.elapsed_time).abs() <= f32::EPSILON
571 }
572
573 #[inline]
575 pub fn blend_factor(&self) -> f32 {
576 self.blend_factor
577 }
578
579 pub(super) fn reset(&mut self) {
580 self.elapsed_time = 0.0;
581 self.blend_factor = 0.0;
582 }
583
584 pub(super) fn update(&mut self, dt: f32) {
585 self.elapsed_time += dt;
586 if self.elapsed_time > self.transition_time {
587 self.elapsed_time = self.transition_time;
588 }
589 self.blend_factor = self.elapsed_time / self.transition_time;
590 }
591}