From 93f764e1003bb6f35b56b7b91a73ae0ca80282c9 Mon Sep 17 00:00:00 2001 From: HampusM Date: Sat, 10 Aug 2024 18:50:45 +0200 Subject: refactor(ecs): create archetype lookup entries on-the-go --- ecs/src/util.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'ecs/src/util.rs') diff --git a/ecs/src/util.rs b/ecs/src/util.rs index f4f8632..5ec21c7 100644 --- a/ecs/src/util.rs +++ b/ecs/src/util.rs @@ -1,3 +1,6 @@ +use std::cell::Ref; +use std::ops::{Deref, DerefMut}; + pub trait Sortable { type Item; @@ -46,3 +49,50 @@ impl Sortable for Vec self.sort_by_key(func) } } + +#[derive(Debug)] +pub struct RefCellRefMap<'a, Value: 'a, MappedValue: 'a> +{ + mapped_value: MappedValue, + _refcell_ref: Ref<'a, Value>, +} + +impl<'a, Value: 'a, MappedValue: 'a> RefCellRefMap<'a, Value, MappedValue> +{ + pub fn new( + refcell_ref: Ref<'a, Value>, + map_fn: impl Fn(&'a Value) -> MappedValue, + ) -> Self + { + // Convert the lifetime to 'static. This is necessary to make the compiler not + // complain about refcell_ref being moved + // + // SAFETY: This is fine since we pass it to map_fn with the original lifetime 'a + let val_ref = unsafe { &*(&*refcell_ref as *const Value) }; + + let mapped_value = map_fn(val_ref); + + Self { + mapped_value, + _refcell_ref: refcell_ref, + } + } +} + +impl<'a, Value: 'a, MappedValue: 'a> Deref for RefCellRefMap<'a, Value, MappedValue> +{ + type Target = MappedValue; + + fn deref(&self) -> &Self::Target + { + &self.mapped_value + } +} + +impl<'a, Value: 'a, MappedValue: 'a> DerefMut for RefCellRefMap<'a, Value, MappedValue> +{ + fn deref_mut(&mut self) -> &mut Self::Target + { + &mut self.mapped_value + } +} -- cgit v1.2.3-18-g5258