use alloc::collections::BTreeMap;
use alloc::string::String;
use alloc::vec::Vec;
use crate::components::{Behavior, BehaviorLiteral};
#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
pub struct BehaviorState {
#[serde(default)]
pub vars: BTreeMap<String, BehaviorLiteral>,
#[serde(default)]
pub fired: Vec<(u32, u64)>,
}
pub trait BehaviorStore: core::fmt::Debug + Send {
fn read(&self) -> Option<BehaviorState>;
fn write(&self, state: &BehaviorState);
}
pub fn def_hash(def: &Behavior) -> u64 {
let bytes = postcard::to_allocvec(def).unwrap_or_default();
let mut hash: u64 = 0xcbf2_9ce4_8422_2325;
for byte in bytes {
hash ^= byte as u64;
hash = hash.wrapping_mul(0x0000_0100_0000_01b3);
}
hash
}
#[cfg(test)]
mod tests {
use super::*;
use crate::components::BehaviorSource;
use crate::ecs::asset_id::AssetId;
use alloc::string::ToString;
#[test]
fn def_hash_tracks_content_not_identity() {
let a = Behavior {
asset_id: AssetId(1),
on: BehaviorSource::Tick,
..Default::default()
};
let same_content = Behavior {
asset_id: AssetId(9),
..a.clone()
};
assert_eq!(def_hash(&a), def_hash(&same_content));
let edited = Behavior {
on: BehaviorSource::Variable("v".to_string()),
..a.clone()
};
assert_ne!(def_hash(&a), def_hash(&edited));
}
}