doing a bunch of stuff all at once
This commit is contained in:
parent
974943d954
commit
2cc99fc24e
File diff suppressed because it is too large
Load Diff
26
Cargo.toml
26
Cargo.toml
|
@ -1,20 +1,6 @@
|
|||
[package]
|
||||
name = "cart"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
buddy-alloc = { version = "0.4.1", optional = true }
|
||||
strum = { version = "0.24", features = ["derive"], default-features = false }
|
||||
|
||||
[profile.release]
|
||||
opt-level = "z"
|
||||
lto = true
|
||||
|
||||
[features]
|
||||
# use `--no-default-features` or comment out next line to disable allocator
|
||||
default = ["buddy-alloc"]
|
||||
[workspace]
|
||||
members = [
|
||||
"ecs",
|
||||
"ecs_derive",
|
||||
"ecs_derive_test",
|
||||
]
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "buddy-alloc"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ff9f338986406db85e2b5deb40a9255b796ca03a194c7457403d215173f3fd5"
|
||||
|
||||
[[package]]
|
||||
name = "cart"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"buddy-alloc",
|
||||
"enum_dispatch",
|
||||
"strum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enum_dispatch"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11f36e95862220b211a6e2aa5eca09b4fa391b13cd52ceb8035a24bf65a79de2"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.24.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f"
|
||||
dependencies = [
|
||||
"strum_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.24.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
|
|
@ -0,0 +1,22 @@
|
|||
[package]
|
||||
name = "cart"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
buddy-alloc = { version = "0.4.1", optional = true }
|
||||
strum = { version = "0.24", features = ["derive"], default-features = false }
|
||||
enum_dispatch = "0.3.11"
|
||||
ecs_derive = { path = "../ecs_derive" }
|
||||
|
||||
[profile.release]
|
||||
opt-level = "z"
|
||||
lto = true
|
||||
|
||||
[features]
|
||||
# use `--no-default-features` or comment out next line to disable allocator
|
||||
default = ["buddy-alloc"]
|
|
@ -0,0 +1,132 @@
|
|||
use strum::{EnumDiscriminants, EnumCount, EnumIter};
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use crate::wasm4::trace;
|
||||
|
||||
pub struct Scene {
|
||||
entities: Vec<Option<Entity>>,
|
||||
components: Vec<Option<ComponentRecord>>,
|
||||
|
||||
unused_entity_ids: Vec<EntityId>,
|
||||
unused_component_ids: Vec<ComponentId>
|
||||
}
|
||||
|
||||
struct ComponentRecord {
|
||||
component: SparseComponent,
|
||||
owning_entity: EntityId,
|
||||
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
pub fn new() -> Scene {
|
||||
Scene {
|
||||
entities: Vec::with_capacity(32),
|
||||
components: Vec::with_capacity(128),
|
||||
unused_entity_ids: Vec::new(),
|
||||
unused_component_ids: Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_entity(&mut self){
|
||||
|
||||
}
|
||||
|
||||
pub fn query_entities<const N: usize>(&self, query: &[SparseComponentDiscriminants; N]) -> Vec<(EntityId, [ComponentId; N])> {
|
||||
let mut result = Vec::new();
|
||||
for entity_index in 0..self.entities.len() {
|
||||
if let Some(entity) = &self.entities[entity_index] {
|
||||
if let Some(component_ids) = entity.component_ids(query) {
|
||||
result.push((EntityId(entity_index), component_ids));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn borrow_component_ids<const N: usize>(&mut self, ids: &[ComponentId; N]) -> [Option<&SparseComponent>; N] {
|
||||
let mut result = [None; N];
|
||||
for id_index in 0..ids.len() {
|
||||
let ComponentId(id) = ids[id_index];
|
||||
if id >= self.components.len() {
|
||||
trace(format!("tried to borrow a component with id {} when there are {} components", id, self.components.len()));
|
||||
}
|
||||
|
||||
match &self.components[id] {
|
||||
Some(ComponentRecord { component, owning_entity }) => {
|
||||
result[id_index] = Some(component);
|
||||
},
|
||||
None => trace(format!("tried to borrow a component with id {} but it has been removed.", id))
|
||||
}
|
||||
}
|
||||
result.into()
|
||||
}
|
||||
|
||||
pub unsafe fn mut_borrow_component_unsafely(&self, id: &ComponentId) -> Option<&SparseComponent> {
|
||||
let ComponentId(id) = *id;
|
||||
if id >= self.components.len(){
|
||||
trace(format!("tried to mutably borrow a component with id {} when there are {} components", id, self.components.len()));
|
||||
return None;
|
||||
}
|
||||
match &self.components[id] {
|
||||
Some(ComponentRecord { component, owning_entity }) => {
|
||||
let component_ptr = component as *const SparseComponent;
|
||||
let component_mut_ptr = component_ptr as *mut SparseComponent;
|
||||
return Some(&mut *component_mut_ptr);
|
||||
},
|
||||
None => trace(format!("tried to mutably borrow a component with id {} but it has been removed.", id))
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct EntityId(usize);
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct ComponentId(usize);
|
||||
|
||||
pub struct Entity {
|
||||
components: [Option<usize>; SparseComponent::COUNT]
|
||||
}
|
||||
|
||||
impl Entity {
|
||||
pub fn new() -> Entity {
|
||||
Entity {
|
||||
components: [None; SparseComponent::COUNT]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn component_ids<const N: usize>(&self, query: &[SparseComponentDiscriminants; N]) -> Option<[ComponentId; N]>{
|
||||
let mut result: [ComponentId; N] = [ComponentId(0); N];
|
||||
for query_index in 0..query.len() {
|
||||
let discriminant = query[query_index];
|
||||
if let Some(id) = self.components[discriminant as usize] {
|
||||
result[query_index] = ComponentId(id);
|
||||
}
|
||||
else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
return Some(result);
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(usize)]
|
||||
#[derive(EnumDiscriminants, EnumCount, EnumIter)]
|
||||
#[strum_discriminants(repr(usize))]
|
||||
pub enum SparseComponent {
|
||||
Name(&'static str),
|
||||
Pronouns(&'static [&'static str]),
|
||||
|
||||
}
|
||||
|
||||
#[repr(usize)]
|
||||
#[derive(EnumDiscriminants, EnumCount, EnumIter)]
|
||||
#[strum_discriminants(repr(usize))]
|
||||
pub enum DenseComponent {
|
||||
Position { x: u8, y: u8 },
|
||||
Acceleration { x: u8, y: u8 },
|
||||
Velocity { x: u8, y: u8 }
|
||||
|
||||
}
|
|
@ -24,11 +24,13 @@ const SMILEY: [u8; 8] = [
|
|||
];
|
||||
|
||||
|
||||
/*
|
||||
todo strum seems to have pulled in std??
|
||||
#[cfg_attr(not(test), panic_handler)]
|
||||
fn panic(info: &PanicInfo) -> ! {
|
||||
trace(format!("{}", info));
|
||||
loop {}
|
||||
}
|
||||
} */
|
||||
|
||||
#[no_mangle]
|
||||
fn update() {
|
|
@ -0,0 +1,16 @@
|
|||
[package]
|
||||
name = "ecs_derive"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[lib]
|
||||
name = "ecs_derive"
|
||||
path = "src/lib.rs"
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
syn = { version = "*", features = ["extra-traits"] }
|
||||
quote = "*"
|
||||
proc-macro2 = "*"
|
||||
r3bl_rs_utils = "*"
|
|
@ -0,0 +1,40 @@
|
|||
use proc_macro::TokenStream;
|
||||
use quote::ToTokens;
|
||||
use r3bl_rs_utils::{style_primary, style_prompt};
|
||||
use syn::{ItemFn, parse_str};
|
||||
|
||||
|
||||
fn viz_ast(ast: ItemFn) {
|
||||
// Simply dump the AST to the console.
|
||||
let ast_clone = ast.clone();
|
||||
eprintln!("{} => {:#?}", style_primary("Debug::ast"), ast_clone);
|
||||
|
||||
// Parse AST to dump some items to the console.
|
||||
let ItemFn {
|
||||
attrs,
|
||||
vis,
|
||||
sig,
|
||||
block,
|
||||
} = ast;
|
||||
|
||||
eprintln!(
|
||||
"{} ast_item_fn < attrs.len:{}, vis:{}, sig:'{}' stmt: '{}' >",
|
||||
style_primary("=>"),
|
||||
style_prompt(&attrs.len().to_string()),
|
||||
style_prompt(match vis {
|
||||
syn::Visibility::Public(_) => "public",
|
||||
syn::Visibility::Crate(_) => "crate",
|
||||
syn::Visibility::Restricted(_) => "restricted",
|
||||
syn::Visibility::Inherited => "inherited",
|
||||
}),
|
||||
style_prompt(&sig.ident.to_string()),
|
||||
style_prompt(&match block.stmts.first() {
|
||||
Some(stmt) => {
|
||||
let expr_str = stmt.to_token_stream().to_string().clone();
|
||||
expr_str
|
||||
}
|
||||
None => "empty".to_string(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
extern crate proc_macro;
|
||||
use proc_macro::TokenStream;
|
||||
use syn::{parse_macro_input, Token, Type, Ident, parse::Parse};
|
||||
|
||||
mod ast_viz_debug;
|
||||
|
||||
/*
|
||||
#[proc_macro]
|
||||
pub fn fn_macro_ast_viz_debug(input: TokenStream) -> TokenStream {
|
||||
ast_viz_debug::fn_proc_macro_impl(input)
|
||||
} */
|
||||
|
||||
/*
|
||||
|
||||
component_container {
|
||||
sparse name: Name,
|
||||
dense pos: Position,
|
||||
}
|
||||
*/
|
||||
|
||||
#[proc_macro]
|
||||
pub fn component_container(input: TokenStream) -> TokenStream {
|
||||
let container = parse_macro_input!(input as ComponentContainer);
|
||||
|
||||
TokenStream::new()
|
||||
}
|
||||
|
||||
mod kw {
|
||||
syn::custom_keyword!(sparse);
|
||||
syn::custom_keyword!(dense);
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ComponentStorage {
|
||||
Sparse,
|
||||
Dense
|
||||
}
|
||||
|
||||
fn parse_storage(input: &syn::parse::ParseStream) -> syn::Result<ComponentStorage> {
|
||||
let lookahead = input.lookahead1();
|
||||
if lookahead.peek(kw::sparse) {
|
||||
input.parse::<kw::sparse>()?;
|
||||
Ok(ComponentStorage::Sparse)
|
||||
} else if lookahead.peek(kw::dense) {
|
||||
input.parse::<kw::dense>()?;
|
||||
Ok(ComponentStorage::Dense)
|
||||
} else {
|
||||
Err(lookahead.error())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Component {
|
||||
name: Ident,
|
||||
ty: Type,
|
||||
storage: ComponentStorage
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ComponentContainer {
|
||||
components: Vec<Component>
|
||||
}
|
||||
|
||||
impl Parse for ComponentContainer {
|
||||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
||||
let mut components = vec![];
|
||||
loop {
|
||||
let storage = parse_storage(&input)?;
|
||||
let name: Ident = input.parse()?;
|
||||
input.parse::<Token![:]>()?;
|
||||
let ty: Type = input.parse()?;
|
||||
|
||||
components.push(Component {
|
||||
name, ty, storage
|
||||
});
|
||||
|
||||
if input.is_empty() {
|
||||
break;
|
||||
}
|
||||
|
||||
input.parse::<Token![,]>()?;
|
||||
|
||||
if input.is_empty() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ComponentContainer {
|
||||
components
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
#[proc_macro]
|
||||
pub fn component_container(input: TokenStream) -> TokenStream {
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_component_container(){
|
||||
component_container!();
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "ecs_derive_test"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
ecs_derive = { path = "../ecs_derive" }
|
|
@ -0,0 +1,13 @@
|
|||
use ecs_derive::{component_container};
|
||||
|
||||
struct Location {
|
||||
x: u32,
|
||||
y: u32
|
||||
}
|
||||
|
||||
fn main() {
|
||||
component_container!{
|
||||
sparse name: Name,
|
||||
dense pos: Position,
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue