ecs: Resource -> Global

master
q3k 2021-03-21 16:12:58 +00:00
parent 05e8bb7d1f
commit bf378bd288
6 changed files with 71 additions and 71 deletions

View File

@ -8,8 +8,8 @@ rust_library(
"src/borrow.rs", "src/borrow.rs",
"src/component.rs", "src/component.rs",
"src/componentmap.rs", "src/componentmap.rs",
"src/globalmap.rs",
"src/entity.rs", "src/entity.rs",
"src/resourcemap.rs",
"src/system.rs", "src/system.rs",
"src/world.rs", "src/world.rs",
], ],

View File

@ -8,9 +8,9 @@ pub fn component_id<T: Component>() -> ID {
std::any::TypeId::of::<T>() std::any::TypeId::of::<T>()
} }
pub trait Resource: 'static { pub trait Global: 'static {
} }
pub fn resource_id<T: Resource>() -> ID { pub fn global_id<T: Global>() -> ID {
std::any::TypeId::of::<T>() std::any::TypeId::of::<T>()
} }

View File

@ -5,13 +5,13 @@ use std::ops::{Deref, DerefMut};
use crate::component; use crate::component;
use crate::borrow; use crate::borrow;
struct ResourceMapEntry { struct GlobalMapEntry {
resource: Box<dyn component::Resource>, global: Box<dyn component::Global>,
borrow: Cell<borrow::Flag>, borrow: Cell<borrow::Flag>,
} }
pub struct ResourceMap { pub struct GlobalMap {
value: UnsafeCell<BTreeMap<component::ID, ResourceMapEntry>>, value: UnsafeCell<BTreeMap<component::ID, GlobalMapEntry>>,
borrow: Cell<borrow::Flag>, borrow: Cell<borrow::Flag>,
} }
@ -24,7 +24,7 @@ impl AccessError {
} }
} }
impl ResourceMap { impl GlobalMap {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
value: UnsafeCell::new(BTreeMap::new()), value: UnsafeCell::new(BTreeMap::new()),
@ -32,78 +32,78 @@ impl ResourceMap {
} }
} }
pub fn get<'a, T: component::Resource>(&'a self) -> Result<ResourceRef<'a, T>, AccessError> { pub fn get<'a, T: component::Global>(&'a self) -> Result<GlobalRef<'a, T>, AccessError> {
match borrow::RefMut::new(&self.borrow) { match borrow::RefMut::new(&self.borrow) {
None => Err(AccessError::concurrent()), None => Err(AccessError::concurrent()),
Some(b) => { Some(b) => {
let map = self.value.get(); let map = self.value.get();
unsafe { unsafe {
match (*map).get(&component::resource_id::<T>()) { match (*map).get(&component::global_id::<T>()) {
Some(entry) => { Some(entry) => {
let val = &entry.resource; let val = &entry.global;
match borrow::Ref::new(&entry.borrow) { match borrow::Ref::new(&entry.borrow) {
None => Err(AccessError::concurrent()), None => Err(AccessError::concurrent()),
Some(b2) => { Some(b2) => {
let val = val.as_ref(); let val = val.as_ref();
let val = & *(val as *const (dyn component::Resource) as *const T); let val = & *(val as *const (dyn component::Global) as *const T);
drop(b); drop(b);
Ok(ResourceRef { val, borrow: Some(b2) }) Ok(GlobalRef { val, borrow: Some(b2) })
}, },
} }
}, },
None => Err(AccessError("resource absent from world".to_string())), None => Err(AccessError("global absent from world".to_string())),
} }
} }
} }
} }
} }
pub fn get_mut<'a, T: component::Resource>(&'a self) -> Result<ResourceRefMut<'a, T>, AccessError> { pub fn get_mut<'a, T: component::Global>(&'a self) -> Result<GlobalRefMut<'a, T>, AccessError> {
match borrow::RefMut::new(&self.borrow) { match borrow::RefMut::new(&self.borrow) {
None => Err(AccessError::concurrent()), None => Err(AccessError::concurrent()),
Some(b) => { Some(b) => {
let map = self.value.get(); let map = self.value.get();
unsafe { unsafe {
match (*map).get_mut(&component::resource_id::<T>()) { match (*map).get_mut(&component::global_id::<T>()) {
Some(entry) => { Some(entry) => {
let val = &mut entry.resource; let val = &mut entry.global;
match borrow::RefMut::new(&entry.borrow) { match borrow::RefMut::new(&entry.borrow) {
None => Err(AccessError::concurrent()), None => Err(AccessError::concurrent()),
Some(b2) => { Some(b2) => {
let val = val.as_mut(); let val = val.as_mut();
let val = &mut *(val as *mut (dyn component::Resource) as *mut T); let val = &mut *(val as *mut (dyn component::Global) as *mut T);
drop(b); drop(b);
Ok(ResourceRefMut { val, borrow: Some(b2) }) Ok(GlobalRefMut { val, borrow: Some(b2) })
}, },
} }
}, },
None => Err(AccessError("resource absent from world".to_string())), None => Err(AccessError("global absent from world".to_string())),
} }
} }
} }
} }
} }
pub fn set<'a, T: component::Resource>(&'a self, r: T) -> Result<(), AccessError> { pub fn set<'a, T: component::Global>(&'a self, r: T) -> Result<(), AccessError> {
match borrow::RefMut::new(&self.borrow) { match borrow::RefMut::new(&self.borrow) {
None => Err(AccessError::concurrent()), None => Err(AccessError::concurrent()),
Some(b) => { Some(b) => {
let map = self.value.get(); let map = self.value.get();
let rid = component::resource_id::<T>(); let rid = component::global_id::<T>();
unsafe { unsafe {
match (*map).get_mut(&rid) { match (*map).get_mut(&rid) {
Some(entry) => { Some(entry) => {
match borrow::RefMut::new(&entry.borrow) { match borrow::RefMut::new(&entry.borrow) {
None => { return Err(AccessError::concurrent()); }, None => { return Err(AccessError::concurrent()); },
Some(b2) => { Some(b2) => {
entry.resource = Box::new(r); entry.global = Box::new(r);
drop(b2); drop(b2);
}, },
}; };
}, },
None => { None => {
(*map).insert(rid, ResourceMapEntry { (*map).insert(rid, GlobalMapEntry {
resource: Box::new(r), global: Box::new(r),
borrow: Cell::new(borrow::UNUSED), borrow: Cell::new(borrow::UNUSED),
}); });
}, },
@ -116,12 +116,12 @@ impl ResourceMap {
} }
} }
pub struct ResourceRef<'a, T: component::Resource> { pub struct GlobalRef<'a, T: component::Global> {
val: *const T, val: *const T,
borrow: Option<borrow::Ref<'a>>, borrow: Option<borrow::Ref<'a>>,
} }
impl<'a, T: component::Resource> Deref for ResourceRef<'a, T> { impl<'a, T: component::Global> Deref for GlobalRef<'a, T> {
type Target = T; type Target = T;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
@ -131,24 +131,24 @@ impl<'a, T: component::Resource> Deref for ResourceRef<'a, T> {
} }
} }
impl <'a, T: component::Resource> Drop for ResourceRef<'a, T> { impl <'a, T: component::Global> Drop for GlobalRef<'a, T> {
fn drop(&mut self) { fn drop(&mut self) {
self.borrow = None; self.borrow = None;
} }
} }
pub struct ResourceRefMut<'a, T: component::Resource> { pub struct GlobalRefMut<'a, T: component::Global> {
val: *mut T, val: *mut T,
borrow: Option<borrow::RefMut<'a>>, borrow: Option<borrow::RefMut<'a>>,
} }
impl <'a, T: component::Resource> Drop for ResourceRefMut<'a, T> { impl <'a, T: component::Global> Drop for GlobalRefMut<'a, T> {
fn drop(&mut self) { fn drop(&mut self) {
self.borrow = None; self.borrow = None;
} }
} }
impl <'a, T: component::Resource> Deref for ResourceRefMut<'a, T> { impl <'a, T: component::Global> Deref for GlobalRefMut<'a, T> {
type Target = T; type Target = T;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
unsafe { unsafe {
@ -157,7 +157,7 @@ impl <'a, T: component::Resource> Deref for ResourceRefMut<'a, T> {
} }
} }
impl <'a, T: component::Resource> DerefMut for ResourceRefMut<'a, T> { impl <'a, T: component::Global> DerefMut for GlobalRefMut<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { unsafe {
&mut(*self.val) &mut(*self.val)

View File

@ -2,17 +2,17 @@ pub mod borrow;
pub mod component; pub mod component;
pub mod componentmap; pub mod componentmap;
pub mod entity; pub mod entity;
pub mod resourcemap; pub mod globalmap;
pub mod system; pub mod system;
pub mod world; pub mod world;
pub use component::Component as Component; pub use component::Component as Component;
pub use component::Resource as Resource; pub use component::Global as Global;
pub use world::World as World; pub use world::World as World;
pub use world::ReadComponent as ReadComponent; pub use world::ReadComponent as ReadComponent;
pub use world::ReadWriteComponent as ReadWriteComponent; pub use world::ReadWriteComponent as ReadWriteComponent;
pub use world::ReadResource as ReadResource; pub use world::ReadGlobal as ReadGlobal;
pub use world::ReadWriteResource as ReadWriteResource; pub use world::ReadWriteGlobal as ReadWriteGlobal;
pub use system::System as System; pub use system::System as System;
pub use system::Join as Join; pub use system::Join as Join;
pub use system::Processor as Processor; pub use system::Processor as Processor;

View File

@ -6,7 +6,7 @@ use crate::{
world::{ world::{
ReadComponent, ReadComponentIter, ReadComponent, ReadComponentIter,
ReadWriteComponent, ReadWriteComponentIter, ReadWriteComponent, ReadWriteComponentIter,
ReadResource, ReadWriteResource, ReadGlobal, ReadWriteGlobal,
World, World,
} }
}; };
@ -69,15 +69,15 @@ impl<'a, T: component::Component> AccessComponent<'a> for ReadWriteComponent<'a,
} }
} }
impl<'a, T: component::Resource> Access<'a> for ReadResource<'a, T> { impl<'a, T: component::Global> Access<'a> for ReadGlobal<'a, T> {
fn fetch(world: &'a World) -> Self { fn fetch(world: &'a World) -> Self {
world.resource() world.global()
} }
} }
impl<'a, T: component::Resource> Access<'a> for ReadWriteResource<'a, T> { impl<'a, T: component::Global> Access<'a> for ReadWriteGlobal<'a, T> {
fn fetch(world: &'a World) -> Self { fn fetch(world: &'a World) -> Self {
world.resource_mut() world.global_mut()
} }
} }
@ -197,21 +197,21 @@ impl <'a, J: Join<'a>> Iterator for JoinIter<'a, J> {
mod test { mod test {
use crate::{ use crate::{
component::Component, component::Component,
component::Resource, component::Global,
system, system,
system::Join, system::Join,
world::{ReadComponent, ReadWriteComponent, ReadResource, ReadWriteResource, World}, world::{ReadComponent, ReadWriteComponent, ReadGlobal, ReadWriteGlobal, World},
}; };
#[derive(Clone,Debug,Default)] #[derive(Clone,Debug,Default)]
struct Delta(f32); struct Delta(f32);
impl Resource for Delta {} impl Global for Delta {}
#[derive(Clone,Debug)] #[derive(Clone,Debug)]
struct PhysicsStatus { struct PhysicsStatus {
object_count: u64, object_count: u64,
} }
impl Resource for PhysicsStatus {} impl Global for PhysicsStatus {}
#[derive(Clone,Debug)] #[derive(Clone,Debug)]
struct Position { struct Position {
@ -233,8 +233,8 @@ mod test {
impl<'a> system::System<'a> for Physics { impl<'a> system::System<'a> for Physics {
type SystemData = ( ReadWriteComponent<'a, Position> type SystemData = ( ReadWriteComponent<'a, Position>
, ReadComponent<'a, Velocity> , ReadComponent<'a, Velocity>
, ReadResource<'a, Delta> , ReadGlobal<'a, Delta>
, ReadWriteResource<'a, PhysicsStatus>); , ReadWriteGlobal<'a, PhysicsStatus>);
fn run(&mut self, (pos, vel, delta, status): Self::SystemData) { fn run(&mut self, (pos, vel, delta, status): Self::SystemData) {
let d = delta.get(); let d = delta.get();
@ -254,8 +254,8 @@ mod test {
let mut world = World::new(); let mut world = World::new();
world.new_entity().with(Velocity { x: 0.0, y: 0.0, z: 1.0 }).with(Position { x: 1.0, y: 2.0, z: 3.0 }).build(); world.new_entity().with(Velocity { x: 0.0, y: 0.0, z: 1.0 }).with(Position { x: 1.0, y: 2.0, z: 3.0 }).build();
world.new_entity().with(Velocity { x: 0.0, y: 0.0, z: 2.0 }).with(Position { x: 4.0, y: 5.0, z: 6.0 }).build(); world.new_entity().with(Velocity { x: 0.0, y: 0.0, z: 2.0 }).with(Position { x: 4.0, y: 5.0, z: 6.0 }).build();
world.set_resource(Delta(1.0)); world.set_global(Delta(1.0));
world.set_resource(PhysicsStatus { object_count: 0u64 }); world.set_global(PhysicsStatus { object_count: 0u64 });
let mut p = system::Processor { let mut p = system::Processor {
world: &world, world: &world,
@ -267,9 +267,9 @@ mod test {
assert_eq!(vec![3.0, 6.0], positions.iter().map(|(_, el)| el.z).collect::<Vec<f32>>()); assert_eq!(vec![3.0, 6.0], positions.iter().map(|(_, el)| el.z).collect::<Vec<f32>>());
p.run(); p.run();
assert_eq!(vec![4.0, 8.0], positions.iter().map(|(_, el)| el.z).collect::<Vec<f32>>()); assert_eq!(vec![4.0, 8.0], positions.iter().map(|(_, el)| el.z).collect::<Vec<f32>>());
world.set_resource(Delta(2.0)); world.set_global(Delta(2.0));
p.run(); p.run();
assert_eq!(vec![6.0, 12.0], positions.iter().map(|(_, el)| el.z).collect::<Vec<f32>>()); assert_eq!(vec![6.0, 12.0], positions.iter().map(|(_, el)| el.z).collect::<Vec<f32>>());
assert_eq!(2, world.resource::<PhysicsStatus>().get().object_count); assert_eq!(2, world.global::<PhysicsStatus>().get().object_count);
} }
} }

View File

@ -7,10 +7,10 @@ use crate::componentmap::{
ComponentMapIter, ComponentMapIter,
ComponentMapIterMut, ComponentMapIterMut,
}; };
use crate::resourcemap::{ use crate::globalmap::{
ResourceMap, GlobalMap,
ResourceRef, GlobalRef,
ResourceRefMut, GlobalRefMut,
}; };
use crate::entity; use crate::entity;
use crate::component; use crate::component;
@ -91,31 +91,31 @@ impl <'a, T: component::Component> Iterator for ReadWriteComponentIter<'a, T> {
} }
} }
pub struct ReadResource<'a, T: component::Resource> { pub struct ReadGlobal<'a, T: component::Global> {
world: &'a World, world: &'a World,
phantom: PhantomData<&'a T>, phantom: PhantomData<&'a T>,
} }
impl<'a, T: component::Resource> ReadResource<'a, T> { impl<'a, T: component::Global> ReadGlobal<'a, T> {
pub fn get(&self) -> ResourceRef<'a, T> { pub fn get(&self) -> GlobalRef<'a, T> {
self.world.resources.get::<T>().unwrap() self.world.globals.get::<T>().unwrap()
} }
} }
pub struct ReadWriteResource<'a, T: component::Resource> { pub struct ReadWriteGlobal<'a, T: component::Global> {
world: &'a World, world: &'a World,
phantom: PhantomData<&'a T>, phantom: PhantomData<&'a T>,
} }
impl<'a, T: component::Resource> ReadWriteResource<'a, T> { impl<'a, T: component::Global> ReadWriteGlobal<'a, T> {
pub fn get(&self) -> ResourceRefMut<'a, T> { pub fn get(&self) -> GlobalRefMut<'a, T> {
self.world.resources.get_mut::<T>().unwrap() self.world.globals.get_mut::<T>().unwrap()
} }
} }
pub struct World { pub struct World {
components: BTreeMap<component::ID, ComponentMap>, components: BTreeMap<component::ID, ComponentMap>,
resources: ResourceMap, globals: GlobalMap,
next_id: entity::ID, next_id: entity::ID,
} }
@ -123,7 +123,7 @@ impl World {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
components: BTreeMap::new(), components: BTreeMap::new(),
resources: ResourceMap::new(), globals: GlobalMap::new(),
next_id: 1u64, next_id: 1u64,
} }
} }
@ -158,22 +158,22 @@ impl World {
} }
} }
pub fn resource<'a, T: component::Resource>(&'a self) -> ReadResource<'a, T> { pub fn global<'a, T: component::Global>(&'a self) -> ReadGlobal<'a, T> {
ReadResource { ReadGlobal {
world: self, world: self,
phantom: PhantomData, phantom: PhantomData,
} }
} }
pub fn resource_mut<'a, T: component::Resource>(&'a self) -> ReadWriteResource<'a, T> { pub fn global_mut<'a, T: component::Global>(&'a self) -> ReadWriteGlobal<'a, T> {
ReadWriteResource { ReadWriteGlobal {
world: self, world: self,
phantom: PhantomData, phantom: PhantomData,
} }
} }
pub fn set_resource<T: component::Resource>(&self, r: T) { pub fn set_global<T: component::Global>(&self, r: T) {
self.resources.set(r).unwrap(); self.globals.set(r).unwrap();
} }
} }