#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct MasterSeed(pub u64);
impl MasterSeed {
pub fn from_str(s: &str) -> Self {
Self(seed_from_str(s))
}
pub fn entity(&self, entity_id: u32) -> u64 {
entity_seed(self.0, entity_id)
}
pub fn raw(&self) -> u64 {
self.0
}
}
pub const DEFAULT_MASTER_SEED: &str = "AXICOR";
pub const fn seed_from_str(s: &str) -> u64 {
let bytes = s.as_bytes();
let mut hash: u64 = 0xcbf29ce484222325;
let mut i = 0;
while i < bytes.len() {
hash ^= bytes[i] as u64;
hash = hash.wrapping_mul(0x00000100000001B3);
i += 1;
}
hash
}
#[inline(always)]
pub const fn entity_seed(master_seed: u64, entity_id: u32) -> u64 {
let seed = master_seed
.wrapping_add(entity_id as u64)
.wrapping_add(0x60bee2bee120fc15);
let mut tmp = (seed as u128).wrapping_mul(0xa3b195354a39b70d);
let m1 = (tmp >> 64) ^ tmp;
tmp = m1.wrapping_mul(0x1b03738712fad5c9);
((tmp >> 64) ^ tmp) as u64
}
pub fn random_f32(seed: u64) -> f32 {
let bits = (seed >> 41) as u32 | 0x3F800000;
f32::from_bits(bits) - 1.0
}
pub fn shuffle_indices(len: usize, seed: u64) -> Vec<usize> {
let mut indices: Vec<usize> = (0..len).collect();
let mut s = seed;
for i in (1..len).rev() {
s = entity_seed(s, i as u32);
let j = (s as usize) % (i + 1);
indices.swap(i, j);
}
indices
}
#[cfg(test)]
#[path = "test_seed.rs"]
mod test_seed;