Skip to content

Commit 2796c83

Browse files
authored
perf: reduces size of ScriptValue to 64 bytes, moves some dynamic function methods into function info (#404)
# Summary Before this the size of `ScriptValue` was 168 bytes, this is a reduction of ~2.5x, which should reduce cache pressure and help with cloning/conversion performance.
1 parent ba14095 commit 2796c83

File tree

2 files changed

+31
-59
lines changed

2 files changed

+31
-59
lines changed

crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs

+19-59
Original file line numberDiff line numberDiff line change
@@ -70,24 +70,24 @@ impl FunctionCallContext {
7070
}
7171
}
7272

73-
#[derive(Clone, Reflect)]
73+
#[derive(Reflect, Clone)]
7474
#[reflect(opaque)]
7575
/// A dynamic script function.
7676
pub struct DynamicScriptFunction {
7777
/// The meta information about the function
78-
pub info: FunctionInfo,
78+
pub info: Arc<FunctionInfo>,
7979
// TODO: info about the function, this is hard right now because of non 'static lifetimes in wrappers, we can't use TypePath etc
8080
func: Arc<
8181
dyn Fn(FunctionCallContext, VecDeque<ScriptValue>) -> ScriptValue + Send + Sync + 'static,
8282
>,
8383
}
8484

85-
#[derive(Clone, Reflect)]
85+
#[derive(Reflect, Clone)]
8686
#[reflect(opaque)]
8787
/// A dynamic mutable script function.
8888
pub struct DynamicScriptFunctionMut {
8989
/// The meta information about the function
90-
pub info: FunctionInfo,
90+
pub info: Arc<FunctionInfo>,
9191
func: Arc<
9292
RwLock<
9393
// I'd rather consume an option or something instead of having the RWLock but I just wanna get this release out
@@ -129,30 +129,9 @@ impl DynamicScriptFunction {
129129
}
130130

131131
/// Set the meta information about the function
132-
pub fn with_info(self, info: FunctionInfo) -> Self {
133-
Self { info, ..self }
134-
}
135-
136-
/// Set the name of the function
137-
pub fn with_name<N: Into<Cow<'static, str>>>(self, name: N) -> Self {
138-
Self {
139-
info: FunctionInfo {
140-
name: name.into(),
141-
..self.info
142-
},
143-
func: self.func,
144-
}
145-
}
146-
147-
/// Set the namespace of the function
148-
pub fn with_namespace(self, namespace: Namespace) -> Self {
149-
Self {
150-
info: FunctionInfo {
151-
namespace,
152-
..self.info
153-
},
154-
func: self.func,
155-
}
132+
pub fn with_info(mut self, info: FunctionInfo) -> Self {
133+
self.info = Arc::new(info);
134+
self
156135
}
157136
}
158137

@@ -187,30 +166,9 @@ impl DynamicScriptFunctionMut {
187166
}
188167

189168
/// Set the meta information about the function
190-
pub fn with_info(self, info: FunctionInfo) -> Self {
191-
Self { info, ..self }
192-
}
193-
194-
/// Set the name of the function
195-
pub fn with_name<N: Into<Cow<'static, str>>>(self, name: N) -> Self {
196-
Self {
197-
info: FunctionInfo {
198-
name: name.into(),
199-
..self.info
200-
},
201-
func: self.func,
202-
}
203-
}
204-
205-
/// Set the namespace of the function
206-
pub fn with_namespace(self, namespace: Namespace) -> Self {
207-
Self {
208-
info: FunctionInfo {
209-
namespace,
210-
..self.info
211-
},
212-
func: self.func,
213-
}
169+
pub fn with_info(mut self, info: FunctionInfo) -> Self {
170+
self.info = Arc::new(info);
171+
self
214172
}
215173
}
216174

@@ -248,10 +206,11 @@ where
248206
{
249207
fn from(fn_: F) -> Self {
250208
DynamicScriptFunction {
251-
info: FunctionInfo::default(),
209+
info: FunctionInfo::default()
210+
.with_name(std::any::type_name::<F>())
211+
.into(),
252212
func: Arc::new(fn_),
253213
}
254-
.with_name(std::any::type_name::<F>())
255214
}
256215
}
257216

@@ -261,10 +220,11 @@ where
261220
{
262221
fn from(fn_: F) -> Self {
263222
DynamicScriptFunctionMut {
264-
info: FunctionInfo::default(),
223+
info: FunctionInfo::default()
224+
.with_name(std::any::type_name::<F>())
225+
.into(),
265226
func: Arc::new(RwLock::new(fn_)),
266227
}
267-
.with_name(std::any::type_name::<F>())
268228
}
269229
}
270230

@@ -711,7 +671,7 @@ mod test {
711671
#[test]
712672
fn test_invalid_amount_of_args_errors_nicely() {
713673
let fn_ = |a: usize, b: usize| a + b;
714-
let script_function = fn_.into_dynamic_script_function().with_name("my_fn");
674+
let script_function = fn_.into_dynamic_script_function();
715675

716676
with_local_world(|| {
717677
let out = script_function.call(
@@ -723,7 +683,7 @@ mod test {
723683
assert_eq!(
724684
out.unwrap_err(),
725685
InteropError::function_interop_error(
726-
"my_fn",
686+
"<bevy_mod_scripting_core::bindings::function::script_function::test::test_invalid_amount_of_args_errors_nicely::{{closure}} as bevy_mod_scripting_core::bindings::function::script_function::ScriptFunction<fn(usize, usize) -> usize>>::into_dynamic_script_function::{{closure}}",
727687
Namespace::Global,
728688
InteropError::argument_count_mismatch(2, 1)
729689
)
@@ -737,7 +697,7 @@ mod test {
737697
struct Comp;
738698

739699
let fn_ = |_a: crate::bindings::function::from::Mut<Comp>| 0usize;
740-
let script_function = fn_.into_dynamic_script_function().with_name("my_fn");
700+
let script_function = fn_.into_dynamic_script_function();
741701

742702
with_local_world(|| {
743703
let out = script_function.call(

crates/bevy_mod_scripting_core/src/docgen/info.rs

+12
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,18 @@ impl FunctionInfo {
5858
}
5959
}
6060

61+
/// Set the name of the function info.
62+
pub fn with_name(mut self, name: impl Into<Cow<'static, str>>) -> Self {
63+
self.name = name.into();
64+
self
65+
}
66+
67+
/// Set the namespace of the function info.
68+
pub fn with_namespace(mut self, namespace: Namespace) -> Self {
69+
self.namespace = namespace;
70+
self
71+
}
72+
6173
/// Add an argument to the function info.
6274
pub fn add_arg<T: ArgMeta + TypedThrough + 'static>(
6375
mut self,

0 commit comments

Comments
 (0)