Ruby support #1

Open
jaroslaw wants to merge 165 commits from ruby into main
5 changed files with 64 additions and 58 deletions
Showing only changes of commit c75f158dfb - Show all commits

View file

@ -78,7 +78,7 @@ where
inner_system.apply_deferred(world); inner_system.apply_deferred(world);
let mut runtime = world.get_resource_mut::<R>().expect("No runtime resource"); 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| { runtime.with_engine_mut(move |engine| {
Out::into_runtime_value_with_engine(result, engine) Out::into_runtime_value_with_engine(result, engine)
}) })
@ -110,7 +110,7 @@ macro_rules! impl_tuple {
inner_system.initialize(world); inner_system.initialize(world);
let system_fn = move |args: In<Vec<RN::Value>>, world: &mut 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 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| { 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), )+ $($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); let result = inner_system.run(args, world);
inner_system.apply_deferred(world); inner_system.apply_deferred(world);
let mut runtime = world.get_resource_mut::<RN>().expect("No runtime resource"); 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| { runtime.with_engine_mut(move |engine| {
Out::into_runtime_value_with_engine(result, 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 Value: Send + Clone;
type RawEngine; type RawEngine;
fn is_current_thread() -> bool; fn needs_own_thread() -> bool;
/// Provides mutable reference to raw scripting engine instance. /// Provides mutable reference to raw scripting engine instance.
/// Can be used to directly interact with an interpreter to use interfaces /// 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) self.with_engine(f)
} }
fn is_current_thread() -> bool { fn needs_own_thread() -> bool {
true true
} }
} }

View file

@ -208,7 +208,7 @@ impl Runtime for RhaiRuntime {
self.with_engine(f) self.with_engine(f)
} }
fn is_current_thread() -> bool { fn needs_own_thread() -> bool {
true 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 { impl Runtime for RubyRuntime {
type Schedule = RubySchedule; type Schedule = RubySchedule;
@ -308,20 +330,14 @@ impl Runtime for RubyRuntime {
&mut self, &mut self,
f: impl FnOnce(&mut Self::RawEngine) -> T + Send + 'static, f: impl FnOnce(&mut Self::RawEngine) -> T + Send + 'static,
) -> T { ) -> T {
self.ruby_thread self.execute_in_thread_mut(f)
.as_ref()
.unwrap()
.execute(Box::new(move |mut ruby| f(&mut ruby)))
} }
fn with_engine_thread<T: Send + 'static>( fn with_engine_thread<T: Send + 'static>(
&self, &self,
f: impl FnOnce(&Self::RawEngine) -> T + Send + 'static, f: impl FnOnce(&Self::RawEngine) -> T + Send + 'static,
) -> T { ) -> T {
self.ruby_thread self.execute_in_thread(f)
.as_ref()
.unwrap()
.execute(Box::new(move |ruby| f(&ruby)))
} }
fn with_engine_mut<T>(&mut self, _f: impl FnOnce(&mut Self::RawEngine) -> T) -> T { fn with_engine_mut<T>(&mut self, _f: impl FnOnce(&mut Self::RawEngine) -> T) -> T {
@ -338,10 +354,7 @@ impl Runtime for RubyRuntime {
entity: bevy::prelude::Entity, entity: bevy::prelude::Entity,
) -> Result<Self::ScriptData, crate::ScriptingError> { ) -> Result<Self::ScriptData, crate::ScriptingError> {
let script = script.0.clone(); let script = script.0.clone();
self.ruby_thread self.execute_in_thread(Box::new(move |ruby: &Ruby| {
.as_ref()
.unwrap()
.execute(Box::new(move |ruby| {
let var = ruby let var = ruby
.class_object() .class_object()
.const_get::<_, RModule>("Bevy") .const_get::<_, RModule>("Bevy")
@ -403,10 +416,7 @@ impl Runtime for RubyRuntime {
result.into_value() result.into_value()
} }
self.ruby_thread self.execute_in_thread(Box::new(move |ruby: &Ruby| {
.as_ref()
.unwrap()
.execute(Box::new(move |ruby| {
ruby.define_global_function(&name, function!(callback, -1)); ruby.define_global_function(&name, function!(callback, -1));
RubyValue::nil(&ruby) RubyValue::nil(&ruby)
})); }));
@ -422,10 +432,7 @@ impl Runtime for RubyRuntime {
args: impl for<'a> crate::FuncArgs<'a, Self::Value, Self> + Send + 'static, args: impl for<'a> crate::FuncArgs<'a, Self::Value, Self> + Send + 'static,
) -> Result<Self::Value, crate::ScriptingError> { ) -> Result<Self::Value, crate::ScriptingError> {
let name = name.to_string(); let name = name.to_string();
self.ruby_thread self.execute_in_thread(Box::new(move |ruby: &Ruby| {
.as_ref()
.unwrap()
.execute(Box::new(move |ruby| {
let var = ruby let var = ruby
.class_object() .class_object()
.const_get::<_, RModule>("Bevy") .const_get::<_, RModule>("Bevy")
@ -439,8 +446,7 @@ impl Runtime for RubyRuntime {
.into_iter() .into_iter()
.map(|a| ruby.get_inner(a.0)) .map(|a| ruby.get_inner(a.0))
.collect(); .collect();
let return_value: magnus::Value = let return_value: magnus::Value = ruby.class_object().funcall(name, args.as_slice())?;
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();
@ -471,7 +477,7 @@ impl Runtime for RubyRuntime {
})) }))
} }
fn is_current_thread() -> bool { fn needs_own_thread() -> bool {
false false
} }
} }