Ruby support #1
5 changed files with 64 additions and 58 deletions
|
|
@ -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)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,22 +354,19 @@ 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()
|
let var = ruby
|
||||||
.unwrap()
|
.class_object()
|
||||||
.execute(Box::new(move |ruby| {
|
.const_get::<_, RModule>("Bevy")
|
||||||
let var = ruby
|
.unwrap()
|
||||||
.class_object()
|
.const_get::<_, RClass>("Entity")
|
||||||
.const_get::<_, RModule>("Bevy")
|
.unwrap();
|
||||||
.unwrap()
|
var.ivar_set("_current", BevyEntity(entity)).unwrap();
|
||||||
.const_get::<_, RClass>("Entity")
|
let value = ruby.eval::<magnus::value::Value>(&script).unwrap();
|
||||||
.unwrap();
|
var.ivar_set("_current", ruby.qnil().as_value()).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)
|
Ok(RubyScriptData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -403,13 +416,10 @@ impl Runtime for RubyRuntime {
|
||||||
result.into_value()
|
result.into_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ruby_thread
|
self.execute_in_thread(Box::new(move |ruby: &Ruby| {
|
||||||
.as_ref()
|
ruby.define_global_function(&name, function!(callback, -1));
|
||||||
.unwrap()
|
RubyValue::nil(&ruby)
|
||||||
.execute(Box::new(move |ruby| {
|
}));
|
||||||
ruby.define_global_function(&name, function!(callback, -1));
|
|
||||||
RubyValue::nil(&ruby)
|
|
||||||
}));
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -422,30 +432,26 @@ 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()
|
let var = ruby
|
||||||
.unwrap()
|
.class_object()
|
||||||
.execute(Box::new(move |ruby| {
|
.const_get::<_, RModule>("Bevy")
|
||||||
let var = ruby
|
.unwrap()
|
||||||
.class_object()
|
.const_get::<_, RClass>("Entity")
|
||||||
.const_get::<_, RModule>("Bevy")
|
.unwrap();
|
||||||
.unwrap()
|
var.ivar_set("_current", BevyEntity(entity)).unwrap();
|
||||||
.const_get::<_, RClass>("Entity")
|
|
||||||
.unwrap();
|
|
||||||
var.ivar_set("_current", BevyEntity(entity)).unwrap();
|
|
||||||
|
|
||||||
let args: Vec<_> = args
|
let args: Vec<_> = args
|
||||||
.parse(&ruby)
|
.parse(&ruby)
|
||||||
.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();
|
||||||
|
|
||||||
Ok(RubyValue::new(return_value))
|
Ok(RubyValue::new(return_value))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_fn_from_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
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue