Ruby support #1
5 changed files with 55 additions and 8 deletions
|
|
@ -31,7 +31,7 @@ mlua = { version = "0.9.8", features = [
|
||||||
"vendored",
|
"vendored",
|
||||||
"send",
|
"send",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
magnus = { version = "0.7.1", optional = true }
|
magnus = { version = "0.7.1", optional = true, features = ["embed"] }
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "call_function_from_rust_rhai"
|
name = "call_function_from_rust_rhai"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
$state = {
|
||||||
|
times_called: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_func
|
||||||
|
$state[:times_called] += 1
|
||||||
|
end
|
||||||
|
|
@ -259,7 +259,11 @@ use std::{
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
use bevy::{app::MainScheduleOrder, ecs::{component::Mutable, schedule::ScheduleLabel}, prelude::*};
|
use bevy::{
|
||||||
|
app::MainScheduleOrder,
|
||||||
|
ecs::{component::Mutable, schedule::ScheduleLabel},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
use callback::{Callback, IntoCallbackSystem};
|
use callback::{Callback, IntoCallbackSystem};
|
||||||
use systems::{init_callbacks, log_errors, process_calls};
|
use systems::{init_callbacks, log_errors, process_calls};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
@ -269,7 +273,7 @@ use self::{
|
||||||
systems::{process_new_scripts, reload_scripts},
|
systems::{process_new_scripts, reload_scripts},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(any(feature = "rhai", feature = "lua"))]
|
#[cfg(any(feature = "rhai", feature = "lua", feature = "ruby"))]
|
||||||
const ENTITY_VAR_NAME: &str = "entity";
|
const ENTITY_VAR_NAME: &str = "entity";
|
||||||
|
|
||||||
/// An error that can occur when internal [ScriptingPlugin] systems are being executed
|
/// An error that can occur when internal [ScriptingPlugin] systems are being executed
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,17 @@
|
||||||
|
use std::{
|
||||||
|
cell::{LazyCell, OnceCell},
|
||||||
|
sync::{LazyLock, Mutex, OnceLock},
|
||||||
|
};
|
||||||
|
|
||||||
use bevy::{
|
use bevy::{
|
||||||
asset::Asset,
|
asset::Asset,
|
||||||
ecs::{component::Component, entity::Entity, resource::Resource, schedule::ScheduleLabel},
|
ecs::{component::Component, entity::Entity, resource::Resource, schedule::ScheduleLabel},
|
||||||
reflect::TypePath,
|
reflect::TypePath,
|
||||||
};
|
};
|
||||||
|
use magnus::{
|
||||||
|
embed::{init, Cleanup},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -25,18 +34,37 @@ pub struct RubyScriptData;
|
||||||
|
|
||||||
impl GetExtensions for RubyScript {
|
impl GetExtensions for RubyScript {
|
||||||
fn extensions() -> &'static [&'static str] {
|
fn extensions() -> &'static [&'static str] {
|
||||||
todo!()
|
&["rb"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<String> for RubyScript {
|
impl From<String> for RubyScript {
|
||||||
fn from(value: String) -> Self {
|
fn from(value: String) -> Self {
|
||||||
todo!()
|
Self(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn hello(subject: String) -> String {
|
||||||
|
format!("hello, {}", subject)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RubyEngine(Cleanup);
|
||||||
|
|
||||||
|
unsafe impl Send for RubyEngine {}
|
||||||
|
|
||||||
|
static RUBY_ENGINE: OnceLock<Mutex<RubyEngine>> = OnceLock::new();
|
||||||
|
|
||||||
impl Default for RubyRuntime {
|
impl Default for RubyRuntime {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
RUBY_ENGINE.get_or_init(|| Mutex::new(RubyEngine(unsafe { magnus::embed::init() })));
|
||||||
|
// TODO: Add SAFETY?
|
||||||
|
|
||||||
|
// engine.define_global_function("hello", magnus::function!(hello, 1));
|
||||||
|
// engine
|
||||||
|
// .eval::<magnus::value::Qnil>(r#"puts hello("world")"#)
|
||||||
|
// .unwrap();
|
||||||
|
//
|
||||||
|
// Self { engine }
|
||||||
Self {}
|
Self {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +98,11 @@ impl Runtime for RubyRuntime {
|
||||||
script: &Self::ScriptAsset,
|
script: &Self::ScriptAsset,
|
||||||
entity: bevy::prelude::Entity,
|
entity: bevy::prelude::Entity,
|
||||||
) -> Result<Self::ScriptData, crate::ScriptingError> {
|
) -> Result<Self::ScriptData, crate::ScriptingError> {
|
||||||
todo!()
|
let engine =
|
||||||
|
RUBY_ENGINE.get_or_init(|| Mutex::new(RubyEngine(unsafe { magnus::embed::init() })));
|
||||||
|
let engine = engine.lock().unwrap();
|
||||||
|
engine.0.eval::<magnus::value::Qnil>(&script.0);
|
||||||
|
Ok(RubyScriptData)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_fn(
|
fn register_fn(
|
||||||
|
|
@ -97,7 +129,11 @@ impl Runtime for RubyRuntime {
|
||||||
entity: bevy::prelude::Entity,
|
entity: bevy::prelude::Entity,
|
||||||
args: impl for<'a> crate::FuncArgs<'a, Self::Value, Self>,
|
args: impl for<'a> crate::FuncArgs<'a, Self::Value, Self>,
|
||||||
) -> Result<Self::Value, crate::ScriptingError> {
|
) -> Result<Self::Value, crate::ScriptingError> {
|
||||||
todo!()
|
let engine =
|
||||||
|
RUBY_ENGINE.get_or_init(|| Mutex::new(RubyEngine(unsafe { magnus::embed::init() })));
|
||||||
|
let ruby = magnus::Ruby::get().unwrap();
|
||||||
|
let _: magnus::value::Value = ruby.class_object().funcall(name, ()).unwrap();
|
||||||
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_fn_from_value(
|
fn call_fn_from_value(
|
||||||
|
|
|
||||||
|
|
@ -297,7 +297,7 @@ macro_rules! scripting_tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_script_function_gets_called_from_rust() {
|
fn test_script_function_gets_called_from_rust_without_params() {
|
||||||
let mut app = build_test_app();
|
let mut app = build_test_app();
|
||||||
|
|
||||||
app.add_scripting::<$runtime>(|_| {});
|
app.add_scripting::<$runtime>(|_| {});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue