summaryrefslogtreecommitdiff
path: root/engine-ecs/src/lock.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2026-06-08 13:37:40 +0200
committerHampusM <hampus@hampusmat.com>2026-06-08 13:37:40 +0200
commit661ef626dd8b78a199aa76c58f788349cbbcbe46 (patch)
tree85e6b3ee0316c85166b1f211a26560f40964cb76 /engine-ecs/src/lock.rs
parent04bde94d9088f5a7c2a885d812495fa173cd67c0 (diff)
feat(engine-ecs): add support for dyn Any component handles
Diffstat (limited to 'engine-ecs/src/lock.rs')
-rw-r--r--engine-ecs/src/lock.rs70
1 files changed, 54 insertions, 16 deletions
diff --git a/engine-ecs/src/lock.rs b/engine-ecs/src/lock.rs
index fe4e08b..3db29e8 100644
--- a/engine-ecs/src/lock.rs
+++ b/engine-ecs/src/lock.rs
@@ -82,14 +82,33 @@ pub enum Error
}
#[derive(Debug)]
-pub struct ReadGuard<'guard, Value>
+pub struct ReadGuard<'guard, Value: ?Sized>
{
inner: RwLockReadGuard<'guard, Value>,
value_type_name: &'static str,
}
-impl<'guard, Value> ReadGuard<'guard, Value>
+impl<'guard, Value: ?Sized> ReadGuard<'guard, Value>
{
+ pub fn map<NewValue: ?Sized>(
+ this: Self,
+ func: impl FnOnce(&Value) -> &NewValue,
+ ) -> MappedReadGuard<'guard, NewValue>
+ {
+ let value_type_name = this.value_type_name;
+
+ // The 'inner' field cannot be moved out of ReadGuard in a normal way since
+ // ReadGuard implements Drop
+ let inner = unsafe { std::ptr::read(&raw const this.inner) };
+
+ forget(this);
+
+ MappedReadGuard {
+ inner: RwLockReadGuard::map(inner, func),
+ value_type_name: value_type_name,
+ }
+ }
+
pub fn try_map<NewValue>(
this: Self,
func: impl FnOnce(&Value) -> Option<&NewValue>,
@@ -114,7 +133,7 @@ impl<'guard, Value> ReadGuard<'guard, Value>
}
}
-impl<Value> Deref for ReadGuard<'_, Value>
+impl<Value: ?Sized> Deref for ReadGuard<'_, Value>
{
type Target = Value;
@@ -124,7 +143,7 @@ impl<Value> Deref for ReadGuard<'_, Value>
}
}
-impl<Value> Drop for ReadGuard<'_, Value>
+impl<Value: ?Sized> Drop for ReadGuard<'_, Value>
{
fn drop(&mut self)
{
@@ -133,13 +152,13 @@ impl<Value> Drop for ReadGuard<'_, Value>
}
#[derive(Debug)]
-pub struct MappedReadGuard<'guard, Value>
+pub struct MappedReadGuard<'guard, Value: ?Sized>
{
inner: MappedRwLockReadGuard<'guard, Value>,
value_type_name: &'static str,
}
-impl<Value> Deref for MappedReadGuard<'_, Value>
+impl<Value: ?Sized> Deref for MappedReadGuard<'_, Value>
{
type Target = Value;
@@ -149,7 +168,7 @@ impl<Value> Deref for MappedReadGuard<'_, Value>
}
}
-impl<Value> Drop for MappedReadGuard<'_, Value>
+impl<Value: ?Sized> Drop for MappedReadGuard<'_, Value>
{
fn drop(&mut self)
{
@@ -161,14 +180,33 @@ impl<Value> Drop for MappedReadGuard<'_, Value>
}
#[derive(Debug)]
-pub struct WriteGuard<'guard, Value>
+pub struct WriteGuard<'guard, Value: ?Sized>
{
inner: RwLockWriteGuard<'guard, Value>,
value_type_name: &'static str,
}
-impl<'guard, Value> WriteGuard<'guard, Value>
+impl<'guard, Value: ?Sized> WriteGuard<'guard, Value>
{
+ pub fn map<NewValue: ?Sized>(
+ this: Self,
+ func: impl FnOnce(&mut Value) -> &mut NewValue,
+ ) -> MappedWriteGuard<'guard, NewValue>
+ {
+ let value_type_name = this.value_type_name;
+
+ // The 'inner' field cannot be moved out of ReadGuard in a normal way since
+ // ReadGuard implements Drop
+ let inner = unsafe { std::ptr::read(&raw const this.inner) };
+
+ forget(this);
+
+ MappedWriteGuard {
+ inner: RwLockWriteGuard::map(inner, func),
+ value_type_name: value_type_name,
+ }
+ }
+
pub fn try_map<NewValue>(
this: Self,
func: impl FnOnce(&mut Value) -> Option<&mut NewValue>,
@@ -193,7 +231,7 @@ impl<'guard, Value> WriteGuard<'guard, Value>
}
}
-impl<Value> Deref for WriteGuard<'_, Value>
+impl<Value: ?Sized> Deref for WriteGuard<'_, Value>
{
type Target = Value;
@@ -203,7 +241,7 @@ impl<Value> Deref for WriteGuard<'_, Value>
}
}
-impl<Value> DerefMut for WriteGuard<'_, Value>
+impl<Value: ?Sized> DerefMut for WriteGuard<'_, Value>
{
fn deref_mut(&mut self) -> &mut Self::Target
{
@@ -211,7 +249,7 @@ impl<Value> DerefMut for WriteGuard<'_, Value>
}
}
-impl<Value> Drop for WriteGuard<'_, Value>
+impl<Value: ?Sized> Drop for WriteGuard<'_, Value>
{
fn drop(&mut self)
{
@@ -223,13 +261,13 @@ impl<Value> Drop for WriteGuard<'_, Value>
}
#[derive(Debug)]
-pub struct MappedWriteGuard<'guard, Value>
+pub struct MappedWriteGuard<'guard, Value: ?Sized>
{
inner: MappedRwLockWriteGuard<'guard, Value>,
value_type_name: &'static str,
}
-impl<Value> Deref for MappedWriteGuard<'_, Value>
+impl<Value: ?Sized> Deref for MappedWriteGuard<'_, Value>
{
type Target = Value;
@@ -239,7 +277,7 @@ impl<Value> Deref for MappedWriteGuard<'_, Value>
}
}
-impl<Value> DerefMut for MappedWriteGuard<'_, Value>
+impl<Value: ?Sized> DerefMut for MappedWriteGuard<'_, Value>
{
fn deref_mut(&mut self) -> &mut Self::Target
{
@@ -247,7 +285,7 @@ impl<Value> DerefMut for MappedWriteGuard<'_, Value>
}
}
-impl<Value> Drop for MappedWriteGuard<'_, Value>
+impl<Value: ?Sized> Drop for MappedWriteGuard<'_, Value>
{
fn drop(&mut self)
{