Skip to content

Commit

Permalink
feat: add scripting demo.
Browse files Browse the repository at this point in the history
  • Loading branch information
zicklag committed Oct 31, 2023
1 parent 2562df0 commit 9bd7a8c
Show file tree
Hide file tree
Showing 10 changed files with 528 additions and 265 deletions.
477 changes: 267 additions & 210 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions demos/scripting/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "demo_scripting"
edition.workspace = true
version.workspace = true
license.workspace = true
publish = false

[dependencies]
bones_framework = { path = "../../framework_crates/bones_framework" }
bones_bevy_renderer = { path = "../../framework_crates/bones_bevy_renderer" }
1 change: 1 addition & 0 deletions demos/scripting/assets/game.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
update: ./update.lua
1 change: 1 addition & 0 deletions demos/scripting/assets/pack.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
root: game.yaml
4 changes: 4 additions & 0 deletions demos/scripting/assets/update.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
local data = world.resources:get(s"DemoData")

local new_data = s"DemoData":create();
info(new_data)
38 changes: 38 additions & 0 deletions demos/scripting/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use bones_bevy_renderer::BonesBevyRenderer;
use bones_framework::prelude::*;

#[derive(HasSchema, Default, Clone)]
#[type_data(metadata_asset("game"))]
#[repr(C)]
struct GameMeta {
update: Handle<LuaScript>,
}

#[derive(HasSchema, Default, Clone)]
#[repr(C)]
struct DemoData {
name: String,
age: f32,
}

fn main() {
let mut game = Game::new();
game.install_plugin(DefaultGamePlugin);
GameMeta::schema();
DemoData::schema();

let default_session = game.sessions.create("default");
default_session
.install_plugin(DefaultSessionPlugin)
.add_system_to_stage(Update, update_script);
default_session.world.insert_resource(DemoData {
name: "default name".into(),
age: 10.0,
});

BonesBevyRenderer::new(game).app().run();
}

fn update_script(world: &World, lua_engine: Res<LuaEngine>, meta: Root<GameMeta>) {
lua_engine.run_script_system(world, meta.update);
}
2 changes: 1 addition & 1 deletion framework_crates/bones_framework/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ image = { version = "0.24", default-features = false }

# Gui
egui = { version = "0.23", optional = true }
ttf-parser = { version = "0.19.1", default-features = false, optional = true }
ttf-parser = { version = "0.20", default-features = false, optional = true }

# Audio
kira = { git = "https://github.com/zicklag/kira.git", branch = "feat/sync", features = [
Expand Down
117 changes: 116 additions & 1 deletion framework_crates/bones_schema/src/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,115 @@ impl<'pointer> SchemaRef<'pointer> {
.hash_fn
.map(|hash_fn| unsafe { (hash_fn)(self.ptr.as_ptr()) })
}

/// Debug format the value stored in the schema box.
///
/// This is used in the display and debug implementations.
pub fn debug_format_value(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match &self.schema.kind {
SchemaKind::Struct(info) => {
let is_tuple = info.fields.iter().any(|x| x.name.is_none());
if is_tuple {
let mut builder = f.debug_tuple(&self.schema.name);
for ((_, offset), info) in
self.schema.field_offsets().iter().zip(info.fields.iter())
{
let schemaref = SchemaRef {
ptr: unsafe { self.ptr.byte_add(*offset) },
schema: info.schema,
};
builder.field(&SchemaRefValueDebug(schemaref));
}
builder.finish()
} else {
let mut builder = f.debug_struct(&self.schema.name);
for ((_, offset), info) in
self.schema.field_offsets().iter().zip(info.fields.iter())
{
let schemaref = SchemaRef {
ptr: unsafe { self.ptr.byte_add(*offset) },
schema: info.schema,
};
builder.field(
info.name
.as_ref()
.map(|x| x.as_ref())
.unwrap_or("[unnamed]"),
&SchemaRefValueDebug(schemaref),
);
}
builder.finish()
}
}
SchemaKind::Vec(_) => {
let mut builder = f.debug_list();
// SOUND: the schema asserts that it is a schema vec.
let list = unsafe { self.ptr.deref::<SchemaVec>() };
for item in list.iter() {
builder.entry(&SchemaRefValueDebug(item));
}
builder.finish()
}
SchemaKind::Enum(_) => {
todo!();
}
SchemaKind::Map { .. } => {
let mut builder = f.debug_map();
// SOUND: the schema asserts that it is a schema map.
let map = unsafe { self.ptr.deref::<SchemaMap>() };
for (key, value) in map.iter() {
builder.key(&SchemaRefValueDebug(key));
builder.value(&SchemaRefValueDebug(value));
}
builder.finish()
}
// SOUND: schema asserts this is a schema box
SchemaKind::Box(_) => unsafe { self.ptr.deref::<SchemaBox>() }
.as_ref()
.debug_format_value(f),
SchemaKind::Primitive(p) => match p {
Primitive::Bool => f.write_fmt(format_args!("{}", self.cast::<bool>())),
Primitive::U8 => f.write_fmt(format_args!("{}", self.cast::<u8>())),
Primitive::U16 => f.write_fmt(format_args!("{}", self.cast::<u16>())),
Primitive::U32 => f.write_fmt(format_args!("{}", self.cast::<u32>())),
Primitive::U64 => f.write_fmt(format_args!("{}", self.cast::<u64>())),
Primitive::U128 => f.write_fmt(format_args!("{}", self.cast::<u128>())),
Primitive::I8 => f.write_fmt(format_args!("{}", self.cast::<i8>())),
Primitive::I16 => f.write_fmt(format_args!("{}", self.cast::<i16>())),
Primitive::I32 => f.write_fmt(format_args!("{}", self.cast::<i32>())),
Primitive::I64 => f.write_fmt(format_args!("{}", self.cast::<i64>())),
Primitive::I128 => f.write_fmt(format_args!("{}", self.cast::<i128>())),
Primitive::F32 => f.write_fmt(format_args!("{}", self.cast::<f32>())),
Primitive::F64 => f.write_fmt(format_args!("{}", self.cast::<f64>())),
Primitive::String => f.write_fmt(format_args!("{:?}", self.cast::<String>())),
Primitive::Opaque { size, align } => f
.debug_struct("Opaque")
.field("size", size)
.field("align", align)
.finish(),
},
}
}
}

struct SchemaRefValueDebug<'a>(SchemaRef<'a>);
impl std::fmt::Debug for SchemaRefValueDebug<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.debug_format_value(f)
}
}

impl std::fmt::Debug for SchemaRef<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("SchemaRef<'_>")
.field(&SchemaRefValueDebug(*self))
.finish()
}
}
impl std::fmt::Display for SchemaRef<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
<SchemaRefValueDebug as std::fmt::Debug>::fmt(&SchemaRefValueDebug(*self), f)
}
}

/// An untyped mutable reference that knows the [`Schema`] of the pointee and that can be cast to a matching
Expand Down Expand Up @@ -540,10 +649,16 @@ unsafe impl Send for SchemaBox {}
impl std::fmt::Debug for SchemaBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SchemaBox")
.field("schema", &self.schema)
.field("schema", &self.schema.full_name)
.field("value", &SchemaRefValueDebug(self.as_ref()))
.finish_non_exhaustive()
}
}
impl std::fmt::Display for SchemaBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.as_ref().fmt(f)
}
}

impl Hash for SchemaBox {
#[track_caller]
Expand Down
20 changes: 12 additions & 8 deletions framework_crates/bones_scripting/src/lua.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ impl LuaEngine {
// Wrap world reference so that it can be converted to lua userdata.
let world = WorldRef(world);

lua.try_run(|ctx| {
let result = lua.try_run(|ctx| {
// Create a thread
let thread = Thread::new(&ctx);

Expand All @@ -159,7 +159,12 @@ impl LuaEngine {
.store
.asset_ids
.get(&script.untyped())
.expect("Script asset not loaded");
.ok_or_else(|| {
tracing::warn!("Script asset not loaded.");
ProtoCompileError::Parser(
piccolo::compiler::ParserError::EndOfStream { expected: None },
)
})?;

let mut compiled_scripts = self.state.compiled_scripts.lock();
let closure = compiled_scripts.get(&cid);
Expand Down Expand Up @@ -208,14 +213,13 @@ impl LuaEngine {
}

// Take the thread result and print any errors
let result = thread.take_return::<()>(ctx)?;
if let Err(e) = result {
tracing::error!("{e}");
}
thread.take_return::<()>(ctx)??;

Ok(())
})
.unwrap();
});
if let Err(e) = result {
tracing::error!("{e}");
}
});
});
}
Expand Down
Loading

0 comments on commit 9bd7a8c

Please sign in to comment.