#![feature(use_extern_macros)]
extern crate rand;
extern crate wasm_bindgen;
#[macro_use]
extern crate lazy_static;
use std::sync::Mutex;
use wasm_bindgen::prelude::*;
pub use rand::*;
pub struct MathRandomRng(());
pub fn math_random_rng() -> MathRandomRng {
MathRandomRng(())
}
#[wasm_bindgen]
extern {
#[wasm_bindgen(js_namespace = Math)]
fn random() -> f64;
}
impl Rng for MathRandomRng {
fn next_u32(&mut self) -> u32 {
(random() * (u32::max_value() as f64)) as u32
}
}
pub struct WasmRng(());
pub fn wasm_rng() -> WasmRng {
WasmRng(())
}
lazy_static! {
static ref RNG: Mutex<reseeding::ReseedingRng<IsaacRng, WasmRngReseed>> = {
Mutex::new(reseeding::ReseedingRng::new(math_random_rng().gen(), 32, WasmRngReseed))
};
}
struct WasmRngReseed;
impl reseeding::Reseeder<IsaacRng> for WasmRngReseed {
fn reseed(&mut self, rng: &mut IsaacRng) {
*rng = math_random_rng().gen();
}
}
impl Rng for WasmRng {
fn next_u32(&mut self) -> u32 {
RNG.lock()
.unwrap_or_else(|e| e.into_inner())
.next_u32()
}
fn next_u64(&mut self) -> u64 {
RNG.lock()
.unwrap_or_else(|e| e.into_inner())
.next_u64()
}
fn fill_bytes(&mut self, bytes: &mut [u8]) {
RNG.lock()
.unwrap_or_else(|e| e.into_inner())
.fill_bytes(bytes)
}
}