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§
source§impl<'a, F> RunOwn<'a, WrapXY, F>where
F: Clone + Sync + Send + ForbidPattern,
impl<'a, F> RunOwn<'a, WrapXY, F>where
F: Clone + Sync + Send + ForbidPattern,
pub fn new_forbid<R: Rng>(
output_size: Size,
global_stats: &'a GlobalStats,
forbid: F,
rng: &mut R
) -> Self
source§impl<'a, W: Wrap, F> RunOwn<'a, W, F>where
F: Clone + Sync + Send + ForbidPattern,
impl<'a, W: Wrap, F> RunOwn<'a, W, F>where
F: Clone + Sync + Send + ForbidPattern,
sourcepub fn new_wrap_forbid<R: Rng>(
output_size: Size,
global_stats: &'a GlobalStats,
wrap: W,
forbid: F,
rng: &mut R
) -> Self
pub fn new_wrap_forbid<R: Rng>(
output_size: Size,
global_stats: &'a GlobalStats,
wrap: W,
forbid: F,
rng: &mut R
) -> Self
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)
}
source§impl<'a, W: Wrap, F> RunOwn<'a, W, F>where
F: Clone + Sync + Send + ForbidPattern,
impl<'a, W: Wrap, F> RunOwn<'a, W, F>where
F: Clone + Sync + Send + ForbidPattern,
sourcepub fn borrow_mut(&mut self) -> RunBorrow<'_, W, ForbidRef<'_, F>>
pub fn borrow_mut(&mut self) -> RunBorrow<'_, W, ForbidRef<'_, F>>
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)
}
pub fn step<R: Rng>(&mut self, rng: &mut R) -> Result<Observe, PropagateError>
sourcepub fn collapse<R: Rng>(&mut self, rng: &mut R) -> Result<(), PropagateError>
pub fn collapse<R: Rng>(&mut self, rng: &mut R) -> Result<(), PropagateError>
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;
}
}
}
}
}
pub fn wave_cell_ref(&self, coord: Coord) -> WaveCellRef<'_>
pub fn wave_cell_ref_iter(&self) -> impl Iterator<Item = WaveCellRef<'_>>
pub fn wave_cell_ref_enumerate(
&self
) -> impl Iterator<Item = (Coord, WaveCellRef<'_>)>
sourcepub fn into_wave(self) -> Wave
pub fn into_wave(self) -> Wave
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;
}
}
}
}
}