Compare commits
2 commits
da5e137432
...
540be64f6a
Author | SHA1 | Date | |
---|---|---|---|
540be64f6a | |||
a073f8e520 |
5 changed files with 185 additions and 22 deletions
|
@ -4,18 +4,20 @@ use std::{
|
|||
time::Duration,
|
||||
};
|
||||
|
||||
use crate::{world::ComponentChange, *};
|
||||
use crate::{resources::Resource, world::ComponentChange, *};
|
||||
|
||||
enum CommandsTypes {
|
||||
enum CommandTypes {
|
||||
InsertEntity(EntityObject),
|
||||
RemoveEntity(Entity),
|
||||
UpdateEntity(Entity, ComponentChange),
|
||||
|
||||
Event(TypeId, Box<dyn Any + Send + Sync>),
|
||||
|
||||
InsertResource(TypeId, Box<dyn Resource>),
|
||||
}
|
||||
|
||||
pub struct Commands {
|
||||
commands: Vec<CommandsTypes>,
|
||||
commands: Vec<CommandTypes>,
|
||||
now: Duration,
|
||||
}
|
||||
|
||||
|
@ -35,24 +37,24 @@ impl Commands {
|
|||
let entity = entity_object.as_entity();
|
||||
|
||||
self.commands
|
||||
.push(CommandsTypes::InsertEntity(entity_object));
|
||||
.push(CommandTypes::InsertEntity(entity_object));
|
||||
|
||||
entity
|
||||
}
|
||||
|
||||
pub fn remove_entity(&mut self, entity: Entity) {
|
||||
self.commands.push(CommandsTypes::RemoveEntity(entity));
|
||||
self.commands.push(CommandTypes::RemoveEntity(entity));
|
||||
}
|
||||
|
||||
pub fn insert_component<T: EntityComponent>(&mut self, entity: Entity, component: T) {
|
||||
self.commands.push(CommandsTypes::UpdateEntity(
|
||||
self.commands.push(CommandTypes::UpdateEntity(
|
||||
entity,
|
||||
ComponentChange::Added(TypeId::of::<T>(), Box::new(component)),
|
||||
));
|
||||
}
|
||||
|
||||
pub fn remove_component<T: EntityComponent>(&mut self, entity: Entity) {
|
||||
self.commands.push(CommandsTypes::UpdateEntity(
|
||||
self.commands.push(CommandTypes::UpdateEntity(
|
||||
entity,
|
||||
ComponentChange::Removed(TypeId::of::<T>()),
|
||||
));
|
||||
|
@ -60,20 +62,32 @@ impl Commands {
|
|||
|
||||
pub fn write_event<T: Any + Send + Sync>(&mut self, payload: T) {
|
||||
self.commands
|
||||
.push(CommandsTypes::Event(TypeId::of::<T>(), Box::new(payload)));
|
||||
.push(CommandTypes::Event(TypeId::of::<T>(), Box::new(payload)));
|
||||
}
|
||||
|
||||
pub fn insert_resource<T: Resource>(&mut self, resource: T) {
|
||||
self.commands.push(CommandTypes::InsertResource(
|
||||
TypeId::of::<T>(),
|
||||
Box::new(resource),
|
||||
));
|
||||
}
|
||||
|
||||
pub(crate) fn apply_deferred(self, world: &mut World) -> Result<()> {
|
||||
for command in self.commands {
|
||||
match command {
|
||||
CommandsTypes::InsertEntity(entity_object) => {
|
||||
CommandTypes::InsertEntity(entity_object) => {
|
||||
world.add_entity(entity_object)?;
|
||||
}
|
||||
CommandsTypes::RemoveEntity(entity) => world.remove_entity(entity),
|
||||
CommandsTypes::UpdateEntity(entity, component_change) => {
|
||||
CommandTypes::RemoveEntity(entity) => world.remove_entity(entity),
|
||||
CommandTypes::UpdateEntity(entity, component_change) => {
|
||||
world.component_change(entity, component_change)
|
||||
}
|
||||
CommandsTypes::Event(type_id, any) => world.events.write_payload(type_id, any),
|
||||
CommandTypes::Event(type_id, payload) => {
|
||||
world.events.write_payload(type_id, payload)
|
||||
}
|
||||
CommandTypes::InsertResource(type_id, resource) => {
|
||||
world.resources.insert_resource(type_id, resource)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ pub mod get_disjoint_mut;
|
|||
pub mod resources;
|
||||
mod type_map;
|
||||
mod unsafe_component_store;
|
||||
mod update_testing;
|
||||
mod updates;
|
||||
mod world;
|
||||
|
||||
|
|
|
@ -38,6 +38,10 @@ impl Resources {
|
|||
.flatten()
|
||||
}
|
||||
|
||||
pub(crate) fn insert_resource(&mut self, type_id: TypeId, resource: Box<dyn Resource>) {
|
||||
self.map.insert(type_id, resource);
|
||||
}
|
||||
|
||||
pub fn insert_if_not_exists<T: Resource + Default>(&mut self) {
|
||||
if !self.contains::<T>() {
|
||||
self.insert(T::default());
|
||||
|
|
154
ecs/src/update_testing.rs
Normal file
154
ecs/src/update_testing.rs
Normal file
|
@ -0,0 +1,154 @@
|
|||
#![allow(unused)]
|
||||
|
||||
use anyhow::Result;
|
||||
use std::marker::PhantomData;
|
||||
use std::{ops::Deref, ops::DerefMut};
|
||||
|
||||
use crate::*;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Query<C, F = EmptyFilter>
|
||||
where
|
||||
F: StaticCheckFilter,
|
||||
{
|
||||
entity: Entity,
|
||||
c: C,
|
||||
filter: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<C, F: StaticCheckFilter> Query<C, F> {
|
||||
pub fn entity(&self) -> Entity {
|
||||
self.entity
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, F: StaticCheckFilter> Deref for Query<C, F> {
|
||||
type Target = C;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.c
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, F: StaticCheckFilter> DerefMut for Query<C, F> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.c
|
||||
}
|
||||
}
|
||||
|
||||
trait CreateQueryArchetype<T, R, Func, Filter> {
|
||||
fn create(f: Func) -> Self;
|
||||
}
|
||||
|
||||
pub trait StaticCheckFilter: Send + Sync + Default + Clone {
|
||||
fn check(entity: &EntityObject) -> bool;
|
||||
fn verify_dedup<O: EntityComponent>();
|
||||
}
|
||||
|
||||
impl StaticCheckFilter for EmptyFilter {
|
||||
fn check(_entity: &EntityObject) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn verify_dedup<O>() {}
|
||||
}
|
||||
|
||||
pub struct QueryArchetype {
|
||||
check_entity: Box<dyn Fn(&EntityObject) -> bool + Send + Sync>,
|
||||
create_callback: Box<
|
||||
dyn Fn(
|
||||
&EntityObject,
|
||||
)
|
||||
-> Result<Box<dyn Fn(&mut Commands, &mut World) -> Result<()> + Send + Sync>>
|
||||
+ Send
|
||||
+ Sync,
|
||||
>,
|
||||
|
||||
entities: Vec<Box<dyn Fn(&mut Commands, &mut World) -> Result<()> + Send + Sync>>,
|
||||
}
|
||||
|
||||
macro_rules! impl_query_singleton_update {
|
||||
( $($var:ident $(,)?)+ ) => {
|
||||
impl<Func, Filter, $( $var, )+> CreateQueryArchetype<( $( $var, )+ ), (), Func, Filter> for QueryArchetype
|
||||
where
|
||||
Func: Fn(&mut Commands, Query<( $( &mut $var, )+ ), Filter>) -> Result<()> + Send + Sync + Clone + 'static,
|
||||
Filter: StaticCheckFilter,
|
||||
$(
|
||||
$var: EntityComponent + ComponentDebug,
|
||||
)+
|
||||
{
|
||||
paste::item! {
|
||||
fn create(f: Func) -> Self {
|
||||
$(
|
||||
Filter::verify_dedup::<$var>();
|
||||
)+
|
||||
|
||||
Self {
|
||||
check_entity: Box::new({
|
||||
move |entity| {
|
||||
$(
|
||||
if !entity.components.contains::<$var>() {
|
||||
return false;
|
||||
}
|
||||
)+
|
||||
|
||||
if !Filter::check(entity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}),
|
||||
|
||||
create_callback: Box::new(move |entity| {
|
||||
$(
|
||||
let [< $var:lower >] = UnsafeComponentStore::from(
|
||||
entity.get_component::<$var>()?
|
||||
);
|
||||
)+
|
||||
|
||||
let e = entity.as_entity();
|
||||
let f = f.clone();
|
||||
|
||||
Ok(Box::new(move |commands, _world| {
|
||||
let q = Query {
|
||||
entity: e,
|
||||
c: unsafe { ($([< $var:lower >].as_mut(),)+) },
|
||||
filter: PhantomData,
|
||||
};
|
||||
|
||||
f(commands, q)
|
||||
}))
|
||||
}),
|
||||
|
||||
entities: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_query_singleton_update!(R);
|
||||
|
||||
struct T {}
|
||||
|
||||
impl EntityComponent for T {
|
||||
fn name(&self) -> &str {
|
||||
Self::debug_name()
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentDebug for T {
|
||||
fn debug_name() -> &'static str {
|
||||
"T"
|
||||
}
|
||||
}
|
||||
|
||||
fn system(_commands: &mut Commands, mut _query: Query<&mut T>) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test() {
|
||||
// let q = QueryArchetype::create(system);
|
||||
}
|
|
@ -3,7 +3,6 @@
|
|||
use std::any::TypeId;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
#[cfg(feature = "timings")]
|
||||
use std::time::Instant;
|
||||
|
||||
|
@ -418,15 +417,6 @@ macro_rules! impl_update_filter {
|
|||
};
|
||||
}
|
||||
|
||||
pub struct Query<T, F = EmptyFilter>
|
||||
where
|
||||
F: CheckFilter,
|
||||
{
|
||||
pub components: T,
|
||||
|
||||
d: PhantomData<F>,
|
||||
}
|
||||
|
||||
pub trait AddUpdates<T, R, Func, Filter> {
|
||||
fn add_update(&mut self, name: &str, priority: u32, func: Func, filter: Filter) -> Result<()>;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue