Update 2024 & move ecs out of engine
This commit is contained in:
parent
b773002bdd
commit
22662557ba
35 changed files with 428 additions and 436 deletions
|
@ -21,7 +21,7 @@ members = [
|
||||||
"map",
|
"map",
|
||||||
"rpg_components",
|
"rpg_components",
|
||||||
"entity_manager",
|
"entity_manager",
|
||||||
"character_window",
|
"character_window", "ecs",
|
||||||
]
|
]
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
name = "config_handler"
|
name = "config_handler"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
name = "networking"
|
name = "networking"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
@ -19,5 +19,5 @@ trust-dns-resolver = { workspace = true, optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
local_ip = ["if-addrs"]
|
local_ip = ["if-addrs"]
|
||||||
public_ip = ["public-ip", "async-std"]
|
public_ip = ["async-std", "public-ip"]
|
||||||
resolve_dns = ["trust-dns-resolver"]
|
resolve_dns = ["trust-dns-resolver"]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "asset"
|
name = "asset"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "character_window"
|
name = "character_window"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
name = "context"
|
name = "context"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["hodasemi <superschneider@t-online.de>"]
|
authors = ["hodasemi <superschneider@t-online.de>"]
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
utilities = { workspace = true }
|
utilities = { workspace = true }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
name = "controllable_thread"
|
name = "controllable_thread"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
|
18
ecs/Cargo.toml
Normal file
18
ecs/Cargo.toml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
[package]
|
||||||
|
name = "ecs"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow.workspace = true
|
||||||
|
destructure_traitobject.workspace = true
|
||||||
|
indexmap.workspace = true
|
||||||
|
serde = { workspace = true, features = ["derive"] }
|
||||||
|
paste.workspace = true
|
||||||
|
ron.workspace = true
|
||||||
|
|
||||||
|
scene_update_macros = { path = "../scene_update_macros" }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
timings = []
|
|
@ -1,24 +1,14 @@
|
||||||
use crate::prelude::*;
|
|
||||||
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use std::any::TypeId;
|
use std::any::TypeId;
|
||||||
use std::cmp::Ordering;
|
|
||||||
use std::{num::ParseIntError, str::FromStr};
|
use std::{num::ParseIntError, str::FromStr};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{ComponentDebug, ComponentNotFoundError, EntityComponent, MultiMut, TypeMap};
|
||||||
|
|
||||||
pub const COMPONENT_SEPARATOR: char = '§';
|
pub const COMPONENT_SEPARATOR: char = '§';
|
||||||
|
|
||||||
// Used for serialisation over network
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
pub struct EntityCreateInfo {
|
|
||||||
gltf_file: Option<String>,
|
|
||||||
network_id: Option<NetworkID>,
|
|
||||||
ignore_transactions: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ComponentCreateInfo<'_> for EntityCreateInfo {}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ActivationState {
|
pub struct ActivationState {
|
||||||
activated: bool,
|
activated: bool,
|
||||||
|
@ -34,7 +24,7 @@ impl ActivationState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EntityObject {
|
pub struct EntityObject<S> {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
pub debug_name: Option<String>,
|
pub debug_name: Option<String>,
|
||||||
|
|
||||||
|
@ -48,16 +38,16 @@ pub struct EntityObject {
|
||||||
pub entity_id: u32,
|
pub entity_id: u32,
|
||||||
|
|
||||||
// component map
|
// component map
|
||||||
pub(crate) components: TypeMap,
|
pub(crate) components: TypeMap<S>,
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
component_names: Vec<String>,
|
component_names: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for EntityObject {}
|
unsafe impl<S> Send for EntityObject<S> {}
|
||||||
unsafe impl Sync for EntityObject {}
|
unsafe impl<S> Sync for EntityObject<S> {}
|
||||||
|
|
||||||
impl EntityObject {
|
impl<S> EntityObject<S> {
|
||||||
pub(crate) fn new(id: u32) -> Self {
|
pub(crate) fn new(id: u32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
|
@ -80,11 +70,11 @@ impl EntityObject {
|
||||||
self.gltf_file.as_ref()
|
self.gltf_file.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn multi_mut(&mut self) -> MultiMut<'_> {
|
pub fn multi_mut(&mut self) -> MultiMut<'_, S> {
|
||||||
self.components.multi_mut()
|
self.components.multi_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_component<T: EntityComponent + ComponentDebug>(
|
pub fn insert_component<T: EntityComponent<S> + ComponentDebug>(
|
||||||
&mut self,
|
&mut self,
|
||||||
component: T,
|
component: T,
|
||||||
) -> Option<T> {
|
) -> Option<T> {
|
||||||
|
@ -108,8 +98,11 @@ impl EntityObject {
|
||||||
pub(crate) fn insert_component_by_id(
|
pub(crate) fn insert_component_by_id(
|
||||||
&mut self,
|
&mut self,
|
||||||
type_id: TypeId,
|
type_id: TypeId,
|
||||||
component: Box<dyn EntityComponent>,
|
component: Box<dyn EntityComponent<S>>,
|
||||||
) -> Option<Box<dyn EntityComponent>> {
|
) -> Option<Box<dyn EntityComponent<S>>>
|
||||||
|
where
|
||||||
|
S: 'static,
|
||||||
|
{
|
||||||
assert!(
|
assert!(
|
||||||
!self.activation_state.is_active(),
|
!self.activation_state.is_active(),
|
||||||
"inserting components while the entity is activated is not allowed"
|
"inserting components while the entity is activated is not allowed"
|
||||||
|
@ -127,7 +120,7 @@ impl EntityObject {
|
||||||
self.components.insert_type(type_id, component)
|
self.components.insert_type(type_id, component)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_component<T: EntityComponent>(&mut self) -> Option<T> {
|
pub fn remove_component<T: EntityComponent<S>>(&mut self) -> Option<T> {
|
||||||
assert!(
|
assert!(
|
||||||
!self.activation_state.is_active(),
|
!self.activation_state.is_active(),
|
||||||
"removing components while the entity is activated is not allowed"
|
"removing components while the entity is activated is not allowed"
|
||||||
|
@ -152,7 +145,10 @@ impl EntityObject {
|
||||||
pub(crate) fn remove_component_by_id(
|
pub(crate) fn remove_component_by_id(
|
||||||
&mut self,
|
&mut self,
|
||||||
type_id: TypeId,
|
type_id: TypeId,
|
||||||
) -> Option<Box<dyn EntityComponent>> {
|
) -> Option<Box<dyn EntityComponent<S>>>
|
||||||
|
where
|
||||||
|
S: 'static,
|
||||||
|
{
|
||||||
assert!(
|
assert!(
|
||||||
!self.activation_state.is_active(),
|
!self.activation_state.is_active(),
|
||||||
"removing components while the entity is activated is not allowed"
|
"removing components while the entity is activated is not allowed"
|
||||||
|
@ -179,19 +175,19 @@ impl EntityObject {
|
||||||
&self.component_names
|
&self.component_names
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_component<T: EntityComponent + ComponentDebug>(
|
pub fn get_component<T: EntityComponent<S> + ComponentDebug>(
|
||||||
&self,
|
&self,
|
||||||
) -> std::result::Result<&T, ComponentNotFoundError> {
|
) -> std::result::Result<&T, ComponentNotFoundError> {
|
||||||
self.components.get()
|
self.components.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_component_mut<T: EntityComponent + ComponentDebug>(
|
pub fn get_component_mut<T: EntityComponent<S> + ComponentDebug>(
|
||||||
&mut self,
|
&mut self,
|
||||||
) -> std::result::Result<&mut T, ComponentNotFoundError> {
|
) -> std::result::Result<&mut T, ComponentNotFoundError> {
|
||||||
self.components.get_mut()
|
self.components.get_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains_component<T: EntityComponent>(&self) -> bool {
|
pub fn contains_component<T: EntityComponent<S>>(&self) -> bool {
|
||||||
self.components.contains::<T>()
|
self.components.contains::<T>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +199,7 @@ impl EntityObject {
|
||||||
Entity { id: self.entity_id }
|
Entity { id: self.entity_id }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone_without_components(&self, engine: &Engine) -> EntityObject {
|
pub(crate) fn clone_without_components(&self, id: u32) -> EntityObject<S> {
|
||||||
EntityObject {
|
EntityObject {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
debug_name: self.debug_name.clone(),
|
debug_name: self.debug_name.clone(),
|
||||||
|
@ -213,17 +209,17 @@ impl EntityObject {
|
||||||
|
|
||||||
activation_state: Default::default(),
|
activation_state: Default::default(),
|
||||||
|
|
||||||
entity_id: engine.assets().get_entity_id(),
|
entity_id: id,
|
||||||
|
|
||||||
// component map
|
// component map
|
||||||
components: TypeMap::new(),
|
components: TypeMap::default(),
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
component_names: Vec::new(),
|
component_names: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone_component_from<T: EntityComponent + ComponentDebug + Clone>(
|
pub fn clone_component_from<T: EntityComponent<S> + ComponentDebug + Clone>(
|
||||||
&mut self,
|
&mut self,
|
||||||
other: &Self,
|
other: &Self,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
@ -240,8 +236,8 @@ pub struct Entity {
|
||||||
pub(crate) id: u32,
|
pub(crate) id: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq<EntityObject> for Entity {
|
impl<S> PartialEq<EntityObject<S>> for Entity {
|
||||||
fn eq(&self, entity: &EntityObject) -> bool {
|
fn eq(&self, entity: &EntityObject<S>) -> bool {
|
||||||
self.id == entity.entity_id
|
self.id == entity.entity_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -265,77 +261,3 @@ impl FromStr for Entity {
|
||||||
Ok(Self { id: s.parse()? })
|
Ok(Self { id: s.parse()? })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
|
||||||
pub struct NetworkID {
|
|
||||||
pub(crate) id: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NetworkID {
|
|
||||||
pub fn display_vector(v: &Vec<Self>) -> String {
|
|
||||||
// add starting bracket
|
|
||||||
let mut s = String::from("[");
|
|
||||||
|
|
||||||
for id in v {
|
|
||||||
s += &format!("{},", id.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove last comma
|
|
||||||
s.pop();
|
|
||||||
|
|
||||||
// add closing bracket
|
|
||||||
s += "]";
|
|
||||||
|
|
||||||
s
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_opt(me: Option<Self>) -> String {
|
|
||||||
match me {
|
|
||||||
Some(nid) => format!("Some({})", nid),
|
|
||||||
None => "None".to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn try_opt(s: &str) -> Result<Option<Self>> {
|
|
||||||
Ok(if s == "None" {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
if !s.starts_with("Some") {
|
|
||||||
panic!("unexpected string when parsing Option<NetworkID>: {}", s);
|
|
||||||
}
|
|
||||||
|
|
||||||
let tmp = s
|
|
||||||
.trim_start_matches("Some")
|
|
||||||
.trim_start_matches('(')
|
|
||||||
.trim_end_matches(')');
|
|
||||||
|
|
||||||
Some(tmp.parse()?)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for NetworkID {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
write!(f, "{}", self.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for NetworkID {
|
|
||||||
type Err = ParseIntError;
|
|
||||||
|
|
||||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
|
||||||
Ok(Self { id: s.parse()? })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Ord for NetworkID {
|
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
|
||||||
self.id.cmp(&other.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialOrd for NetworkID {
|
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
||||||
Some(self.cmp(other))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,20 +5,25 @@ use std::{
|
||||||
ops::DerefMut,
|
ops::DerefMut,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::prelude::SceneContents;
|
pub struct Events<C> {
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct Events {
|
|
||||||
events: HashMap<
|
events: HashMap<
|
||||||
TypeId,
|
TypeId,
|
||||||
(
|
(
|
||||||
Vec<Box<dyn Any + Send + Sync>>,
|
Vec<Box<dyn Any + Send + Sync>>,
|
||||||
Vec<Box<dyn Fn(&mut SceneContents<'_>, &dyn Any) -> anyhow::Result<()> + Send + Sync>>,
|
Vec<Box<dyn Fn(&mut C, &dyn Any) -> anyhow::Result<()> + Send + Sync>>,
|
||||||
),
|
),
|
||||||
>,
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Events {
|
impl<C> Default for Events<C> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
events: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C> Events<C> {
|
||||||
pub(crate) fn clone_from_register(&self) -> Self {
|
pub(crate) fn clone_from_register(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
events: self
|
events: self
|
||||||
|
@ -54,13 +59,13 @@ impl Events {
|
||||||
|
|
||||||
pub fn add_reader<T: Any + Send + Sync, F>(&mut self, f: F)
|
pub fn add_reader<T: Any + Send + Sync, F>(&mut self, f: F)
|
||||||
where
|
where
|
||||||
F: Fn(&mut SceneContents<'_>, &T) -> anyhow::Result<()> + Send + Sync + 'static,
|
F: Fn(&mut C, &T) -> anyhow::Result<()> + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
match self.events.get_mut(&TypeId::of::<T>()) {
|
match self.events.get_mut(&TypeId::of::<T>()) {
|
||||||
Some((_, listener)) => listener.push(Box::new(move |scene, payload| {
|
Some((_, listener)) => listener.push(Box::new(move |c, payload| {
|
||||||
let typed_payload: &T = payload.downcast_ref().unwrap();
|
let typed_payload: &T = payload.downcast_ref().unwrap();
|
||||||
|
|
||||||
f(scene, typed_payload)
|
f(c, typed_payload)
|
||||||
})),
|
})),
|
||||||
None => panic!("register event type first!"),
|
None => panic!("register event type first!"),
|
||||||
}
|
}
|
||||||
|
@ -73,11 +78,11 @@ impl Events {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fire_events(&mut self, scene: &mut SceneContents<'_>) -> anyhow::Result<()> {
|
pub(crate) fn fire_events(&mut self, c: &mut C) -> anyhow::Result<()> {
|
||||||
for (payloads, listeners) in self.events.values_mut() {
|
for (payloads, listeners) in self.events.values_mut() {
|
||||||
for payload in payloads.iter_mut() {
|
for payload in payloads.iter_mut() {
|
||||||
for listener in listeners.iter_mut() {
|
for listener in listeners.iter_mut() {
|
||||||
(listener)(scene, payload.deref_mut())?;
|
(listener)(c, payload.deref_mut())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
17
ecs/src/lib.rs
Normal file
17
ecs/src/lib.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
mod entity;
|
||||||
|
mod events;
|
||||||
|
mod resources;
|
||||||
|
mod type_map;
|
||||||
|
mod unsafe_component_store;
|
||||||
|
mod updates;
|
||||||
|
mod world;
|
||||||
|
|
||||||
|
pub use crate::entity::{Entity, EntityObject};
|
||||||
|
pub use crate::events::Events;
|
||||||
|
pub use crate::resources::{ResourceMultiMut, Resources};
|
||||||
|
pub use crate::type_map::{
|
||||||
|
ComponentCreateInfo, ComponentDebug, ComponentNotFoundError, EntityComponent, MultiMut, TypeMap,
|
||||||
|
};
|
||||||
|
pub use crate::unsafe_component_store::UnsafeComponentStore;
|
||||||
|
pub use crate::updates::*;
|
||||||
|
pub use crate::world::World;
|
|
@ -2,8 +2,8 @@ use std::mem::transmute;
|
||||||
use std::{
|
use std::{
|
||||||
any::{Any, TypeId},
|
any::{Any, TypeId},
|
||||||
collections::{
|
collections::{
|
||||||
hash_map::{Iter, IterMut},
|
|
||||||
HashMap,
|
HashMap,
|
||||||
|
hash_map::{Iter, IterMut},
|
||||||
},
|
},
|
||||||
fmt::Display,
|
fmt::Display,
|
||||||
};
|
};
|
||||||
|
@ -12,14 +12,12 @@ use anyhow::Result;
|
||||||
use destructure_traitobject;
|
use destructure_traitobject;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::prelude::*;
|
pub trait EntityComponent<S>: Any + Send + Sync {
|
||||||
|
fn enable(&mut self, _scene: &mut S) -> Result<()> {
|
||||||
pub trait EntityComponent: Any + Send + Sync {
|
|
||||||
fn enable(&mut self, _scene: &mut Scene) -> Result<()> {
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn disable(&mut self, _scene: &mut Scene) -> Result<()> {
|
fn disable(&mut self, _scene: &mut S) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,19 +45,20 @@ pub trait ComponentCreateInfo<'de>: Serialize + Deserialize<'de> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
pub struct TypeMap<S> {
|
||||||
pub struct TypeMap {
|
map: HashMap<TypeId, Box<dyn EntityComponent<S>>>,
|
||||||
map: HashMap<TypeId, Box<dyn EntityComponent>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeMap {
|
impl<S> Default for TypeMap<S> {
|
||||||
pub fn new() -> Self {
|
fn default() -> Self {
|
||||||
TypeMap {
|
Self {
|
||||||
map: HashMap::new(),
|
map: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn insert<T: EntityComponent + ComponentDebug>(&mut self, value: T) -> Option<T> {
|
impl<S> TypeMap<S> {
|
||||||
|
pub fn insert<T: EntityComponent<S> + ComponentDebug>(&mut self, value: T) -> Option<T> {
|
||||||
self.map
|
self.map
|
||||||
.insert(TypeId::of::<T>(), Box::new(value))
|
.insert(TypeId::of::<T>(), Box::new(value))
|
||||||
.map(|any| *Self::downcast_unchecked(any))
|
.map(|any| *Self::downcast_unchecked(any))
|
||||||
|
@ -68,21 +67,21 @@ impl TypeMap {
|
||||||
pub fn insert_type(
|
pub fn insert_type(
|
||||||
&mut self,
|
&mut self,
|
||||||
type_id: TypeId,
|
type_id: TypeId,
|
||||||
component: Box<dyn EntityComponent>,
|
component: Box<dyn EntityComponent<S>>,
|
||||||
) -> Option<Box<dyn EntityComponent>> {
|
) -> Option<Box<dyn EntityComponent<S>>> {
|
||||||
self.map.insert(type_id, component)
|
self.map.insert(type_id, component)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove<T: EntityComponent>(&mut self) -> Option<T> {
|
pub fn remove<T: EntityComponent<S>>(&mut self) -> Option<T> {
|
||||||
self.remove_by_type_id(&TypeId::of::<T>())
|
self.remove_by_type_id(&TypeId::of::<T>())
|
||||||
.map(|any| *Self::downcast_unchecked(any))
|
.map(|any| *Self::downcast_unchecked(any))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_by_type_id(&mut self, type_id: &TypeId) -> Option<Box<dyn EntityComponent>> {
|
pub fn remove_by_type_id(&mut self, type_id: &TypeId) -> Option<Box<dyn EntityComponent<S>>> {
|
||||||
self.map.remove(type_id)
|
self.map.remove(type_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get<T: EntityComponent + ComponentDebug>(
|
pub fn get<T: EntityComponent<S> + ComponentDebug>(
|
||||||
&self,
|
&self,
|
||||||
) -> std::result::Result<&T, ComponentNotFoundError> {
|
) -> std::result::Result<&T, ComponentNotFoundError> {
|
||||||
self.map
|
self.map
|
||||||
|
@ -94,13 +93,13 @@ impl TypeMap {
|
||||||
pub fn get_by_type_id(
|
pub fn get_by_type_id(
|
||||||
&self,
|
&self,
|
||||||
type_id: &TypeId,
|
type_id: &TypeId,
|
||||||
) -> std::result::Result<&Box<dyn EntityComponent>, ComponentNotFoundError> {
|
) -> std::result::Result<&Box<dyn EntityComponent<S>>, ComponentNotFoundError> {
|
||||||
self.map
|
self.map
|
||||||
.get(type_id)
|
.get(type_id)
|
||||||
.ok_or_else(|| ComponentNotFoundError::type_id(*type_id))
|
.ok_or_else(|| ComponentNotFoundError::type_id(*type_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mut<T: EntityComponent + ComponentDebug>(
|
pub fn get_mut<T: EntityComponent<S> + ComponentDebug>(
|
||||||
&mut self,
|
&mut self,
|
||||||
) -> std::result::Result<&mut T, ComponentNotFoundError> {
|
) -> std::result::Result<&mut T, ComponentNotFoundError> {
|
||||||
self.map
|
self.map
|
||||||
|
@ -112,13 +111,13 @@ impl TypeMap {
|
||||||
pub fn get_mut_by_type_id(
|
pub fn get_mut_by_type_id(
|
||||||
&mut self,
|
&mut self,
|
||||||
type_id: &TypeId,
|
type_id: &TypeId,
|
||||||
) -> std::result::Result<&mut Box<dyn EntityComponent>, ComponentNotFoundError> {
|
) -> std::result::Result<&mut Box<dyn EntityComponent<S>>, ComponentNotFoundError> {
|
||||||
self.map
|
self.map
|
||||||
.get_mut(type_id)
|
.get_mut(type_id)
|
||||||
.ok_or_else(|| ComponentNotFoundError::type_id(*type_id))
|
.ok_or_else(|| ComponentNotFoundError::type_id(*type_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains<T: EntityComponent>(&self) -> bool {
|
pub fn contains<T: EntityComponent<S>>(&self) -> bool {
|
||||||
self.contains_type_id(&TypeId::of::<T>())
|
self.contains_type_id(&TypeId::of::<T>())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,24 +125,24 @@ impl TypeMap {
|
||||||
self.map.contains_key(type_id)
|
self.map.contains_key(type_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn multi_mut(&mut self) -> MultiMut<'_> {
|
pub fn multi_mut(&mut self) -> MultiMut<'_, S> {
|
||||||
MultiMut::new(&mut self.map)
|
MultiMut::new(&mut self.map)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter(&self) -> Iter<'_, TypeId, Box<dyn EntityComponent>> {
|
pub fn iter(&self) -> Iter<'_, TypeId, Box<dyn EntityComponent<S>>> {
|
||||||
self.map.iter()
|
self.map.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_mut(&mut self) -> IterMut<'_, TypeId, Box<dyn EntityComponent>> {
|
pub fn iter_mut(&mut self) -> IterMut<'_, TypeId, Box<dyn EntityComponent<S>>> {
|
||||||
self.map.iter_mut()
|
self.map.iter_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn downcast_unchecked<T: EntityComponent>(boxed: Box<dyn EntityComponent>) -> Box<T> {
|
fn downcast_unchecked<T: EntityComponent<S>>(boxed: Box<dyn EntityComponent<S>>) -> Box<T> {
|
||||||
unsafe { Box::from_raw(Box::into_raw(boxed) as *mut T) }
|
unsafe { Box::from_raw(Box::into_raw(boxed) as *mut T) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn downcast_ref_unchecked<T: EntityComponent>(
|
pub fn downcast_ref_unchecked<T: EntityComponent<S>>(
|
||||||
boxed_ref: &Box<dyn EntityComponent>,
|
boxed_ref: &Box<dyn EntityComponent<S>>,
|
||||||
) -> &T {
|
) -> &T {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr_to_ptr: *const *const T =
|
let ptr_to_ptr: *const *const T =
|
||||||
|
@ -153,8 +152,8 @@ impl TypeMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn downcast_mut_unchecked<T: EntityComponent>(
|
pub fn downcast_mut_unchecked<T: EntityComponent<S>>(
|
||||||
boxed_ref: &mut Box<dyn EntityComponent>,
|
boxed_ref: &mut Box<dyn EntityComponent<S>>,
|
||||||
) -> &mut T {
|
) -> &mut T {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr_to_ptr: *mut *mut T =
|
let ptr_to_ptr: *mut *mut T =
|
||||||
|
@ -166,13 +165,13 @@ impl TypeMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allows mutable access to multiple components at once
|
/// Allows mutable access to multiple components at once
|
||||||
pub struct MultiMut<'a> {
|
pub struct MultiMut<'a, S> {
|
||||||
map: &'a mut HashMap<TypeId, Box<dyn EntityComponent>>,
|
map: &'a mut HashMap<TypeId, Box<dyn EntityComponent<S>>>,
|
||||||
buffer: Vec<*mut Box<dyn EntityComponent>>,
|
buffer: Vec<*mut Box<dyn EntityComponent<S>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> MultiMut<'a> {
|
impl<'a, S> MultiMut<'a, S> {
|
||||||
fn new(map: &'a mut HashMap<TypeId, Box<dyn EntityComponent>>) -> Self {
|
fn new(map: &'a mut HashMap<TypeId, Box<dyn EntityComponent<S>>>) -> Self {
|
||||||
MultiMut {
|
MultiMut {
|
||||||
map,
|
map,
|
||||||
buffer: Vec::new(),
|
buffer: Vec::new(),
|
||||||
|
@ -180,7 +179,7 @@ impl<'a> MultiMut<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns requested type on success
|
/// Returns requested type on success
|
||||||
pub fn get<T: EntityComponent + ComponentDebug>(
|
pub fn get<T: EntityComponent<S> + ComponentDebug>(
|
||||||
&mut self,
|
&mut self,
|
||||||
) -> std::result::Result<&'a mut T, ComponentNotFoundError> {
|
) -> std::result::Result<&'a mut T, ComponentNotFoundError> {
|
||||||
self.get_by_type_id(&TypeId::of::<T>())
|
self.get_by_type_id(&TypeId::of::<T>())
|
||||||
|
@ -192,7 +191,7 @@ impl<'a> MultiMut<'a> {
|
||||||
pub fn get_by_type_id(
|
pub fn get_by_type_id(
|
||||||
&mut self,
|
&mut self,
|
||||||
type_id: &TypeId,
|
type_id: &TypeId,
|
||||||
) -> std::result::Result<&'a mut Box<dyn EntityComponent>, ComponentNotFoundError> {
|
) -> std::result::Result<&'a mut Box<dyn EntityComponent<S>>, ComponentNotFoundError> {
|
||||||
match self.map.get_mut(type_id) {
|
match self.map.get_mut(type_id) {
|
||||||
Some(v) => {
|
Some(v) => {
|
||||||
let ptr = v as *mut _;
|
let ptr = v as *mut _;
|
||||||
|
@ -206,7 +205,7 @@ impl<'a> MultiMut<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let t: Option<&'a mut Box<dyn EntityComponent>> = unsafe { transmute(ptr) };
|
let t: Option<&'a mut Box<dyn EntityComponent<S>>> = unsafe { transmute(ptr) };
|
||||||
|
|
||||||
t.ok_or_else(|| ComponentNotFoundError::type_id(*type_id))
|
t.ok_or_else(|| ComponentNotFoundError::type_id(*type_id))
|
||||||
}
|
}
|
||||||
|
@ -262,7 +261,7 @@ struct Test {
|
||||||
z: u32,
|
z: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EntityComponent for Test {
|
impl<S> EntityComponent<S> for Test {
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"Test"
|
"Test"
|
||||||
}
|
}
|
||||||
|
@ -282,7 +281,7 @@ impl PartialEq for Test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn verify_multi_mut() {
|
fn verify_multi_mut() {
|
||||||
let mut map = TypeMap::new();
|
let mut map = TypeMap::<()>::default();
|
||||||
|
|
||||||
map.insert(Test::default());
|
map.insert(Test::default());
|
||||||
|
|
||||||
|
@ -300,7 +299,7 @@ fn verify_multi_mut() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn verify_insert() {
|
fn verify_insert() {
|
||||||
let mut map = TypeMap::new();
|
let mut map = TypeMap::<()>::default();
|
||||||
|
|
||||||
let reference = Test { x: 5, y: 20, z: 30 };
|
let reference = Test { x: 5, y: 20, z: 30 };
|
||||||
|
|
||||||
|
@ -312,7 +311,7 @@ fn verify_insert() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn verify_get() {
|
fn verify_get() {
|
||||||
let mut map = TypeMap::new();
|
let mut map = TypeMap::<()>::default();
|
||||||
|
|
||||||
let reference = Test { x: 5, y: 20, z: 30 };
|
let reference = Test { x: 5, y: 20, z: 30 };
|
||||||
|
|
||||||
|
@ -323,7 +322,7 @@ fn verify_get() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn verify_get_mut() {
|
fn verify_get_mut() {
|
||||||
let mut map = TypeMap::new();
|
let mut map = TypeMap::<()>::default();
|
||||||
|
|
||||||
let reference = Test { x: 5, y: 20, z: 30 };
|
let reference = Test { x: 5, y: 20, z: 30 };
|
||||||
|
|
|
@ -27,7 +27,7 @@ impl<T> UnsafeComponentStore<T> {
|
||||||
"Called UnsafeComponentStore while being empty"
|
"Called UnsafeComponentStore while being empty"
|
||||||
);
|
);
|
||||||
|
|
||||||
self.ptr.as_mut().unwrap()
|
unsafe { self.ptr.as_mut().unwrap() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_init(&self) -> bool {
|
pub fn is_init(&self) -> bool {
|
|
@ -1,7 +1,6 @@
|
||||||
#![allow(clippy::type_complexity)]
|
#![allow(clippy::type_complexity)]
|
||||||
|
|
||||||
use std::any::TypeId;
|
use std::any::TypeId;
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
#[cfg(feature = "timings")]
|
#[cfg(feature = "timings")]
|
||||||
|
@ -13,19 +12,19 @@ use indexmap::IndexMap;
|
||||||
#[cfg(feature = "timings")]
|
#[cfg(feature = "timings")]
|
||||||
use super::super::timings::Timings;
|
use super::super::timings::Timings;
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::*;
|
||||||
use scene_update_macros::implement_pair_update;
|
use scene_update_macros::implement_pair_update;
|
||||||
|
|
||||||
macro_rules! impl_singleton_update {
|
macro_rules! impl_singleton_update {
|
||||||
( $name: ident, $([$var: ident]$(,)?)+ ) => {
|
( $name: ident, $([$var: ident]$(,)?)+ ) => {
|
||||||
impl Archetype {
|
impl<C> Archetype<C> {
|
||||||
paste::item! {
|
paste::item! {
|
||||||
pub fn [<create_ $name>]<F, Filter, $($var,)+>(f: F, filter: Filter) -> Self
|
pub fn [<create_ $name>]<F, Filter, $($var,)+>(f: F, filter: Filter) -> Self
|
||||||
where
|
where
|
||||||
F: Fn(&mut SceneContents<'_>, Entity, $(&mut $var,)+) -> Result<()> + Send + Sync + Clone + 'static,
|
F: Fn(&mut C, Entity, $(&mut $var,)+) -> Result<()> + Send + Sync + Clone + 'static,
|
||||||
Filter: CheckFilter + 'static,
|
Filter: CheckFilter<C> + 'static,
|
||||||
$(
|
$(
|
||||||
$var: EntityComponent + ComponentDebug,
|
$var: EntityComponent<C> + ComponentDebug,
|
||||||
)+
|
)+
|
||||||
{
|
{
|
||||||
$(
|
$(
|
||||||
|
@ -69,13 +68,13 @@ macro_rules! impl_singleton_update {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Func, Filter, $( $var, )+> AddUpdates2<( $( $var, )+ ), Func, Filter> for Updates
|
impl<C, Func, Filter, $( $var, )+> AddUpdates2<C, ( $( $var, )+ ), Func, Filter> for Updates<C>
|
||||||
where
|
where
|
||||||
$(
|
$(
|
||||||
$var: EntityComponent + ComponentDebug,
|
$var: EntityComponent<C> + ComponentDebug,
|
||||||
)+
|
)+
|
||||||
Func: Fn(& mut SceneContents<'_>, Entity, $(&mut $var,)+) -> Result<()> + Send + Sync + Clone + 'static,
|
Func: Fn(& mut C, Entity, $(&mut $var,)+) -> Result<()> + Send + Sync + Clone + 'static,
|
||||||
Filter: CheckFilter + 'static
|
Filter: CheckFilter<C> + 'static
|
||||||
{
|
{
|
||||||
fn add_update(
|
fn add_update(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -83,7 +82,7 @@ macro_rules! impl_singleton_update {
|
||||||
priority: u32,
|
priority: u32,
|
||||||
func: Func,
|
func: Func,
|
||||||
filter: Filter,
|
filter: Filter,
|
||||||
entities: &IndexMap<Entity, EntityObject>
|
entities: &IndexMap<Entity, EntityObject<C>>
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
paste::item! {
|
paste::item! {
|
||||||
self.add(name, priority, Update::Single(Archetype::[<create_ $name>](func, filter)), entities)
|
self.add(name, priority, Update::Single(Archetype::[<create_ $name>](func, filter)), entities)
|
||||||
|
@ -91,13 +90,14 @@ macro_rules! impl_singleton_update {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Func, Filter, $( $var, )+> AddUpdates<( $( $var, )+ ), Func, Filter> for Scene
|
impl<C, Func, Filter, $( $var, )+> AddUpdates<( $( $var, )+ ), Func, Filter> for World<C>
|
||||||
where
|
where
|
||||||
$(
|
$(
|
||||||
$var: EntityComponent + ComponentDebug,
|
$var: EntityComponent<C> + ComponentDebug,
|
||||||
)+
|
)+
|
||||||
Func: Fn(& mut SceneContents<'_>, Entity, $(&mut $var,)+) -> Result<()> + Send + Sync + Clone + 'static,
|
Func: Fn(& mut C, Entity, $(&mut $var,)+) -> Result<()> + Send + Sync + Clone + 'static,
|
||||||
Filter: CheckFilter + 'static
|
Filter: CheckFilter<C> + 'static,
|
||||||
|
C: Send + Sync
|
||||||
{
|
{
|
||||||
fn add_update(
|
fn add_update(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -110,25 +110,25 @@ macro_rules! impl_singleton_update {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scene {
|
// impl Scene {
|
||||||
paste::item! {
|
// paste::item! {
|
||||||
pub fn [<add_ $name _archetype>]<F, Filter, $($var,)+>(&mut self, name: impl ToString, f: F, filter: Filter) -> Result<()>
|
// pub fn [<add_ $name _archetype>]<F, Filter, $($var,)+>(&mut self, name: impl ToString, f: F, filter: Filter) -> Result<()>
|
||||||
where
|
// where
|
||||||
F: Fn(&mut SceneContents<'_>, Entity, $(&mut $var,)+) -> Result<()> + Send + Sync + Clone + 'static,
|
// F: Fn(&mut SceneContents<'_>, Entity, $(&mut $var,)+) -> Result<()> + Send + Sync + Clone + 'static,
|
||||||
Filter: CheckFilter + 'static,
|
// Filter: CheckFilter + 'static,
|
||||||
$(
|
// $(
|
||||||
$var: EntityComponent + ComponentDebug,
|
// $var: EntityComponent + ComponentDebug,
|
||||||
)+
|
// )+
|
||||||
{
|
// {
|
||||||
let mut archetype = Archetype::[<create_ $name>](f, filter);
|
// let mut archetype = Archetype::[<create_ $name>](f, filter);
|
||||||
archetype.setup(&self.entities)?;
|
// archetype.setup(&self.entities)?;
|
||||||
|
|
||||||
self.archetypes.insert(name.to_string(), archetype);
|
// self.archetypes.insert(name.to_string(), archetype);
|
||||||
|
|
||||||
Ok(())
|
// Ok(())
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,19 +139,19 @@ macro_rules! impl_pair_update {
|
||||||
$rhs_id: expr,
|
$rhs_id: expr,
|
||||||
( $([$rhs_little: ident: $rhs_big: ident]$(,)?)+ )
|
( $([$rhs_little: ident: $rhs_big: ident]$(,)?)+ )
|
||||||
) => {
|
) => {
|
||||||
impl ArchetypePair {
|
impl<C> ArchetypePair<C> {
|
||||||
paste::item! {
|
paste::item! {
|
||||||
pub fn [<create_lhs_ $lhs_id _rhs_ $rhs_id>] <F, LeftFilter, RightFilter, $($lhs_big,)+ $($rhs_big,)+>
|
pub fn [<create_lhs_ $lhs_id _rhs_ $rhs_id>] <F, LeftFilter, RightFilter, $($lhs_big,)+ $($rhs_big,)+>
|
||||||
(f: F, left_filter: LeftFilter, right_filter: RightFilter) -> Self
|
(f: F, left_filter: LeftFilter, right_filter: RightFilter) -> Self
|
||||||
where
|
where
|
||||||
F: Fn(&mut SceneContents<'_>, (Entity, $(&mut $lhs_big,)+), (Entity, $(&mut $rhs_big,)+)) -> Result<()> + Send + Sync + Clone + 'static,
|
F: Fn(&mut C, (Entity, $(&mut $lhs_big,)+), (Entity, $(&mut $rhs_big,)+)) -> Result<()> + Send + Sync + Clone + 'static,
|
||||||
LeftFilter: CheckFilter + 'static,
|
LeftFilter: CheckFilter<C> + 'static,
|
||||||
RightFilter: CheckFilter + 'static,
|
RightFilter: CheckFilter<C> + 'static,
|
||||||
$(
|
$(
|
||||||
$rhs_big: EntityComponent + ComponentDebug,
|
$rhs_big: EntityComponent<C> + ComponentDebug,
|
||||||
)+
|
)+
|
||||||
$(
|
$(
|
||||||
$lhs_big: EntityComponent + ComponentDebug,
|
$lhs_big: EntityComponent<C> + ComponentDebug,
|
||||||
)+
|
)+
|
||||||
{
|
{
|
||||||
$(
|
$(
|
||||||
|
@ -220,17 +220,17 @@ macro_rules! impl_pair_update {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Func, LhsFilter, RhsFilter, $( $lhs_big, )+ $($rhs_big,)+> AddUpdates2<( ($( $lhs_big, )+), ($($rhs_big,)+) ), Func, (LhsFilter, RhsFilter)> for Updates
|
impl<C, Func, LhsFilter, RhsFilter, $( $lhs_big, )+ $($rhs_big,)+> AddUpdates2<C, ( ($( $lhs_big, )+), ($($rhs_big,)+) ), Func, (LhsFilter, RhsFilter)> for Updates<C>
|
||||||
where
|
where
|
||||||
$(
|
$(
|
||||||
$rhs_big: EntityComponent + ComponentDebug,
|
$rhs_big: EntityComponent<C> + ComponentDebug,
|
||||||
)+
|
)+
|
||||||
$(
|
$(
|
||||||
$lhs_big: EntityComponent + ComponentDebug,
|
$lhs_big: EntityComponent<C> + ComponentDebug,
|
||||||
)+
|
)+
|
||||||
Func: Fn(& mut SceneContents<'_>, (Entity, $(&mut $lhs_big,)+), (Entity, $(&mut $rhs_big,)+)) -> Result<()> + Send + Sync + Clone + 'static,
|
Func: Fn(& mut C, (Entity, $(&mut $lhs_big,)+), (Entity, $(&mut $rhs_big,)+)) -> Result<()> + Send + Sync + Clone + 'static,
|
||||||
LhsFilter: CheckFilter + 'static,
|
LhsFilter: CheckFilter<C> + 'static,
|
||||||
RhsFilter: CheckFilter + 'static
|
RhsFilter: CheckFilter<C> + 'static
|
||||||
{
|
{
|
||||||
fn add_update(
|
fn add_update(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -238,7 +238,7 @@ macro_rules! impl_pair_update {
|
||||||
priority: u32,
|
priority: u32,
|
||||||
func: Func,
|
func: Func,
|
||||||
filter: (LhsFilter, RhsFilter),
|
filter: (LhsFilter, RhsFilter),
|
||||||
entities: &IndexMap<Entity, EntityObject>
|
entities: &IndexMap<Entity, EntityObject<C>>
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
paste::item! {
|
paste::item! {
|
||||||
self.add(name, priority, Update::Pair(ArchetypePair::[<create_lhs_ $lhs_id _rhs_ $rhs_id>](func, filter.0, filter.1)), entities)?;
|
self.add(name, priority, Update::Pair(ArchetypePair::[<create_lhs_ $lhs_id _rhs_ $rhs_id>](func, filter.0, filter.1)), entities)?;
|
||||||
|
@ -248,17 +248,18 @@ macro_rules! impl_pair_update {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Func, LhsFilter, RhsFilter, $( $lhs_big, )+ $($rhs_big,)+> AddUpdates<( ($( $lhs_big, )+), ($($rhs_big,)+) ), Func, (LhsFilter, RhsFilter)> for Scene
|
impl<C, Func, LhsFilter, RhsFilter, $( $lhs_big, )+ $($rhs_big,)+> AddUpdates<( ($( $lhs_big, )+), ($($rhs_big,)+) ), Func, (LhsFilter, RhsFilter)> for World<C>
|
||||||
where
|
where
|
||||||
$(
|
$(
|
||||||
$rhs_big: EntityComponent + ComponentDebug,
|
$rhs_big: EntityComponent<C> + ComponentDebug,
|
||||||
)+
|
)+
|
||||||
$(
|
$(
|
||||||
$lhs_big: EntityComponent + ComponentDebug,
|
$lhs_big: EntityComponent<C> + ComponentDebug,
|
||||||
)+
|
)+
|
||||||
Func: Fn(& mut SceneContents<'_>, (Entity, $(&mut $lhs_big,)+), (Entity, $(&mut $rhs_big,)+)) -> Result<()> + Send + Sync + Clone + 'static,
|
Func: Fn(& mut C, (Entity, $(&mut $lhs_big,)+), (Entity, $(&mut $rhs_big,)+)) -> Result<()> + Send + Sync + Clone + 'static,
|
||||||
LhsFilter: CheckFilter + 'static,
|
LhsFilter: CheckFilter<C> + 'static,
|
||||||
RhsFilter: CheckFilter + 'static
|
RhsFilter: CheckFilter<C> + 'static,
|
||||||
|
C: Send + Sync
|
||||||
{
|
{
|
||||||
fn add_update(
|
fn add_update(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -271,47 +272,56 @@ macro_rules! impl_pair_update {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Func, Filter, $( $lhs_big, )+ $($rhs_big,)+> AddUpdates<( ($( $lhs_big, )+), ($($rhs_big,)+) ), Func, Filter> for Scene
|
// impl<Func, Filter, $( $lhs_big, )+ $($rhs_big,)+> AddUpdates<( ($( $lhs_big, )+), ($($rhs_big,)+) ), Func, Filter> for Scene
|
||||||
where
|
// where
|
||||||
$(
|
// $(
|
||||||
$rhs_big: EntityComponent + ComponentDebug,
|
// $rhs_big: EntityComponent + ComponentDebug,
|
||||||
)+
|
// )+
|
||||||
$(
|
// $(
|
||||||
$lhs_big: EntityComponent + ComponentDebug,
|
// $lhs_big: EntityComponent + ComponentDebug,
|
||||||
)+
|
// )+
|
||||||
Func: Fn(& mut SceneContents<'_>, (Entity, $(&mut $lhs_big,)+), (Entity, $(&mut $rhs_big,)+)) -> Result<()> + Send + Sync + Clone + 'static,
|
// Func: Fn(& mut SceneContents<'_>, (Entity, $(&mut $lhs_big,)+), (Entity, $(&mut $rhs_big,)+)) -> Result<()> + Send + Sync + Clone + 'static,
|
||||||
Filter: CheckFilter + 'static,
|
// Filter: CheckFilter + 'static,
|
||||||
{
|
// {
|
||||||
fn add_update(
|
// fn add_update(
|
||||||
&mut self,
|
// &mut self,
|
||||||
name: &str,
|
// name: &str,
|
||||||
priority: u32,
|
// priority: u32,
|
||||||
func: Func,
|
// func: Func,
|
||||||
filter: Filter,
|
// filter: Filter,
|
||||||
) -> Result<()> {
|
// ) -> Result<()> {
|
||||||
paste::item! {
|
// paste::item! {
|
||||||
self.updates.add_update(name, priority, func, (filter.clone(), filter), &self.entities)?;
|
// self.updates.add_update(name, priority, func, (filter.clone(), filter), &self.entities)?;
|
||||||
}
|
// }
|
||||||
|
|
||||||
Ok(())
|
// Ok(())
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_update_filter {
|
macro_rules! impl_update_filter {
|
||||||
( $name: ident, $([$big: ident, $little: ident]$(,)?)+ ) => {
|
( $name: ident, $([$big: ident, $little: ident]$(,)?)+ ) => {
|
||||||
paste::item! {
|
paste::item! {
|
||||||
pub struct [<$name Filter>]<$($big: EntityComponent,)+>
|
pub struct [<$name Filter>]<C, $($big: EntityComponent<C>,)+>
|
||||||
|
where
|
||||||
|
C: Send + Sync
|
||||||
{
|
{
|
||||||
|
c: std::marker::PhantomData<C>,
|
||||||
|
|
||||||
$(
|
$(
|
||||||
$little: std::marker::PhantomData<$big>,
|
$little: std::marker::PhantomData<$big>,
|
||||||
)+
|
)+
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<$($big: EntityComponent,)+> Default for [<$name Filter>]<$($big,)+> {
|
impl<C, $($big: EntityComponent<C>,)+> Default for [<$name Filter>]<C, $($big,)+>
|
||||||
|
where
|
||||||
|
C: Send + Sync
|
||||||
|
{
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
c: std::marker::PhantomData,
|
||||||
|
|
||||||
$(
|
$(
|
||||||
$little: std::marker::PhantomData,
|
$little: std::marker::PhantomData,
|
||||||
)+
|
)+
|
||||||
|
@ -319,8 +329,11 @@ macro_rules! impl_update_filter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<$($big: EntityComponent,)+> CheckFilter for [<$name Filter>]<$($big,)+> {
|
impl<C, $($big: EntityComponent<C>,)+> CheckFilter<C> for [<$name Filter>]<C, $($big,)+>
|
||||||
fn check(&self, entity: &EntityObject) -> bool {
|
where
|
||||||
|
C: Send + Sync
|
||||||
|
{
|
||||||
|
fn check(&self, entity: &EntityObject<C>) -> bool {
|
||||||
$(
|
$(
|
||||||
if entity.contains_component::<$big>() {
|
if entity.contains_component::<$big>() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -330,7 +343,7 @@ macro_rules! impl_update_filter {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_dedup<O: EntityComponent>(&self) {
|
fn verify_dedup<O: EntityComponent<C>>(&self) {
|
||||||
$(
|
$(
|
||||||
if TypeId::of::<O>() == TypeId::of::<$big>() {
|
if TypeId::of::<O>() == TypeId::of::<$big>() {
|
||||||
panic!("Type is used as input and filter at the same time");
|
panic!("Type is used as input and filter at the same time");
|
||||||
|
@ -339,9 +352,14 @@ macro_rules! impl_update_filter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<$($big: EntityComponent,)+> Clone for [<$name Filter>]<$($big,)+> {
|
impl<C, $($big: EntityComponent<C>,)+> Clone for [<$name Filter>]<C, $($big,)+>
|
||||||
|
where
|
||||||
|
C: Send + Sync
|
||||||
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
c: self.c.clone(),
|
||||||
|
|
||||||
$(
|
$(
|
||||||
$little: self.$little.clone(),
|
$little: self.$little.clone(),
|
||||||
)+
|
)+
|
||||||
|
@ -352,39 +370,41 @@ macro_rules! impl_update_filter {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Query<T, F = EmptyFilter>
|
pub struct Query<C, T, F = EmptyFilter>
|
||||||
where
|
where
|
||||||
F: CheckFilter,
|
F: CheckFilter<C>,
|
||||||
{
|
{
|
||||||
pub components: T,
|
pub components: T,
|
||||||
|
|
||||||
d: PhantomData<F>,
|
d: PhantomData<F>,
|
||||||
|
c: PhantomData<C>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AddUpdates<T, Func, Filter> {
|
pub trait AddUpdates<T, Func, Filter> {
|
||||||
fn add_update(&mut self, name: &str, priority: u32, func: Func, filter: Filter) -> Result<()>;
|
fn add_update(&mut self, name: &str, priority: u32, func: Func, filter: Filter) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
trait AddUpdates2<T, Func, Filter> {
|
trait AddUpdates2<C, T, Func, Filter> {
|
||||||
fn add_update(
|
fn add_update(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
priority: u32,
|
priority: u32,
|
||||||
func: Func,
|
func: Func,
|
||||||
filter: Filter,
|
filter: Filter,
|
||||||
entities: &IndexMap<Entity, EntityObject>,
|
entities: &IndexMap<Entity, EntityObject<C>>,
|
||||||
) -> Result<()>;
|
) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CheckFilter: Send + Sync + Default + Clone {
|
pub trait CheckFilter<C>: Send + Sync + Default + Clone {
|
||||||
fn check(&self, entity: &EntityObject) -> bool;
|
fn check(&self, entity: &EntityObject<C>) -> bool;
|
||||||
fn verify_dedup<O: EntityComponent>(&self);
|
fn verify_dedup<O: EntityComponent<C>>(&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct EmptyFilter;
|
pub struct EmptyFilter;
|
||||||
|
|
||||||
impl CheckFilter for EmptyFilter {
|
impl<C> CheckFilter<C> for EmptyFilter {
|
||||||
fn check(&self, _entity: &EntityObject) -> bool {
|
fn check(&self, _entity: &EntityObject<C>) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,23 +430,19 @@ impl ArchetypeInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Archetype {
|
pub struct Archetype<C> {
|
||||||
check_entity: Box<dyn Fn(&EntityObject) -> bool + Send + Sync>,
|
check_entity: Box<dyn Fn(&EntityObject<C>) -> bool + Send + Sync>,
|
||||||
create_callback: Box<
|
create_callback: Box<
|
||||||
dyn Fn(
|
dyn Fn(&EntityObject<C>) -> Result<Box<dyn Fn(Entity, &mut C) -> Result<()> + Send + Sync>>
|
||||||
&EntityObject,
|
|
||||||
)
|
|
||||||
-> Result<Box<dyn Fn(Entity, &mut SceneContents<'_>) -> Result<()> + Send + Sync>>
|
|
||||||
+ Send
|
+ Send
|
||||||
+ Sync,
|
+ Sync,
|
||||||
>,
|
>,
|
||||||
|
|
||||||
entities:
|
entities: IndexMap<Entity, Box<dyn Fn(Entity, &mut C) -> Result<()> + Send + Sync>>,
|
||||||
IndexMap<Entity, Box<dyn Fn(Entity, &mut SceneContents<'_>) -> Result<()> + Send + Sync>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Archetype {
|
impl<C> Archetype<C> {
|
||||||
pub fn add_entity(&mut self, entity_object: &EntityObject) -> Result<()> {
|
pub fn add_entity(&mut self, entity_object: &EntityObject<C>) -> Result<()> {
|
||||||
if (self.check_entity)(entity_object) {
|
if (self.check_entity)(entity_object) {
|
||||||
let cb = (self.create_callback)(entity_object)?;
|
let cb = (self.create_callback)(entity_object)?;
|
||||||
|
|
||||||
|
@ -440,7 +456,7 @@ impl Archetype {
|
||||||
self.entities.swap_remove(&entity);
|
self.entities.swap_remove(&entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(&self, scene_contents: &mut SceneContents<'_>) -> Result<()> {
|
pub fn execute(&self, scene_contents: &mut C) -> Result<()> {
|
||||||
for (entity, callback) in self.entities.iter() {
|
for (entity, callback) in self.entities.iter() {
|
||||||
callback(*entity, scene_contents)?;
|
callback(*entity, scene_contents)?;
|
||||||
}
|
}
|
||||||
|
@ -448,7 +464,7 @@ impl Archetype {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup(&mut self, entities: &IndexMap<Entity, EntityObject>) -> Result<()> {
|
pub fn setup(&mut self, entities: &IndexMap<Entity, EntityObject<C>>) -> Result<()> {
|
||||||
for (entity, entity_object) in entities.iter() {
|
for (entity, entity_object) in entities.iter() {
|
||||||
if (self.check_entity)(entity_object) {
|
if (self.check_entity)(entity_object) {
|
||||||
let cb = (self.create_callback)(entity_object)?;
|
let cb = (self.create_callback)(entity_object)?;
|
||||||
|
@ -462,37 +478,34 @@ impl Archetype {
|
||||||
|
|
||||||
pub(crate) fn entities(
|
pub(crate) fn entities(
|
||||||
&self,
|
&self,
|
||||||
) -> &IndexMap<Entity, Box<dyn Fn(Entity, &mut SceneContents<'_>) -> Result<()> + Send + Sync>>
|
) -> &IndexMap<Entity, Box<dyn Fn(Entity, &mut C) -> Result<()> + Send + Sync>> {
|
||||||
{
|
|
||||||
&self.entities
|
&self.entities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ArchetypePair {
|
pub struct ArchetypePair<C> {
|
||||||
check_left_entity: Box<dyn Fn(&EntityObject) -> bool + Send + Sync>,
|
check_left_entity: Box<dyn Fn(&EntityObject<C>) -> bool + Send + Sync>,
|
||||||
check_right_entity: Box<dyn Fn(&EntityObject) -> bool + Send + Sync>,
|
check_right_entity: Box<dyn Fn(&EntityObject<C>) -> bool + Send + Sync>,
|
||||||
|
|
||||||
create_callback: Box<
|
create_callback: Box<
|
||||||
dyn Fn(
|
dyn Fn(
|
||||||
&EntityObject,
|
&EntityObject<C>,
|
||||||
&EntityObject,
|
&EntityObject<C>,
|
||||||
) -> Result<
|
)
|
||||||
Box<dyn Fn(Entity, Entity, &mut SceneContents<'_>) -> Result<()> + Send + Sync>,
|
-> Result<Box<dyn Fn(Entity, Entity, &mut C) -> Result<()> + Send + Sync>>
|
||||||
> + Send
|
+ Send
|
||||||
+ Sync,
|
+ Sync,
|
||||||
>,
|
>,
|
||||||
|
|
||||||
entities: IndexMap<
|
entities:
|
||||||
(Entity, Entity),
|
IndexMap<(Entity, Entity), Box<dyn Fn(Entity, Entity, &mut C) -> Result<()> + Send + Sync>>,
|
||||||
Box<dyn Fn(Entity, Entity, &mut SceneContents<'_>) -> Result<()> + Send + Sync>,
|
|
||||||
>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ArchetypePair {
|
impl<C> ArchetypePair<C> {
|
||||||
pub(crate) fn add_entity(
|
pub(crate) fn add_entity(
|
||||||
&mut self,
|
&mut self,
|
||||||
entity_object: &EntityObject,
|
entity_object: &EntityObject<C>,
|
||||||
entities: &IndexMap<Entity, EntityObject>,
|
entities: &IndexMap<Entity, EntityObject<C>>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
for (other_entity, other_entity_object) in entities.iter() {
|
for (other_entity, other_entity_object) in entities.iter() {
|
||||||
if entity_object.as_entity() == *other_entity {
|
if entity_object.as_entity() == *other_entity {
|
||||||
|
@ -533,7 +546,7 @@ impl ArchetypePair {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn execute(&self, scene_contents: &mut SceneContents<'_>) -> Result<()> {
|
pub(crate) fn execute(&self, scene_contents: &mut C) -> Result<()> {
|
||||||
for ((left_entity, right_entity), callback) in self.entities.iter() {
|
for ((left_entity, right_entity), callback) in self.entities.iter() {
|
||||||
callback(*left_entity, *right_entity, scene_contents)?;
|
callback(*left_entity, *right_entity, scene_contents)?;
|
||||||
}
|
}
|
||||||
|
@ -541,7 +554,7 @@ impl ArchetypePair {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn setup(&mut self, entities: &IndexMap<Entity, EntityObject>) -> Result<()> {
|
pub(crate) fn setup(&mut self, entities: &IndexMap<Entity, EntityObject<C>>) -> Result<()> {
|
||||||
for (lhs_entity, lhs_entity_object) in entities.iter() {
|
for (lhs_entity, lhs_entity_object) in entities.iter() {
|
||||||
for (rhs_entity, rhs_entity_object) in entities.iter() {
|
for (rhs_entity, rhs_entity_object) in entities.iter() {
|
||||||
if lhs_entity != rhs_entity
|
if lhs_entity != rhs_entity
|
||||||
|
@ -559,33 +572,43 @@ impl ArchetypePair {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Update {
|
pub enum Update<C> {
|
||||||
Single(Archetype),
|
Single(Archetype<C>),
|
||||||
Pair(ArchetypePair),
|
Pair(ArchetypePair<C>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Archetype> for Update {
|
impl<C> From<Archetype<C>> for Update<C> {
|
||||||
fn from(archetype: Archetype) -> Self {
|
fn from(archetype: Archetype<C>) -> Self {
|
||||||
Self::Single(archetype)
|
Self::Single(archetype)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ArchetypePair> for Update {
|
impl<C> From<ArchetypePair<C>> for Update<C> {
|
||||||
fn from(pair: ArchetypePair) -> Self {
|
fn from(pair: ArchetypePair<C>) -> Self {
|
||||||
Self::Pair(pair)
|
Self::Pair(pair)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
pub struct Updates<C> {
|
||||||
pub struct Updates {
|
|
||||||
#[cfg(feature = "timings")]
|
#[cfg(feature = "timings")]
|
||||||
timings: Timings,
|
timings: Timings,
|
||||||
|
|
||||||
updates: Vec<(String, u32, Update)>,
|
updates: Vec<(String, u32, Update<C>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Updates {
|
impl<C> Default for Updates<C> {
|
||||||
pub(crate) fn update(&mut self, scene_contents: &mut SceneContents<'_>) -> Result<()> {
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
#[cfg(feature = "timings")]
|
||||||
|
timings: Timings::default,
|
||||||
|
|
||||||
|
updates: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C> Updates<C> {
|
||||||
|
pub(crate) fn update(&mut self, scene_contents: &mut C) -> Result<()> {
|
||||||
#[cfg(feature = "timings")]
|
#[cfg(feature = "timings")]
|
||||||
if let Some(timings) = self.timings.check_timing(scene_contents.now(), None) {
|
if let Some(timings) = self.timings.check_timing(scene_contents.now(), None) {
|
||||||
if !timings.is_empty() {
|
if !timings.is_empty() {
|
||||||
|
@ -622,8 +645,8 @@ impl Updates {
|
||||||
|
|
||||||
pub(crate) fn add_entity(
|
pub(crate) fn add_entity(
|
||||||
&mut self,
|
&mut self,
|
||||||
entity_object: &EntityObject,
|
entity_object: &EntityObject<C>,
|
||||||
entities: &IndexMap<Entity, EntityObject>,
|
entities: &IndexMap<Entity, EntityObject<C>>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
for (_, _, update) in self.updates.iter_mut() {
|
for (_, _, update) in self.updates.iter_mut() {
|
||||||
match update {
|
match update {
|
||||||
|
@ -663,8 +686,8 @@ impl Updates {
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
priority: u32,
|
priority: u32,
|
||||||
mut update: Update,
|
mut update: Update<C>,
|
||||||
entities: &IndexMap<Entity, EntityObject>,
|
entities: &IndexMap<Entity, EntityObject<C>>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
match &mut update {
|
match &mut update {
|
||||||
Update::Single(archetype) => archetype.setup(entities)?,
|
Update::Single(archetype) => archetype.setup(entities)?,
|
||||||
|
@ -682,46 +705,46 @@ impl Updates {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
// #[derive(Default)]
|
||||||
pub struct Archetypes {
|
// pub struct Archetypes {
|
||||||
archetypes: HashMap<String, Archetype>,
|
// archetypes: HashMap<String, Archetype>,
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl Archetypes {
|
// impl Archetypes {
|
||||||
pub(crate) fn add_entity(&mut self, entity_object: &EntityObject) -> Result<()> {
|
// pub(crate) fn add_entity(&mut self, entity_object: &EntityObject) -> Result<()> {
|
||||||
for archetype in self.archetypes.values_mut() {
|
// for archetype in self.archetypes.values_mut() {
|
||||||
archetype.add_entity(entity_object)?;
|
// archetype.add_entity(entity_object)?;
|
||||||
}
|
// }
|
||||||
|
|
||||||
Ok(())
|
// Ok(())
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub(crate) fn remove_entity(&mut self, entity: Entity) {
|
// pub(crate) fn remove_entity(&mut self, entity: Entity) {
|
||||||
for archetype in self.archetypes.values_mut() {
|
// for archetype in self.archetypes.values_mut() {
|
||||||
archetype.remove_entity(entity);
|
// archetype.remove_entity(entity);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub(crate) fn clear(&mut self) {
|
// pub(crate) fn clear(&mut self) {
|
||||||
self.archetypes.clear();
|
// self.archetypes.clear();
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub(crate) fn insert(&mut self, name: String, archetype: Archetype) {
|
// pub(crate) fn insert(&mut self, name: String, archetype: Archetype) {
|
||||||
assert!(self.archetypes.insert(name, archetype).is_none());
|
// assert!(self.archetypes.insert(name, archetype).is_none());
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub(crate) fn get(&self, name: &String) -> Option<&Archetype> {
|
// pub(crate) fn get(&self, name: &String) -> Option<&Archetype> {
|
||||||
self.archetypes.get(name)
|
// self.archetypes.get(name)
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub(crate) fn execute(
|
// pub(crate) fn execute(
|
||||||
&self,
|
// &self,
|
||||||
name: &String,
|
// name: &String,
|
||||||
scene_contents: &mut SceneContents<'_>,
|
// scene_contents: &mut SceneContents<'_>,
|
||||||
) -> Result<()> {
|
// ) -> Result<()> {
|
||||||
self.archetypes[name].execute(scene_contents)
|
// self.archetypes[name].execute(scene_contents)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
impl_singleton_update!(single, [R]);
|
impl_singleton_update!(single, [R]);
|
21
ecs/src/world.rs
Normal file
21
ecs/src/world.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
pub struct World<SCENE: Send + Sync> {
|
||||||
|
pub(crate) updates: Updates<SCENE>,
|
||||||
|
pub(crate) events: Events<SCENE>,
|
||||||
|
pub(crate) resources: Resources,
|
||||||
|
pub(crate) entities: IndexMap<Entity, EntityObject<SCENE>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<SCENE: Send + Sync> Default for World<SCENE> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
updates: Updates::default(),
|
||||||
|
events: Events::default(),
|
||||||
|
resources: Resources::default(),
|
||||||
|
entities: IndexMap::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
name = "engine"
|
name = "engine"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# needed
|
# needed
|
||||||
|
@ -24,8 +24,7 @@ lua-wrapper = { path = "../lua-wrapper" }
|
||||||
scene_update_macros = { path = "../scene_update_macros" }
|
scene_update_macros = { path = "../scene_update_macros" }
|
||||||
asset = { path = "../asset" }
|
asset = { path = "../asset" }
|
||||||
loading_screen = { path = "../loading-screen" }
|
loading_screen = { path = "../loading-screen" }
|
||||||
context = { path = "../context", features = ["sound", "bundle_sdl2"] }
|
context = { path = "../context", features = ["bundle_sdl2", "sound"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
timings = []
|
timings = []
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::any::Any;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
use super::engine_object_data::{EngineObjectAccess, EngineObjectDataHandle};
|
// use super::engine_object_data::{EngineObjectAccess, EngineObjectDataHandle};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum EngineEvent {
|
pub enum EngineEvent {
|
||||||
|
@ -29,68 +29,71 @@ pub enum EngineEvent {
|
||||||
FileDrop(String),
|
FileDrop(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait EngineObjectHelper: Any {
|
// pub trait EngineObjectHelper: Any {
|
||||||
type Payload: Send + Sync;
|
// type Payload: Send + Sync;
|
||||||
|
|
||||||
fn access(&self) -> EngineObjectAccess<'_, Self::Payload>;
|
// fn access(&self) -> EngineObjectAccess<'_, Self::Payload>;
|
||||||
fn payload(&self) -> EngineObjectDataHandle<Self::Payload>;
|
// fn payload(&self) -> EngineObjectDataHandle<Self::Payload>;
|
||||||
fn ui(&self) -> &States;
|
// fn ui(&self) -> &States;
|
||||||
fn ui_mut(&mut self) -> &mut States;
|
// fn ui_mut(&mut self) -> &mut States;
|
||||||
|
|
||||||
fn access_callback_mut<F>(&self, f: F) -> impl FnMut() -> Result<()> + Send + Sync + 'static
|
// fn access_callback_mut<'a, F>(
|
||||||
where
|
// &'a self,
|
||||||
F: FnMut(EngineObjectAccess<'_, Self::Payload>) -> Result<()> + Send + Sync + 'static,
|
// f: F,
|
||||||
{
|
// ) -> impl FnMut() -> Result<()> + Send + Sync + 'static
|
||||||
self.payload().access_callback_mut(f)
|
// where
|
||||||
}
|
// F: FnMut(EngineObjectAccess<'a, Self::Payload>) -> Result<()> + Send + Sync + 'static,
|
||||||
|
// {
|
||||||
|
// self.payload().access_callback_mut(f)
|
||||||
|
// }
|
||||||
|
|
||||||
fn access_callback<F>(&self, f: F) -> impl Fn() -> Result<()> + Send + Sync + 'static
|
// fn access_callback<F>(&self, f: F) -> impl Fn() -> Result<()> + Send + Sync + 'static
|
||||||
where
|
// where
|
||||||
F: Fn(EngineObjectAccess<'_, Self::Payload>) -> Result<()> + Send + Sync + 'static,
|
// F: Fn(EngineObjectAccess<'_, Self::Payload>) -> Result<()> + Send + Sync + 'static,
|
||||||
{
|
// {
|
||||||
self.payload().access_callback(f)
|
// self.payload().access_callback(f)
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn handle_callback_mut<F>(&self, mut f: F) -> impl FnMut() -> Result<()> + Send + Sync + 'static
|
// fn handle_callback_mut<F>(&self, mut f: F) -> impl FnMut() -> Result<()> + Send + Sync + 'static
|
||||||
where
|
// where
|
||||||
F: FnMut(
|
// F: FnMut(
|
||||||
EngineObjectDataHandle<Self::Payload>,
|
// EngineObjectDataHandle<Self::Payload>,
|
||||||
EngineObjectAccess<'_, Self::Payload>,
|
// EngineObjectAccess<'_, Self::Payload>,
|
||||||
) -> Result<()>
|
// ) -> Result<()>
|
||||||
+ Send
|
// + Send
|
||||||
+ Sync
|
// + Sync
|
||||||
+ 'static,
|
// + 'static,
|
||||||
{
|
// {
|
||||||
let handle = self.payload();
|
// let handle = self.payload();
|
||||||
|
|
||||||
move || {
|
// move || {
|
||||||
let data = handle.as_data();
|
// let data = handle.as_data();
|
||||||
let access = data.access();
|
// let access = data.access();
|
||||||
|
|
||||||
f(handle.copy(), access)
|
// f(handle.copy(), access)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn handle_callback<F>(&self, f: F) -> impl Fn() -> Result<()> + Send + Sync + 'static
|
// fn handle_callback<F>(&self, f: F) -> impl Fn() -> Result<()> + Send + Sync + 'static
|
||||||
where
|
// where
|
||||||
F: Fn(
|
// F: Fn(
|
||||||
EngineObjectDataHandle<Self::Payload>,
|
// EngineObjectDataHandle<Self::Payload>,
|
||||||
EngineObjectAccess<'_, Self::Payload>,
|
// EngineObjectAccess<'_, Self::Payload>,
|
||||||
) -> Result<()>
|
// ) -> Result<()>
|
||||||
+ Send
|
// + Send
|
||||||
+ Sync
|
// + Sync
|
||||||
+ 'static,
|
// + 'static,
|
||||||
{
|
// {
|
||||||
let handle = self.payload();
|
// let handle = self.payload();
|
||||||
|
|
||||||
move || {
|
// move || {
|
||||||
let data = handle.as_data();
|
// let data = handle.as_data();
|
||||||
let access = data.access();
|
// let access = data.access();
|
||||||
|
|
||||||
f(handle.copy(), access)
|
// f(handle.copy(), access)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub trait EngineObject: Any {
|
pub trait EngineObject: Any {
|
||||||
fn name(&self) -> &str;
|
fn name(&self) -> &str;
|
||||||
|
|
|
@ -4,4 +4,4 @@ pub mod enginesettings;
|
||||||
pub mod engineobject;
|
pub mod engineobject;
|
||||||
|
|
||||||
pub mod asset_handler;
|
pub mod asset_handler;
|
||||||
pub mod engine_object_data;
|
// pub mod engine_object_data;
|
||||||
|
|
|
@ -7,8 +7,11 @@ pub use loading_screen::*;
|
||||||
pub use crate::scene::prelude::*;
|
pub use crate::scene::prelude::*;
|
||||||
|
|
||||||
pub use crate::engine::{
|
pub use crate::engine::{
|
||||||
engine_object_data::*,
|
// engine_object_data::*,
|
||||||
engineobject::{EngineObject, EngineObjectHelper},
|
engineobject::{
|
||||||
|
EngineObject,
|
||||||
|
// EngineObjectHelper
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use crate::engine::asset_handler::{AssetHandler, AssetLoader};
|
pub use crate::engine::asset_handler::{AssetHandler, AssetLoader};
|
||||||
|
@ -17,8 +20,8 @@ pub use crate::engine::{engine::*, enginesettings::*};
|
||||||
pub use crate::engine::engineobject::EngineEvent;
|
pub use crate::engine::engineobject::EngineEvent;
|
||||||
|
|
||||||
pub use serde::{
|
pub use serde::{
|
||||||
ser::{SerializeMap, SerializeSeq, SerializeStruct},
|
|
||||||
Deserialize, Deserializer, Serialize, Serializer,
|
Deserialize, Deserializer, Serialize, Serializer,
|
||||||
|
ser::{SerializeMap, SerializeSeq, SerializeStruct},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use ron;
|
pub use ron;
|
||||||
|
|
|
@ -1,12 +1,5 @@
|
||||||
pub mod components;
|
pub mod components;
|
||||||
|
|
||||||
pub mod entity;
|
|
||||||
pub mod map;
|
pub mod map;
|
||||||
pub mod unsafe_component_store;
|
|
||||||
pub mod updates;
|
|
||||||
|
|
||||||
pub mod events;
|
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
pub mod query;
|
mod query;
|
||||||
mod resources;
|
|
||||||
pub mod type_map;
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
pub use super::map::Map;
|
pub use super::map::Map;
|
||||||
|
|
||||||
pub use super::entity::{Entity, EntityObject, NetworkID};
|
|
||||||
|
|
||||||
pub use super::components::{animation::Animation, audio::Audio, draw::Draw};
|
pub use super::components::{animation::Animation, audio::Audio, draw::Draw};
|
||||||
|
|
||||||
pub use super::components::{
|
pub use super::components::{
|
||||||
|
@ -12,11 +10,3 @@ pub use super::components::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use super::query::SceneQuery;
|
pub use super::query::SceneQuery;
|
||||||
pub use super::unsafe_component_store::UnsafeComponentStore;
|
|
||||||
pub use super::updates::*;
|
|
||||||
|
|
||||||
pub use super::type_map::{
|
|
||||||
ComponentCreateInfo, ComponentDebug, ComponentNotFoundError, EntityComponent, MultiMut, TypeMap,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub use super::resources::{ResourceMultiMut, Resources};
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "entity_manager"
|
name = "entity_manager"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
|
|
|
@ -3,7 +3,7 @@ name = "gavania-core"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["hodasemi <superschneider@t-online.de>"]
|
authors = ["hodasemi <superschneider@t-online.de>"]
|
||||||
build = "src/osbuild.rs"
|
build = "src/osbuild.rs"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rusqlite = { workspace = true }
|
rusqlite = { workspace = true }
|
||||||
|
@ -27,4 +27,3 @@ entity_manager = { path = "../entity_manager" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
wayland = []
|
wayland = []
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
name = "gltf-loader"
|
name = "gltf-loader"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["hodasemi <superschneider@t-online.de>"]
|
authors = ["hodasemi <superschneider@t-online.de>"]
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
gltf = { workspace = true }
|
gltf = { workspace = true }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
name = "loading_screen"
|
name = "loading_screen"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
context = { path = "../context" }
|
context = { path = "../context" }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
name = "lua-wrapper"
|
name = "lua-wrapper"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
mlua = { workspace = true }
|
mlua = { workspace = true }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "map"
|
name = "map"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
name = "math"
|
name = "math"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["shnie <hagen.m42ller@gmail.com>"]
|
authors = ["shnie <hagen.m42ller@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
name = "presentation"
|
name = "presentation"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["hodasemi <superschneider@t-online.de>"]
|
authors = ["hodasemi <superschneider@t-online.de>"]
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
vulkan-rs = { workspace = true }
|
vulkan-rs = { workspace = true }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
name = "promise"
|
name = "promise"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "ring_buffer"
|
name = "ring_buffer"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "rpg_components"
|
name = "rpg_components"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
name = "scene_update_macros"
|
name = "scene_update_macros"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
name = "transaction_derive"
|
name = "transaction_derive"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
Loading…
Reference in a new issue