Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_reflect/derive/src/impls/common.rs
9383 views
1
use bevy_macro_utils::fq_std::{FQAny, FQOption, FQResult};
2
3
use quote::quote;
4
5
use crate::{derive_data::ReflectMeta, where_clause_options::WhereClauseOptions};
6
7
pub fn impl_full_reflect(where_clause_options: &WhereClauseOptions) -> proc_macro2::TokenStream {
8
let meta = where_clause_options.meta();
9
let bevy_reflect_path = meta.bevy_reflect_path();
10
let type_path = meta.type_path();
11
12
let (impl_generics, ty_generics, where_clause) = type_path.generics().split_for_impl();
13
let where_reflect_clause = where_clause_options.extend_where_clause(where_clause);
14
15
let any_impls = if meta.is_remote_wrapper() {
16
quote! {
17
#[inline]
18
fn into_any(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box<Self>) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #FQAny> {
19
#bevy_reflect_path::__macro_exports::alloc_utils::Box::new(self.0)
20
}
21
22
#[inline]
23
fn as_any(&self) -> &dyn #FQAny {
24
&self.0
25
}
26
27
#[inline]
28
fn as_any_mut(&mut self) -> &mut dyn #FQAny {
29
&mut self.0
30
}
31
}
32
} else {
33
quote! {
34
#[inline]
35
fn into_any(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box<Self>) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #FQAny> {
36
self
37
}
38
39
#[inline]
40
fn as_any(&self) -> &dyn #FQAny {
41
self
42
}
43
44
#[inline]
45
fn as_any_mut(&mut self) -> &mut dyn #FQAny {
46
self
47
}
48
}
49
};
50
51
quote! {
52
impl #impl_generics #bevy_reflect_path::Reflect for #type_path #ty_generics #where_reflect_clause {
53
#any_impls
54
55
#[inline]
56
fn into_reflect(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box<Self>) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::Reflect> {
57
self
58
}
59
60
#[inline]
61
fn as_reflect(&self) -> &dyn #bevy_reflect_path::Reflect {
62
self
63
}
64
65
#[inline]
66
fn as_reflect_mut(&mut self) -> &mut dyn #bevy_reflect_path::Reflect {
67
self
68
}
69
70
#[inline]
71
fn set(
72
&mut self,
73
value: #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::Reflect>
74
) -> #FQResult<(), #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::Reflect>> {
75
*self = <dyn #bevy_reflect_path::Reflect>::take(value)?;
76
#FQResult::Ok(())
77
}
78
}
79
}
80
}
81
82
pub fn common_partial_reflect_methods(
83
meta: &ReflectMeta,
84
default_partial_eq_delegate: impl FnOnce() -> Option<proc_macro2::TokenStream>,
85
default_hash_delegate: impl FnOnce() -> Option<proc_macro2::TokenStream>,
86
default_partial_ord_delegate: impl FnOnce() -> Option<proc_macro2::TokenStream>,
87
) -> proc_macro2::TokenStream {
88
let bevy_reflect_path = meta.bevy_reflect_path();
89
90
let debug_fn = meta.attrs().get_debug_impl();
91
let partial_eq_fn = meta
92
.attrs()
93
.get_partial_eq_impl(bevy_reflect_path)
94
.or_else(move || {
95
let default_delegate = default_partial_eq_delegate();
96
default_delegate.map(|func| {
97
quote! {
98
fn reflect_partial_eq(&self, value: &dyn #bevy_reflect_path::PartialReflect) -> #FQOption<bool> {
99
(#func)(self, value)
100
}
101
}
102
})
103
});
104
let partial_ord_fn = meta
105
.attrs()
106
.get_partial_ord_impl(bevy_reflect_path)
107
.or_else(move || {
108
let default_delegate = default_partial_ord_delegate();
109
default_delegate.map(|func| {
110
quote! {
111
fn reflect_partial_cmp(&self, value: &dyn #bevy_reflect_path::PartialReflect) -> #FQOption<::core::cmp::Ordering> {
112
(#func)(self, value)
113
}
114
}
115
})
116
});
117
let hash_fn = meta
118
.attrs()
119
.get_hash_impl(bevy_reflect_path)
120
.or_else(move || {
121
let default_delegate = default_hash_delegate();
122
default_delegate.map(|func| {
123
quote! {
124
fn reflect_hash(&self) -> #FQOption<u64> {
125
(#func)(self)
126
}
127
}
128
})
129
});
130
131
quote! {
132
#[inline]
133
fn try_into_reflect(
134
self: #bevy_reflect_path::__macro_exports::alloc_utils::Box<Self>
135
) -> #FQResult<#bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::Reflect>, #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::PartialReflect>> {
136
#FQResult::Ok(self)
137
}
138
139
#[inline]
140
fn try_as_reflect(&self) -> #FQOption<&dyn #bevy_reflect_path::Reflect> {
141
#FQOption::Some(self)
142
}
143
144
#[inline]
145
fn try_as_reflect_mut(&mut self) -> #FQOption<&mut dyn #bevy_reflect_path::Reflect> {
146
#FQOption::Some(self)
147
}
148
149
#[inline]
150
fn into_partial_reflect(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box<Self>) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::PartialReflect> {
151
self
152
}
153
154
#[inline]
155
fn as_partial_reflect(&self) -> &dyn #bevy_reflect_path::PartialReflect {
156
self
157
}
158
159
#[inline]
160
fn as_partial_reflect_mut(&mut self) -> &mut dyn #bevy_reflect_path::PartialReflect {
161
self
162
}
163
164
#hash_fn
165
166
#partial_eq_fn
167
168
#partial_ord_fn
169
170
#debug_fn
171
}
172
}
173
174
#[cfg(feature = "auto_register")]
175
pub fn reflect_auto_registration(meta: &ReflectMeta) -> Option<proc_macro2::TokenStream> {
176
if meta.attrs().no_auto_register() {
177
return None;
178
}
179
180
let bevy_reflect_path = meta.bevy_reflect_path();
181
let type_path = meta.type_path();
182
183
if type_path.impl_is_generic() {
184
return None;
185
};
186
187
#[cfg(feature = "auto_register_static")]
188
{
189
use std::{
190
env, fs,
191
io::Write,
192
path::PathBuf,
193
sync::{LazyLock, Mutex},
194
};
195
196
// Skip unless env var is set, otherwise this might slow down rust-analyzer
197
if env::var("BEVY_REFLECT_AUTO_REGISTER_STATIC").is_err() {
198
return None;
199
}
200
201
// Names of registrations functions will be stored in this file.
202
// To allow writing to this file from multiple threads during compilation it is protected by mutex.
203
// This static is valid for the duration of compilation of one crate and we have one file per crate,
204
// so it is enough to protect compilation threads from overwriting each other.
205
// This file is reset on every crate recompilation.
206
//
207
// It might make sense to replace the mutex with File::lock when file_lock feature becomes stable.
208
static REGISTRATION_FNS_EXPORT: LazyLock<Mutex<fs::File>> = LazyLock::new(|| {
209
let path = PathBuf::from("target").join("bevy_reflect_type_registrations");
210
fs::DirBuilder::new()
211
.recursive(true)
212
.create(&path)
213
.unwrap_or_else(|_| panic!("Failed to create {path:?}"));
214
let file_path = path.join(env::var("CARGO_CRATE_NAME").unwrap());
215
let file = fs::OpenOptions::new()
216
.create(true)
217
.write(true)
218
.truncate(true)
219
.open(&file_path)
220
.unwrap_or_else(|_| panic!("Failed to create {file_path:?}"));
221
Mutex::new(file)
222
});
223
224
let export_name = format!("_bevy_reflect_register_{}", uuid::Uuid::new_v4().as_u128());
225
226
{
227
let mut file = REGISTRATION_FNS_EXPORT.lock().unwrap();
228
writeln!(file, "{export_name}")
229
.unwrap_or_else(|_| panic!("Failed to write registration function {export_name}"));
230
// We must sync_data to ensure all content is written before releasing the lock.
231
file.sync_data().unwrap();
232
};
233
234
Some(quote! {
235
/// # Safety
236
/// This function must only be used by the `load_type_registrations` macro.
237
#[unsafe(export_name=#export_name)]
238
pub unsafe extern "Rust" fn bevy_register_type(registry: &mut #bevy_reflect_path::TypeRegistry) {
239
<#type_path as #bevy_reflect_path::__macro_exports::RegisterForReflection>::__register(registry);
240
}
241
})
242
}
243
244
#[cfg(all(
245
feature = "auto_register_inventory",
246
not(feature = "auto_register_static")
247
))]
248
{
249
Some(quote! {
250
#bevy_reflect_path::__macro_exports::auto_register::inventory::submit!{
251
#bevy_reflect_path::__macro_exports::auto_register::AutomaticReflectRegistrations(
252
<#type_path as #bevy_reflect_path::__macro_exports::auto_register::RegisterForReflection>::__register
253
)
254
}
255
})
256
}
257
}
258
259