goud_engine/ecs/schedule/
system_ordering.rs1use std::fmt;
4
5use crate::ecs::system::SystemId;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
24pub enum SystemOrdering {
25 Before {
27 system: SystemId,
29 before: SystemId,
31 },
32 After {
34 system: SystemId,
36 after: SystemId,
38 },
39}
40
41impl SystemOrdering {
42 #[inline]
44 pub fn before(system: SystemId, other: SystemId) -> Self {
45 SystemOrdering::Before {
46 system,
47 before: other,
48 }
49 }
50
51 #[inline]
53 pub fn after(system: SystemId, other: SystemId) -> Self {
54 SystemOrdering::After {
55 system,
56 after: other,
57 }
58 }
59
60 #[inline]
62 pub fn first(&self) -> SystemId {
63 match self {
64 SystemOrdering::Before { system, .. } => *system,
65 SystemOrdering::After { after, .. } => *after,
66 }
67 }
68
69 #[inline]
71 pub fn second(&self) -> SystemId {
72 match self {
73 SystemOrdering::Before { before, .. } => *before,
74 SystemOrdering::After { system, .. } => *system,
75 }
76 }
77
78 #[inline]
82 pub fn as_edge(&self) -> (SystemId, SystemId) {
83 (self.first(), self.second())
84 }
85
86 #[inline]
88 pub fn involves(&self, id: SystemId) -> bool {
89 self.first() == id || self.second() == id
90 }
91}
92
93impl fmt::Display for SystemOrdering {
94 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95 match self {
96 SystemOrdering::Before { system, before } => {
97 write!(f, "System {} before {}", system.raw(), before.raw())
98 }
99 SystemOrdering::After { system, after } => {
100 write!(f, "System {} after {}", system.raw(), after.raw())
101 }
102 }
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109 use std::collections::HashSet;
110
111 #[test]
112 fn test_ordering_before() {
113 let a = SystemId::from_raw(1);
114 let b = SystemId::from_raw(2);
115 let ordering = SystemOrdering::before(a, b);
116 assert_eq!(ordering.first(), a);
117 assert_eq!(ordering.second(), b);
118 assert_eq!(ordering.as_edge(), (a, b));
119 }
120
121 #[test]
122 fn test_ordering_after() {
123 let a = SystemId::from_raw(1);
124 let b = SystemId::from_raw(2);
125 let ordering = SystemOrdering::after(a, b);
126 assert_eq!(ordering.first(), b);
127 assert_eq!(ordering.second(), a);
128 assert_eq!(ordering.as_edge(), (b, a));
129 }
130
131 #[test]
132 fn test_ordering_involves() {
133 let a = SystemId::from_raw(1);
134 let b = SystemId::from_raw(2);
135 let c = SystemId::from_raw(3);
136 let ordering = SystemOrdering::before(a, b);
137 assert!(ordering.involves(a));
138 assert!(ordering.involves(b));
139 assert!(!ordering.involves(c));
140 }
141
142 #[test]
143 fn test_ordering_display() {
144 let a = SystemId::from_raw(1);
145 let b = SystemId::from_raw(2);
146 let before = SystemOrdering::before(a, b);
147 let after = SystemOrdering::after(a, b);
148 let before_str = format!("{}", before);
149 let after_str = format!("{}", after);
150 assert!(before_str.contains("before"));
151 assert!(after_str.contains("after"));
152 }
153
154 #[test]
155 fn test_ordering_equality() {
156 let a = SystemId::from_raw(1);
157 let b = SystemId::from_raw(2);
158 let o1 = SystemOrdering::before(a, b);
159 let o2 = SystemOrdering::before(a, b);
160 let o3 = SystemOrdering::before(b, a);
161 assert_eq!(o1, o2);
162 assert_ne!(o1, o3);
163 }
164
165 #[test]
166 fn test_ordering_hash() {
167 let a = SystemId::from_raw(1);
168 let b = SystemId::from_raw(2);
169 let mut set = HashSet::new();
170 set.insert(SystemOrdering::before(a, b));
171 set.insert(SystemOrdering::before(a, b));
172 set.insert(SystemOrdering::before(b, a));
173 assert_eq!(set.len(), 2);
174 }
175
176 #[test]
177 fn test_ordering_clone() {
178 let a = SystemId::from_raw(1);
179 let b = SystemId::from_raw(2);
180 let o1 = SystemOrdering::before(a, b);
181 let o2 = o1;
182 assert_eq!(o1, o2);
183 }
184}