Skip to main content

nil_core/resources/
diff.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4use super::{Food, Iron, Resources, Stone, Wood};
5use derive_more::{Deref, Display, Into};
6use serde::{Deserialize, Serialize};
7use std::cmp::Ordering;
8use std::ops::{Add, AddAssign, Sub, SubAssign};
9
10#[derive(Clone, Debug, Default, Deserialize, Serialize)]
11#[serde(default, rename_all = "camelCase")]
12pub struct ResourcesDiff {
13  pub food: FoodDiff,
14  pub iron: IronDiff,
15  pub stone: StoneDiff,
16  pub wood: WoodDiff,
17}
18
19impl Add for ResourcesDiff {
20  type Output = Self;
21
22  fn add(self, rhs: Self) -> Self {
23    Self {
24      food: self.food + rhs.food,
25      iron: self.iron + rhs.iron,
26      stone: self.stone + rhs.stone,
27      wood: self.wood + rhs.wood,
28    }
29  }
30}
31
32impl Add<Resources> for ResourcesDiff {
33  type Output = Self;
34
35  fn add(self, rhs: Resources) -> Self {
36    Self {
37      food: self.food + rhs.food,
38      iron: self.iron + rhs.iron,
39      stone: self.stone + rhs.stone,
40      wood: self.wood + rhs.wood,
41    }
42  }
43}
44
45impl Add<ResourcesDiff> for Resources {
46  type Output = Self;
47
48  fn add(self, rhs: ResourcesDiff) -> Self {
49    Self {
50      food: self.food + rhs.food,
51      iron: self.iron + rhs.iron,
52      stone: self.stone + rhs.stone,
53      wood: self.wood + rhs.wood,
54    }
55  }
56}
57
58impl AddAssign for ResourcesDiff {
59  fn add_assign(&mut self, rhs: Self) {
60    *self = Self {
61      food: self.food + rhs.food,
62      iron: self.iron + rhs.iron,
63      stone: self.stone + rhs.stone,
64      wood: self.wood + rhs.wood,
65    };
66  }
67}
68
69impl AddAssign<Resources> for ResourcesDiff {
70  fn add_assign(&mut self, rhs: Resources) {
71    *self = Self {
72      food: self.food + rhs.food,
73      iron: self.iron + rhs.iron,
74      stone: self.stone + rhs.stone,
75      wood: self.wood + rhs.wood,
76    };
77  }
78}
79
80impl AddAssign<ResourcesDiff> for Resources {
81  fn add_assign(&mut self, rhs: ResourcesDiff) {
82    *self = Self {
83      food: self.food + rhs.food,
84      iron: self.iron + rhs.iron,
85      stone: self.stone + rhs.stone,
86      wood: self.wood + rhs.wood,
87    };
88  }
89}
90
91impl Sub for ResourcesDiff {
92  type Output = Self;
93
94  fn sub(self, rhs: Self) -> Self {
95    Self {
96      food: self.food - rhs.food,
97      iron: self.iron - rhs.iron,
98      stone: self.stone - rhs.stone,
99      wood: self.wood - rhs.wood,
100    }
101  }
102}
103
104impl Sub<ResourcesDiff> for Resources {
105  type Output = Self;
106
107  fn sub(self, rhs: ResourcesDiff) -> Self {
108    Self {
109      food: self.food - rhs.food,
110      iron: self.iron - rhs.iron,
111      stone: self.stone - rhs.stone,
112      wood: self.wood - rhs.wood,
113    }
114  }
115}
116
117impl SubAssign for ResourcesDiff {
118  fn sub_assign(&mut self, rhs: Self) {
119    *self = Self {
120      food: self.food - rhs.food,
121      iron: self.iron - rhs.iron,
122      stone: self.stone - rhs.stone,
123      wood: self.wood - rhs.wood,
124    };
125  }
126}
127
128impl SubAssign<Resources> for ResourcesDiff {
129  fn sub_assign(&mut self, rhs: Resources) {
130    *self = Self {
131      food: self.food - rhs.food,
132      iron: self.iron - rhs.iron,
133      stone: self.stone - rhs.stone,
134      wood: self.wood - rhs.wood,
135    };
136  }
137}
138
139impl SubAssign<ResourcesDiff> for Resources {
140  fn sub_assign(&mut self, rhs: ResourcesDiff) {
141    *self = Self {
142      food: self.food - rhs.food,
143      iron: self.iron - rhs.iron,
144      stone: self.stone - rhs.stone,
145      wood: self.wood - rhs.wood,
146    };
147  }
148}
149
150macro_rules! decl_resource_diff {
151  ($($resource:ident),+ $(,)?) => {
152    paste::paste! {
153      $(
154        #[derive(
155          Clone,
156          Copy,
157          Debug,
158          Default,
159          Deref,
160          Display,
161          Into,
162          PartialEq,
163          Eq,
164          PartialOrd,
165          Ord,
166          Deserialize,
167          Serialize,
168        )]
169        #[into(i32, f64)]
170        pub struct [<$resource Diff>](i32);
171
172        impl [<$resource Diff>] {
173          #[inline]
174          pub const fn new(value: i32) -> Self {
175            Self(value)
176          }
177
178          #[inline]
179          pub const fn zero() -> Self {
180            Self(0)
181          }
182        }
183
184        impl PartialEq<i32> for [<$resource Diff>] {
185          fn eq(&self, other: &i32) -> bool {
186            self.0.eq(other)
187          }
188        }
189
190        impl PartialOrd<i32> for [<$resource Diff>] {
191          fn partial_cmp(&self, other: &i32) -> Option<Ordering> {
192            self.0.partial_cmp(other)
193          }
194        }
195
196        impl Add for [<$resource Diff>] {
197          type Output = Self;
198
199          fn add(self, rhs: Self) -> Self {
200            Self(self.0.saturating_add(rhs.0))
201          }
202        }
203
204        impl Add<$resource> for [<$resource Diff>] {
205          type Output = Self;
206
207          fn add(self, rhs: $resource) -> Self {
208            Self(self.0.saturating_add_unsigned(rhs.0))
209          }
210        }
211
212        impl Add<[<$resource Diff>]> for $resource {
213          type Output = Self;
214
215          fn add(self, rhs: [<$resource Diff>]) -> Self {
216            Self(self.0.saturating_add_signed(rhs.0))
217          }
218        }
219
220        impl Add<i32> for [<$resource Diff>] {
221          type Output = Self;
222
223          fn add(self, rhs: i32) -> Self {
224            Self(self.0.saturating_add(rhs))
225          }
226        }
227
228        impl Add<u32> for [<$resource Diff>] {
229          type Output = Self;
230
231          fn add(self, rhs: u32) -> Self {
232            Self(self.0.saturating_add_unsigned(rhs))
233          }
234        }
235
236        impl AddAssign for [<$resource Diff>] {
237          fn add_assign(&mut self, rhs: Self) {
238            *self = *self + rhs;
239          }
240        }
241
242        impl AddAssign<$resource> for [<$resource Diff>] {
243          fn add_assign(&mut self, rhs: $resource) {
244            *self = *self + rhs;
245          }
246        }
247
248        impl AddAssign<[<$resource Diff>]> for $resource {
249          fn add_assign(&mut self, rhs: [<$resource Diff>]) {
250            *self = *self + rhs;
251          }
252        }
253
254        impl AddAssign<i32> for [<$resource Diff>] {
255          fn add_assign(&mut self, rhs: i32) {
256            *self = *self + rhs;
257          }
258        }
259
260        impl AddAssign<u32> for [<$resource Diff>] {
261          fn add_assign(&mut self, rhs: u32) {
262            *self = *self + rhs;
263          }
264        }
265
266        impl Sub for [<$resource Diff>] {
267          type Output = Self;
268
269          fn sub(self, rhs: Self) -> Self {
270            Self(self.0.saturating_sub(rhs.0))
271          }
272        }
273
274        impl Sub<$resource> for [<$resource Diff>] {
275          type Output = Self;
276
277          fn sub(self, rhs: $resource) -> Self {
278            Self(self.0.saturating_sub_unsigned(rhs.0))
279          }
280        }
281
282        impl Sub<[<$resource Diff>]> for $resource {
283          type Output = Self;
284
285          fn sub(self, rhs: [<$resource Diff>]) -> Self {
286            Self(self.0.saturating_sub_signed(rhs.0))
287          }
288        }
289
290        impl Sub<i32> for [<$resource Diff>] {
291          type Output = Self;
292
293          fn sub(self, rhs: i32) -> Self {
294            Self(self.0.saturating_sub(rhs))
295          }
296        }
297
298        impl Sub<u32> for [<$resource Diff>] {
299          type Output = Self;
300
301          fn sub(self, rhs: u32) -> Self {
302            Self(self.0.saturating_sub_unsigned(rhs))
303          }
304        }
305
306        impl SubAssign for [<$resource Diff>] {
307          fn sub_assign(&mut self, rhs: Self) {
308            *self = *self - rhs;
309          }
310        }
311
312        impl SubAssign<$resource> for [<$resource Diff>] {
313          fn sub_assign(&mut self, rhs: $resource) {
314            *self = *self - rhs;
315          }
316        }
317
318        impl SubAssign<[<$resource Diff>]> for $resource {
319          fn sub_assign(&mut self, rhs: [<$resource Diff>]) {
320            *self = *self - rhs;
321          }
322        }
323
324        impl SubAssign<i32> for [<$resource Diff>] {
325          fn sub_assign(&mut self, rhs: i32) {
326            *self = *self - rhs;
327          }
328        }
329
330        impl SubAssign<u32> for [<$resource Diff>] {
331          fn sub_assign(&mut self, rhs: u32) {
332            *self = *self - rhs;
333          }
334        }
335      )+
336    }
337  }
338}
339
340decl_resource_diff!(Food, Iron, Stone, Wood);