lyra-engine/lyra-scripting/src/world.rs

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)))))
}
}