summaryrefslogtreecommitdiff
path: root/ecs/src/util.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ecs/src/util.rs')
-rw-r--r--ecs/src/util.rs50
1 files changed, 50 insertions, 0 deletions
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<Item> Sortable for Vec<Item>
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
+ }
+}