1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
use rand::Rng; use wfc::{PropagateError, RunBorrow, RunOwn, Wave}; use wrap::Wrap; pub trait RetryOwn: Copy + private::Sealed { type Return; fn retry<'a, W, R>(&mut self, run: RunOwn<'a, W>, rng: &mut R) -> Self::Return where W: Wrap, R: Rng; } #[derive(Debug, Clone, Copy)] pub struct Forever; impl RetryOwn for Forever { type Return = Wave; fn retry<'a, W, R>(&mut self, mut run: RunOwn<'a, W>, rng: &mut R) -> Self::Return where W: Wrap, R: Rng, { loop { match run.collapse(rng) { Ok(()) => (), Err(PropagateError::Contradiction) => continue, } return run.into_wave(); } } } #[derive(Debug, Clone, Copy)] pub struct NumTimes(pub usize); impl RetryOwn for NumTimes { type Return = Result<Wave, PropagateError>; fn retry<'a, W, R>(&mut self, mut run: RunOwn<'a, W>, rng: &mut R) -> Self::Return where W: Wrap, R: Rng, { loop { match run.collapse(rng) { Ok(()) => return Ok(run.into_wave()), Err(e) => { if self.0 == 0 { return Err(e); } else { self.0 -= 1; } } } } } } pub trait RetryBorrow: Copy + private::Sealed { type Return; fn retry<'a, W, R>( &mut self, run: &mut RunBorrow<'a, W>, rng: &mut R, ) -> Self::Return where W: Wrap, R: Rng; } impl RetryBorrow for Forever { type Return = (); fn retry<'a, W, R>(&mut self, run: &mut RunBorrow<'a, W>, rng: &mut R) -> Self::Return where W: Wrap, R: Rng, { loop { match run.collapse(rng) { Ok(()) => break, Err(PropagateError::Contradiction) => continue, } } } } impl RetryBorrow for NumTimes { type Return = Result<(), PropagateError>; fn retry<'a, W, R>(&mut self, run: &mut RunBorrow<'a, W>, rng: &mut R) -> Self::Return where W: Wrap, R: Rng, { loop { match run.collapse(rng) { Ok(()) => return Ok(()), Err(e) => { if self.0 == 0 { return Err(e); } else { self.0 -= 1; } } } } } } mod private { use super::*; pub trait Sealed {} impl Sealed for Forever {} impl Sealed for NumTimes {} }