wowlab_engine_domain/rotation/lower/
value.rs1use super::super::{backend::RotationBackend, expr::FieldType};
2
3pub(in crate::rotation) enum EvalValueAbstract<B>
4where
5 B: RotationBackend,
6{
7 Bool(B::Bool),
8 Int(B::Int),
9 Float(B::Float),
10}
11
12#[cold]
14#[inline(never)]
15fn unexpected_field_type(context: &str, field_type: FieldType) {
16 tracing::error!(
17 ?field_type,
18 context,
19 "unexpected FieldType discriminant in width dispatch, defaulting to Float"
20 );
21}
22
23pub(crate) fn typed_load<B>(b: &mut B, offset: usize, field_type: FieldType) -> EvalValueAbstract<B>
24where
25 B: RotationBackend,
26{
27 match field_type {
28 FieldType::Bool => EvalValueAbstract::Bool(b.load_bool(offset)),
29 FieldType::Int => EvalValueAbstract::Int(b.load_i32(offset)),
30 FieldType::Float => EvalValueAbstract::Float(b.load_f64(offset)),
31 other => {
32 unexpected_field_type("typed_load", other);
33
34 EvalValueAbstract::Float(b.load_f64(offset))
35 }
36 }
37}
38
39pub(crate) fn typed_store<B>(
40 b: &mut B,
41 offset: usize,
42 field_type: FieldType,
43 value: EvalValueAbstract<B>,
44) where
45 B: RotationBackend,
46{
47 match field_type {
48 FieldType::Bool => {
49 let v = value.into_bool(b);
50
51 b.store_bool(offset, v);
52 }
53 FieldType::Int => {
54 let v = value.into_int(b);
55
56 b.store_i32(offset, v);
57 }
58 FieldType::Float => {
59 let v = value.into_float(b);
60
61 b.store_f64(offset, v);
62 }
63 other => {
64 unexpected_field_type("typed_store", other);
65 let v = value.into_float(b);
66
67 b.store_f64(offset, v);
68 }
69 }
70}
71
72pub(crate) fn typed_select<B>(
73 b: &mut B,
74 field_type: FieldType,
75 cond: B::Bool,
76 on_true: EvalValueAbstract<B>,
77 on_false: EvalValueAbstract<B>,
78) -> EvalValueAbstract<B>
79where
80 B: RotationBackend,
81{
82 match field_type {
83 FieldType::Bool => {
84 let t = on_true.into_bool(b);
85 let f = on_false.into_bool(b);
86
87 EvalValueAbstract::Bool(b.select_b(cond, t, f))
88 }
89 FieldType::Int => {
90 let t = on_true.into_int(b);
91 let f = on_false.into_int(b);
92
93 EvalValueAbstract::Int(b.select_i(cond, t, f))
94 }
95 FieldType::Float => {
96 let t = on_true.into_float(b);
97 let f = on_false.into_float(b);
98
99 EvalValueAbstract::Float(b.select_f(cond, t, f))
100 }
101 other => {
102 unexpected_field_type("typed_select", other);
103 let t = on_true.into_float(b);
104 let f = on_false.into_float(b);
105
106 EvalValueAbstract::Float(b.select_f(cond, t, f))
107 }
108 }
109}
110
111impl<B> EvalValueAbstract<B>
112where
113 B: RotationBackend,
114{
115 pub(crate) fn into_bool(self, b: &mut B) -> B::Bool {
116 match self {
117 Self::Bool(v) => v,
118 Self::Int(v) => b.int_to_bool(v),
119 Self::Float(v) => b.float_to_bool(v),
120 }
121 }
122
123 pub(crate) fn into_int(self, b: &mut B) -> B::Int {
124 match self {
125 Self::Bool(v) => b.bool_to_int(v),
126 Self::Int(v) => v,
127 Self::Float(v) => b.float_to_int(v),
128 }
129 }
130
131 pub(crate) fn into_float(self, b: &mut B) -> B::Float {
132 match self {
133 Self::Bool(v) => b.bool_to_float(v),
134 Self::Int(v) => b.int_to_float(v),
135 Self::Float(v) => v,
136 }
137 }
138}