1extern crate proc_macro;
2use proc_macro::TokenStream;
3use quote::quote;
4use syn::{parse::Parser, parse_macro_input, DeriveInput};
5
6#[proc_macro_attribute]
7pub fn objectinit_without_implements(_args: TokenStream, input: TokenStream) -> TokenStream {
8 let mut ast = parse_macro_input!(input as DeriveInput);
9 match &mut ast.data {
10 syn::Data::Struct(ref mut struct_data) => {
11 if let syn::Fields::Named(fields) = &mut struct_data.fields {
12 fields.named.push(
13 syn::Field::parse_named
14 .parse2(quote! {
15 pub transform: let_engine::Transform
16 })
17 .expect("transform failed"),
18 );
19 fields.named.push(
20 syn::Field::parse_named
21 .parse2(quote! {
22 parent_transform: let_engine::Transform
23 })
24 .expect("public transform failed"),
25 );
26 fields.named.push(
27 syn::Field::parse_named
28 .parse2(quote! {
29 pub appearance: let_engine::objects::Appearance
30 })
31 .expect("appearance failed"),
32 );
33 fields.named.push(
34 syn::Field::parse_named
35 .parse2(quote! {
36 id: usize
37 })
38 .expect("id failed"),
39 );
40 fields.named.push(
41 syn::Field::parse_named
42 .parse2(quote! {
43 reference: Option<let_engine::WeakObject>
44 })
45 .expect("weak object failed"),
46 );
47 fields.named.push(
48 syn::Field::parse_named
49 .parse2(quote! {
50 physics: let_engine::physics::ObjectPhysics
51 })
52 .expect("collider failed"),
53 );
54 }
55 }
56 _ => panic!("`object` has to be used with structs."),
57 };
58
59 quote! {
60 #[derive(Clone)]
61 #ast
62 }
63 .into()
64}
65
66#[proc_macro_attribute]
72pub fn object(_args: TokenStream, input: TokenStream) -> TokenStream {
73 let ast = parse_macro_input!(input as DeriveInput);
74 let name = &ast.ident;
75
76 quote! {
77 #[let_engine::objectinit_without_implements]
78 #ast
79 impl let_engine::objects::GameObject for #name {
80 fn transform(&self) -> Transform {
81 self.transform
82 }
83 fn set_isometry(&mut self, position: let_engine::Vec2, rotation: f32) {
84 self.transform.position = position;
85 self.transform.rotation = rotation;
86 }
87 fn public_transform(&self) -> Transform {
88 self.transform.combine(self.parent_transform)
89 }
90 fn set_parent_transform(&mut self, transform: Transform) {
91 self.parent_transform = transform;
92 }
93 fn appearance(&self) -> &let_engine::objects::Appearance {
94 &self.appearance
95 }
96 fn id(&self) -> usize {
97 self.id
98 }
99 fn init_to_layer(&mut self, id: usize, parent: &let_engine::NObject, mut rigid_body_parent: let_engine::objects::RigidBodyParent, layer: &let_engine::Layer) -> let_engine::NObject {
100 self.id = id;
101 self.physics.physics = Some(layer.physics.clone());
102 self.parent_transform = self.physics.update(&self.transform, parent, &mut rigid_body_parent, id as u128);
103 let node: let_engine::NObject = std::sync::Arc::new(let_engine::Mutex::new(let_engine::objects::Node{
104 object: Box::new(self.clone()),
105 parent: Some(std::sync::Arc::downgrade(parent)),
106 rigid_body_parent: rigid_body_parent.clone(),
107 children: vec![],
108 }));
109 if let Some(value) = &rigid_body_parent {
110 if value.is_none() && self.physics.rigid_body.is_some() {
111 layer.rigid_body_roots.lock().insert(id, node.clone());
112 }
113 }
114
115 self.reference = Some(std::sync::Arc::downgrade(&node));
116 node
117 }
118 fn remove_event(&mut self) {
119 self.physics.remove()
120 }
121 fn as_any(&self) -> &dyn std::any::Any {
122 self
123 }
124 fn as_node(&self) -> let_engine::NObject {
125 self.reference.as_ref().unwrap().upgrade().unwrap()
126 }
127 fn rigidbody_handle(&self) -> Option<let_engine::rapier2d::dynamics::RigidBodyHandle> {
128 self.physics.rigid_body_handle
129 }
130 fn collider_handle(&self) -> Option<let_engine::rapier2d::geometry::ColliderHandle> {
131 self.physics.collider_handle
132 }
133 }
134 impl #name {
135 pub fn update(&mut self) { if let Some(arc) = self.reference.clone().unwrap().upgrade() {
137 let object = &arc.lock().object;
138 self.transform = object.transform();
139 self.appearance = object.appearance().clone();
140 } else {
141 Self::remove_event(self);
142 }
143 }
144 pub fn sync(&mut self) { let node = self.reference.clone().unwrap().upgrade().unwrap();
147 {
148 let mut node = node.lock();
149 self.parent_transform = self.physics.update(
150 &self.transform,
151 &node.parent.clone().unwrap().upgrade().unwrap(),
152 &mut node.rigid_body_parent, self.id as u128
153 );
154 }
155 node.lock().update_children_position(Self::public_transform(self));
156 let arc = self.reference.clone().unwrap().upgrade().unwrap();
157 let mut object = arc.lock();
158 object.object = Box::new(self.clone());
159 }
160 pub fn collider(&self) -> Option<&let_engine::physics::Collider> {
161 self.physics.collider.as_ref()
162 }
163 pub fn set_collider(&mut self, collider: Option<let_engine::physics::Collider>) {
164 self.physics.collider = collider;
165 }
166 pub fn collider_mut(&mut self) -> &mut Option<let_engine::physics::Collider> {
167 &mut self.physics.collider
168 }
169 pub fn rigid_body(&self) -> Option<&let_engine::physics::RigidBody> {
170 self.physics.rigid_body.as_ref()
171 }
172 pub fn set_rigid_body(&mut self, rigid_body: Option<let_engine::physics::RigidBody>) {
173 self.physics.rigid_body = rigid_body;
174 }
175 pub fn rigid_body_mut(&mut self) -> &mut Option<let_engine::physics::RigidBody> {
176 &mut self.physics.rigid_body
177 }
178 pub fn local_collider_position(&self) -> let_engine::Vec2 {
179 self.physics.local_collider_position
180 }
181 pub fn set_local_collider_position(&mut self, pos: let_engine::Vec2) {
182 self.physics.local_collider_position = pos;
183 }
184 }
185 }
186 .into()
187}