Groundwork for dynamic types in archetypes
This commit is contained in:
parent
808cb77040
commit
e867aaeadb
|
@ -1,6 +1,6 @@
|
||||||
use std::{any::TypeId, ptr::{NonNull, self}, alloc::{self, Layout, alloc, dealloc}, mem, collections::HashMap, cell::{RefCell, Ref, RefMut, BorrowError, BorrowMutError}, ops::{DerefMut, Deref}};
|
use std::{any::TypeId, ptr::{NonNull, self}, alloc::{self, Layout, alloc, dealloc}, mem, collections::HashMap, cell::{RefCell, Ref, RefMut, BorrowError, BorrowMutError}, ops::{DerefMut, Deref}};
|
||||||
|
|
||||||
use crate::{world::{Entity, ArchetypeEntityId}, bundle::Bundle, component_info::ComponentInfo};
|
use crate::{world::{Entity, ArchetypeEntityId}, bundle::Bundle, component_info::ComponentInfo, DynTypeId};
|
||||||
|
|
||||||
pub struct ComponentColumn {
|
pub struct ComponentColumn {
|
||||||
data: RefCell<NonNull<u8>>,
|
data: RefCell<NonNull<u8>>,
|
||||||
|
@ -16,8 +16,8 @@ impl Drop for ComponentColumn {
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
// layout of current alloc
|
// layout of current alloc
|
||||||
let layout = Layout::from_size_align_unchecked(self.info.layout.size() * self.capacity,
|
let layout = Layout::from_size_align_unchecked(self.info.layout.size * self.capacity,
|
||||||
self.info.layout.align());
|
self.info.layout.alignment);
|
||||||
dealloc(data, layout);
|
dealloc(data, layout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ impl ComponentColumn {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn new(info: ComponentInfo, capacity: usize) -> Self {
|
pub unsafe fn new(info: ComponentInfo, capacity: usize) -> Self {
|
||||||
let data = ComponentColumn::alloc(info.layout, capacity);
|
let data = ComponentColumn::alloc(info.layout.into_layout_unchecked(), capacity);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
data: RefCell::new(data),
|
data: RefCell::new(data),
|
||||||
|
@ -71,8 +71,8 @@ impl ComponentColumn {
|
||||||
let mut data = self.data.borrow_mut();
|
let mut data = self.data.borrow_mut();
|
||||||
let data = data.deref_mut();
|
let data = data.deref_mut();
|
||||||
|
|
||||||
let dest = NonNull::new_unchecked(data.as_ptr().add(entity_index * self.info.layout.size()));
|
let dest = NonNull::new_unchecked(data.as_ptr().add(entity_index * self.info.layout.size));
|
||||||
ptr::copy_nonoverlapping(comp_src.as_ptr(), dest.as_ptr(), self.info.layout.size());
|
ptr::copy_nonoverlapping(comp_src.as_ptr(), dest.as_ptr(), self.info.layout.size);
|
||||||
self.len += 1;
|
self.len += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ impl ComponentColumn {
|
||||||
let data = data.deref();
|
let data = data.deref();
|
||||||
|
|
||||||
let ptr = NonNull::new_unchecked(data.as_ptr()
|
let ptr = NonNull::new_unchecked(data.as_ptr()
|
||||||
.add(entity_index * self.info.layout.size()))
|
.add(entity_index * self.info.layout.size))
|
||||||
.cast();
|
.cast();
|
||||||
&*ptr.as_ptr()
|
&*ptr.as_ptr()
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ impl ComponentColumn {
|
||||||
|
|
||||||
let p = data.as_ptr()
|
let p = data.as_ptr()
|
||||||
.cast::<T>()
|
.cast::<T>()
|
||||||
.add(entity_index * self.info.layout.size());
|
.add(entity_index * self.info.layout.size);
|
||||||
&mut *p
|
&mut *p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,17 +120,17 @@ impl ComponentColumn {
|
||||||
let mut data = self.data.borrow_mut();
|
let mut data = self.data.borrow_mut();
|
||||||
//let data = data.deref_mut();
|
//let data = data.deref_mut();
|
||||||
|
|
||||||
let mut new_ptr = Self::alloc(self.info.layout, new_capacity);
|
let mut new_ptr = Self::alloc(self.info.layout.into_layout_unchecked(), new_capacity);
|
||||||
|
|
||||||
if self.len > 0 {
|
if self.len > 0 {
|
||||||
ptr::copy_nonoverlapping(data.as_ptr(), new_ptr.as_ptr(), self.len * self.info.layout.size());
|
ptr::copy_nonoverlapping(data.as_ptr(), new_ptr.as_ptr(), self.len * self.info.layout.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// dont attempt to free if we weren't able to store anything anyway
|
// dont attempt to free if we weren't able to store anything anyway
|
||||||
if self.capacity != 0 {
|
if self.capacity != 0 {
|
||||||
let old_layout = Layout::from_size_align_unchecked(
|
let old_layout = Layout::from_size_align_unchecked(
|
||||||
self.info.layout.size().checked_mul(self.capacity).unwrap(),
|
self.info.layout.size.checked_mul(self.capacity).unwrap(),
|
||||||
self.info.layout.align()
|
self.info.layout.alignment
|
||||||
);
|
);
|
||||||
|
|
||||||
mem::swap(data.deref_mut(), &mut new_ptr);
|
mem::swap(data.deref_mut(), &mut new_ptr);
|
||||||
|
@ -148,14 +148,14 @@ impl ComponentColumn {
|
||||||
let data = data.deref_mut();
|
let data = data.deref_mut();
|
||||||
|
|
||||||
let mut old_comp_ptr = NonNull::new_unchecked(data.as_ptr()
|
let mut old_comp_ptr = NonNull::new_unchecked(data.as_ptr()
|
||||||
.add(entity_index * self.info.layout.size()));
|
.add(entity_index * self.info.layout.size));
|
||||||
|
|
||||||
let moved_index = if entity_index != self.len - 1 {
|
let moved_index = if entity_index != self.len - 1 {
|
||||||
let moved_index = self.len - 1;
|
let moved_index = self.len - 1;
|
||||||
let mut new_comp_ptr = NonNull::new_unchecked(data.as_ptr()
|
let mut new_comp_ptr = NonNull::new_unchecked(data.as_ptr()
|
||||||
.add(moved_index * self.info.layout.size()));
|
.add(moved_index * self.info.layout.size));
|
||||||
|
|
||||||
ptr::copy_nonoverlapping(new_comp_ptr.as_ptr(), old_comp_ptr.as_ptr(), self.info.layout.size());
|
ptr::copy_nonoverlapping(new_comp_ptr.as_ptr(), old_comp_ptr.as_ptr(), self.info.layout.size);
|
||||||
|
|
||||||
mem::swap(&mut old_comp_ptr, &mut new_comp_ptr); // new_comp_ptr is now the old ptr
|
mem::swap(&mut old_comp_ptr, &mut new_comp_ptr); // new_comp_ptr is now the old ptr
|
||||||
Some(moved_index)
|
Some(moved_index)
|
||||||
|
@ -276,7 +276,7 @@ impl Archetype {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a boolean indicating whether this archetype can store the TypeIds given
|
/// Returns a boolean indicating whether this archetype can store the TypeIds given
|
||||||
pub(crate) fn is_archetype_for(&self, types: Vec<TypeId>) -> bool {
|
pub(crate) fn is_archetype_for(&self, types: Vec<DynTypeId>) -> bool {
|
||||||
self.columns.iter().all(|c| types.contains(&c.info.type_id))
|
self.columns.iter().all(|c| types.contains(&c.info.type_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
use std::{any::{TypeId, Any}, ptr::NonNull, mem::size_of};
|
use std::{any::{TypeId, Any}, ptr::NonNull, mem::size_of};
|
||||||
|
|
||||||
use crate::{component::Component, component_info::ComponentInfo};
|
use crate::{component::Component, component_info::ComponentInfo, DynTypeId};
|
||||||
|
|
||||||
pub trait Bundle {
|
pub trait Bundle {
|
||||||
/// Get a list of type ids that this bundle is storing
|
/// Get a list of type ids that this bundle is storing
|
||||||
fn type_ids(&self) -> Vec<TypeId>;
|
fn type_ids(&self) -> Vec<DynTypeId>;
|
||||||
|
|
||||||
/// Get ComponentInfo's for the components in this bundle
|
/// Get ComponentInfo's for the components in this bundle
|
||||||
fn info(&self) -> Vec<ComponentInfo>;
|
fn info(&self) -> Vec<ComponentInfo>;
|
||||||
|
|
||||||
/// Take the bundle by calling the closure with pointers to each component, its type and size.
|
/// Take the bundle by calling the closure with pointers to each component, its type and size.
|
||||||
/// The closure is expected to take ownership of the pointer.
|
/// The closure is expected to take ownership of the pointer.
|
||||||
fn take(self, f: impl FnMut(NonNull<u8>, TypeId, usize));
|
fn take(self, f: impl FnMut(NonNull<u8>, DynTypeId, usize));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The macro below can implement this for us, but this is here for development
|
// The macro below can implement this for us, but this is here for development
|
||||||
impl<C1: Component> Bundle for (C1,) {
|
impl<C1: Component> Bundle for (C1,) {
|
||||||
fn type_ids(&self) -> Vec<TypeId> {
|
fn type_ids(&self) -> Vec<DynTypeId> {
|
||||||
vec![self.0.type_id()]
|
vec![DynTypeId::of::<C1>()]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn info(&self) -> Vec<ComponentInfo> {
|
fn info(&self) -> Vec<ComponentInfo> {
|
||||||
vec![ComponentInfo::new::<C1>()]
|
vec![ComponentInfo::new::<C1>()]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn take(self, mut f: impl FnMut(NonNull<u8>, TypeId, usize)) {
|
fn take(self, mut f: impl FnMut(NonNull<u8>, DynTypeId, usize)) {
|
||||||
let (c1, ) = self;
|
let (c1, ) = self;
|
||||||
|
|
||||||
f(NonNull::from(&c1).cast(), TypeId::of::<C1>(), size_of::<C1>());
|
f(NonNull::from(&c1).cast(), DynTypeId::of::<C1>(), size_of::<C1>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,21 +35,21 @@ macro_rules! impl_bundle_tuple {
|
||||||
( $($name: ident),+ ) => (
|
( $($name: ident),+ ) => (
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
impl<$($name: Component),+> Bundle for ($($name,)+) {
|
impl<$($name: Component),+> Bundle for ($($name,)+) {
|
||||||
fn type_ids(&self) -> Vec<TypeId> {
|
fn type_ids(&self) -> Vec<DynTypeId> {
|
||||||
// these names wont follow rust convention, but its a macro so deal with it
|
// these names wont follow rust convention, but its a macro so deal with it
|
||||||
let ($($name),+) = self;
|
let ($($name),+) = self;
|
||||||
vec![$($name.type_id()),+]
|
vec![$(DynTypeId::of::<$name>()),+]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn info(&self) -> Vec<ComponentInfo> {
|
fn info(&self) -> Vec<ComponentInfo> {
|
||||||
vec![$(ComponentInfo::new::<$name>()),+]
|
vec![$(ComponentInfo::new::<$name>()),+]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn take(self, mut f: impl FnMut(NonNull<u8>, TypeId, usize)) {
|
fn take(self, mut f: impl FnMut(NonNull<u8>, DynTypeId, usize)) {
|
||||||
// these names wont follow rust convention, but its a macro so deal with it
|
// these names wont follow rust convention, but its a macro so deal with it
|
||||||
let ($($name),+) = self;
|
let ($($name),+) = self;
|
||||||
|
|
||||||
$(f(NonNull::from(&$name).cast(), TypeId::of::<$name>(), size_of::<$name>());)+
|
$(f(NonNull::from(&$name).cast(), DynTypeId::of::<$name>(), size_of::<$name>());)+
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,18 +1,91 @@
|
||||||
use std::{any::{TypeId, type_name}, alloc::Layout};
|
use std::{any::{TypeId, type_name}, alloc::{Layout, LayoutError}};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct MemoryLayout {
|
||||||
|
pub size: usize,
|
||||||
|
pub alignment: usize
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryInto<Layout> for MemoryLayout {
|
||||||
|
type Error = LayoutError;
|
||||||
|
|
||||||
|
fn try_into(self) -> Result<Layout, Self::Error> {
|
||||||
|
Layout::from_size_align(self.size, self.alignment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Layout> for MemoryLayout {
|
||||||
|
fn from(value: Layout) -> Self {
|
||||||
|
Self {
|
||||||
|
size: value.size(),
|
||||||
|
alignment: value.align(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MemoryLayout {
|
||||||
|
pub fn new(size: usize, alignment: usize) -> Self {
|
||||||
|
MemoryLayout {
|
||||||
|
size,
|
||||||
|
alignment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn into_layout_unchecked(self) -> Layout {
|
||||||
|
Layout::from_size_align_unchecked(self.size, self.alignment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A dynamic type id. Supports types that are not known to Rust.
|
||||||
|
#[derive(Clone, Copy, Hash, Debug, PartialEq, Eq)]
|
||||||
|
pub enum DynTypeId {
|
||||||
|
Rust(TypeId),
|
||||||
|
Unknown(u128),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<DynTypeId> for u128 {
|
||||||
|
fn into(self) -> DynTypeId {
|
||||||
|
DynTypeId::Unknown(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<TypeId> for DynTypeId {
|
||||||
|
fn from(value: TypeId) -> Self {
|
||||||
|
DynTypeId::Rust(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DynTypeId {
|
||||||
|
pub fn of<T: 'static>() -> Self {
|
||||||
|
Self::Rust(TypeId::of::<T>())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ComponentInfo {
|
pub struct ComponentInfo {
|
||||||
pub type_id: TypeId,
|
pub type_id: DynTypeId,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub layout: Layout,
|
pub layout: MemoryLayout,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ComponentInfo {
|
impl ComponentInfo {
|
||||||
pub fn new<T: 'static>() -> Self {
|
pub fn new<T: 'static>() -> Self {
|
||||||
Self {
|
Self {
|
||||||
type_id: TypeId::of::<T>(),
|
type_id: DynTypeId::from(TypeId::of::<T>()),
|
||||||
name: type_name::<T>().to_string(),
|
name: type_name::<T>().to_string(),
|
||||||
layout: Layout::new::<T>(),
|
layout: MemoryLayout::from(Layout::new::<T>()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create ComponentInfo from a type that is not known to rust
|
||||||
|
pub fn new_unknown<D>(type_id: D, name: &str, layout: MemoryLayout) -> Self
|
||||||
|
where
|
||||||
|
D: Into<DynTypeId>,
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
type_id: type_id.into(),
|
||||||
|
name: name.to_string(),
|
||||||
|
layout,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{marker::PhantomData, any::TypeId, ptr::NonNull, cell::{Ref, RefCell, RefMut}};
|
use std::{marker::PhantomData, any::TypeId, ptr::NonNull, cell::{Ref, RefCell, RefMut}};
|
||||||
|
|
||||||
use crate::{world::World, ComponentColumn};
|
use crate::{world::World, ComponentColumn, DynTypeId};
|
||||||
|
|
||||||
use super::{Fetch, Query, AsQuery};
|
use super::{Fetch, Query, AsQuery};
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ where
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub struct QueryBorrow<T> {
|
pub struct QueryBorrow<T> {
|
||||||
type_id: TypeId,
|
type_id: DynTypeId,
|
||||||
_phantom: PhantomData<T>
|
_phantom: PhantomData<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ impl<T> Clone for QueryBorrow<T> {
|
||||||
impl<T: 'static> QueryBorrow<T> {
|
impl<T: 'static> QueryBorrow<T> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
type_id: TypeId::of::<T>(),
|
type_id: DynTypeId::of::<T>(),
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ where
|
||||||
|
|
||||||
FetchBorrow {
|
FetchBorrow {
|
||||||
col,
|
col,
|
||||||
size: col.info.layout.size(),
|
size: col.info.layout.size,
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ where
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub struct QueryBorrowMut<T> {
|
pub struct QueryBorrowMut<T> {
|
||||||
type_id: TypeId,
|
type_id: DynTypeId,
|
||||||
_phantom: PhantomData<T>
|
_phantom: PhantomData<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ impl<T> Clone for QueryBorrowMut<T> {
|
||||||
impl<T: 'static> QueryBorrowMut<T> {
|
impl<T: 'static> QueryBorrowMut<T> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
type_id: TypeId::of::<T>(),
|
type_id: DynTypeId::of::<T>(),
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ where
|
||||||
|
|
||||||
FetchBorrowMut {
|
FetchBorrowMut {
|
||||||
col,
|
col,
|
||||||
size: col.info.layout.size(),
|
size: col.info.layout.size,
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ impl<T: 'static> AsQuery for &mut T {
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::{any::TypeId, mem::size_of, marker::PhantomData};
|
use std::{any::TypeId, mem::size_of, marker::PhantomData};
|
||||||
|
|
||||||
use crate::{world::{World, Entity, EntityId}, archetype::{Archetype, ArchetypeId}, query::View, tests::Vec2, bundle::Bundle, Fetch};
|
use crate::{world::{World, Entity, EntityId}, archetype::{Archetype, ArchetypeId}, query::View, tests::Vec2, bundle::Bundle, Fetch, DynTypeId};
|
||||||
|
|
||||||
use super::{QueryBorrow, QueryBorrowMut, FetchBorrowMut};
|
use super::{QueryBorrow, QueryBorrowMut, FetchBorrowMut};
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ mod tests {
|
||||||
let world = prepare_world();
|
let world = prepare_world();
|
||||||
|
|
||||||
let borrow = QueryBorrow::<Vec2> {
|
let borrow = QueryBorrow::<Vec2> {
|
||||||
type_id: TypeId::of::<Vec2>(),
|
type_id: DynTypeId::of::<Vec2>(),
|
||||||
_phantom: std::marker::PhantomData,
|
_phantom: std::marker::PhantomData,
|
||||||
};
|
};
|
||||||
let archetypes: Vec<&Archetype> = world.archetypes.values().collect();
|
let archetypes: Vec<&Archetype> = world.archetypes.values().collect();
|
||||||
|
@ -231,7 +231,7 @@ mod tests {
|
||||||
let world = prepare_world();
|
let world = prepare_world();
|
||||||
|
|
||||||
let borrow = QueryBorrowMut::<Vec2> {
|
let borrow = QueryBorrowMut::<Vec2> {
|
||||||
type_id: TypeId::of::<Vec2>(),
|
type_id: DynTypeId::of::<Vec2>(),
|
||||||
_phantom: std::marker::PhantomData,
|
_phantom: std::marker::PhantomData,
|
||||||
};
|
};
|
||||||
let archetypes: Vec<&Archetype> = world.archetypes.values().collect();
|
let archetypes: Vec<&Archetype> = world.archetypes.values().collect();
|
||||||
|
@ -248,7 +248,7 @@ mod tests {
|
||||||
// Now make sure the changes were actually made
|
// Now make sure the changes were actually made
|
||||||
|
|
||||||
let borrow = QueryBorrow::<Vec2> {
|
let borrow = QueryBorrow::<Vec2> {
|
||||||
type_id: TypeId::of::<Vec2>(),
|
type_id: DynTypeId::of::<Vec2>(),
|
||||||
_phantom: std::marker::PhantomData,
|
_phantom: std::marker::PhantomData,
|
||||||
};
|
};
|
||||||
let archetypes: Vec<&Archetype> = world.archetypes.values().collect();
|
let archetypes: Vec<&Archetype> = world.archetypes.values().collect();
|
||||||
|
@ -273,7 +273,7 @@ mod tests {
|
||||||
}, (Vec2::rand(),));
|
}, (Vec2::rand(),));
|
||||||
}
|
}
|
||||||
|
|
||||||
let col = a.columns.iter().find(|c| c.info.type_id == TypeId::of::<Vec2>()).unwrap();
|
let col = a.columns.iter().find(|c| c.info.type_id == DynTypeId::of::<Vec2>()).unwrap();
|
||||||
|
|
||||||
let mut bmut = FetchBorrowMut::<Vec2> {
|
let mut bmut = FetchBorrowMut::<Vec2> {
|
||||||
col,
|
col,
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
|
use crate::{Fetch, world::World, Query};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Hash)]
|
||||||
|
enum TypeId {
|
||||||
|
Rust(std::any::TypeId),
|
||||||
|
Unknown(u128),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Hash)]
|
||||||
|
pub struct DynamicTypeInfo {
|
||||||
|
id: TypeId,
|
||||||
|
size: usize,
|
||||||
|
alignment: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Data that is unknown to rust
|
||||||
|
pub struct DynamicType {
|
||||||
|
info: DynamicTypeInfo,
|
||||||
|
ptr: NonNull<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FetchDynamicType {
|
||||||
|
info: Option<DynamicTypeInfo>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Fetch<'a> for FetchDynamicType {
|
||||||
|
type Item = DynamicType;
|
||||||
|
|
||||||
|
fn dangling() -> Self {
|
||||||
|
Self {
|
||||||
|
info: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn get_item(&mut self, entity: crate::ArchetypeEntityId) -> Self::Item {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct QueryDynamicType {
|
||||||
|
info: DynamicTypeInfo,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Query for QueryDynamicType {
|
||||||
|
type Item<'a> = DynamicType;
|
||||||
|
|
||||||
|
type Fetch<'a> = FetchDynamicType;
|
||||||
|
|
||||||
|
const ALWAYS_FETCHES: bool = false;
|
||||||
|
|
||||||
|
fn new() -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn can_visit_archetype(&self, _archetype: &crate::archetype::Archetype) -> bool {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn fetch<'a>(&self, world: &'a World, _arch_id: crate::archetype::ArchetypeId, _archetype: &'a crate::archetype::Archetype) -> Self::Fetch<'a> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,10 @@ pub mod resource;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
pub use resource::*;
|
pub use resource::*;
|
||||||
|
|
||||||
|
pub mod dynamic;
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
pub use dynamic::*;
|
||||||
|
|
||||||
/// A [`Fetch`]er implementation gets data out of an archetype.
|
/// A [`Fetch`]er implementation gets data out of an archetype.
|
||||||
pub trait Fetch<'a> {
|
pub trait Fetch<'a> {
|
||||||
/// The type that this Fetch yields
|
/// The type that this Fetch yields
|
||||||
|
|
Loading…
Reference in New Issue