lyra-engine/crates/lyra-ecs/src/query/dynamic/mod.rs

86 lines
No EOL
2.2 KiB
Rust

use std::ptr::NonNull;
use crate::{World, ComponentColumn, ComponentInfo};
mod view;
pub use view::*;
mod view_one;
pub use view_one::*;
use super::Fetch;
/// Data that rust does not know the type of
pub struct DynamicType {
pub info: ComponentInfo,
pub ptr: NonNull<u8>,
}
impl DynamicType {
pub fn is<T: 'static>(&self) -> bool {
self.info.type_id().is::<T>()
}
}
/// A struct that fetches a dynamic type.
///
/// Currently it can only fetch from archetypes, later it will be able to fetch dynamic
/// resources as well. Its meant to be a single Fetcher for all dynamic types.
///
/// # Safety
/// Internally, this struct has a `NonNull<ComponentColumn>`. You must ensure that the column
/// is not dropped while this is still alive.
pub struct FetchDynamicTypeUnsafe {
pub col: NonNull<ComponentColumn>,
pub info: ComponentInfo,
}
impl<'a> Fetch<'a> for FetchDynamicTypeUnsafe {
type Item = DynamicType;
fn dangling() -> Self {
unreachable!()
}
unsafe fn get_item(&mut self, entity: crate::ArchetypeEntityId) -> Self::Item {
let ptr = unsafe { self.col.as_ref() }.borrow_ptr();
let ptr = NonNull::new_unchecked(ptr.as_ptr()
.add(entity.0 as usize * self.info.layout().size()));
DynamicType {
info: self.info,
ptr,
}
}
}
/// A query for receiving a dynamic type.
///
/// There are no Ref or RefMut variants since this fetches the pointer to the component.
#[derive(Clone, Copy)]
pub struct QueryDynamicType {
info: ComponentInfo,
}
impl QueryDynamicType {
pub fn from_info(info: ComponentInfo) -> Self {
Self {
info,
}
}
pub fn can_visit_archetype(&self, archetype: &crate::archetype::Archetype) -> bool {
archetype.has_column(self.info.type_id())
}
pub unsafe fn fetch<'a>(&self, _world: &'a World, _arch_id: crate::archetype::ArchetypeId, archetype: &'a crate::archetype::Archetype) -> FetchDynamicTypeUnsafe {
let col = archetype.get_column(self.info.type_id())
.expect("You ignored 'can_visit_archetype'!");
FetchDynamicTypeUnsafe {
col: NonNull::from(col),
info: self.info
}
}
}