1use super::mc::pos::IntCoordinates;
2use super::mc::EntityTarget;
3use super::reg::GetUsedRegs;
4use super::val::{MutableValue, Value};
5use super::{Identifier, ResourceLocation, ResourceLocationTag};
6use std::fmt::Debug;
7use std::iter;
8
9#[derive(Clone, PartialEq)]
11pub enum Condition {
12 Not(Box<Condition>),
13 And(Box<Condition>, Box<Condition>),
14 Or(Box<Condition>, Box<Condition>),
15 Xor(Box<Condition>, Box<Condition>),
16 Equal(Value, Value),
17 Exists(Value),
18 GreaterThan(Value, Value),
19 GreaterThanOrEqual(Value, Value),
20 LessThan(Value, Value),
21 LessThanOrEqual(Value, Value),
22 Bool(Value),
23 NotBool(Value),
24 Entity(EntityTarget),
25 Predicate(ResourceLocation),
26 Biome(IntCoordinates, ResourceLocationTag),
27 Loaded(IntCoordinates),
28 Dimension(ResourceLocation),
29 Function(ResourceLocationTag),
30}
31
32impl Condition {
33 pub fn iter_used_regs_mut(&mut self) -> Box<dyn Iterator<Item = &mut Identifier> + '_> {
34 match self {
35 Self::Equal(l, r)
36 | Self::GreaterThan(l, r)
37 | Self::GreaterThanOrEqual(l, r)
38 | Self::LessThan(l, r)
39 | Self::LessThanOrEqual(l, r) => Box::new(
40 l.get_used_regs_mut()
41 .into_iter()
42 .chain(r.get_used_regs_mut()),
43 ),
44 Self::Exists(val) | Self::Bool(val) | Self::NotBool(val) => {
45 Box::new(val.get_used_regs_mut().into_iter())
46 }
47 Self::Not(condition) => condition.iter_used_regs_mut(),
48 Self::And(l, r) | Self::Or(l, r) | Self::Xor(l, r) => {
49 Box::new(l.iter_used_regs_mut().chain(r.iter_used_regs_mut()))
50 }
51 Self::Entity(..)
52 | Self::Predicate(..)
53 | Self::Biome(..)
54 | Self::Loaded(..)
55 | Self::Dimension(..)
56 | Self::Function(..) => Box::new(iter::empty()),
57 }
58 }
59
60 pub fn iter_mut_vals(&mut self) -> Box<dyn Iterator<Item = &mut MutableValue> + '_> {
61 match self {
62 Self::Equal(l, r)
63 | Self::GreaterThan(l, r)
64 | Self::GreaterThanOrEqual(l, r)
65 | Self::LessThan(l, r)
66 | Self::LessThanOrEqual(l, r) => Box::new(l.iter_mut_val().into_iter().chain(r.iter_mut_val())),
67 Self::Exists(val) | Self::Bool(val) | Self::NotBool(val) => {
68 Box::new(val.iter_mut_val().into_iter())
69 }
70 Self::Not(condition) => condition.iter_mut_vals(),
71 Self::And(l, r) | Self::Xor(l, r) | Self::Or(l, r) => {
72 Box::new(l.iter_mut_vals().chain(r.iter_mut_vals()))
73 }
74 Self::Entity(..)
75 | Self::Predicate(..)
76 | Self::Biome(..)
77 | Self::Loaded(..)
78 | Self::Dimension(..)
79 | Self::Function(..) => Box::new(iter::empty()),
80 }
81 }
82
83 pub fn has_side_effects(&self) -> bool {
84 match self {
85 Self::Function(..) => true,
86 _ => false,
87 }
88 }
89}
90
91impl GetUsedRegs for Condition {
92 fn append_used_regs<'a>(&'a self, regs: &mut Vec<&'a Identifier>) {
93 match self {
94 Self::Equal(l, r)
95 | Self::GreaterThan(l, r)
96 | Self::GreaterThanOrEqual(l, r)
97 | Self::LessThan(l, r)
98 | Self::LessThanOrEqual(l, r) => {
99 l.append_used_regs(regs);
100 r.append_used_regs(regs);
101 }
102 Self::Exists(val) | Self::Bool(val) | Self::NotBool(val) => {
103 val.append_used_regs(regs);
104 }
105 Self::Not(condition) => {
106 condition.append_used_regs(regs);
107 }
108 Self::And(l, r) | Self::Or(l, r) | Self::Xor(l, r) => {
109 l.append_used_regs(regs);
110 r.append_used_regs(regs);
111 }
112 Self::Entity(..)
113 | Self::Predicate(..)
114 | Self::Biome(..)
115 | Self::Loaded(..)
116 | Self::Dimension(..)
117 | Self::Function(..) => {}
118 }
119 }
120}
121
122impl Debug for Condition {
123 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
124 match self {
125 Self::Equal(l, r) => write!(f, "{l:?} == {r:?}"),
126 Self::Exists(val) => write!(f, "exi {val:?}"),
127 Self::Not(condition) => write!(f, "not {condition:?}"),
128 Self::And(l, r) => write!(f, "and {l:?} {r:?}"),
129 Self::Or(l, r) => write!(f, "or {l:?} {r:?}"),
130 Self::Xor(l, r) => write!(f, "xor {l:?} {r:?}"),
131 Self::GreaterThan(l, r) => write!(f, "{l:?} > {r:?}"),
132 Self::GreaterThanOrEqual(l, r) => write!(f, "{l:?} >= {r:?}"),
133 Self::LessThan(l, r) => write!(f, "{l:?} < {r:?}"),
134 Self::LessThanOrEqual(l, r) => write!(f, "{l:?} <= {r:?}"),
135 Self::Bool(val) => write!(f, "bool {val:?}"),
136 Self::NotBool(val) => write!(f, "nbool {val:?}"),
137 Self::Entity(ent) => write!(f, "ent {ent:?}"),
138 Self::Predicate(pred) => write!(f, "pred {pred:?}"),
139 Self::Biome(loc, biome) => write!(f, "bio {loc:?} {biome}"),
140 Self::Loaded(loc) => write!(f, "load {loc:?}"),
141 Self::Dimension(dim) => write!(f, "dim {dim}"),
142 Self::Function(func) => write!(f, "fn {func}"),
143 }
144 }
145}