From b498da957db0e8422c70c2f7053f18020316a5bf Mon Sep 17 00:00:00 2001 From: Jaroslaw Konik Date: Tue, 13 May 2025 22:42:39 +0200 Subject: [PATCH] args wip --- Cargo.toml | 1 + ...tion_gets_called_from_script_with_param.rb | 3 +++ src/callback.rs | 19 ++++++++++++++----- src/runtimes/ruby.rs | 13 +++++++++++-- 4 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 assets/tests/ruby/rust_function_gets_called_from_script_with_param.rb diff --git a/Cargo.toml b/Cargo.toml index 60f10ad..014e017 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ mlua = { version = "0.9.8", features = [ ], optional = true } magnus = { version = "0.7.1", optional = true, features = ["embed"] } crossbeam-channel = "0.5.15" +rb-sys = "0.9.114" [[example]] name = "call_function_from_rust_rhai" diff --git a/assets/tests/ruby/rust_function_gets_called_from_script_with_param.rb b/assets/tests/ruby/rust_function_gets_called_from_script_with_param.rb new file mode 100644 index 0000000..5a49c25 --- /dev/null +++ b/assets/tests/ruby/rust_function_gets_called_from_script_with_param.rb @@ -0,0 +1,3 @@ +def test_func + rust_func(5) +end diff --git a/src/callback.rs b/src/callback.rs index 54edd92..f3b544e 100644 --- a/src/callback.rs +++ b/src/callback.rs @@ -110,11 +110,20 @@ macro_rules! impl_tuple { inner_system.initialize(world); let system_fn = move |args: In>, world: &mut World| { let mut runtime = world.get_resource_mut::().expect("No runtime resource"); - let args = 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), )+ - ) - }); + 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), )+ + ) + }) + } 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); inner_system.apply_deferred(world); let mut runtime = world.get_resource_mut::().expect("No runtime resource"); diff --git a/src/runtimes/ruby.rs b/src/runtimes/ruby.rs index 9324f67..39055b0 100644 --- a/src/runtimes/ruby.rs +++ b/src/runtimes/ruby.rs @@ -2,6 +2,7 @@ // TODO: make sure ruby is statically linked use std::{ collections::HashMap, + ffi::{c_void, CString}, sync::{Arc, Condvar, LazyLock, Mutex}, thread::{self, JoinHandle}, }; @@ -13,6 +14,7 @@ use bevy::{ }; use magnus::Ruby; use magnus::{function, prelude::*}; +use rb_sys::rb_define_global_function; use serde::Deserialize; use crate::{ @@ -207,7 +209,7 @@ impl Runtime for RubyRuntime { let mut callbacks = RUBY_CALLBACKS.lock().unwrap(); 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 method_name: magnus::value::StaticSymbol = ruby.class_object().funcall("__method__", ()).unwrap(); @@ -222,7 +224,14 @@ impl Runtime for RubyRuntime { .as_ref() .unwrap() .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(()) }));