55 lines
1.5 KiB
Rust
55 lines
1.5 KiB
Rust
use std::{ops::Deref, ptr::NonNull, sync::Arc};
|
|
|
|
use lyra_ecs::{World, Entity};
|
|
use parking_lot::{MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
|
|
|
#[derive(Clone)]
|
|
pub struct ScriptEntity(pub Entity);
|
|
|
|
impl std::ops::Deref for ScriptEntity {
|
|
type Target = Entity;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct ScriptWorldPtr(Arc<RwLock<NonNull<World>>>);
|
|
|
|
impl ScriptWorldPtr {
|
|
pub fn read(&self) -> MappedRwLockReadGuard<World> {
|
|
RwLockReadGuard::map(self.0.read(), |p| unsafe { p.as_ref() })
|
|
}
|
|
|
|
pub fn write(&self) -> MappedRwLockWriteGuard<World> {
|
|
RwLockWriteGuard::map(self.0.write(), |p| unsafe { p.as_mut() })
|
|
}
|
|
}
|
|
|
|
// SAFETY: The inner NonNull pointer is wrapped in an Arc<RwLock<>>
|
|
unsafe impl Send for ScriptWorldPtr {}
|
|
unsafe impl Sync for ScriptWorldPtr {}
|
|
|
|
#[derive(Clone)]
|
|
pub struct ScriptWorldPtrGuard(ScriptWorldPtr);
|
|
|
|
impl Deref for ScriptWorldPtrGuard {
|
|
type Target = ScriptWorldPtr;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
impl ScriptWorldPtrGuard {
|
|
/// Creates a new world pointer.
|
|
///
|
|
/// # Safety
|
|
/// The original `&mut World` must not be used while this guard is created.
|
|
/// The [World] may only be accessed through this guard or one of its cloned [ScriptWorldPtr]s.
|
|
#[allow(clippy::arc_with_non_send_sync)]
|
|
pub unsafe fn new(world: &mut World) -> Self {
|
|
ScriptWorldPtrGuard(ScriptWorldPtr(Arc::new(RwLock::new(NonNull::from(world)))))
|
|
}
|
|
} |