Ruby support #1
4 changed files with 29 additions and 7 deletions
|
|
@ -33,6 +33,7 @@ mlua = { version = "0.9.8", features = [
|
||||||
], optional = true }
|
], optional = true }
|
||||||
magnus = { version = "0.7.1", optional = true, features = ["embed"] }
|
magnus = { version = "0.7.1", optional = true, features = ["embed"] }
|
||||||
crossbeam-channel = "0.5.15"
|
crossbeam-channel = "0.5.15"
|
||||||
|
rb-sys = "0.9.114"
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "call_function_from_rust_rhai"
|
name = "call_function_from_rust_rhai"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
def test_func
|
||||||
|
rust_func(5)
|
||||||
|
end
|
||||||
|
|
@ -110,11 +110,20 @@ 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 = runtime.with_engine_mut(move |engine| {
|
let args = if RN::is_current_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), )+
|
$($t::from_runtime_value_with_engine(args.get($idx).expect(&format!("Failed to get function argument for index {}", $idx)).clone(), engine), )+
|
||||||
)
|
)
|
||||||
});
|
})
|
||||||
|
} else {
|
||||||
|
runtime.with_engine_thread_mut(move |engine| {
|
||||||
|
(
|
||||||
|
$($t::from_runtime_value_with_engine(args.get($idx).expect(&format!("Failed to get function argument for index {}", $idx)).clone(), engine), )+
|
||||||
|
)
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
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");
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// TODO: make sure ruby is statically linked
|
// TODO: make sure ruby is statically linked
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
|
ffi::{c_void, CString},
|
||||||
sync::{Arc, Condvar, LazyLock, Mutex},
|
sync::{Arc, Condvar, LazyLock, Mutex},
|
||||||
thread::{self, JoinHandle},
|
thread::{self, JoinHandle},
|
||||||
};
|
};
|
||||||
|
|
@ -13,6 +14,7 @@ use bevy::{
|
||||||
};
|
};
|
||||||
use magnus::Ruby;
|
use magnus::Ruby;
|
||||||
use magnus::{function, prelude::*};
|
use magnus::{function, prelude::*};
|
||||||
|
use rb_sys::rb_define_global_function;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -207,7 +209,7 @@ impl Runtime for RubyRuntime {
|
||||||
let mut callbacks = RUBY_CALLBACKS.lock().unwrap();
|
let mut callbacks = RUBY_CALLBACKS.lock().unwrap();
|
||||||
callbacks.insert(name.clone(), Box::new(f));
|
callbacks.insert(name.clone(), Box::new(f));
|
||||||
|
|
||||||
fn callback() -> magnus::Value {
|
unsafe extern "C" fn callback(_rb_self: magnus::Value) -> 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();
|
||||||
|
|
@ -222,7 +224,14 @@ impl Runtime for RubyRuntime {
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.execute(Box::new(move |ruby| {
|
.execute(Box::new(move |ruby| {
|
||||||
ruby.define_global_function(&name, function!(callback, 0));
|
let name = CString::new(name).unwrap();
|
||||||
|
unsafe {
|
||||||
|
rb_define_global_function(
|
||||||
|
name.as_ptr(),
|
||||||
|
std::mem::transmute(callback as *mut c_void),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
}
|
||||||
RubyValue(())
|
RubyValue(())
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue