1use alloc::vec::Vec;
6
7use maplike::{Container, Get};
8
9use crate::{Add, Clip, Inflate, PolygonId, Sub};
10#[cfg(feature = "undoredo")]
11use crate::{Polygon, RecordingPolygonSet, RecordingPolygonUnionFind};
12
13#[cfg(feature = "undoredo")]
14use core::marker::PhantomData;
15#[cfg(feature = "undoredo")]
16use undoredo::{ApplyDelta, Delta, FlushDelta};
17
18#[derive(Clone, Debug)]
19pub struct Inflated<I, K> {
20 inflatee: I,
21 offset: K,
22}
23
24impl<I, K> Inflated<I, K> {
25 #[inline]
26 pub fn inflatee(&self) -> &I {
27 &self.inflatee
28 }
29
30 #[inline]
31 pub fn offset(&self) -> &K {
32 &self.offset
33 }
34}
35
36impl<I: Default, K> Inflated<I, K> {
37 #[inline]
38 pub fn new(offset: K) -> Self {
39 Self {
40 inflatee: I::default(),
41 offset,
42 }
43 }
44}
45
46impl<K: Clone, P: Clone + Inflate<K>, S: Add<P, Output = PolygonId>> Add<P> for Inflated<S, K> {
47 type Output = PolygonId;
48
49 fn add(&mut self, polygon: P) -> PolygonId {
50 self.inflatee.add(polygon.inflate(self.offset.clone()))
51 }
52}
53
54impl<K: Clone, P: Clone + Inflate<K>, S: Sub<P>> Sub<P> for Inflated<S, K> {
55 type Output = S::Output;
56
57 fn sub(&mut self, polygon: P) -> S::Output {
58 self.inflatee.sub(polygon.inflate(self.offset.clone()))
59 }
60}
61
62impl<I: Container, K> Container for Inflated<I, K> {
63 type Key = I::Key;
64 type Value = I::Value;
65}
66
67impl<I: Get<K2>, K, K2> Get<K2> for Inflated<I, K> {
68 #[inline]
69 fn get(&self, key: &K2) -> Option<&Self::Value> {
70 self.inflatee.get(key)
71 }
72}
73
74#[derive(Clone, Debug)]
75pub struct Negated<M, S> {
76 minuend: M,
77 subtrahend: S,
78}
79
80impl<M, S> Negated<M, S> {
81 #[inline]
82 pub fn minuend(&self) -> &M {
83 &self.minuend
84 }
85
86 #[inline]
87 pub fn subtrahend(&self) -> &S {
88 &self.subtrahend
89 }
90
91 #[inline]
92 pub fn new(minuend: M, subtrahend: S) -> Self {
93 Self {
94 minuend,
95 subtrahend,
96 }
97 }
98}
99
100impl<M: Default, S: Default> Default for Negated<M, S> {
101 #[inline]
102 fn default() -> Self {
103 Self {
104 minuend: M::default(),
105 subtrahend: S::default(),
106 }
107 }
108}
109
110impl<
111 P: Clone,
112 M: Sub<P, Output = (Vec<PolygonId>, Vec<P>)>,
113 S: Add<P, Output = PolygonId> + Get<PolygonId, Value = P>,
114> Add<P> for Negated<M, S>
115{
116 type Output = (Vec<PolygonId>, Vec<P>);
117
118 fn add(&mut self, polygon: P) -> (Vec<PolygonId>, Vec<P>) {
119 let id = self.subtrahend.add(polygon.clone());
120
121 self.minuend.sub(self.subtrahend.get(&id).unwrap().clone())
122 }
123}
124
125#[derive(Clone, Debug)]
126pub struct Paralleled<S> {
127 primary: S,
128 parallels: Vec<S>,
129}
130
131impl<S> Paralleled<S> {
132 #[inline]
133 pub fn primary(&self) -> &S {
134 &self.primary
135 }
136
137 #[inline]
138 pub fn parallels(&self) -> &Vec<S> {
139 &self.parallels
140 }
141}
142
143impl<S> Paralleled<S> {
144 #[inline]
145 pub fn new(primary: S, parallels: Vec<S>) -> Self {
146 Self { primary, parallels }
147 }
148}
149
150impl<P: Clone, S: Add<P>> Add<P> for Paralleled<S> {
151 type Output = (S::Output, Vec<S::Output>);
152
153 fn add(&mut self, polygon: P) -> (S::Output, Vec<S::Output>) {
154 let mut parallel_outputs = Vec::with_capacity(self.parallels.len());
155
156 for parallel in &mut self.parallels {
157 parallel_outputs.push(parallel.add(polygon.clone()));
158 }
159
160 let primary_output = self.primary.add(polygon);
161 (primary_output, parallel_outputs)
162 }
163}
164
165impl<P: Clone, S: Sub<P>> Sub<P> for Paralleled<S> {
166 type Output = (S::Output, Vec<S::Output>);
167
168 fn sub(&mut self, polygon: P) -> (S::Output, Vec<S::Output>) {
169 let mut parallel_outputs = Vec::with_capacity(self.parallels.len());
170
171 for parallel in &mut self.parallels {
172 parallel_outputs.push(parallel.sub(polygon.clone()));
173 }
174
175 let primary_output = self.primary.sub(polygon);
176 (primary_output, parallel_outputs)
177 }
178}
179
180impl<P: Clone, S: Clip<P>> Clip<P> for Paralleled<S> {
181 type Output = S::Output;
182
183 fn clip(&mut self, polygon: P) -> S::Output {
184 for parallel in &mut self.parallels {
185 parallel.clip(polygon.clone());
186 }
187
188 self.primary.clip(polygon)
189 }
190}
191
192#[cfg(feature = "undoredo")]
193pub type RecordingInflated<K, P = Polygon<K>> = Inflated<RecordingPolygonUnionFind<K, P>, K>;
195
196#[cfg(feature = "undoredo")]
197pub type InflatedHalfDelta<IE, K> = Inflated<IE, PhantomData<K>>;
199
200#[cfg(feature = "undoredo")]
201pub type InflatedDelta<IE, K> = Delta<InflatedHalfDelta<IE, K>>;
203
204#[cfg(feature = "undoredo")]
205impl<IE: Clone, IC: Clone + ApplyDelta<IE>, K> ApplyDelta<InflatedHalfDelta<IE, K>>
206 for Inflated<IC, K>
207{
208 fn apply_delta(&mut self, delta: InflatedDelta<IE, K>) {
209 let (removed, inserted) = delta.dissolve();
210
211 let inflatee_delta = Delta::with_removed_inserted(removed.inflatee, inserted.inflatee);
212 self.inflatee.apply_delta(inflatee_delta);
213 }
214}
215
216#[cfg(feature = "undoredo")]
217impl<IE: Clone, IC: FlushDelta<IE>, K> FlushDelta<InflatedHalfDelta<IE, K>> for Inflated<IC, K> {
218 fn flush_delta(&mut self) -> InflatedDelta<IE, K> {
219 let (removed_inflatee, inserted_inflatee) = self.inflatee.flush_delta().dissolve();
220
221 Delta::with_removed_inserted(
222 Inflated {
223 inflatee: removed_inflatee,
224 offset: PhantomData,
225 },
226 Inflated {
227 inflatee: inserted_inflatee,
228 offset: PhantomData,
229 },
230 )
231 }
232}
233
234#[cfg(feature = "undoredo")]
235pub type RecordingNegated<K, P = Polygon<K>> =
237 Negated<RecordingPolygonSet<K, P>, RecordingInflated<K, P>>;
238
239#[cfg(feature = "undoredo")]
240pub type NegatedHalfDelta<ME, SE> = Negated<ME, SE>;
242
243#[cfg(feature = "undoredo")]
244pub type NegatedDelta<ME, SE> = Delta<NegatedHalfDelta<ME, SE>>;
246
247#[cfg(feature = "undoredo")]
248impl<ME: Clone, M: Clone + ApplyDelta<ME>, SE: Clone, S: Clone + ApplyDelta<SE>>
249 ApplyDelta<NegatedHalfDelta<ME, SE>> for Negated<M, S>
250{
251 fn apply_delta(&mut self, delta: NegatedDelta<ME, SE>) {
252 let (removed, inserted) = delta.dissolve();
253
254 let minuend_delta = Delta::with_removed_inserted(removed.minuend, inserted.minuend);
255 self.minuend.apply_delta(minuend_delta);
256
257 let subtrahend_delta =
258 Delta::with_removed_inserted(removed.subtrahend, inserted.subtrahend);
259 self.subtrahend.apply_delta(subtrahend_delta);
260 }
261}
262
263#[cfg(feature = "undoredo")]
264impl<ME: Clone, M: FlushDelta<ME>, SE: Clone, S: FlushDelta<SE>>
265 FlushDelta<NegatedHalfDelta<ME, SE>> for Negated<M, S>
266{
267 fn flush_delta(&mut self) -> NegatedDelta<ME, SE> {
268 let (removed_minuend, inserted_minuend) = self.minuend.flush_delta().dissolve();
269 let (removed_subtrahend, inserted_subtrahend) = self.subtrahend.flush_delta().dissolve();
270
271 Delta::with_removed_inserted(
272 Negated {
273 minuend: removed_minuend,
274 subtrahend: removed_subtrahend,
275 },
276 Negated {
277 minuend: inserted_minuend,
278 subtrahend: inserted_subtrahend,
279 },
280 )
281 }
282}
283
284#[cfg(feature = "undoredo")]
285pub type RecordingParalleled<K, P = Polygon<K>> = Paralleled<RecordingNegated<K, P>>;
287
288#[cfg(feature = "undoredo")]
289pub type ParalleledHalfDelta<SE> = Paralleled<SE>;
291
292#[cfg(feature = "undoredo")]
293pub type ParalleledDelta<SE> = Delta<ParalleledHalfDelta<SE>>;
295
296#[cfg(feature = "undoredo")]
297impl<SE: Clone, S: Clone + ApplyDelta<SE>> ApplyDelta<ParalleledHalfDelta<SE>> for Paralleled<S> {
298 fn apply_delta(&mut self, delta: ParalleledDelta<SE>) {
299 let (removed, inserted) = delta.dissolve();
300
301 let primary_delta = Delta::with_removed_inserted(removed.primary, inserted.primary);
302 self.primary.apply_delta(primary_delta);
303
304 for (parallel, (removed_parallel, inserted_parallel)) in self.parallels.iter_mut().zip(
305 removed
306 .parallels
307 .into_iter()
308 .zip(inserted.parallels.into_iter()),
309 ) {
310 parallel.apply_delta(Delta::with_removed_inserted(
311 removed_parallel,
312 inserted_parallel,
313 ));
314 }
315 }
316}
317
318#[cfg(feature = "undoredo")]
319impl<SE: Clone, S: FlushDelta<SE>> FlushDelta<ParalleledHalfDelta<SE>> for Paralleled<S> {
320 fn flush_delta(&mut self) -> ParalleledDelta<SE> {
321 let (removed_primary, inserted_primary) = self.primary.flush_delta().dissolve();
322
323 let mut removed_parallels = Vec::with_capacity(self.parallels.len());
324 let mut inserted_parallels = Vec::with_capacity(self.parallels.len());
325
326 for parallel in &mut self.parallels {
327 let (removed_parallel, inserted_parallel) = parallel.flush_delta().dissolve();
328 removed_parallels.push(removed_parallel);
329 inserted_parallels.push(inserted_parallel);
330 }
331
332 Delta::with_removed_inserted(
333 Paralleled {
334 primary: removed_primary,
335 parallels: removed_parallels,
336 },
337 Paralleled {
338 primary: inserted_primary,
339 parallels: inserted_parallels,
340 },
341 )
342 }
343}