execute ruby stuff on ruby thread
This commit is contained in:
parent
e82278155a
commit
aee3276f2b
1 changed files with 49 additions and 27 deletions
|
|
@ -10,6 +10,7 @@ use bevy::{
|
||||||
ecs::{component::Component, entity::Entity, resource::Resource, schedule::ScheduleLabel},
|
ecs::{component::Component, entity::Entity, resource::Resource, schedule::ScheduleLabel},
|
||||||
reflect::TypePath,
|
reflect::TypePath,
|
||||||
};
|
};
|
||||||
|
use magnus::Ruby;
|
||||||
use magnus::{
|
use magnus::{
|
||||||
embed::{init, Cleanup},
|
embed::{init, Cleanup},
|
||||||
function,
|
function,
|
||||||
|
|
@ -26,7 +27,7 @@ use crate::{
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct RubyRuntime {
|
pub struct RubyRuntime {
|
||||||
ruby_thread: Option<JoinHandle<()>>,
|
ruby_thread: Option<JoinHandle<()>>,
|
||||||
ruby_thread_sender: Option<crossbeam_channel::Sender<()>>,
|
ruby_thread_sender: Option<crossbeam_channel::Sender<Box<dyn FnOnce(Ruby) + Send>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(ScheduleLabel, Clone, PartialEq, Eq, Debug, Hash, Default)]
|
#[derive(ScheduleLabel, Clone, PartialEq, Eq, Debug, Hash, Default)]
|
||||||
|
|
@ -54,16 +55,17 @@ struct RubyEngine(Cleanup);
|
||||||
// TODO: Add SAFETY?
|
// TODO: Add SAFETY?
|
||||||
unsafe impl Send for RubyEngine {}
|
unsafe impl Send for RubyEngine {}
|
||||||
|
|
||||||
static RUBY_ENGINE: LazyLock<Mutex<RubyEngine>> =
|
|
||||||
LazyLock::new(|| Mutex::new(RubyEngine(unsafe { magnus::embed::init() })));
|
|
||||||
|
|
||||||
impl Default for RubyRuntime {
|
impl Default for RubyRuntime {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let (ruby_thread_sender, ruby_thread_receiver) = crossbeam_channel::unbounded::<()>();
|
let (ruby_thread_sender, ruby_thread_receiver) =
|
||||||
|
crossbeam_channel::unbounded::<Box<dyn FnOnce(Ruby) + Send>>();
|
||||||
let ruby_thread = thread::spawn(move || {
|
let ruby_thread = thread::spawn(move || {
|
||||||
let _cleanup = LazyLock::force(&RUBY_ENGINE);
|
static RUBY_ENGINE: LazyLock<Mutex<RubyEngine>> =
|
||||||
|
LazyLock::new(|| Mutex::new(RubyEngine(unsafe { magnus::embed::init() })));
|
||||||
|
LazyLock::force(&RUBY_ENGINE);
|
||||||
while let Ok(val) = ruby_thread_receiver.recv() {
|
while let Ok(val) = ruby_thread_receiver.recv() {
|
||||||
println!("received");
|
let ruby = Ruby::get().unwrap();
|
||||||
|
val(ruby);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -110,8 +112,15 @@ 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> {
|
||||||
let ruby = magnus::Ruby::get().unwrap();
|
let script = script.0.clone();
|
||||||
ruby.eval::<magnus::value::Qnil>(&script.0);
|
self.ruby_thread_sender
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.send(Box::new(move |ruby| {
|
||||||
|
ruby.eval::<magnus::value::Value>(&script).unwrap();
|
||||||
|
}))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
Ok(RubyScriptData)
|
Ok(RubyScriptData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -129,28 +138,34 @@ impl Runtime for RubyRuntime {
|
||||||
+ Sync
|
+ Sync
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) -> Result<(), crate::ScriptingError> {
|
) -> Result<(), crate::ScriptingError> {
|
||||||
let ruby = magnus::Ruby::get().unwrap();
|
// let ruby = magnus::Ruby::get().unwrap();
|
||||||
|
//
|
||||||
|
// static mut FUN: Vec<Box<dyn Fn()>> = Vec::new();
|
||||||
|
// unsafe {
|
||||||
|
// FUN.push(Box::new(move || {
|
||||||
|
// f((), vec![]).unwrap();
|
||||||
|
// }));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
|
||||||
static mut FUN: Vec<Box<dyn Fn()>> = Vec::new();
|
fn callback(val: magnus::Value) -> magnus::Value {
|
||||||
unsafe {
|
// println!("{:?}", val);
|
||||||
FUN.push(Box::new(move || {
|
|
||||||
f((), vec![]).unwrap();
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
let sender = self.ruby_thread_sender.as_ref().clone();
|
|
||||||
let x = 5;
|
|
||||||
|
|
||||||
fn callback() -> magnus::Value {
|
|
||||||
// sender.unwrap().send(());
|
// sender.unwrap().send(());
|
||||||
let ruby = magnus::Ruby::get().unwrap();
|
let ruby = magnus::Ruby::get().unwrap();
|
||||||
unsafe {
|
// unsafe {
|
||||||
FUN.pop().unwrap()();
|
// FUN.pop().unwrap()();
|
||||||
}
|
// }
|
||||||
ruby.qnil().as_value()
|
ruby.qnil().as_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
ruby.define_global_function(&name, function!(callback, 0));
|
self.ruby_thread_sender
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.send(Box::new(move |ruby| {
|
||||||
|
ruby.define_global_function(&name, function!(callback, 1));
|
||||||
|
}))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -161,8 +176,15 @@ 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> {
|
||||||
let ruby = magnus::Ruby::get().unwrap();
|
let name = name.to_string();
|
||||||
let _: magnus::value::Value = ruby.class_object().funcall(name, ()).unwrap();
|
self.ruby_thread_sender
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.send(Box::new(move |ruby| {
|
||||||
|
let _: magnus::value::Value = ruby.class_object().funcall(name, ()).unwrap();
|
||||||
|
}))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
Ok(RubyValue(()))
|
Ok(RubyValue(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue