Change ruby API
This commit is contained in:
parent
fb627ffdda
commit
900d1579ee
4 changed files with 34 additions and 29 deletions
|
|
@ -1,3 +1,3 @@
|
||||||
def test_func
|
def test_func
|
||||||
rust_func($entity.index)
|
rust_func(Bevy::Entity.current.index)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
$index = $entity.index
|
$index = Bevy::Entity.current.index
|
||||||
|
|
||||||
def test_func
|
def test_func
|
||||||
rust_func($index)
|
rust_func($index)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
def test_func
|
def test_func
|
||||||
rust_func($entity)
|
rust_func(Bevy::Entity.current)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,3 @@
|
||||||
// TODO: maybe make all runtime engines not send and spawn threads for them like Ruby, benchmark?
|
|
||||||
// TODO: make sure ruby is statically linked
|
|
||||||
// TODO: add tests for every runtime for return value
|
|
||||||
// TODO: maybe unify api and call non thread methods non_send
|
|
||||||
// TODO: add tests for entity variable and buitin types for every runtime
|
|
||||||
// TODO: line numbers for errors
|
|
||||||
// TODO: caan rhai have Vec3 constructor instead of vec3_new
|
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
sync::{Arc, Condvar, LazyLock, Mutex},
|
sync::{Arc, Condvar, LazyLock, Mutex},
|
||||||
|
|
@ -21,7 +13,7 @@ use bevy::{
|
||||||
};
|
};
|
||||||
use magnus::{
|
use magnus::{
|
||||||
block::Proc, data_type_builder, function, value::Lazy, DataType, DataTypeFunctions, IntoValue,
|
block::Proc, data_type_builder, function, value::Lazy, DataType, DataTypeFunctions, IntoValue,
|
||||||
RClass, Ruby, TryConvert, TypedData,
|
Object, RClass, RModule, Ruby, TryConvert, TypedData,
|
||||||
};
|
};
|
||||||
use magnus::{method, prelude::*};
|
use magnus::{method, prelude::*};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
@ -115,8 +107,10 @@ unsafe impl TypedData for Promise<(), RubyValue> {
|
||||||
fn class(ruby: &Ruby) -> magnus::RClass {
|
fn class(ruby: &Ruby) -> magnus::RClass {
|
||||||
static CLASS: Lazy<RClass> = Lazy::new(|ruby| {
|
static CLASS: Lazy<RClass> = Lazy::new(|ruby| {
|
||||||
let class = ruby
|
let class = ruby
|
||||||
|
.define_module("Bevy")
|
||||||
|
.unwrap()
|
||||||
.define_class("Promise", ruby.class_object())
|
.define_class("Promise", ruby.class_object())
|
||||||
.expect("Failed to define Promise class in Ruby");
|
.expect("Failed to define Bevy::Promise class in Ruby");
|
||||||
class.undef_default_alloc_func();
|
class.undef_default_alloc_func();
|
||||||
class
|
class
|
||||||
});
|
});
|
||||||
|
|
@ -124,7 +118,8 @@ unsafe impl TypedData for Promise<(), RubyValue> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn data_type() -> &'static magnus::DataType {
|
fn data_type() -> &'static magnus::DataType {
|
||||||
static DATA_TYPE: DataType = data_type_builder!(Promise<(), RubyValue>, "promise").build();
|
static DATA_TYPE: DataType =
|
||||||
|
data_type_builder!(Promise<(), RubyValue>, "Bevy::Promise").build();
|
||||||
&DATA_TYPE
|
&DATA_TYPE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -155,7 +150,7 @@ fn then(r_self: magnus::Value) -> magnus::Value {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
#[magnus::wrap(class = "BevyEntity")]
|
#[magnus::wrap(class = "Bevy::Entity")]
|
||||||
pub struct BevyEntity(pub Entity);
|
pub struct BevyEntity(pub Entity);
|
||||||
|
|
||||||
impl BevyEntity {
|
impl BevyEntity {
|
||||||
|
|
@ -219,13 +214,21 @@ impl Default for RubyRuntime {
|
||||||
|
|
||||||
ruby_thread
|
ruby_thread
|
||||||
.execute(Box::new(|ruby| {
|
.execute(Box::new(|ruby| {
|
||||||
// TODO: maybe put promise in a module , maybe do so for other runtimes too
|
let module = ruby.define_module("Bevy")?;
|
||||||
let promise = ruby.define_class("Promise", ruby.class_object())?;
|
|
||||||
promise.define_method("and_then", magnus::method!(then, 0))?;
|
|
||||||
|
|
||||||
let entity = ruby.define_class("BevyEntity", ruby.class_object())?;
|
let entity = module.define_class("Entity", ruby.class_object())?;
|
||||||
|
entity.class().define_method(
|
||||||
|
"current",
|
||||||
|
method!(
|
||||||
|
|r_self: RClass| { r_self.ivar_get::<_, BevyEntity>("_current") },
|
||||||
|
0
|
||||||
|
),
|
||||||
|
)?;
|
||||||
entity.define_method("index", method!(BevyEntity::index, 0))?;
|
entity.define_method("index", method!(BevyEntity::index, 0))?;
|
||||||
|
|
||||||
|
let promise = module.define_class("Promise", ruby.class_object())?;
|
||||||
|
promise.define_method("and_then", magnus::method!(then, 0))?;
|
||||||
|
|
||||||
let vec3 = ruby.define_class("Vec3", ruby.class_object())?;
|
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))?;
|
||||||
vec3.define_method("x", method!(BevyVec3::x, 0))?;
|
vec3.define_method("x", method!(BevyVec3::x, 0))?;
|
||||||
|
|
@ -314,14 +317,14 @@ impl Runtime for RubyRuntime {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.execute(Box::new(move |ruby| {
|
.execute(Box::new(move |ruby| {
|
||||||
let var = ruby
|
let var = ruby
|
||||||
.define_variable(ENTITY_VAR_NAME, BevyEntity(entity))
|
.class_object()
|
||||||
|
.const_get::<_, RModule>("Bevy")
|
||||||
|
.unwrap()
|
||||||
|
.const_get::<_, RClass>("Entity")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
var.ivar_set("_current", BevyEntity(entity)).unwrap();
|
||||||
let value = ruby.eval::<magnus::value::Value>(&script).unwrap();
|
let value = ruby.eval::<magnus::value::Value>(&script).unwrap();
|
||||||
|
var.ivar_set("_current", ruby.qnil().as_value()).unwrap();
|
||||||
// SAFETY: this is guaranteed to be executed on a single thread
|
|
||||||
// so should be safe according to Magnus documentation
|
|
||||||
unsafe { *var = ruby.qnil().as_value() };
|
|
||||||
|
|
||||||
RubyValue::new(value)
|
RubyValue::new(value)
|
||||||
}));
|
}));
|
||||||
|
|
@ -398,8 +401,12 @@ impl Runtime for RubyRuntime {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.execute(Box::new(move |ruby| {
|
.execute(Box::new(move |ruby| {
|
||||||
let var = ruby
|
let var = ruby
|
||||||
.define_variable(ENTITY_VAR_NAME, BevyEntity(entity))
|
.class_object()
|
||||||
|
.const_get::<_, RModule>("Bevy")
|
||||||
|
.unwrap()
|
||||||
|
.const_get::<_, RClass>("Entity")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
var.ivar_set("_current", BevyEntity(entity)).unwrap();
|
||||||
|
|
||||||
let args: Vec<_> = args
|
let args: Vec<_> = args
|
||||||
.parse(&ruby)
|
.parse(&ruby)
|
||||||
|
|
@ -409,9 +416,7 @@ impl Runtime for RubyRuntime {
|
||||||
let return_value: magnus::Value =
|
let return_value: magnus::Value =
|
||||||
ruby.class_object().funcall(name, args.as_slice())?;
|
ruby.class_object().funcall(name, args.as_slice())?;
|
||||||
|
|
||||||
// SAFETY: this is guaranteed to be executed on a single thread
|
var.ivar_set("_current", ruby.qnil().as_value()).unwrap();
|
||||||
// so should be safe according to Magnus documentation
|
|
||||||
unsafe { *var = ruby.qnil().as_value() };
|
|
||||||
|
|
||||||
Ok(RubyValue::new(return_value))
|
Ok(RubyValue::new(return_value))
|
||||||
}))
|
}))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue