less panics
This commit is contained in:
parent
b3cd04aad6
commit
fb627ffdda
1 changed files with 38 additions and 37 deletions
|
|
@ -95,16 +95,16 @@ impl RubyThread {
|
||||||
.send(f(ruby))
|
.send(f(ruby))
|
||||||
.expect("Failed to send callback return value");
|
.expect("Failed to send callback return value");
|
||||||
}))
|
}))
|
||||||
.unwrap();
|
.expect("Faild to send execution unit to Ruby thread");
|
||||||
return_receiver
|
return_receiver
|
||||||
.recv()
|
.recv()
|
||||||
.expect("Faild to send execution unit to Ruby thread")
|
.expect("Failed to receive callback return value")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for RubyThread {
|
impl Drop for RubyThread {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let handle = self.handle.take().unwrap();
|
let handle = self.handle.take().expect("No Ruby thread to join");
|
||||||
handle.join().expect("Failed to join Ruby thread");
|
handle.join().expect("Failed to join Ruby thread");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -136,13 +136,16 @@ impl TryConvert for Promise<(), RubyValue> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn then(r_self: magnus::Value) -> magnus::Value {
|
fn then(r_self: magnus::Value) -> magnus::Value {
|
||||||
let promise: &Promise<(), RubyValue> = TryConvert::try_convert(r_self).unwrap();
|
let promise: &Promise<(), RubyValue> =
|
||||||
let ruby = Ruby::get().unwrap();
|
TryConvert::try_convert(r_self).expect("Couldn't convert self to Promise");
|
||||||
|
let ruby =
|
||||||
|
Ruby::get().expect("Failed to get a handle to Ruby API when registering Promise callback");
|
||||||
promise
|
promise
|
||||||
.clone()
|
.clone()
|
||||||
.then(RubyValue::new(
|
.then(RubyValue::new(
|
||||||
if ruby.block_given() {
|
if ruby.block_given() {
|
||||||
ruby.block_proc().expect("Failed to create Proc")
|
ruby.block_proc()
|
||||||
|
.expect("Failed to create Proc for Promise")
|
||||||
} else {
|
} else {
|
||||||
ruby.proc_new(|ruby, _, _| ruby.qnil().as_value())
|
ruby.proc_new(|ruby, _, _| ruby.qnil().as_value())
|
||||||
}
|
}
|
||||||
|
|
@ -195,38 +198,42 @@ impl TryConvert for BevyVec3 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<magnus::Error> for ScriptingError {
|
||||||
|
fn from(value: magnus::Error) -> Self {
|
||||||
|
ScriptingError::RuntimeError(Box::new(io::Error::other(value.to_string())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for RubyRuntime {
|
impl Default for RubyRuntime {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let (lock, cvar) = &*Arc::clone(&RUBY_THREAD);
|
let (lock, cvar) = &*Arc::clone(&RUBY_THREAD);
|
||||||
let mut ruby_thread = lock.lock().unwrap();
|
let mut ruby_thread = lock.lock().expect("Failed to acquire lock on Ruby thread");
|
||||||
|
|
||||||
while ruby_thread.is_none() {
|
while ruby_thread.is_none() {
|
||||||
ruby_thread = cvar.wait(ruby_thread).unwrap();
|
ruby_thread = cvar
|
||||||
|
.wait(ruby_thread)
|
||||||
|
.expect("Failed to acquire lock on Ruby thread after waiting");
|
||||||
}
|
}
|
||||||
let ruby_thread = ruby_thread.take().unwrap();
|
let ruby_thread = ruby_thread.take().expect("Ruby thread is not available");
|
||||||
cvar.notify_all();
|
cvar.notify_all();
|
||||||
|
|
||||||
ruby_thread.execute(Box::new(|ruby| {
|
ruby_thread
|
||||||
// TODO: maybe put promise in a module , maybe do so for other runtimes too
|
.execute(Box::new(|ruby| {
|
||||||
let promise = ruby.define_class("Promise", ruby.class_object()).unwrap();
|
// TODO: maybe put promise in a module , maybe do so for other runtimes too
|
||||||
promise
|
let promise = ruby.define_class("Promise", ruby.class_object())?;
|
||||||
.define_method("and_then", magnus::method!(then, 0))
|
promise.define_method("and_then", magnus::method!(then, 0))?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let entity = ruby
|
let entity = ruby.define_class("BevyEntity", ruby.class_object())?;
|
||||||
.define_class("BevyEntity", ruby.class_object())
|
entity.define_method("index", method!(BevyEntity::index, 0))?;
|
||||||
.unwrap();
|
|
||||||
entity
|
|
||||||
.define_method("index", method!(BevyEntity::index, 0))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let vec3 = ruby.define_class("Vec3", ruby.class_object()).unwrap();
|
let vec3 = ruby.define_class("Vec3", ruby.class_object())?;
|
||||||
vec3.define_singleton_method("new", function!(BevyVec3::new, 3))
|
vec3.define_singleton_method("new", function!(BevyVec3::new, 3))?;
|
||||||
.unwrap();
|
vec3.define_method("x", method!(BevyVec3::x, 0))?;
|
||||||
vec3.define_method("x", method!(BevyVec3::x, 0)).unwrap();
|
vec3.define_method("y", method!(BevyVec3::y, 0))?;
|
||||||
vec3.define_method("y", method!(BevyVec3::y, 0)).unwrap();
|
vec3.define_method("z", method!(BevyVec3::z, 0))?;
|
||||||
vec3.define_method("z", method!(BevyVec3::z, 0)).unwrap();
|
Ok::<(), ScriptingError>(())
|
||||||
}));
|
}))
|
||||||
|
.unwrap();
|
||||||
Self {
|
Self {
|
||||||
ruby_thread: Some(ruby_thread),
|
ruby_thread: Some(ruby_thread),
|
||||||
}
|
}
|
||||||
|
|
@ -399,12 +406,8 @@ impl Runtime for RubyRuntime {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|a| ruby.get_inner(a.0))
|
.map(|a| ruby.get_inner(a.0))
|
||||||
.collect();
|
.collect();
|
||||||
let return_value: magnus::Value = ruby
|
let return_value: magnus::Value =
|
||||||
.class_object()
|
ruby.class_object().funcall(name, args.as_slice())?;
|
||||||
.funcall(name, args.as_slice())
|
|
||||||
.map_err(|e| {
|
|
||||||
ScriptingError::RuntimeError(Box::new(io::Error::other(e.to_string())))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// SAFETY: this is guaranteed to be executed on a single thread
|
// SAFETY: this is guaranteed to be executed on a single thread
|
||||||
// so should be safe according to Magnus documentation
|
// so should be safe according to Magnus documentation
|
||||||
|
|
@ -433,9 +436,7 @@ impl Runtime for RubyRuntime {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|x| ruby.get_inner(x.0).as_value())
|
.map(|x| ruby.get_inner(x.0).as_value())
|
||||||
.collect();
|
.collect();
|
||||||
let result: magnus::Value = f.funcall("call", args.as_slice()).map_err(|e| {
|
let result: magnus::Value = f.funcall("call", args.as_slice())?;
|
||||||
ScriptingError::RuntimeError(Box::new(io::Error::other(e.to_string())))
|
|
||||||
})?;
|
|
||||||
Ok(RubyValue::new(result))
|
Ok(RubyValue::new(result))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue