Struct wfc::RunOwn

source ·
pub struct RunOwn<'a, W: Wrap = WrapXY, F: ForbidPattern = ForbidNothing> { /* private fields */ }
Expand description

Represents a running instance of wfc which allocates and owns its resources

Implementations§

Examples found in repository?
src/wfc.rs (line 1235)
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
    pub fn new<R: Rng>(
        output_size: Size,
        global_stats: &'a GlobalStats,
        rng: &mut R,
    ) -> Self {
        Self::new_wrap_forbid(output_size, global_stats, WrapXY, ForbidNothing, rng)
    }
}

impl<'a, W: Wrap> RunOwn<'a, W> {
    pub fn new_wrap<R: Rng>(
        output_size: Size,
        global_stats: &'a GlobalStats,
        wrap: W,
        rng: &mut R,
    ) -> Self {
        Self::new_wrap_forbid(output_size, global_stats, wrap, ForbidNothing, rng)
    }
}

impl<'a, F: ForbidPattern> RunOwn<'a, WrapXY, F>
where
    F: Clone + Sync + Send,
{
    pub fn new_forbid<R: Rng>(
        output_size: Size,
        global_stats: &'a GlobalStats,
        forbid: F,
        rng: &mut R,
    ) -> Self {
        Self::new_wrap_forbid(output_size, global_stats, WrapXY, forbid, rng)
    }
Examples found in repository?
src/wfc.rs (line 1285)
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
    pub fn new_wrap_forbid<R: Rng>(
        output_size: Size,
        global_stats: &'a GlobalStats,
        wrap: W,
        forbid: F,
        rng: &mut R,
    ) -> Self {
        let _ = wrap;
        let wave = Wave::new(output_size);
        let context = Context::new();
        let mut s = Self {
            context,
            wave,
            global_stats,
            output_wrap: PhantomData,
            forbid,
        };
        s.borrow_mut().reset(rng);
        s
    }
}

impl<'a, W: Wrap, F: ForbidPattern> RunOwn<'a, W, F>
where
    F: Clone + Sync + Send,
{
    pub fn borrow_mut(&mut self) -> RunBorrow<W, ForbidRef<F>> {
        let core = RunBorrowCore {
            context: &mut self.context,
            wave: &mut self.wave,
            global_stats: self.global_stats,
            output_wrap: self.output_wrap,
        };
        RunBorrow {
            core,
            forbid: ForbidRef(&mut self.forbid),
        }
    }

    pub fn step<R: Rng>(&mut self, rng: &mut R) -> Result<Observe, PropagateError> {
        self.borrow_mut().step(rng)
    }

    pub fn collapse<R: Rng>(&mut self, rng: &mut R) -> Result<(), PropagateError> {
        self.borrow_mut().collapse(rng)
    }
Examples found in repository?
src/retry.rs (line 32)
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
    fn retry<'a, W, F, R>(
        &mut self,
        mut run: RunOwn<'a, W, F>,
        rng: &mut R,
    ) -> Self::Return
    where
        W: Wrap + Clone + Sync + Send,
        F: ForbidPattern + Clone + Sync + Send,
        R: Rng,
    {
        loop {
            match run.collapse(rng) {
                Ok(()) => (),
                Err(PropagateError::Contradiction) => continue,
            }
            return run.into_wave();
        }
    }
}

/// Retry method which retries a specified number of times, possibly in parallel, where the first
/// attempt to complete without contradiction will be taken. A symptom of the parallelism is that
/// running this with an rng with a known seed may still produce inconsistent results due to
/// non-deterministic timing between threads. This retry method is not suitable for use cases where
/// reproducability is important. It outperforms `NumTimes` in cases where the first attempt leads
/// to contradiction.
#[cfg(feature = "parallel")]
#[derive(Debug, Clone, Copy)]
pub struct ParNumTimes(pub usize);

#[cfg(feature = "parallel")]
impl RetryOwn for ParNumTimes {
    type Return = Result<Wave, PropagateError>;
    fn retry<'a, W, F, R>(&mut self, run: RunOwn<'a, W, F>, rng: &mut R) -> Self::Return
    where
        W: Wrap + Clone + Sync + Send,
        F: ForbidPattern + Clone + Sync + Send,
        R: Rng,
    {
        use rand::SeedableRng;
        use rand_xorshift::XorShiftRng;
        use rayon::prelude::*;
        // Each thread runs with a different rng so they can produce different results.  The
        // `RetryOwn` trait doesn't provide a way to produce new rngs of type `R` besides `clone`,
        // which won't help since we want each rng to be different.  Instead, each thread runs with
        // a `XorShiftRng` seeded with a random number taken from the original rng. `XorShiftRng`
        // is chosen because it is fast, and a cryptographically secure rng (which it is not) is
        // not required for this purpose. It does mean that the rng used by this runner can't be
        // chosen by the caller, but the only way to allow this is to change the `RetryOwn`
        // interface which doesn't seem worth it.
        let rngs = (0..self.0)
            .map(|_| XorShiftRng::seed_from_u64(rng.gen()))
            .collect::<Vec<_>>();
        rngs.into_par_iter()
            .filter_map(|mut rng| {
                let mut runner = run.clone();
                let collapse_result = runner.collapse(&mut rng);
                collapse_result.map(|_| runner.into_wave()).ok()
            })
            .find_any(|_| true)
            .ok_or(PropagateError::Contradiction)
    }
}

/// Retry method which retries a specified number of times, sequentially where the first attempt to
/// complete without contradiction will be taken.
#[derive(Debug, Clone, Copy)]
pub struct NumTimes(pub usize);

impl RetryOwn for NumTimes {
    type Return = Result<Wave, PropagateError>;
    fn retry<'a, W, F, R>(
        &mut self,
        mut run: RunOwn<'a, W, F>,
        rng: &mut R,
    ) -> Self::Return
    where
        W: Wrap + Clone + Sync + Send,
        F: ForbidPattern + Clone + Sync + Send,
        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;
                    }
                }
            }
        }
    }
Examples found in repository?
src/retry.rs (line 36)
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
    fn retry<'a, W, F, R>(
        &mut self,
        mut run: RunOwn<'a, W, F>,
        rng: &mut R,
    ) -> Self::Return
    where
        W: Wrap + Clone + Sync + Send,
        F: ForbidPattern + Clone + Sync + Send,
        R: Rng,
    {
        loop {
            match run.collapse(rng) {
                Ok(()) => (),
                Err(PropagateError::Contradiction) => continue,
            }
            return run.into_wave();
        }
    }
}

/// Retry method which retries a specified number of times, possibly in parallel, where the first
/// attempt to complete without contradiction will be taken. A symptom of the parallelism is that
/// running this with an rng with a known seed may still produce inconsistent results due to
/// non-deterministic timing between threads. This retry method is not suitable for use cases where
/// reproducability is important. It outperforms `NumTimes` in cases where the first attempt leads
/// to contradiction.
#[cfg(feature = "parallel")]
#[derive(Debug, Clone, Copy)]
pub struct ParNumTimes(pub usize);

#[cfg(feature = "parallel")]
impl RetryOwn for ParNumTimes {
    type Return = Result<Wave, PropagateError>;
    fn retry<'a, W, F, R>(&mut self, run: RunOwn<'a, W, F>, rng: &mut R) -> Self::Return
    where
        W: Wrap + Clone + Sync + Send,
        F: ForbidPattern + Clone + Sync + Send,
        R: Rng,
    {
        use rand::SeedableRng;
        use rand_xorshift::XorShiftRng;
        use rayon::prelude::*;
        // Each thread runs with a different rng so they can produce different results.  The
        // `RetryOwn` trait doesn't provide a way to produce new rngs of type `R` besides `clone`,
        // which won't help since we want each rng to be different.  Instead, each thread runs with
        // a `XorShiftRng` seeded with a random number taken from the original rng. `XorShiftRng`
        // is chosen because it is fast, and a cryptographically secure rng (which it is not) is
        // not required for this purpose. It does mean that the rng used by this runner can't be
        // chosen by the caller, but the only way to allow this is to change the `RetryOwn`
        // interface which doesn't seem worth it.
        let rngs = (0..self.0)
            .map(|_| XorShiftRng::seed_from_u64(rng.gen()))
            .collect::<Vec<_>>();
        rngs.into_par_iter()
            .filter_map(|mut rng| {
                let mut runner = run.clone();
                let collapse_result = runner.collapse(&mut rng);
                collapse_result.map(|_| runner.into_wave()).ok()
            })
            .find_any(|_| true)
            .ok_or(PropagateError::Contradiction)
    }
}

/// Retry method which retries a specified number of times, sequentially where the first attempt to
/// complete without contradiction will be taken.
#[derive(Debug, Clone, Copy)]
pub struct NumTimes(pub usize);

impl RetryOwn for NumTimes {
    type Return = Result<Wave, PropagateError>;
    fn retry<'a, W, F, R>(
        &mut self,
        mut run: RunOwn<'a, W, F>,
        rng: &mut R,
    ) -> Self::Return
    where
        W: Wrap + Clone + Sync + Send,
        F: ForbidPattern + Clone + Sync + Send,
        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;
                    }
                }
            }
        }
    }

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.