asdsad
This commit is contained in:
parent
383accdb7c
commit
13c6b2e2e0
@ -1 +0,0 @@
|
|||||||
Subproject commit 6e707fe6a877971c9f51ea0b3d4e90d76811be33
|
|
1
type-id-test-rs/.gitignore
vendored
Normal file
1
type-id-test-rs/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/target
|
53
type-id-test-rs/Cargo.lock
generated
Normal file
53
type-id-test-rs/Cargo.lock
generated
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "component-macro"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.79"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.58"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "type-id-test-rs"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"component-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
10
type-id-test-rs/Cargo.toml
Normal file
10
type-id-test-rs/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
workspace = { members = ["component-macro"] }
|
||||||
|
[package]
|
||||||
|
name = "type-id-test-rs"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
component-macro = { version = "0.1.0", path = "./component-macro" }
|
13
type-id-test-rs/component-macro/Cargo.toml
Normal file
13
type-id-test-rs/component-macro/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
[package]
|
||||||
|
name = "component-macro"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
quote = "1.0.35"
|
||||||
|
syn = "2.0.58"
|
26
type-id-test-rs/component-macro/src/lib.rs
Normal file
26
type-id-test-rs/component-macro/src/lib.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
use proc_macro::TokenStream;
|
||||||
|
use quote::quote;
|
||||||
|
use syn;
|
||||||
|
|
||||||
|
#[proc_macro_derive(Component)]
|
||||||
|
pub fn derive_component(input: TokenStream) -> TokenStream {
|
||||||
|
let ast = syn::parse(input).unwrap();
|
||||||
|
impl_derive_macro(&ast)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn impl_derive_macro(ast: &syn::DeriveInput) -> TokenStream {
|
||||||
|
let name = &ast.ident;
|
||||||
|
let gen = quote! {
|
||||||
|
impl Component for #name {
|
||||||
|
fn inner_type_id(&self) -> TypeId {
|
||||||
|
TypeId::of::<Self>()
|
||||||
|
}
|
||||||
|
fn as_any(&mut self) -> &mut dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
gen.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
6
type-id-test-rs/src/component.rs
Normal file
6
type-id-test-rs/src/component.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
use std::any::{Any, TypeId};
|
||||||
|
|
||||||
|
pub trait Component {
|
||||||
|
fn inner_type_id(&self) -> TypeId;
|
||||||
|
fn as_any(&mut self) -> &mut dyn Any;
|
||||||
|
}
|
124
type-id-test-rs/src/main.rs
Normal file
124
type-id-test-rs/src/main.rs
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use std::any::{Any, TypeId};
|
||||||
|
|
||||||
|
use component::Component;
|
||||||
|
use component_macro::Component;
|
||||||
|
|
||||||
|
mod component;
|
||||||
|
|
||||||
|
struct Context<'a> {
|
||||||
|
entities: &'a mut Vec<(u64, Vec<Box<dyn Component>>)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Context<'a> {
|
||||||
|
pub fn entities_with_component<T: 'static>(&self) -> Vec<u64> {
|
||||||
|
let entity_type_id = TypeId::of::<T>();
|
||||||
|
self.entities
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(id, components)| {
|
||||||
|
let contains_component = components.iter().any(|entity| {
|
||||||
|
let is_id = (*entity).inner_type_id() == entity_type_id;
|
||||||
|
is_id
|
||||||
|
});
|
||||||
|
if contains_component {
|
||||||
|
Some(*id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn entity_component<T: 'static>(&mut self, entity_id: u64) -> &mut T {
|
||||||
|
let entity_type_id = TypeId::of::<T>();
|
||||||
|
let (_id, components) = self
|
||||||
|
.entities
|
||||||
|
.iter_mut()
|
||||||
|
.find(|(id, _)| *id == entity_id)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let component = components
|
||||||
|
.iter_mut()
|
||||||
|
.find_map(|entity| {
|
||||||
|
let is_id = (*entity).inner_type_id() == entity_type_id;
|
||||||
|
if is_id {
|
||||||
|
Some(entity.as_any().downcast_mut::<T>().unwrap())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
component
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait System {
|
||||||
|
fn on_update(&self, context: &mut Context);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
struct Position {
|
||||||
|
pub x: i32,
|
||||||
|
pub y: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
struct NotPosition {
|
||||||
|
pub a: i32,
|
||||||
|
pub b: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Gravity;
|
||||||
|
struct NotGravity;
|
||||||
|
|
||||||
|
impl System for Gravity {
|
||||||
|
fn on_update(&self, context: &mut Context) {
|
||||||
|
let entities_with_position = context.entities_with_component::<Position>();
|
||||||
|
for entity_id in entities_with_position {
|
||||||
|
let position = context.entity_component::<Position>(entity_id);
|
||||||
|
position.y -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl System for NotGravity {
|
||||||
|
fn on_update(&self, context: &mut Context) {
|
||||||
|
let entities_with_position = context.entities_with_component::<NotPosition>();
|
||||||
|
for entity_id in entities_with_position {
|
||||||
|
let position = context.entity_component::<NotPosition>(entity_id);
|
||||||
|
position.a -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut entities: Vec<(u64, Vec<Box<dyn Component>>)> = Vec::new();
|
||||||
|
let mut systems: Vec<Box<dyn System>> = Vec::new();
|
||||||
|
|
||||||
|
systems.push(Box::new(Gravity));
|
||||||
|
systems.push(Box::new(NotGravity));
|
||||||
|
entities.push((
|
||||||
|
0,
|
||||||
|
vec![
|
||||||
|
Box::new(Position { x: 0, y: 0 }),
|
||||||
|
Box::new(NotPosition { a: 0, b: 0 }),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
|
||||||
|
entities.push((
|
||||||
|
1,
|
||||||
|
vec![
|
||||||
|
Box::new(Position { x: 0, y: 0 }),
|
||||||
|
Box::new(NotPosition { a: 0, b: 0 }),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
|
||||||
|
let mut context = Context {
|
||||||
|
entities: &mut entities,
|
||||||
|
};
|
||||||
|
|
||||||
|
for system in systems {
|
||||||
|
system.on_update(&mut context)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user