lib/ecs_macros: implement
A small little proc_macro to generate ecs::Access for any struct. This can be used instead of tuples in SystemData.master
parent
45d271c39b
commit
591e3146cd
|
@ -51,6 +51,9 @@ rust_binary(
|
|||
"@com_github_q3k_q3d//:q3d_rs",
|
||||
"@rules_rust//tools/runfiles",
|
||||
],
|
||||
proc_macro_deps = [
|
||||
"//lib/ecs_macros",
|
||||
],
|
||||
data = [
|
||||
"//engine/shaders:forward_vert",
|
||||
"//engine/shaders:forward_frag",
|
||||
|
|
|
@ -26,6 +26,7 @@ mod util;
|
|||
mod physics;
|
||||
|
||||
use ecs::{Component, World, Processor};
|
||||
use ecs_macros::Access;
|
||||
use render::vulkan::data;
|
||||
use render::material::{Texture, PBRMaterialBuilder};
|
||||
use render::{Light, Material, Mesh, Transform, Renderable};
|
||||
|
@ -153,13 +154,17 @@ impl Main {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Access)]
|
||||
struct MainData<'a> {
|
||||
scene_info: ecs::ReadWriteGlobal<'a, render::SceneInfo>,
|
||||
time: ecs::ReadGlobal<'a, Time>,
|
||||
transforms: ecs::ReadWriteComponent<'a, Transform>,
|
||||
}
|
||||
|
||||
impl<'a> ecs::System <'a> for Main {
|
||||
type SystemData = ( ecs::ReadWriteGlobal<'a, render::SceneInfo>
|
||||
, ecs::ReadGlobal<'a, Time>
|
||||
, ecs::ReadWriteComponent<'a, Transform>
|
||||
);
|
||||
fn run(&mut self, (scene_info, time, transforms): Self::SystemData) {
|
||||
let position = (time.get().instant() / 10.0) * 3.14 * 2.0;
|
||||
type SystemData = MainData<'a>;
|
||||
fn run(&mut self, sd: Self::SystemData) {
|
||||
let position = (sd.time.get().instant() / 10.0) * 3.14 * 2.0;
|
||||
|
||||
let camera = cgm::Point3::new(
|
||||
7.0 + (position / 4.0).sin(),
|
||||
|
@ -173,16 +178,16 @@ impl<'a> ecs::System <'a> for Main {
|
|||
cgm::Vector3::new(0.0, 0.0, 1.0)
|
||||
);
|
||||
|
||||
scene_info.get().camera = camera;
|
||||
scene_info.get().view = view;
|
||||
sd.scene_info.get().camera = camera;
|
||||
sd.scene_info.get().view = view;
|
||||
|
||||
*transforms.get_mut(self.light1).unwrap() = Transform::at(
|
||||
*sd.transforms.get_mut(self.light1).unwrap() = Transform::at(
|
||||
-0.0 + (position*3.0).sin() * 4.0,
|
||||
-0.0 + (position*4.0).cos() * 4.0,
|
||||
-0.0 + (position*2.0).sin() * 3.0,
|
||||
);
|
||||
|
||||
*transforms.get_mut(self.light2).unwrap() = Transform::at(
|
||||
*sd.transforms.get_mut(self.light2).unwrap() = Transform::at(
|
||||
-0.0 + (position*3.0).cos() * 4.0,
|
||||
-0.0 + (position*4.0).sin() * 4.0,
|
||||
-0.0 + (position*2.0).cos() * 3.0,
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
load("@rules_rust//rust:defs.bzl", "rust_proc_macro")
|
||||
|
||||
rust_proc_macro(
|
||||
name = "ecs_macros",
|
||||
edition = "2018",
|
||||
srcs = [
|
||||
"src/lib.rs",
|
||||
],
|
||||
visibility = ["//engine:__subpackages__"],
|
||||
deps = [
|
||||
"//third_party/cargo:proc_macro2",
|
||||
"//third_party/cargo:quote",
|
||||
"//third_party/cargo:syn",
|
||||
],
|
||||
)
|
|
@ -0,0 +1,63 @@
|
|||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::parse_macro_input;
|
||||
|
||||
#[proc_macro_derive(Access)]
|
||||
pub fn derive_access(input: TokenStream) -> TokenStream {
|
||||
let syn::DeriveInput { ident, data, .. } = parse_macro_input!(input);
|
||||
|
||||
let fields: Vec<proc_macro2::TokenStream> = match data {
|
||||
syn::Data::Struct(st) => match st.fields {
|
||||
syn::Fields::Named(syn::FieldsNamed { named, .. }) => {
|
||||
named.iter().filter(|field| {
|
||||
field.ident.is_some()
|
||||
}).map(|field| {
|
||||
let ident = &field.ident;
|
||||
let mut ty = field.ty.clone();
|
||||
// Yeet out path.segments.arguments (ie. type arguments), as these need to be
|
||||
// absent in instantiations:
|
||||
// struct Foo<'a, T> {
|
||||
// bar: baz<'a, T>,
|
||||
// }
|
||||
// but:
|
||||
// Foo {
|
||||
// bar: baz::new(),
|
||||
// }
|
||||
// Ugh.
|
||||
match ty {
|
||||
syn::Type::Path(syn::TypePath { ref mut path, .. }) => {
|
||||
let segments = path.segments.clone().iter().map(|seg| {
|
||||
let mut seg = seg.clone();
|
||||
seg.arguments = syn::PathArguments::None;
|
||||
seg
|
||||
}).collect();
|
||||
path.segments = segments;
|
||||
},
|
||||
_ => (),
|
||||
};
|
||||
quote! {
|
||||
#ident : #ty::fetch(world)
|
||||
}
|
||||
}).collect()
|
||||
},
|
||||
_ => {
|
||||
panic!("can only derive Access on structs with named fields");
|
||||
},
|
||||
}
|
||||
_ => panic!("can only derive Access on structs"),
|
||||
};
|
||||
|
||||
let output = quote! {
|
||||
impl <'a> ecs::system::Access<'a> for #ident<'a> {
|
||||
fn fetch(world: &'a ecs::World) -> Self {
|
||||
Self {
|
||||
#( #fields, )*
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let tokens = output.into();
|
||||
//eprintln!("TOKENS: {}", tokens);
|
||||
tokens
|
||||
}
|
|
@ -16,6 +16,8 @@ winit = "0.24.0"
|
|||
cgmath = "0.18.0"
|
||||
#openvr = "0.6.0"
|
||||
flatbuffers = "0.6.1"
|
||||
quote = "1.0.8"
|
||||
syn = "1.0.58"
|
||||
|
||||
[workspace.metadata.raze]
|
||||
workspace_path = "//third_party/cargo"
|
||||
|
@ -72,3 +74,6 @@ gen_buildrs = true
|
|||
|
||||
[workspace.metadata.raze.crates.winapi.'0.3.9']
|
||||
gen_buildrs = true
|
||||
|
||||
[workspace.metadata.raze.crates.proc-macro2.'1.0.24']
|
||||
gen_buildrs = true
|
||||
|
|
|
@ -29,8 +29,36 @@ licenses([
|
|||
])
|
||||
|
||||
# Generated Targets
|
||||
# buildifier: disable=load-on-top
|
||||
load(
|
||||
"@rules_rust//cargo:cargo_build_script.bzl",
|
||||
"cargo_build_script",
|
||||
)
|
||||
|
||||
# Unsupported target "build-script-build" with type "custom-build" omitted
|
||||
cargo_build_script(
|
||||
name = "proc_macro2_build_script",
|
||||
srcs = glob(["**/*.rs"]),
|
||||
build_script_env = {
|
||||
},
|
||||
crate_features = [
|
||||
"default",
|
||||
"proc-macro",
|
||||
],
|
||||
crate_root = "build.rs",
|
||||
data = glob(["**"]),
|
||||
edition = "2018",
|
||||
rustc_flags = [
|
||||
"--cap-lints=allow",
|
||||
],
|
||||
tags = [
|
||||
"cargo-raze",
|
||||
"manual",
|
||||
],
|
||||
version = "1.0.24",
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
],
|
||||
)
|
||||
|
||||
rust_library(
|
||||
name = "proc_macro2",
|
||||
|
@ -53,6 +81,7 @@ rust_library(
|
|||
version = "1.0.24",
|
||||
# buildifier: leave-alone
|
||||
deps = [
|
||||
":proc_macro2_build_script",
|
||||
"//third_party/cargo/vendor/unicode-xid-0.2.1:unicode_xid",
|
||||
],
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue