Skip to content

Commit

Permalink
Initial query
Browse files Browse the repository at this point in the history
  • Loading branch information
Suficio committed Oct 26, 2022
1 parent 753ca55 commit ba27ee5
Show file tree
Hide file tree
Showing 6 changed files with 423 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod builder;
pub mod inspector;
pub mod lend;
mod loader;
mod query;
mod resource;
mod runtime;
pub mod runtimes;
Expand Down
148 changes: 148 additions & 0 deletions src/query/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
mod ptr;
mod vec;

pub use ptr::{ComponentPtr, ComponentPtrDense};
pub use vec::VecPtr;

#[allow(unreachable_code)]
pub(crate) unsafe fn debug_checked_unreachable() -> ! {
#[cfg(debug_assertions)]
unreachable!();
std::hint::unreachable_unchecked();
}

#[cfg(test)]
mod tests {
use super::*;
use bevy::{
prelude::*,
reflect::{ReflectFromPtr, TypeRegistry},
};

#[derive(Component)]
struct A;

#[derive(Component)]
#[component(storage = "SparseSet")]
struct B;

#[derive(Component, Reflect, PartialEq, Debug)]
struct Data(String);

#[test]
fn query_empty() {
let mut world = World::new();
let component_id = world.init_component::<A>();

let mut query = unsafe {
QueryState::<&ComponentPtrDense, ()>::new_with_state(&mut world, component_id, ())
};
let count = query.iter(&mut world).count();
assert_eq!(count, 0);

let mut query = unsafe {
QueryState::<VecPtr<&ComponentPtrDense>, ()>::new_with_state(
&mut world,
vec![component_id],
(),
)
};
let count = query.iter(&mut world).count();
assert_eq!(count, 0);
}

#[test]
fn query() {
let mut world = World::new();

let a = world.init_component::<A>();
let b = world.init_component::<B>();

world.spawn((A, B));
world.spawn(A);

let mut query =
unsafe { QueryState::<&ComponentPtrDense, ()>::new_with_state(&mut world, a, ()) };
let count = query.iter(&mut world).count();
assert_eq!(count, 2);

let mut query =
unsafe { QueryState::<&ComponentPtr, ()>::new_with_state(&mut world, b, ()) };
let count = query.iter(&mut world).count();
assert_eq!(count, 1);

let mut query = unsafe {
QueryState::<(&ComponentPtrDense, &ComponentPtr), ()>::new_with_state(
&mut world,
(a, b),
(),
)
};
let count = query.iter(&mut world).count();
assert_eq!(count, 1);

// Pick VecPtr<&ComponentPtr> due to presence of &ComponentPtr in query
let mut query = unsafe {
QueryState::<VecPtr<&ComponentPtr>, ()>::new_with_state(&mut world, vec![a, b], ())
};
let count = query.iter(&mut world).count();
assert_eq!(count, 1);
}

#[test]
fn query_data() {
let mut world = World::new();
let type_registry = TypeRegistry::default();
let mut type_registry = type_registry.write();

type_registry.register::<Data>();
let component_id = world.init_component::<Data>();

world.spawn(Data("Hello, World!".to_string()));

let mut query = unsafe {
QueryState::<&ComponentPtrDense, ()>::new_with_state(&mut world, component_id, ())
};

for data in query.iter(&mut world) {
let reflect_data = type_registry.get(std::any::TypeId::of::<Data>()).unwrap();
let reflect_from_ptr = reflect_data.data::<ReflectFromPtr>().unwrap();

let data = unsafe { reflect_from_ptr.as_reflect_ptr(data) };
let data = data.as_any().downcast_ref::<Data>().unwrap();

assert_eq!(data, &Data("Hello, World!".to_string()))
}
}

#[test]
fn query_data_multiple() {
let mut world = World::new();
let type_registry = TypeRegistry::default();
let mut type_registry = type_registry.write();

type_registry.register::<Data>();
let component_id = world.init_component::<Data>();

world.spawn(Data("Hello, World!".to_string()));
world.spawn(Data("Hello, World!".to_string()));
world.spawn(Data("Hello, World!".to_string()));

let mut query = unsafe {
QueryState::<&ComponentPtrDense, ()>::new_with_state(&mut world, component_id, ())
};

let res = query.iter_mut(&mut world).collect::<Vec<_>>();
assert_eq!(res.len(), 3);

for data in res.into_iter() {
let reflect_data = type_registry.get(std::any::TypeId::of::<Data>()).unwrap();
let reflect_from_ptr = reflect_data.data::<ReflectFromPtr>().unwrap();

let data = unsafe { reflect_from_ptr.as_reflect_ptr(data) };
let data = data.as_any().downcast_ref::<Data>().unwrap();

assert_eq!(data.0, "Hello, World!".to_string());
}
}
}
Loading

0 comments on commit ba27ee5

Please sign in to comment.