use std::marker::PhantomData;
use bevy_ecs::world::Mut;
use type_map::TypeMap;
use crate::{CapSet, ImmEntity, ImmId, imm_id};
pub struct ImmTypeMap {
type_map: TypeMap,
}
impl ImmTypeMap {
#[inline]
pub(crate) fn new() -> Self {
Self {
type_map: TypeMap::new(),
}
}
#[inline]
pub fn contains<T: 'static>(&self) -> bool {
self.type_map.contains::<T>()
}
#[inline]
pub fn entry<T: 'static>(&mut self) -> type_map::Entry<'_, T> {
self.type_map.entry()
}
#[inline]
pub fn get<T: 'static>(&self) -> Option<&T> {
self.type_map.get()
}
#[inline]
pub fn get_mut<T: 'static>(&mut self) -> Option<&mut T> {
self.type_map.get_mut()
}
#[inline]
pub fn insert<T: 'static>(&mut self, val: T) -> Option<T> {
self.type_map.insert(val)
}
#[inline]
pub fn remove<T: 'static>(&mut self) -> Option<T> {
self.type_map.remove()
}
}
#[must_use = "You want to store processed value"]
pub struct ImmLocalHashMemoryHelper<T> {
key: ImmId,
state: ImmId,
changed: bool,
_ph: PhantomData<T>,
}
impl<T> ImmLocalHashMemoryHelper<T>
where
T: std::hash::Hash,
{
pub fn new<Caps>(
store_on_entity: &mut ImmEntity<Caps>,
memory_key: impl std::hash::Hash,
default_value: &T,
) -> ImmLocalHashMemoryHelper<T>
where
Caps: CapSet,
{
let key = imm_id(memory_key);
let mut changed = false;
let current_key = store_on_entity.hash_get(key).unwrap_or_else(|| {
changed = true;
imm_id(default_value)
});
ImmLocalHashMemoryHelper {
key,
state: current_key,
changed,
_ph: PhantomData,
}
}
pub fn is_stored(&self, value: &T) -> bool {
self.state == imm_id(value)
}
pub fn store(&mut self, value: &T) -> bool {
let value = imm_id(value);
if self.state != value {
self.state = value;
self.changed = true;
true
} else {
false
}
}
pub fn finalize<Caps: CapSet>(self, store_on_entity: &mut ImmEntity<Caps>) {
if self.changed {
store_on_entity.hash_set(self.key, self.state);
}
}
}
pub trait Mutable<T> {
fn read(&self) -> &T;
fn write(&mut self) -> &mut T;
}
impl<T> Mutable<T> for T {
fn read(&self) -> &T {
self
}
fn write(&mut self) -> &mut T {
self
}
}
impl<T> Mutable<T> for Mut<'_, T> {
fn read(&self) -> &T {
self
}
fn write(&mut self) -> &mut T {
self
}
}