Skip to content

Non primitive assign (rebase #28) #36

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Nov 16, 2022
13 changes: 9 additions & 4 deletions assets/scripts/breakout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,22 @@ function run() {
if (i % 60 == 0) {
let score = world.resource(Scoreboard)!;
score.score += 1;
info(score.score);
// info(score.score);
}

let input = world.resource(Input(KeyCode))!;
let pressed = input.get_pressed();
info(pressed.toString());
// let input = world.resource(Input(KeyCode))!;
// let pressed = input.get_pressed();
// info(pressed.toString());


if (firstIteration) {
firstIteration = false;

// let value = Value.create(Transform, {
// translation: { x: 5.0, y: 2.0 }
// });
// info(value.toString());

/*for (const item of world.query(Transform, Velocity)) {
let [transform, velocity] = item.components;

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod transpile;
use asset::JsScriptLoader;
use bevy::{asset::AssetStage, prelude::*, utils::HashSet};

pub use bevy_reflect_fns;
pub use asset::JsScript;
pub use bevy_ecs_dynamic;
pub use runtime::{
Expand Down
44 changes: 44 additions & 0 deletions src/runtime/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ fn op_bevy_mod_js_scripting(
args: serde_json::Value,
) -> Result<serde_json::Value, AnyError> {
with_state(state, |state, custom_op_state| {
let args = convert_safe_ints(args);
let script_info = state.borrow::<ScriptInfo>();
let ops = state.borrow::<Ops>();
let op_names = state.borrow::<OpNames>();
Expand Down Expand Up @@ -352,3 +353,46 @@ fn with_state<T: 'static, R, F: FnOnce(&mut OpState, &mut T) -> R>(state: &mut O

r
}

/// Takes a [`serde_json::Value`] and converts all floating point number types that are safe
/// integers, to integers.
///
/// This is important for deserializing numbers to integers, because of the way `serde_json` handles
/// them.
///
/// For example, `serde_json` will not deserialize `1.0` to a `u32` without an error, but it will
/// deserialize `1`. `serde_v8` seems to retun numbers with a decimal point, even when they are
/// valid integers, so this function makes the conversion of safe integers back to integers without
/// a decimal point.
fn convert_safe_ints(value: serde_json::Value) -> serde_json::Value {
match value {
serde_json::Value::Number(n) => {
let max_safe_int = (2u64.pow(53) - 1) as f64;

serde_json::Value::Number(if let Some(f) = n.as_f64() {
if f.abs() <= max_safe_int && f.fract() == 0.0 {
if f == 0.0 {
serde_json::Number::from(0u64)
} else if f.is_sign_negative() {
serde_json::Number::from(f as i64)
} else {
serde_json::Number::from(f as u64)
}
} else {
n
}
} else {
n
})
}
serde_json::Value::Array(arr) => {
serde_json::Value::Array(arr.into_iter().map(|x| convert_safe_ints(x)).collect())
}
serde_json::Value::Object(obj) => serde_json::Value::Object(
obj.into_iter()
.map(|(k, v)| (k, convert_safe_ints(v)))
.collect(),
),
other => other,
}
}
21 changes: 17 additions & 4 deletions src/runtime/ops/ecs/ecs.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
default:
const collected = collectedQuery(target);
const prop = collected[propName];
return prop.bind ? prop.bind(collected) : prop;
return prop && prop.bind ? prop.bind(collected) : prop;
}
}
})
Expand All @@ -98,6 +98,10 @@
Value.unwrapValueRef(value)
);
}

spawn() {
return Value.wrapValueRef(bevyModJsScriptingOpSync("ecs_entity_spawn"));
}
}

const VALUE_REF_GET_INNER = Symbol("value_ref_get_inner");
Expand All @@ -107,7 +111,16 @@
unwrapValueRef(valueRefProxy) {
if (valueRefProxy === null || valueRefProxy === undefined) return valueRefProxy;
const inner = valueRefProxy[VALUE_REF_GET_INNER]
return inner ? inner : valueRefProxy;
if (inner) {
return inner;
} else {
if (typeof valueRefProxy == 'object') {
for (const key of Reflect.ownKeys(valueRefProxy)) {
valueRefProxy[key] = Value.unwrapValueRef(valueRefProxy[key]);
}
}
return valueRefProxy;
}
},

// keep primitives, null and undefined as is, otherwise wraps the object
Expand Down Expand Up @@ -161,7 +174,7 @@
"ecs_value_ref_set",
target.valueRef,
p,
value
Value.unwrapValueRef(value)
);
},
apply: (target, thisArg, args) => {
Expand All @@ -180,7 +193,7 @@

// Instantiates the default value of a given bevy type
create(type, patch) {
return Value.wrapValueRef(bevyModJsScriptingOpSync("ecs_value_ref_default", type, patch));
return Value.wrapValueRef(bevyModJsScriptingOpSync("ecs_value_ref_default", type, Value.unwrapValueRef(patch)));
},

patch(value, patch) {
Expand Down
6 changes: 4 additions & 2 deletions src/runtime/ops/ecs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use crate::runtime::{JsRuntimeOp, OpMap};

use self::types::{JsReflectFunctions, JsValueRefs};

mod component;
mod info;
mod query;
mod resource;
pub mod types;
mod value;
mod world;

pub fn insert_ecs_ops(ops: &mut OpMap) {
ops.insert("ecs.js", Box::new(EcsJs));
Expand Down Expand Up @@ -41,9 +41,11 @@ pub fn insert_ecs_ops(ops: &mut OpMap) {
);
ops.insert("ecs_value_ref_patch", Box::new(value::ecs_value_ref_patch));
ops.insert("ecs_value_ref_cleanup", Box::new(value::EcsValueRefCleanup));
ops.insert("ecs_entity_spawn", Box::new(world::ecs_entity_spawn));
ops.insert("ecs_value_ref_cleanup", Box::new(value::EcsValueRefCleanup));
ops.insert(
"ecs_component_insert",
Box::new(component::ecs_component_insert),
Box::new(world::ecs_component_insert),
);
}

Expand Down
Loading