Ruby support #1
4 changed files with 43 additions and 14 deletions
|
|
@ -65,7 +65,7 @@ where
|
||||||
fn into_callback_system(self, world: &mut World) -> CallbackSystem<R>;
|
fn into_callback_system(self, world: &mut World) -> CallbackSystem<R>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Runtime, Out, FN, Marker> IntoCallbackSystem<R, (), Out, Marker> for FN
|
impl<R: Runtime, Out: Send + 'static, FN, Marker> IntoCallbackSystem<R, (), Out, Marker> for FN
|
||||||
where
|
where
|
||||||
FN: IntoSystem<(), Out, Marker>,
|
FN: IntoSystem<(), Out, Marker>,
|
||||||
Out: for<'a> IntoRuntimeValueWithEngine<'a, Out, R>,
|
Out: for<'a> IntoRuntimeValueWithEngine<'a, Out, R>,
|
||||||
|
|
@ -90,12 +90,12 @@ where
|
||||||
|
|
||||||
macro_rules! impl_tuple {
|
macro_rules! impl_tuple {
|
||||||
($($idx:tt $t:tt),+) => {
|
($($idx:tt $t:tt),+) => {
|
||||||
impl<RN: Runtime, $($t,)+ Out, FN, Marker> IntoCallbackSystem<RN, In<($($t,)+)>, Out, Marker>
|
impl<RN: Runtime, $($t,)+ Out: Send + 'static, FN, Marker> IntoCallbackSystem<RN, In<($($t,)+)>, Out, Marker>
|
||||||
for FN
|
for FN
|
||||||
where
|
where
|
||||||
FN: IntoSystem<In<($($t,)+)>, Out, Marker>,
|
FN: IntoSystem<In<($($t,)+)>, Out, Marker>,
|
||||||
Out: for<'a> IntoRuntimeValueWithEngine<'a, Out, RN>,
|
Out: for<'a> IntoRuntimeValueWithEngine<'a, Out, RN>,
|
||||||
$($t: 'static + for<'a> FromRuntimeValueWithEngine<'a, RN>,)+
|
$($t: Send + 'static + for<'a> FromRuntimeValueWithEngine<'a, RN>,)+
|
||||||
{
|
{
|
||||||
fn into_callback_system(self, world: &mut World) -> CallbackSystem<RN> {
|
fn into_callback_system(self, world: &mut World) -> CallbackSystem<RN> {
|
||||||
let mut inner_system = IntoSystem::into_system(self);
|
let mut inner_system = IntoSystem::into_system(self);
|
||||||
|
|
|
||||||
|
|
@ -303,7 +303,10 @@ pub trait Runtime: Resource + Default {
|
||||||
/// 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
|
||||||
/// that bevy_scriptum does not provided adapters for.
|
/// that bevy_scriptum does not provided adapters for.
|
||||||
fn with_engine_mut<T>(&mut self, f: impl FnOnce(&mut Self::RawEngine) -> T) -> T;
|
fn with_engine_mut<T: Send + 'static>(
|
||||||
|
&mut self,
|
||||||
|
f: impl FnOnce(&mut Self::RawEngine) -> T + Send + 'static,
|
||||||
|
) -> T;
|
||||||
|
|
||||||
/// Provides immutable reference to raw scripting engine instance.
|
/// Provides immutable 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
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// TODO: make sure ruby is statically linked
|
// TODO: make sure ruby is statically linked
|
||||||
use std::{
|
use std::{
|
||||||
sync::LazyLock,
|
sync::{LazyLock, Mutex},
|
||||||
thread::{self, JoinHandle},
|
thread::{self, JoinHandle},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -49,6 +49,7 @@ struct RubyThread {
|
||||||
handle: Option<JoinHandle<()>>,
|
handle: Option<JoinHandle<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Can we put references to those in runtime struct?
|
||||||
static RUBY_THREAD: LazyLock<RubyThread> = LazyLock::new(|| RubyThread::spawn());
|
static RUBY_THREAD: LazyLock<RubyThread> = LazyLock::new(|| RubyThread::spawn());
|
||||||
|
|
||||||
impl RubyThread {
|
impl RubyThread {
|
||||||
|
|
@ -112,8 +113,11 @@ impl Runtime for RubyRuntime {
|
||||||
|
|
||||||
type RawEngine = magnus::Ruby;
|
type RawEngine = magnus::Ruby;
|
||||||
|
|
||||||
fn with_engine_mut<T>(&mut self, f: impl FnOnce(&mut Self::RawEngine) -> T) -> T {
|
fn with_engine_mut<T: Send + 'static>(
|
||||||
f(&mut magnus::Ruby::get().unwrap())
|
&mut self,
|
||||||
|
f: impl FnOnce(&mut Self::RawEngine) -> T + Send + 'static,
|
||||||
|
) -> T {
|
||||||
|
RUBY_THREAD.execute_in(Box::new(move |mut ruby| f(&mut ruby)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_engine<T: Send + 'static>(
|
fn with_engine<T: Send + 'static>(
|
||||||
|
|
@ -150,12 +154,34 @@ impl Runtime for RubyRuntime {
|
||||||
+ Sync
|
+ Sync
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) -> Result<(), crate::ScriptingError> {
|
) -> Result<(), crate::ScriptingError> {
|
||||||
|
static RUBY_CALLBACKS: LazyLock<
|
||||||
|
Mutex<
|
||||||
|
Vec<
|
||||||
|
Box<
|
||||||
|
dyn Fn(
|
||||||
|
(),
|
||||||
|
Vec<RubyValue>,
|
||||||
|
) -> Result<
|
||||||
|
crate::promise::Promise<(), RubyValue>,
|
||||||
|
crate::ScriptingError,
|
||||||
|
> + Send
|
||||||
|
+ Sync
|
||||||
|
+ 'static,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
> = LazyLock::new(|| Mutex::new(Vec::new()));
|
||||||
|
let mut callbacks = RUBY_CALLBACKS.lock().unwrap();
|
||||||
|
callbacks.push(Box::new(f));
|
||||||
|
|
||||||
fn callback() -> magnus::Value {
|
fn callback() -> magnus::Value {
|
||||||
let ruby = magnus::Ruby::get().unwrap();
|
let ruby = magnus::Ruby::get().unwrap();
|
||||||
let method_name: magnus::value::StaticSymbol =
|
let method_name: magnus::value::StaticSymbol =
|
||||||
ruby.class_object().funcall("__method__", ()).unwrap();
|
ruby.class_object().funcall("__method__", ()).unwrap();
|
||||||
let method_name = method_name.to_string();
|
let method_name = method_name.to_string();
|
||||||
dbg!(method_name);
|
let mut callbacks = RUBY_CALLBACKS.lock().unwrap();
|
||||||
|
let f = callbacks.pop().unwrap();
|
||||||
|
f((), vec![]);
|
||||||
ruby.qnil().as_value()
|
ruby.qnil().as_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -493,13 +493,13 @@ mod ruby_tests {
|
||||||
type ScriptData = RubyScriptData;
|
type ScriptData = RubyScriptData;
|
||||||
|
|
||||||
fn assert_state_key_value_i64(world: &World, _entity_id: Entity, key: &str, value: i64) {
|
fn assert_state_key_value_i64(world: &World, _entity_id: Entity, key: &str, value: i64) {
|
||||||
// let state: magnus::value::Value = Ruby::get()
|
// let runtime = world.get_resource::<RubyRuntime>().unwrap();
|
||||||
// .unwrap()
|
// let key = key.to_string();
|
||||||
// .class_object()
|
// runtime.with_engine(move |engine| {
|
||||||
// .const_get("STATE")
|
// let state: magnus::value::Value = engine.class_object().const_get("STATE").unwrap();
|
||||||
// .unwrap();
|
// let res: i64 = state.funcall_public("[]", (key,)).unwrap();
|
||||||
// let res: i64 = state.funcall_public("[]", (key.to_string(),)).unwrap();
|
|
||||||
// assert_eq!(res, value)
|
// assert_eq!(res, value)
|
||||||
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_state_key_value_i32(world: &World, _entity_id: Entity, key: &str, value: i32) {
|
fn assert_state_key_value_i32(world: &World, _entity_id: Entity, key: &str, value: i32) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue