wowlab_engine_domain/rotation/lower/
eval_kind.rs1#[cfg(feature = "rotation-optimizations")]
2use super::ops::spell::spell_enabled;
3use super::{
4 super::{
5 backend::RotationBackend, buffer::EvalKind, context::SpellUsableOffsets, expr::FieldType,
6 },
7 EvalValueAbstract,
8 ops::{
9 aura::aura_refreshable,
10 cooldown::{cooldown_full_recharge, cooldown_ready},
11 direct::positive_float,
12 resource::{resource_deficit, resource_deficit_pct, resource_pct, resource_time_to_max},
13 spell::{SpellUsableArgs, spell_usable},
14 timestamp,
15 unit::{unit_health_deficit, unit_health_pct},
16 },
17 typed_load,
18};
19
20#[derive(Clone, Copy)]
21pub(super) struct EvalInputs<'a> {
22 pub(super) spell_usable: Option<&'a SpellUsableOffsets>,
23 pub(super) cooldown_bypass_aura_offset: Option<usize>,
24 pub(super) spell_usability_prevalidated: bool,
25}
26
27pub(super) fn lower_eval_kind<B>(
29 b: &mut B,
30 kind: EvalKind,
31 offset: usize,
32 field_type: FieldType,
33 inputs: EvalInputs<'_>,
34) -> EvalValueAbstract<B>
35where
36 B: RotationBackend,
37{
38 match kind {
39 EvalKind::Direct => typed_load(b, offset, field_type),
40 EvalKind::TimestampReady => EvalValueAbstract::Bool(timestamp::ready(b, offset)),
41 EvalKind::TimestampRemaining => EvalValueAbstract::Float(timestamp::remaining(b, offset)),
42 EvalKind::TimestampActive => EvalValueAbstract::Bool(timestamp::active(b, offset)),
43 EvalKind::TimestampElapsed => EvalValueAbstract::Float(timestamp::elapsed(b, offset)),
44 EvalKind::TimestampInactive => EvalValueAbstract::Bool(timestamp::inactive(b, offset)),
45 EvalKind::CooldownReady => EvalValueAbstract::Bool(cooldown_ready(
46 b,
47 offset,
48 inputs.cooldown_bypass_aura_offset,
49 )),
50 EvalKind::CooldownFullRecharge => {
51 EvalValueAbstract::Float(cooldown_full_recharge(b, offset))
52 }
53 EvalKind::AuraRefreshable => EvalValueAbstract::Bool(aura_refreshable(b, offset)),
54 EvalKind::PositiveFloat => EvalValueAbstract::Bool(positive_float(b, offset)),
55 EvalKind::ResourceDeficit => EvalValueAbstract::Float(resource_deficit(b, offset)),
56 EvalKind::ResourcePct => EvalValueAbstract::Float(resource_pct(b, offset)),
57 EvalKind::ResourceDeficitPct => EvalValueAbstract::Float(resource_deficit_pct(b, offset)),
58 EvalKind::ResourceTimeToMax => EvalValueAbstract::Float(resource_time_to_max(b, offset)),
59 EvalKind::UnitHealthPct => EvalValueAbstract::Float(unit_health_pct(b, offset)),
60 EvalKind::UnitHealthDeficit => EvalValueAbstract::Float(unit_health_deficit(b, offset)),
61 EvalKind::SpellUsable => {
62 #[cfg(feature = "rotation-optimizations")]
63 if inputs.spell_usability_prevalidated {
64 return EvalValueAbstract::Bool(spell_enabled(b, offset));
65 }
66
67 #[cfg(not(feature = "rotation-optimizations"))]
68 let _ = inputs.spell_usability_prevalidated;
69
70 let args = match inputs.spell_usable {
72 Some(e) => SpellUsableArgs::from_offsets(offset, e),
73 None => SpellUsableArgs::bare(offset),
74 };
75
76 EvalValueAbstract::Bool(spell_usable(b, &args))
77 }
78 _ => {
80 debug_assert!(
81 false,
82 "lower_eval_kind: unhandled EvalKind variant {kind:?} (offset {offset}, {field_type:?})"
83 );
84 tracing::warn!(
85 ?kind,
86 offset,
87 ?field_type,
88 "lower_eval_kind: unhandled EvalKind variant, falling back to direct load"
89 );
90
91 typed_load(b, offset, field_type)
92 }
93 }
94}