Skip to content

feat: create Language Agnostic Declaration file format and ladfile crate #274

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 8 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ members = [
"crates/bevy_mod_scripting_functions",
"crates/xtask",
"crates/script_integration_test_harness",
"crates/bevy_mod_scripting_derive",
"crates/bevy_mod_scripting_derive", "crates/ladfile",
]
resolver = "2"
exclude = ["crates/bevy_api_gen", "crates/macro_tests"]
Expand Down
2 changes: 2 additions & 0 deletions crates/bevy_mod_scripting_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ bevy = { workspace = true, default-features = false, features = [
"bevy_asset",
"reflect_functions",
] }

thiserror = "1.0.31"
parking_lot = "0.12.1"
dashmap = "6"
Expand All @@ -43,6 +44,7 @@ derivative = "2.2"
profiling = { workspace = true }
bevy_mod_scripting_derive = { workspace = true }


[dev-dependencies]
test_utils = { workspace = true }
tokio = { version = "1", features = ["rt", "macros"] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,6 @@ pub trait IntoScriptRef {
/// a utility for matching types by their [`std::any::TypeId`]
macro_rules! match_by_type {
(match $on:ident {$($id:ident : $ty:ty => $conv:expr),*}) => {
$(
#[allow(unused_variables)]
let $id = std::any::TypeId::of::<$ty>();
)*

match $on {
$(
$id if $id == std::any::TypeId::of::<$ty>() => {$conv},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ mod test {
assert_eq!(test_fn.info.arg_info[1].name, Some("_arg1".into()));

assert_eq!(
test_fn.info.return_info.as_ref().unwrap().type_id,
test_fn.info.return_info.type_id,
std::any::TypeId::of::<()>()
);
}
Expand Down
43 changes: 26 additions & 17 deletions crates/bevy_mod_scripting_core/src/docgen/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct FunctionInfo {
/// Information about the arguments of the function.
pub arg_info: Vec<FunctionArgInfo>,
/// Information about the return value of the function.
pub return_info: Option<FunctionReturnInfo>,
pub return_info: FunctionReturnInfo,
/// Documentation for the function.
pub docs: Option<Cow<'static, str>>,
}
Expand All @@ -41,7 +41,7 @@ impl FunctionInfo {
name: Cow::Borrowed(""),
namespace: Namespace::Global,
arg_info: Vec::new(),
return_info: None,
return_info: FunctionReturnInfo::default(),
docs: None,
}
}
Expand All @@ -52,7 +52,7 @@ impl FunctionInfo {
name,
namespace,
arg_info: Vec::new(),
return_info: None,
return_info: FunctionReturnInfo::default(),
docs: None,
}
}
Expand All @@ -69,7 +69,7 @@ impl FunctionInfo {

/// Add a return value to the function info.
pub fn add_return<T: TypedThrough + 'static>(mut self) -> Self {
self.return_info = Some(FunctionReturnInfo::new_for::<T>());
self.return_info = FunctionReturnInfo::new_for::<T>();
self
}

Expand Down Expand Up @@ -136,6 +136,12 @@ pub struct FunctionReturnInfo {
pub type_id: TypeId,
}

impl Default for FunctionReturnInfo {
fn default() -> Self {
Self::new_for::<()>()
}
}

impl FunctionReturnInfo {
/// Create a new function return info for a specific type.
pub fn new_for<T: 'static>() -> Self {
Expand Down Expand Up @@ -169,7 +175,10 @@ bevy::utils::all_tuples!(impl_documentable, 0, 13, T);

#[cfg(test)]
mod test {
use crate::bindings::function::from::{Mut, Ref, Val};
use crate::{
bindings::function::from::{Mut, Ref, Val},
docgen::typed_through::UntypedWrapperKind,
};

use super::*;

Expand All @@ -183,7 +192,7 @@ mod test {
assert_eq!(info.name, "test_fn");
assert_eq!(info.namespace, Namespace::Global);
assert_eq!(info.arg_info.len(), 2);
assert_eq!(info.return_info.unwrap().type_id, TypeId::of::<f64>());
assert_eq!(info.return_info.type_id, TypeId::of::<f64>());

assert_eq!(info.arg_info[0].type_id, TypeId::of::<i32>());
assert_eq!(info.arg_info[1].type_id, TypeId::of::<f32>());
Expand Down Expand Up @@ -211,33 +220,33 @@ mod test {
assert_eq!(info.name, "test_fn");
assert_eq!(info.namespace, Namespace::Global);
assert_eq!(info.arg_info.len(), 2);
assert_eq!(info.return_info.unwrap().type_id, TypeId::of::<Val<f64>>());
assert_eq!(info.return_info.type_id, TypeId::of::<Val<f64>>());

assert_eq!(info.arg_info[0].type_id, TypeId::of::<Ref<'static, i32>>());
assert_eq!(info.arg_info[1].type_id, TypeId::of::<Mut<'static, f32>>());

match info.arg_info[0].type_info.as_ref().unwrap() {
ThroughTypeInfo::UntypedWrapper {
match &info.arg_info[0].type_info {
Some(ThroughTypeInfo::UntypedWrapper {
through_type,
wrapper_type_id,
wrapper_name,
} => {
wrapper_kind,
}) => {
assert_eq!(through_type.type_id(), TypeId::of::<i32>());
assert_eq!(*wrapper_type_id, TypeId::of::<Ref<'static, i32>>());
assert_eq!(*wrapper_name, "Ref");
assert_eq!(*wrapper_kind, UntypedWrapperKind::Ref);
}
_ => panic!("Expected UntypedWrapper"),
}

match info.arg_info[1].type_info.as_ref().unwrap() {
ThroughTypeInfo::UntypedWrapper {
match &info.arg_info[1].type_info {
Some(ThroughTypeInfo::UntypedWrapper {
through_type,
wrapper_type_id,
wrapper_name,
} => {
wrapper_kind,
}) => {
assert_eq!(through_type.type_id(), TypeId::of::<f32>());
assert_eq!(*wrapper_type_id, TypeId::of::<Mut<'static, f32>>());
assert_eq!(*wrapper_name, "Mut");
assert_eq!(*wrapper_kind, UntypedWrapperKind::Mut);
}
_ => panic!("Expected UntypedWrapper"),
}
Expand Down
19 changes: 15 additions & 4 deletions crates/bevy_mod_scripting_core/src/docgen/typed_through.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,25 @@ pub enum ThroughTypeInfo {
/// The type id of the wrapper type.
wrapper_type_id: TypeId,
/// The name of the wrapper type.
wrapper_name: &'static str,
wrapper_kind: UntypedWrapperKind,
},
/// A wrapper around a through typed type, which itself is also a `Typed` type.
TypedWrapper(TypedWrapperKind),
/// an actual type info
TypeInfo(&'static TypeInfo),
}

#[derive(Debug, Clone, PartialEq, Eq)]
/// The kind of untyped wrapper.
pub enum UntypedWrapperKind {
/// A reference wrapper.
Ref,
/// A mutable reference wrapper.
Mut,
/// A value wrapper.
Val,
}

/// The kind of typed wrapper.
#[derive(Debug, Clone)]
pub enum TypedWrapperKind {
Expand Down Expand Up @@ -73,7 +84,7 @@ impl<T: Typed> TypedThrough for Ref<'_, T> {
ThroughTypeInfo::UntypedWrapper {
through_type: T::type_info(),
wrapper_type_id: TypeId::of::<Ref<T>>(),
wrapper_name: "Ref",
wrapper_kind: UntypedWrapperKind::Ref,
}
}
}
Expand All @@ -83,7 +94,7 @@ impl<T: Typed> TypedThrough for Mut<'_, T> {
ThroughTypeInfo::UntypedWrapper {
through_type: T::type_info(),
wrapper_type_id: TypeId::of::<Mut<T>>(),
wrapper_name: "Mut",
wrapper_kind: UntypedWrapperKind::Mut,
}
}
}
Expand All @@ -93,7 +104,7 @@ impl<T: Typed> TypedThrough for Val<T> {
ThroughTypeInfo::UntypedWrapper {
through_type: T::type_info(),
wrapper_type_id: TypeId::of::<Val<T>>(),
wrapper_name: "Val",
wrapper_kind: UntypedWrapperKind::Val,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/ladfile/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target
23 changes: 23 additions & 0 deletions crates/ladfile/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "ladfile"
version = "0.1.0"
edition = "2021"
authors = ["Maksymilian Mozolewski <makspl17@gmail.com>"]
license = "MIT OR Apache-2.0"
description = "Language Agnostic Declaration (LAD) file format for the bevy_mod_scripting crate"
repository = "https://github.com/makspll/bevy_mod_scripting"
homepage = "https://github.com/makspll/bevy_mod_scripting"
keywords = ["bevy", "gamedev", "scripting", "format", "json"]
categories = ["game-development", "parser-implementations"]
readme = "readme.md"

[dependencies]
bevy_mod_scripting_core = { workspace = true }
# I don't think bevy has a top level feature for this :C
bevy_reflect = { version = "0.15.1", features = ["documentation"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
indexmap = { version = "2.7", features = ["serde"] }

[lints]
workspace = true
Loading
Loading