Ruby support #1

Open
jaroslaw wants to merge 165 commits from ruby into main
4 changed files with 45 additions and 0 deletions
Showing only changes of commit e22236f201 - Show all commits

View file

@ -34,6 +34,7 @@ mlua = { version = "0.9.8", features = [
magnus = { version = "0.7.1", optional = true } magnus = { version = "0.7.1", optional = true }
rb-sys = { version = "*", default-features = false, features = ["link-ruby", "ruby-static"], optional = true } rb-sys = { version = "*", default-features = false, features = ["link-ruby", "ruby-static"], optional = true }
crossbeam-channel = "0.5.15" crossbeam-channel = "0.5.15"
libc = "0.2.172"
[[example]] [[example]]
name = "call_function_from_rust_rhai" name = "call_function_from_rust_rhai"

View file

@ -38,3 +38,13 @@ bevy_scriptum = { version = "0.8", features = ["ruby"] }
If you need a different version of bevy you need to use a matching bevy_scriptum If you need a different version of bevy you need to use a matching bevy_scriptum
version according to the [bevy support matrix](../bevy_support_matrix.md) version according to the [bevy support matrix](../bevy_support_matrix.md)
Ruby also needs dynamic symbol resolution and since `bevy_scriptum` links Ruby
statically the following `build.rs` file is needed to be present in project
root directory.
```rust
fn main() {
println!("cargo:rustc-link-arg=-rdynamic");
}
```

View file

@ -371,6 +371,10 @@ pub trait Runtime: Resource + Default {
context: &Self::CallContext, context: &Self::CallContext,
args: Vec<Self::Value>, args: Vec<Self::Value>,
) -> Result<Self::Value, ScriptingError>; ) -> Result<Self::Value, ScriptingError>;
fn needs_rdynamic_linking() -> bool {
false
}
} }
pub trait FuncArgs<'a, V, R: Runtime> { pub trait FuncArgs<'a, V, R: Runtime> {
@ -433,6 +437,19 @@ impl BuildScriptingRuntime for App {
/// Adds a scripting runtime. Registers required bevy systems that take /// Adds a scripting runtime. Registers required bevy systems that take
/// care of processing and running the scripts. /// care of processing and running the scripts.
fn add_scripting<R: Runtime>(&mut self, f: impl Fn(ScriptingRuntimeBuilder<R>)) -> &mut Self { fn add_scripting<R: Runtime>(&mut self, f: impl Fn(ScriptingRuntimeBuilder<R>)) -> &mut Self {
#[cfg(debug_assertions)]
if R::needs_rdynamic_linking() {
if !is_rdynamic_linking() {
panic!(
"Missing `-rdynamic`: symbol resolution failed.\n\
It is needed by {:?}.\n\
Please add `println!(\"cargo:rustc-link-arg=-rdynamic\");` to your build.rs\n\
or set `RUSTFLAGS=\"-C link-arg=-rdynamic\"`.",
std::any::type_name::<R>()
);
}
}
self.world_mut() self.world_mut()
.resource_mut::<MainScheduleOrder>() .resource_mut::<MainScheduleOrder>()
.insert_after(Update, R::Schedule::default()); .insert_after(Update, R::Schedule::default());
@ -495,6 +512,19 @@ impl<R: Runtime> Default for Callbacks<R> {
} }
} }
pub extern "C" fn is_rdynamic_linking() -> bool {
unsafe {
// Get a function pointer to itself
let addr = is_rdynamic_linking as *const libc::c_void;
let mut info: libc::Dl_info = std::mem::zeroed();
// Try to resolve symbol info
let result = libc::dladdr(addr, &mut info);
result != 0 && !info.dli_sname.is_null()
}
}
pub mod prelude { pub mod prelude {
pub use crate::{BuildScriptingRuntime as _, Runtime as _, Script}; pub use crate::{BuildScriptingRuntime as _, Runtime as _, Script};
} }

View file

@ -505,6 +505,10 @@ impl Runtime for RubyRuntime {
Ok(RubyValue::new(result)) Ok(RubyValue::new(result))
}) })
} }
fn needs_rdynamic_linking() -> bool {
true
}
} }
pub mod magnus { pub mod magnus {