Skip to content

Commit

Permalink
feat: QueryOne
Browse files Browse the repository at this point in the history
  • Loading branch information
ten3roberts committed Oct 15, 2023
1 parent 9bf18cc commit f2267c9
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 99 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ Consider reading the [User Guide](https://ten3roberts.github.io/flax/guide)

## Features

- [Queries](https://docs.rs/flax/latest/flax/query/struct.Query.html)
- [Declarative component macro](https://docs.rs/flax/latest/flax/macro.component.html)
- [Queries](https://docs.rs/flax/latest/flax/struct.Query.html)
- [Change detection](https://docs.rs/flax/latest/flax/struct.Component.html#method.modified)
- [Query filtering](https://docs.rs/flax/latest/flax/filter/index.html)
- [System execution](https://docs.rs/flax/latest/flax/system/struct.System.html)
Expand All @@ -28,7 +29,6 @@ Consider reading the [User Guide](https://ten3roberts.github.io/flax/guide)
- [Ergonomic entity builder](https://docs.rs/flax/latest/flax/struct.EntityBuilder.html)
- [Serialization and deserialization](https://docs.rs/flax/latest/flax/serialize/)
- [(async) event subscription](https://docs.rs/flax/latest/flax/struct.World.html#method.subscribe)
- [Declarative component macro](https://docs.rs/flax/latest/flax/macro.component.html)
- [Runtime components](https://docs.rs/flax/latest/flax/struct.World.html#method.spawn_component)
- ...and more

Expand Down Expand Up @@ -100,7 +100,7 @@ schedule.execute_par(&mut world)?;
```
## Relations

Flax provides first class many to many relations between entities, which is useful for scene
Flax provides first class many-many relations between entities, which is useful for tree scene
hierarchies, graphs, and physics joints between entities.

Relations can be both state-less or have associated data, like spring or joint strengths.
Expand Down
14 changes: 9 additions & 5 deletions src/entity_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ use atomic_refcell::{AtomicRef, BorrowError, BorrowMutError};
use once_cell::unsync::OnceCell;

use crate::{
archetype::{Archetype, RefMut, Slot},
archetype::{Archetype, RefMut},
entity::EntityLocation,
entry::{Entry, OccupiedEntry, VacantEntry},
error::MissingComponent,
format::EntityFormatter,
name,
query::QueryOne,
writer::{EntityWriter, FnWriter, Missing, Replace, SingleComponentWriter, WriteDedup},
ArchetypeId, Component, ComponentKey, ComponentValue, Entity, Fetch, RelationExt, World,
Component, ComponentKey, ComponentValue, Entity, Fetch, RelationExt, World,
};
use crate::{RelationIter, RelationIterMut};

Expand Down Expand Up @@ -107,8 +107,11 @@ impl<'a> EntityRefMut<'a> {
})
}

pub fn query_one<Q: Fetch<'a>>(&self, query: Q) -> Option<QueryOne<'a, Q>> {
todo!()
/// Perform a query on the entity
pub fn query<'q, Q: Fetch<'q>>(&'q self, query: &'q Q) -> QueryOne<'q, Q> {
let loc = self.loc();
let arch = self.world.archetypes.get(self.loc().arch_id);
QueryOne::new(query, self.world, arch, loc)
}

/// Attempt concurrently access a component mutably using and fail if the component is already borrowed
Expand Down Expand Up @@ -372,7 +375,8 @@ impl<'a> EntityRef<'a> {
.update(self.loc.slot, component, WriteDedup::new(value), tick)
}

pub fn query_one<'q, Q: Fetch<'q>>(&'q self, query: &'q Q) -> QueryOne<'q, Q> {
/// Perform a query on the entity
pub fn query<'q, Q: Fetch<'q>>(&'q self, query: &'q Q) -> QueryOne<'q, Q> {
QueryOne::new(query, self.world, self.arch, self.loc)
}

Expand Down
63 changes: 0 additions & 63 deletions src/fetch/entity_access.rs

This file was deleted.

17 changes: 0 additions & 17 deletions src/fetch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ mod cloned;
mod component;
mod component_mut;
mod copied;
mod entity_access;
mod entity_ref;
mod ext;
mod map;
Expand All @@ -30,7 +29,6 @@ pub use as_deref::*;
pub use cloned::*;
pub use component::*;
pub use component_mut::*;
pub use entity_access::EntityAccess;
pub use entity_ref::*;
pub use ext::FetchExt;
pub use map::Map;
Expand Down Expand Up @@ -349,21 +347,6 @@ macro_rules! tuple_impl {

}

impl<'q, $($ty, )*> EntityAccess<'q> for ($($ty,)*)
where $($ty: EntityAccess<'q>,)*
{
type Item = ($($ty::Item,)*);

fn get(&'q self, entity: &'q EntityRef) -> Option<Self::Item> {
Some(
($(
(self.$idx).get(entity)?,
)*)
)
}


}
impl<'q, $($ty, )*> RandomFetch<'q> for ($($ty,)*)
where $($ty: RandomFetch<'q>,)*
{
Expand Down
10 changes: 7 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,12 @@ pub mod query;
mod relation;
/// System execution
pub mod schedule;

#[cfg(feature = "serde")]
/// Allows for efficient serialization and deserialization of the world and the
/// entities therein
#[cfg(feature = "serde")]
pub mod serialize;

/// Provides tuple utilities like `cloned`
mod util;
/// vtable implementation for dynamic dispatching
Expand All @@ -260,16 +262,18 @@ pub use fetch::{
relations_like, EntityIds, Fetch, FetchExt, FetchItem, Mutable, Opt, OptOr, Relations,
};
pub use metadata::{Debuggable, Exclusive};
pub(crate) use query::ArchetypeSearcher;

pub use query::{
Children, Dfs, DfsBorrow, DfsIter, EntityBorrow, EntityQuery, Planar, Query, QueryBorrow,
QueryIter, Topo,
};
pub use relation::{Relation, RelationExt, RelationIter, RelationIterMut};
pub use schedule::{Schedule, ScheduleBuilder, SystemInfo};
pub use system::{BoxedSystem, SharedResource, System, SystemBuilder};
pub(crate) use vtable::ComponentVTable;
pub use world::{MigratedEntities, ReservedEntityIter, World};

pub(crate) use query::ArchetypeSearcher;
pub(crate) use vtable::ComponentVTable;

#[cfg(feature = "derive")]
pub use flax_derive::*;
8 changes: 3 additions & 5 deletions src/query/one.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
use core::{mem, ops::Deref};

use crate::{
archetype::{Archetype, Slice},
entity::EntityLocation,
fetch::{FetchPrepareData, PreparedFetch},
EntityRef, Fetch, FetchItem, World,
Fetch, FetchItem, World,
};

/// Execute a query on a single entity
pub struct QueryOne<'w, Q: Fetch<'w>> {
prepared: Option<Q::Prepared>,
loc: EntityLocation,
// item: <Q::Prepared as PreparedFetch<'static>>::Item,
}

impl<'w, Q: Fetch<'w>> QueryOne<'w, Q> {
Expand All @@ -31,7 +29,7 @@ impl<'w, Q: Fetch<'w>> QueryOne<'w, Q> {
Self { prepared, loc }
}

/// Fetches the query item from the entity, or `None` if the entity does not match the query
/// Fetch the query item from the entity, or `None` if the entity does not match the query
pub fn get(&mut self) -> Option<<Q as FetchItem<'_>>::Item> {
match &mut self.prepared {
Some(prepared) => {
Expand Down
9 changes: 9 additions & 0 deletions src/world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,16 @@ pub(crate) fn update_entity_loc(
*ns.get_mut(id).expect("Entity is not valid") = loc;
}

/// The main entry point of the ECS
///
/// Holds the entities and components of the ECS.
///
/// Provides methods to spawn, despawn and access entities and components.
///
/// More advanced methods for component accesses are provided through the [`EntityRef`] and [`EntityRefMut`] acquired through [`Self::entity`] and
/// [`Self::entity_mut`], respectively.
///
/// For efficient iteration, change tracking, and graph traversal, see [`Query`](crate::Query)
pub struct World {
entities: EntityStores,
pub(crate) archetypes: Archetypes,
Expand Down
6 changes: 3 additions & 3 deletions tests/entity_access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ fn entity_access() {
let query = &(name().cloned(), a());
let query2 = &(name().cloned(), a().as_mut());
{
let mut query = entity.query_one(query);
let mut query = entity.query(query);
assert_eq!(query.get(), Some(("a".into(), &5)));
}

{
let mut query = entity.query_one(query2);
let mut query = entity.query(query2);
*query.get().unwrap().1 += 1;

assert_eq!(query.get(), Some(("a".into(), &mut 6)));
}

let mut query = entity.query_one(query);
let mut query = entity.query(query);
assert_eq!(query.get(), Some(("a".into(), &6)));
}

0 comments on commit f2267c9

Please sign in to comment.