| #[derive(Debug)] | |
| pub struct RngFactory { | |
| stack: Vec<XorShiftRng>, | |
| } | |
| #[derive(Debug)] | |
| pub struct RngWrapper { | |
| ptr: Rc<RefCell<RngFactory>>, | |
| rng: XorShiftRng | |
| } | |
| impl Drop for RngWrapper { | |
| fn drop(&mut self) { | |
| let mut factory = self.ptr.borrow_mut(); | |
| factory.stack.pop(); | |
| } | |
| } | |
| impl Deref for RngWrapper { | |
| type Target = XorShiftRng; | |
| fn deref(&self) -> &XorShiftRng { | |
| &self.rng | |
| } | |
| } | |
| impl DerefMut for RngWrapper { | |
| fn deref_mut(&mut self) -> &mut XorShiftRng { | |
| &mut self.rng | |
| } | |
| } | |
| #[derive(Debug)] | |
| pub struct RngGuard { | |
| ptr: Rc<RefCell<RngFactory>>, | |
| } | |
| impl Drop for RngGuard { | |
| fn drop(&mut self) { | |
| let mut factory = self.ptr.borrow_mut(); | |
| factory.stack.pop(); | |
| } | |
| } | |
| thread_local!(static RNG_STACK: Rc<RefCell<RngFactory>> = { | |
| let mut r = match StdRng::new() { | |
| Ok(r) => r, | |
| Err(e) => panic!("could not initialize thread_rng: {}", e) | |
| }; | |
| let x = r.gen(); | |
| let rf = RngFactory { stack: vec![x] }; | |
| Rc::new(RefCell::new(rf)) | |
| }); | |
| pub fn rng_factory() -> RngWrapper { | |
| RNG_STACK.with(|t| { | |
| let mut factory = t.borrow_mut(); | |
| let mut hd = factory.stack.pop().unwrap(); | |
| let n = hd.gen(); | |
| let m = hd.gen(); | |
| factory.stack.push(hd); | |
| factory.stack.push(m); | |
| RngWrapper { | |
| ptr: t.clone(), | |
| rng: n, | |
| } | |
| }) | |
| } | |
| pub fn seed_rng(seed: [u32; 4]) -> RngGuard { | |
| RNG_STACK.with(|t| { | |
| let mut factory = t.borrow_mut(); | |
| factory.stack.push(XorShiftRng::from_seed(seed)); | |
| RngGuard { | |
| ptr: t.clone(), | |
| } | |
| }) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment