bevy_stat_query/
operations.rs

1use bevy_reflect::TypePath;
2use serde::{Deserialize, Serialize};
3
4/// An single step unordered operation on a [`StatValue`].
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Serialize, Deserialize)]
6pub enum StatOperation<S: StatValue> {
7    Add(S::Add),
8    Mul(S::Mul),
9    Or(S::Bit),
10    Min(S::Bounds),
11    Max(S::Bounds),
12    Base(S::Base),
13}
14
15pub use StatOperation::*;
16
17use crate::Shareable;
18
19impl<S: StatValue> StatOperation<S> {
20    pub fn write_to(&self, to: &mut S) {
21        match self.clone() {
22            StatOperation::Add(item) => to.add(item),
23            StatOperation::Mul(item) => to.mul(item),
24            StatOperation::Or(item) => to.or(item),
25            StatOperation::Min(item) => to.min(item),
26            StatOperation::Max(item) => to.max(item),
27            StatOperation::Base(item) => *to = S::from_base(item),
28        }
29    }
30
31    pub fn into_stat(self) -> S {
32        let mut v = S::default();
33        self.write_to(&mut v);
34        v
35    }
36}
37
38/// A never type indicating an operation is not supported.
39#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, TypePath, Serialize, Deserialize)]
40pub enum Unsupported {}
41
42/// Defines unordered operations on a stat's value.
43#[allow(unused_variables)]
44pub trait StatValue: Shareable + Default {
45    type Out: Shareable + Default;
46
47    fn join(&mut self, other: Self);
48
49    fn join_by_ref(&mut self, other: &Self) {
50        self.join(other.clone())
51    }
52
53    fn eval(&self) -> Self::Out;
54
55    type Add: Shareable;
56    type Mul: Shareable;
57    type Bit: Shareable;
58    type Bounds: Shareable;
59    type Base: Shareable;
60
61    fn add(&mut self, other: Self::Add) {}
62    fn mul(&mut self, other: Self::Mul) {}
63    fn or(&mut self, other: Self::Bit) {}
64
65    fn min(&mut self, other: Self::Bounds) {}
66    fn max(&mut self, other: Self::Bounds) {}
67
68    fn with_add(mut self, other: Self::Add) -> Self {
69        self.add(other);
70        self
71    }
72
73    fn with_mul(mut self, other: Self::Mul) -> Self {
74        self.mul(other);
75        self
76    }
77
78    fn with_min(mut self, other: Self::Bounds) -> Self {
79        self.min(other);
80        self
81    }
82
83    fn with_max(mut self, other: Self::Bounds) -> Self {
84        self.max(other);
85        self
86    }
87
88    fn with_or(mut self, other: Self::Bit) -> Self {
89        self.or(other);
90        self
91    }
92
93    fn with_join(mut self, other: Self) -> Self {
94        self.join(other);
95        self
96    }
97
98    fn with_join_ref(mut self, other: &Self) -> Self {
99        self.join_by_ref(other);
100        self
101    }
102
103    fn from_base(base: Self::Base) -> Self;
104}
105
106impl StatValue for bool {
107    type Out = bool;
108
109    fn join(&mut self, other: Self) {
110        *self |= other
111    }
112
113    fn eval(&self) -> Self::Out {
114        *self
115    }
116
117    type Add = Unsupported;
118
119    type Mul = Unsupported;
120
121    type Bit = Self;
122
123    type Bounds = Unsupported;
124
125    type Base = Self;
126
127    fn from_base(base: Self::Base) -> Self {
128        base
129    }
130}