224 lines
6.3 KiB
Rust
224 lines
6.3 KiB
Rust
use std::cell::{Cell, UnsafeCell};
|
|
use std::collections::BTreeMap;
|
|
use std::collections::btree_map::{
|
|
Iter as BTMIter,
|
|
IterMut as BTMIterMut,
|
|
};
|
|
use std::ops::{Deref, DerefMut};
|
|
|
|
use crate::entity;
|
|
use crate::component;
|
|
use crate::borrow;
|
|
|
|
|
|
pub struct ComponentMap {
|
|
value: UnsafeCell<BTreeMap<entity::ID, Box<dyn component::Component>>>,
|
|
borrow: Cell<borrow::Flag>,
|
|
}
|
|
|
|
#[derive(Clone,Debug)]
|
|
pub struct AccessError(String);
|
|
|
|
impl ComponentMap {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
value: UnsafeCell::new(BTreeMap::new()),
|
|
borrow: Cell::new(borrow::UNUSED),
|
|
}
|
|
}
|
|
|
|
pub fn try_iter<'a>(&'a self) -> Result<ComponentMapIter<'a>, AccessError> {
|
|
match borrow::Ref::new(&self.borrow) {
|
|
None => Err(AccessError("already borrowed mutably".to_string())),
|
|
Some(b) => Ok(ComponentMapIter {
|
|
iter: unsafe {
|
|
let map = &*self.value.get();
|
|
map.iter()
|
|
},
|
|
borrow: Some(b),
|
|
}),
|
|
}
|
|
}
|
|
pub fn try_iter_mut<'a>(&'a self) -> Result<ComponentMapIterMut<'a>, AccessError> {
|
|
match borrow::RefMut::new(&self.borrow) {
|
|
None => Err(AccessError("already borrowed mutable".to_string())),
|
|
Some(b) => Ok(ComponentMapIterMut {
|
|
iter: unsafe {
|
|
let map = &mut *self.value.get();
|
|
map.iter_mut()
|
|
},
|
|
borrow: Some(b),
|
|
}),
|
|
}
|
|
}
|
|
|
|
pub fn insert(&self, e: entity::ID, c: Box<dyn component::Component>) -> Result<(), AccessError> {
|
|
match borrow::RefMut::new(&self.borrow) {
|
|
None => Err(AccessError("already borrow mutably".to_string())),
|
|
Some(b) => {
|
|
unsafe {
|
|
let map = &mut *self.value.get();
|
|
map.insert(e, c);
|
|
}
|
|
drop(b);
|
|
Ok(())
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn get_dyn<'a>(&'a self, e: entity::ID) -> Result<RefDyn<'a>, AccessError> {
|
|
unsafe {
|
|
match borrow::Ref::new(&self.borrow) {
|
|
None => Err(AccessError("already borrowed mutably".to_string())),
|
|
Some(b) => {
|
|
let map = &*self.value.get();
|
|
match map.get(&e) {
|
|
None => Err(AccessError("no such entity".to_string())),
|
|
Some(component) => {
|
|
let component = component.as_ref();
|
|
let val = component as *const (dyn component::Component);
|
|
Ok(RefDyn {
|
|
val,
|
|
borrow: Some(b),
|
|
})
|
|
},
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub unsafe fn get<'a, T: component::Component>(&'a self, e: entity::ID) -> Result<Ref<'a, T>, AccessError> {
|
|
match borrow::Ref::new(&self.borrow) {
|
|
None => Err(AccessError("already borrowed mutably".to_string())),
|
|
Some(b) => {
|
|
let map = &*self.value.get();
|
|
match map.get(&e) {
|
|
None => Err(AccessError("no such entity".to_string())),
|
|
Some(component) => {
|
|
let component = component.as_ref();
|
|
let val = component as *const (dyn component::Component) as *const T;
|
|
Ok(Ref {
|
|
val,
|
|
borrow: Some(b),
|
|
})
|
|
},
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub unsafe fn get_mut<'a, T: component::Component>(&'a self, e: entity::ID) -> Result<RefMut<'a, T>, AccessError> {
|
|
match borrow::RefMut::new(&self.borrow) {
|
|
None => Err(AccessError("already borrowed mutably".to_string())),
|
|
Some(b) => {
|
|
let map = &mut*self.value.get();
|
|
match map.get_mut(&e) {
|
|
None => Err(AccessError("no such entity".to_string())),
|
|
Some(component) => {
|
|
let component = component.as_mut();
|
|
let val = component as *mut (dyn component::Component) as *mut T;
|
|
Ok(RefMut {
|
|
val,
|
|
borrow: Some(b),
|
|
})
|
|
},
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct RefDyn<'a> {
|
|
val: *const (dyn component::Component),
|
|
borrow: Option<borrow::Ref<'a>>,
|
|
}
|
|
|
|
impl <'a> Drop for RefDyn<'a> {
|
|
fn drop(&mut self) {
|
|
self.borrow = None;
|
|
}
|
|
}
|
|
|
|
impl <'a> Deref for RefDyn<'a> {
|
|
type Target = dyn component::Component;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
unsafe {
|
|
&(*self.val)
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct Ref<'a, T: component::Component> {
|
|
val: *const T,
|
|
borrow: Option<borrow::Ref<'a>>,
|
|
}
|
|
|
|
impl <'a, T: component::Component> Drop for Ref<'a, T> {
|
|
fn drop(&mut self) {
|
|
self.borrow = None;
|
|
}
|
|
}
|
|
|
|
impl <'a, T: component::Component> Deref for Ref<'a, T> {
|
|
type Target = T;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
unsafe {
|
|
&(*self.val)
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct RefMut<'a, T: component::Component> {
|
|
val: *mut T,
|
|
borrow: Option<borrow::RefMut<'a>>,
|
|
}
|
|
|
|
impl <'a, T: component::Component> Drop for RefMut<'a, T> {
|
|
fn drop(&mut self) {
|
|
self.borrow = None;
|
|
}
|
|
}
|
|
|
|
impl <'a, T: component::Component> Deref for RefMut<'a, T> {
|
|
type Target = T;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
unsafe {
|
|
&(*self.val)
|
|
}
|
|
}
|
|
}
|
|
|
|
impl <'a, T: component::Component> DerefMut for RefMut<'a, T> {
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
unsafe {
|
|
&mut(*self.val)
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct ComponentMapIter<'a> {
|
|
pub iter: BTMIter<'a, entity::ID, Box<dyn component::Component>>,
|
|
borrow: Option<borrow::Ref<'a>>,
|
|
}
|
|
|
|
impl<'a> Drop for ComponentMapIter<'a> {
|
|
fn drop(&mut self) {
|
|
self.borrow = None;
|
|
}
|
|
}
|
|
|
|
pub struct ComponentMapIterMut<'a> {
|
|
pub iter: BTMIterMut<'a, entity::ID, Box<dyn component::Component>>,
|
|
borrow: Option<borrow::RefMut<'a>>,
|
|
}
|
|
|
|
impl<'a> Drop for ComponentMapIterMut<'a> {
|
|
fn drop(&mut self) {
|
|
self.borrow = None;
|
|
}
|
|
}
|