This commit is contained in:
Jaroslaw Konik 2025-05-21 22:07:45 +02:00
parent 992d19cba7
commit c75f158dfb
5 changed files with 64 additions and 58 deletions

View file

@ -78,7 +78,7 @@ where
inner_system.apply_deferred(world);
let mut runtime = world.get_resource_mut::<R>().expect("No runtime resource");
if R::is_current_thread() {
if R::needs_own_thread() {
runtime.with_engine_mut(move |engine| {
Out::into_runtime_value_with_engine(result, engine)
})
@ -110,7 +110,7 @@ macro_rules! impl_tuple {
inner_system.initialize(world);
let system_fn = move |args: In<Vec<RN::Value>>, world: &mut World| {
let mut runtime = world.get_resource_mut::<RN>().expect("No runtime resource");
let args = if RN::is_current_thread() {
let args = if RN::needs_own_thread() {
runtime.with_engine_mut(move |engine| {
(
$($t::from_runtime_value_with_engine(args.get($idx).expect(&format!("Failed to get function argument for index {}", $idx)).clone(), engine), )+
@ -127,7 +127,7 @@ macro_rules! impl_tuple {
let result = inner_system.run(args, world);
inner_system.apply_deferred(world);
let mut runtime = world.get_resource_mut::<RN>().expect("No runtime resource");
if RN::is_current_thread() {
if RN::needs_own_thread() {
runtime.with_engine_mut(move |engine| {
Out::into_runtime_value_with_engine(result, engine)
})

View file

@ -300,7 +300,7 @@ pub trait Runtime: Resource + Default {
type Value: Send + Clone;
type RawEngine;
fn is_current_thread() -> bool;
fn needs_own_thread() -> bool;
/// Provides mutable reference to raw scripting engine instance.
/// Can be used to directly interact with an interpreter to use interfaces

View file

@ -299,7 +299,7 @@ impl Runtime for LuaRuntime {
self.with_engine(f)
}
fn is_current_thread() -> bool {
fn needs_own_thread() -> bool {
true
}
}

View file

@ -208,7 +208,7 @@ impl Runtime for RhaiRuntime {
self.with_engine(f)
}
fn is_current_thread() -> bool {
fn needs_own_thread() -> bool {
true
}
}

View file

@ -291,6 +291,28 @@ impl RubyValue {
}
}
impl RubyRuntime {
fn execute_in_thread<T: Send + 'static>(
&self,
f: impl FnOnce(&magnus::Ruby) -> T + Send + 'static,
) -> T {
self.ruby_thread
.as_ref()
.unwrap()
.execute(Box::new(move |ruby| f(&ruby)))
}
fn execute_in_thread_mut<T: Send + 'static>(
&self,
f: impl FnOnce(&mut magnus::Ruby) -> T + Send + 'static,
) -> T {
self.ruby_thread
.as_ref()
.unwrap()
.execute(Box::new(move |mut ruby| f(&mut ruby)))
}
}
impl Runtime for RubyRuntime {
type Schedule = RubySchedule;
@ -308,20 +330,14 @@ impl Runtime for RubyRuntime {
&mut self,
f: impl FnOnce(&mut Self::RawEngine) -> T + Send + 'static,
) -> T {
self.ruby_thread
.as_ref()
.unwrap()
.execute(Box::new(move |mut ruby| f(&mut ruby)))
self.execute_in_thread_mut(f)
}
fn with_engine_thread<T: Send + 'static>(
&self,
f: impl FnOnce(&Self::RawEngine) -> T + Send + 'static,
) -> T {
self.ruby_thread
.as_ref()
.unwrap()
.execute(Box::new(move |ruby| f(&ruby)))
self.execute_in_thread(f)
}
fn with_engine_mut<T>(&mut self, _f: impl FnOnce(&mut Self::RawEngine) -> T) -> T {
@ -338,22 +354,19 @@ impl Runtime for RubyRuntime {
entity: bevy::prelude::Entity,
) -> Result<Self::ScriptData, crate::ScriptingError> {
let script = script.0.clone();
self.ruby_thread
.as_ref()
.unwrap()
.execute(Box::new(move |ruby| {
let var = ruby
.class_object()
.const_get::<_, RModule>("Bevy")
.unwrap()
.const_get::<_, RClass>("Entity")
.unwrap();
var.ivar_set("_current", BevyEntity(entity)).unwrap();
let value = ruby.eval::<magnus::value::Value>(&script).unwrap();
var.ivar_set("_current", ruby.qnil().as_value()).unwrap();
self.execute_in_thread(Box::new(move |ruby: &Ruby| {
let var = ruby
.class_object()
.const_get::<_, RModule>("Bevy")
.unwrap()
.const_get::<_, RClass>("Entity")
.unwrap();
var.ivar_set("_current", BevyEntity(entity)).unwrap();
let value = ruby.eval::<magnus::value::Value>(&script).unwrap();
var.ivar_set("_current", ruby.qnil().as_value()).unwrap();
RubyValue::new(value)
}));
RubyValue::new(value)
}));
Ok(RubyScriptData)
}
@ -403,13 +416,10 @@ impl Runtime for RubyRuntime {
result.into_value()
}
self.ruby_thread
.as_ref()
.unwrap()
.execute(Box::new(move |ruby| {
ruby.define_global_function(&name, function!(callback, -1));
RubyValue::nil(&ruby)
}));
self.execute_in_thread(Box::new(move |ruby: &Ruby| {
ruby.define_global_function(&name, function!(callback, -1));
RubyValue::nil(&ruby)
}));
Ok(())
}
@ -422,30 +432,26 @@ impl Runtime for RubyRuntime {
args: impl for<'a> crate::FuncArgs<'a, Self::Value, Self> + Send + 'static,
) -> Result<Self::Value, crate::ScriptingError> {
let name = name.to_string();
self.ruby_thread
.as_ref()
.unwrap()
.execute(Box::new(move |ruby| {
let var = ruby
.class_object()
.const_get::<_, RModule>("Bevy")
.unwrap()
.const_get::<_, RClass>("Entity")
.unwrap();
var.ivar_set("_current", BevyEntity(entity)).unwrap();
self.execute_in_thread(Box::new(move |ruby: &Ruby| {
let var = ruby
.class_object()
.const_get::<_, RModule>("Bevy")
.unwrap()
.const_get::<_, RClass>("Entity")
.unwrap();
var.ivar_set("_current", BevyEntity(entity)).unwrap();
let args: Vec<_> = args
.parse(&ruby)
.into_iter()
.map(|a| ruby.get_inner(a.0))
.collect();
let return_value: magnus::Value =
ruby.class_object().funcall(name, args.as_slice())?;
let args: Vec<_> = args
.parse(&ruby)
.into_iter()
.map(|a| ruby.get_inner(a.0))
.collect();
let return_value: magnus::Value = ruby.class_object().funcall(name, args.as_slice())?;
var.ivar_set("_current", ruby.qnil().as_value()).unwrap();
var.ivar_set("_current", ruby.qnil().as_value()).unwrap();
Ok(RubyValue::new(return_value))
}))
Ok(RubyValue::new(return_value))
}))
}
fn call_fn_from_value(
@ -471,7 +477,7 @@ impl Runtime for RubyRuntime {
}))
}
fn is_current_thread() -> bool {
fn needs_own_thread() -> bool {
false
}
}