doing a bunch of stuff all at once

This commit is contained in:
Vivian Lim 2023-01-29 00:30:48 -08:00
parent 974943d954
commit 2cc99fc24e
13 changed files with 2483 additions and 21 deletions

2031
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -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",
]

105
ecs/Cargo.lock generated Normal file
View File

@ -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"

22
ecs/Cargo.toml Normal file
View File

@ -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"]

132
ecs/src/ecs.rs Normal file
View File

@ -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 }
}

View File

@ -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() {

16
ecs_derive/Cargo.toml Normal file
View File

@ -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 = "*"

View File

@ -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(),
}),
);
}

106
ecs_derive/src/lib.rs Normal file
View File

@ -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!();
}
*/

View File

@ -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" }

View File

@ -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,
}
}