diff --git a/crates/bevy_api_gen/templates/footer.tera b/crates/bevy_api_gen/templates/footer.tera index 8f333ca65a..4c8ea6ada3 100644 --- a/crates/bevy_api_gen/templates/footer.tera +++ b/crates/bevy_api_gen/templates/footer.tera @@ -11,7 +11,8 @@ pub struct {{ "ScriptingPlugin" | prefix_cratename | convert_case(case="upper_ca #[script_bindings( remote, name = "{{ item.ident | convert_case(case="snake") }}_functions", - bms_core_path="bevy_mod_scripting_core" + bms_core_path="bevy_mod_scripting_core", + generated )] impl {{item.import_path}} { {% for function in item.functions %} diff --git a/crates/bevy_mod_scripting_core/src/bindings/globals/core.rs b/crates/bevy_mod_scripting_core/src/bindings/globals/core.rs index ec3e2655e6..5dee9ee92e 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/globals/core.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/globals/core.rs @@ -2,10 +2,21 @@ use std::{collections::HashMap, sync::Arc}; -use bevy::{app::Plugin, ecs::reflect::AppTypeRegistry}; +use bevy::{ + app::Plugin, + ecs::{entity::Entity, reflect::AppTypeRegistry, world::World}, +}; use bevy_mod_scripting_derive::script_globals; -use crate::{bindings::{function::from::{Union, Val}, ScriptComponentRegistration, ScriptResourceRegistration, ScriptTypeRegistration, WorldGuard}, docgen::into_through_type_info, error::InteropError}; +use crate::{ + bindings::{ + function::from::{Union, Val}, + ScriptComponentRegistration, ScriptResourceRegistration, ScriptTypeRegistration, + WorldGuard, + }, + docgen::into_through_type_info, + error::InteropError, +}; use super::AppScriptGlobalsRegistry; @@ -22,54 +33,67 @@ impl Plugin for CoreScriptGlobalsPlugin { fn register_static_core_globals(world: &mut bevy::ecs::world::World) { let global_registry = world - .get_resource_or_init::() - .clone(); - let type_registry = world - .get_resource_or_init::() - .clone(); - let mut global_registry = global_registry.write(); - let type_registry = type_registry.read(); + .get_resource_or_init::() + .clone(); + let type_registry = world.get_resource_or_init::().clone(); + let mut global_registry = global_registry.write(); + let type_registry = type_registry.read(); - // find all reflectable types without generics - for registration in type_registry.iter() { - if !registration.type_info().generics().is_empty() { - continue; - } + // find all reflectable types without generics + for registration in type_registry.iter() { + if !registration.type_info().generics().is_empty() { + continue; + } - if let Some(global_name) = registration.type_info().type_path_table().ident() { - let documentation = "A reference to the type, allowing you to call static methods."; - let type_info = registration.type_info(); - global_registry.register_static_documented_dynamic( - registration.type_id(), - into_through_type_info(type_info), - global_name.into(), - documentation.into(), - ); - } + if let Some(global_name) = registration.type_info().type_path_table().ident() { + let documentation = "A reference to the type, allowing you to call static methods."; + let type_info = registration.type_info(); + global_registry.register_static_documented_dynamic( + registration.type_id(), + into_through_type_info(type_info), + global_name.into(), + documentation.into(), + ); } + } + + // register basic globals + global_registry.register_dummy::("world", "The current ECS world."); + global_registry + .register_dummy::("entity", "The entity this script is attached to if any."); + global_registry.register_dummy::("script_id", "the name/id of this script"); } -#[script_globals( - bms_core_path = "crate", - name = "core_globals", -)] +#[script_globals(bms_core_path = "crate", name = "core_globals")] impl CoreGlobals { /// A cache of types normally available through the `world.get_type_by_name` function. - /// + /// /// You can use this to avoid having to store type references. - fn types(guard: WorldGuard) -> Result, Union, Val>>>, InteropError> { + fn types( + guard: WorldGuard, + ) -> Result< + HashMap< + String, + Union< + Val, + Union, Val>, + >, + >, + InteropError, + > { let type_registry = guard.type_registry(); let type_registry = type_registry.read(); let mut type_cache = HashMap::::default(); - for registration in type_registry.iter(){ + for registration in type_registry.iter() { if let Some(ident) = registration.type_info().type_path_table().ident() { let registration = ScriptTypeRegistration::new(Arc::new(registration.clone())); let registration = guard.clone().get_type_registration(registration)?; - let registration = registration.map_both(Val::from, |u| u.map_both(Val::from, Val::from)); + let registration = + registration.map_both(Val::from, |u| u.map_both(Val::from, Val::from)); type_cache.insert(ident.to_string(), registration); } } - + Ok(type_cache) } -} \ No newline at end of file +} diff --git a/crates/bevy_mod_scripting_core/src/bindings/globals/mod.rs b/crates/bevy_mod_scripting_core/src/bindings/globals/mod.rs index 649620903c..a1f9d7d6ab 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/globals/mod.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/globals/mod.rs @@ -5,12 +5,15 @@ use super::{ script_value::ScriptValue, WorldGuard, }; -use crate::{docgen::{into_through_type_info, typed_through::ThroughTypeInfo}, error::InteropError}; +use crate::{ + docgen::{into_through_type_info, typed_through::ThroughTypeInfo}, + error::InteropError, +}; use bevy::{ecs::system::Resource, reflect::Typed, utils::hashbrown::HashMap}; use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard}; use std::{any::TypeId, borrow::Cow, sync::Arc}; -crate::private::export_all_in_modules!{ +crate::private::export_all_in_modules! { core } @@ -48,10 +51,22 @@ pub struct ScriptGlobal { pub type_information: ThroughTypeInfo, } +/// A dummy global variable that documents globals set via alternative ways. +pub struct ScriptGlobalDummy { + /// The type ID of the global variable. + pub type_id: TypeId, + /// Rich type information the global variable. + pub type_information: Option, + + /// The documentation for the global dummy variable. + pub documentation: Option>, +} + /// A registry of global variables that can be exposed to scripts. #[derive(Default)] pub struct ScriptGlobalsRegistry { globals: HashMap, ScriptGlobal>, + dummies: HashMap, ScriptGlobalDummy>, } impl ScriptGlobalsRegistry { @@ -85,6 +100,11 @@ impl ScriptGlobalsRegistry { self.globals.iter_mut() } + /// Iterates over the dummies in the registry + pub fn iter_dummies(&self) -> impl Iterator, &ScriptGlobalDummy)> { + self.dummies.iter() + } + fn type_erase_maker< T: ScriptReturn, F: Fn(WorldGuard) -> Result + Send + Sync + 'static, @@ -114,6 +134,26 @@ impl ScriptGlobalsRegistry { ) } + /// Registers a dummy global into the registry. + /// Dummies are not actually exposed to languages but exist purely for the purpose of documentation. + /// This can be useful for globals which you cannot expose normally. + /// + /// Dummy globals are stored as non-static instances, i.e. they're expected to be values not type references. + pub fn register_dummy( + &mut self, + name: impl Into>, + documentation: impl Into>, + ) { + self.dummies.insert( + name.into(), + ScriptGlobalDummy { + documentation: Some(documentation.into()), + type_id: TypeId::of::(), + type_information: None, + }, + ); + } + /// Inserts a global into the registry, returns the previous value if it existed. /// /// This is a version of [`Self::register`] which stores type information regarding the global. @@ -153,7 +193,7 @@ impl ScriptGlobalsRegistry { /// Registers a static global into the registry. /// /// This is a version of [`Self::register_static`] which stores rich type information regarding the global. - pub fn register_static_documented( + pub fn register_static_documented( &mut self, name: Cow<'static, str>, documentation: Cow<'static, str>, diff --git a/crates/bevy_mod_scripting_core/src/bindings/mod.rs b/crates/bevy_mod_scripting_core/src/bindings/mod.rs index 90bdcb0c36..6cfb01fc35 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/mod.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/mod.rs @@ -12,4 +12,5 @@ crate::private::export_all_in_modules! { script_system, script_value, world, + type_data } diff --git a/crates/bevy_mod_scripting_core/src/bindings/query.rs b/crates/bevy_mod_scripting_core/src/bindings/query.rs index 06cd380776..648b71bd38 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/query.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/query.rs @@ -14,9 +14,9 @@ use bevy::{ }; use std::{any::TypeId, collections::VecDeque, sync::Arc}; -/// A wrapper around a `TypeRegistration` that provides additional information about the type. +/// A reference to a type which is not a `Resource` or `Component`. /// -/// This is used as a hook to a rust type from a scripting language. We should be able to easily convert between a type name and a [`ScriptTypeRegistration`]. +/// In general think of this as a handle to a type. #[derive(Clone, Reflect)] #[reflect(opaque)] pub struct ScriptTypeRegistration { @@ -24,14 +24,18 @@ pub struct ScriptTypeRegistration { } #[derive(Clone, Reflect, Debug)] -/// A registration for a component type. +/// A reference to a component type's reflection registration. +/// +/// In general think of this as a handle to a type. pub struct ScriptComponentRegistration { pub(crate) registration: ScriptTypeRegistration, pub(crate) component_id: ComponentId, } #[derive(Clone, Reflect, Debug)] -/// A registration for a resource type. +/// A reference to a resource type's reflection registration. +/// +/// In general think of this as a handle to a type. pub struct ScriptResourceRegistration { pub(crate) registration: ScriptTypeRegistration, pub(crate) resource_id: ComponentId, @@ -134,7 +138,25 @@ impl std::fmt::Display for ScriptTypeRegistration { #[derive(Clone, Default, Reflect)] #[reflect(opaque)] -/// A builder for a query. +/// The query builder is used to build ECS queries which retrieve spefific components filtered by specific conditions. +/// +/// For example: +/// ```rust,ignore +/// builder.component(componentA) +/// .component(componentB) +/// .with(componentC) +/// .without(componentD) +/// ``` +/// +/// Will retrieve entities which: +/// - Have componentA +/// - Have componentB +/// - Have componentC +/// - Do not have componentD +/// +/// As well as references to components: +/// - componentA +/// - componentB pub struct ScriptQueryBuilder { pub(crate) components: Vec, with: Vec, diff --git a/crates/bevy_mod_scripting_core/src/bindings/reference.rs b/crates/bevy_mod_scripting_core/src/bindings/reference.rs index a574a393f1..5319e08432 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/reference.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/reference.rs @@ -22,8 +22,13 @@ use bevy::{ }; use std::{any::TypeId, fmt::Debug}; -/// An accessor to a `dyn PartialReflect` struct, stores a base ID of the type and a reflection path -/// safe to build but to reflect on the value inside you need to ensure aliasing rules are upheld +/// A reference to an arbitrary reflected instance. +/// +/// The reference can point to either the ECS, or to the allocator. +/// +/// References are composed of two parts: +/// - The base kind, which specifies where the reference points to +/// - The path, which specifies how to access the value from the base #[derive(Debug, Clone, PartialEq, Eq, Reflect)] #[reflect(Default, opaque)] pub struct ReflectReference { diff --git a/crates/bevy_mod_scripting_core/src/bindings/type_data.rs b/crates/bevy_mod_scripting_core/src/bindings/type_data.rs new file mode 100644 index 0000000000..dd3b06e12d --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/type_data.rs @@ -0,0 +1,42 @@ +//! Contains various `Reflect` type data we use in BMS. + +use bevy::reflect::FromType; + +/// A marker type to indicate that a type is generated. +/// +/// To mark a type as generated use: +/// ```rust,ignore +/// registry.register_type_data::(); +/// ``` +#[derive(Clone, Copy)] +pub struct MarkAsGenerated; + +impl FromType for MarkAsGenerated { + fn from_type() -> Self { + Self + } +} + +/// A marker type to indicate that a type is significant. +/// +/// Significant types appear "before" core types in documentation +#[derive(Clone, Copy)] +pub struct MarkAsSignificant; + +impl FromType for MarkAsSignificant { + fn from_type() -> Self { + Self + } +} + +/// A marker type to indicate that a type is core to BMS. +/// +/// core types appear before insignificant types in documentation. +#[derive(Clone, Copy)] +pub struct MarkAsCore; + +impl FromType for MarkAsCore { + fn from_type() -> Self { + Self + } +} diff --git a/crates/bevy_mod_scripting_core/src/docgen/typed_through.rs b/crates/bevy_mod_scripting_core/src/docgen/typed_through.rs index d2f5d33e9b..7e467b6180 100644 --- a/crates/bevy_mod_scripting_core/src/docgen/typed_through.rs +++ b/crates/bevy_mod_scripting_core/src/docgen/typed_through.rs @@ -16,7 +16,8 @@ use crate::{ script_value::ScriptValue, ReflectReference, }, - error::InteropError, reflection_extensions::TypeInfoExtensions, + error::InteropError, + reflection_extensions::TypeInfoExtensions, }; /// All Through types follow one rule: @@ -75,8 +76,7 @@ pub enum TypedWrapperKind { /// A dynamic version of [`TypedThrough`], which can be used to convert a [`TypeInfo`] into a [`ThroughTypeInfo`]. pub fn into_through_type_info(type_info: &'static TypeInfo) -> ThroughTypeInfo { - - let option = (||{ + let option = (|| { if let Ok(array) = type_info.as_array() { let len = array.capacity(); let inner = array.item_info()?; @@ -84,10 +84,10 @@ pub fn into_through_type_info(type_info: &'static TypeInfo) -> ThroughTypeInfo { Box::new(into_through_type_info(inner)), len, ))); - } else if let Ok(hash_map) = type_info.as_map() { + } else if let Ok(hash_map) = type_info.as_map() { let key_type = hash_map.key_info()?; let value_type = hash_map.value_info()?; - + return Some(ThroughTypeInfo::TypedWrapper(TypedWrapperKind::HashMap( Box::new(into_through_type_info(key_type)), Box::new(into_through_type_info(value_type)), @@ -97,7 +97,7 @@ pub fn into_through_type_info(type_info: &'static TypeInfo) -> ThroughTypeInfo { return Some(ThroughTypeInfo::TypedWrapper(TypedWrapperKind::Vec( Box::new(into_through_type_info(inner)), ))); - } else if type_info.is_option(){ + } else if type_info.is_option() { let enum_ = type_info.as_enum().ok()?; let inner = enum_.variant("Some")?; let inner = inner.as_tuple_variant().ok()?; @@ -110,14 +110,14 @@ pub fn into_through_type_info(type_info: &'static TypeInfo) -> ThroughTypeInfo { let enum_ = type_info.as_enum().ok()?; // let error_variant = enum_.variant("Err")?; // TODO verify error variant is InteropError - + let inner = enum_.variant("Ok")?; let inner = inner.as_tuple_variant().ok()?; let inner = inner.field_at(0)?; let inner = inner.type_info()?; - return Some(ThroughTypeInfo::TypedWrapper(TypedWrapperKind::InteropResult( - Box::new(into_through_type_info(inner)), - ))); + return Some(ThroughTypeInfo::TypedWrapper( + TypedWrapperKind::InteropResult(Box::new(into_through_type_info(inner))), + )); } else if let Ok(tuple) = type_info.as_tuple() { let mut tuple_types = Vec::new(); for i in 0..tuple.field_len() { @@ -125,12 +125,17 @@ pub fn into_through_type_info(type_info: &'static TypeInfo) -> ThroughTypeInfo { let field_type = field.type_info()?; tuple_types.push(into_through_type_info(field_type)); } - return Some(ThroughTypeInfo::TypedWrapper(TypedWrapperKind::Tuple(tuple_types))); + return Some(ThroughTypeInfo::TypedWrapper(TypedWrapperKind::Tuple( + tuple_types, + ))); } None })(); - - option.unwrap_or(ThroughTypeInfo::UntypedWrapper { through_type: type_info, wrapper_kind: UntypedWrapperKind::Val }) + + option.unwrap_or(ThroughTypeInfo::UntypedWrapper { + through_type: type_info, + wrapper_kind: UntypedWrapperKind::Val, + }) } /// A trait for types that can be converted to a [`ThroughTypeInfo`]. @@ -262,7 +267,6 @@ macro_rules! impl_through_typed_tuple { bevy::utils::all_tuples!(impl_through_typed_tuple, 0, 13, T); - #[cfg(test)] mod test { use super::*; @@ -280,12 +284,15 @@ mod test { } } - fn assert_dynamic_through_type_is_val_info () { + fn assert_dynamic_through_type_is_val_info() { let type_info = T::type_info(); let through_type_info = into_through_type_info(type_info); match through_type_info { - ThroughTypeInfo::UntypedWrapper{through_type, wrapper_kind} => { + ThroughTypeInfo::UntypedWrapper { + through_type, + wrapper_kind, + } => { assert_eq!(wrapper_kind, UntypedWrapperKind::Val); assert_eq!(through_type.type_id(), type_info.type_id()); assert_eq!(through_type.type_path(), type_info.type_path()); @@ -379,12 +386,12 @@ mod test { into_through_type_info(Vec::::type_info()), ThroughTypeInfo::TypedWrapper(TypedWrapperKind::Vec(..)) )); - + assert!(matches!( into_through_type_info(std::collections::HashMap::::type_info()), ThroughTypeInfo::TypedWrapper(TypedWrapperKind::HashMap(..)) )); - + assert!(matches!( into_through_type_info(Result::::type_info()), ThroughTypeInfo::TypedWrapper(TypedWrapperKind::InteropResult(..)) @@ -403,6 +410,6 @@ mod test { assert!(matches!( into_through_type_info(<(i32, f32)>::type_info()), ThroughTypeInfo::TypedWrapper(TypedWrapperKind::Tuple(..)) - )); + )); } } diff --git a/crates/bevy_mod_scripting_derive/src/derive/script_bindings.rs b/crates/bevy_mod_scripting_derive/src/derive/script_bindings.rs index 8dd1569519..df4d9b957b 100644 --- a/crates/bevy_mod_scripting_derive/src/derive/script_bindings.rs +++ b/crates/bevy_mod_scripting_derive/src/derive/script_bindings.rs @@ -51,10 +51,45 @@ pub fn script_bindings( format_ident!("new") }; + let mark_as_generated = if args.generated { + quote_spanned! {impl_span=> + + let registry = world.get_resource_or_init::(); + let mut registry = registry.write(); + registry.register_type_data::<#type_ident_with_generics, #bms_core_path::bindings::MarkAsGenerated>(); + } + } else { + Default::default() + }; + + let mark_as_core = if bms_core_path.is_ident("crate") || args.core { + quote_spanned! {impl_span=> + let registry = world.get_resource_or_init::(); + let mut registry = registry.write(); + registry.register_type_data::<#type_ident_with_generics, #bms_core_path::bindings::MarkAsCore>(); + } + } else { + Default::default() + }; + + let mark_as_significant = if args.significant { + quote_spanned! {impl_span=> + let registry = world.get_resource_or_init::(); + let mut registry = registry.write(); + registry.register_type_data::<#type_ident_with_generics, #bms_core_path::bindings::MarkAsSignificant>(); + } + } else { + Default::default() + }; + let out = quote_spanned! {impl_span=> #visibility fn #function_name(world: &mut bevy::ecs::world::World) { #bms_core_path::bindings::function::namespace::NamespaceBuilder::<#type_ident_with_generics>::#builder_function_name(world) #(#function_registrations)*; + + #mark_as_generated + #mark_as_core + #mark_as_significant } #impl_block @@ -72,6 +107,12 @@ struct Args { pub bms_core_path: syn::Path, /// If true will use `new_unregistered` instead of `new` for the namespace builder pub unregistered: bool, + /// If true registers a marker type against the type registry to state that the type is generated (if unregistered is not set) + pub generated: bool, + /// If true registers a marker type against the type registry to state that the type is core to BMS (if unregistered is not set) + pub core: bool, + /// If true registers a marker type against the type registry to state that the type is significant (if unregistered is not set) + pub significant: bool, } impl syn::parse::Parse for Args { @@ -83,6 +124,9 @@ impl syn::parse::Parse for Args { let mut name = syn::Ident::new("functions", Span::call_site()); let mut remote = false; let mut unregistered = false; + let mut generated = false; + let mut core = false; + let mut significant = false; let mut bms_core_path = syn::Path::from(syn::Ident::new("bevy_mod_scripting", Span::call_site())); bms_core_path.segments.push(syn::PathSegment { @@ -99,6 +143,15 @@ impl syn::parse::Parse for Args { } else if path.is_ident("unregistered") { unregistered = true; continue; + } else if path.is_ident("generated") { + generated = true; + continue; + } else if path.is_ident("core") { + core = true; + continue; + } else if path.is_ident("significant") { + significant = true; + continue; } } syn::Meta::NameValue(name_value) => { @@ -136,6 +189,9 @@ impl syn::parse::Parse for Args { bms_core_path, name, unregistered, + generated, + core, + significant, }) } } diff --git a/crates/bevy_mod_scripting_derive/src/lib.rs b/crates/bevy_mod_scripting_derive/src/lib.rs index ed091dc6dc..b3a8620c6a 100644 --- a/crates/bevy_mod_scripting_derive/src/lib.rs +++ b/crates/bevy_mod_scripting_derive/src/lib.rs @@ -25,6 +25,10 @@ pub fn into_script(input: proc_macro::TokenStream) -> proc_macro::TokenStream { /// - `remote`: If true the original impl block will be ignored, and only the function registrations will be generated /// - `bms_core_path`: If set the path to override bms imports, normally only used internally /// - `unregistered`: If set, will use `new_unregistered` instead of `new` for the namespace builder +/// - `core`: If set, marks the type as `core` using the `MarkAsCore` type data +/// - `significant`: If set, marks the type as `significant` using the `MarkAsSignificant` type data +/// +/// It is encouraged to place `significant` markers on your own types, for the purposes of documentation generation. #[proc_macro_attribute] pub fn script_bindings( args: proc_macro::TokenStream, diff --git a/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_core.rs b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_core.rs index 5a74b8c8b8..2d2e6ee754 100644 --- a/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_core.rs +++ b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_core.rs @@ -15,7 +15,8 @@ pub struct BevyCoreScriptingPlugin; #[script_bindings( remote, name = "name_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::core::prelude::Name { fn clone(_self: Ref) -> Val { diff --git a/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_ecs.rs b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_ecs.rs index 2e7bd6901b..aabe3ae722 100644 --- a/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_ecs.rs +++ b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_ecs.rs @@ -15,7 +15,8 @@ pub struct BevyEcsScriptingPlugin; #[script_bindings( remote, name = "entity_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::ecs::entity::Entity { fn clone(_self: Ref) -> Val { @@ -90,31 +91,36 @@ impl bevy::ecs::entity::Entity { #[script_bindings( remote, name = "on_add_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::ecs::world::OnAdd {} #[script_bindings( remote, name = "on_insert_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::ecs::world::OnInsert {} #[script_bindings( remote, name = "on_remove_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::ecs::world::OnRemove {} #[script_bindings( remote, name = "on_replace_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::ecs::world::OnReplace {} #[script_bindings( remote, name = "component_id_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::ecs::component::ComponentId { fn assert_receiver_is_total_eq(_self: Ref) -> () { @@ -163,7 +169,8 @@ impl bevy::ecs::component::ComponentId { #[script_bindings( remote, name = "tick_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::ecs::component::Tick { fn assert_receiver_is_total_eq(_self: Ref) -> () { @@ -227,7 +234,8 @@ impl bevy::ecs::component::Tick { #[script_bindings( remote, name = "component_ticks_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::ecs::component::ComponentTicks { fn clone( @@ -305,7 +313,8 @@ impl bevy::ecs::component::ComponentTicks { #[script_bindings( remote, name = "identifier_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::ecs::identifier::Identifier { fn clone( @@ -362,7 +371,8 @@ impl bevy::ecs::identifier::Identifier { #[script_bindings( remote, name = "entity_hash_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::ecs::entity::EntityHash { fn clone( @@ -378,7 +388,8 @@ impl bevy::ecs::entity::EntityHash { #[script_bindings( remote, name = "removed_component_entity_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::ecs::removal_detection::RemovedComponentEntity { fn clone( @@ -394,7 +405,8 @@ impl bevy::ecs::removal_detection::RemovedComponentEntity { #[script_bindings( remote, name = "system_id_marker_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::ecs::system::SystemIdMarker {} impl ::bevy::app::Plugin for BevyEcsScriptingPlugin { diff --git a/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_hierarchy.rs b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_hierarchy.rs index 2c730db0b1..529c8c7f5d 100644 --- a/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_hierarchy.rs +++ b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_hierarchy.rs @@ -15,7 +15,8 @@ pub struct BevyHierarchyScriptingPlugin; #[script_bindings( remote, name = "children_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::hierarchy::prelude::Children { /// Swaps the child at `a_index` with the child at `b_index`. @@ -36,7 +37,8 @@ impl bevy::hierarchy::prelude::Children { #[script_bindings( remote, name = "parent_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::hierarchy::prelude::Parent { fn assert_receiver_is_total_eq(_self: Ref) -> () { @@ -70,7 +72,8 @@ impl bevy::hierarchy::prelude::Parent { #[script_bindings( remote, name = "hierarchy_event_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::hierarchy::HierarchyEvent { fn assert_receiver_is_total_eq(_self: Ref) -> () { diff --git a/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_input.rs b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_input.rs index ab06dabc55..712fa729dc 100644 --- a/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_input.rs +++ b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_input.rs @@ -15,7 +15,8 @@ pub struct BevyInputScriptingPlugin; #[script_bindings( remote, name = "gamepad_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::Gamepad { /// Returns the directional pad as a [`Vec2`] @@ -101,7 +102,8 @@ impl bevy::input::gamepad::Gamepad { #[script_bindings( remote, name = "gamepad_axis_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::GamepadAxis { fn assert_receiver_is_total_eq(_self: Ref) -> () { @@ -134,7 +136,8 @@ impl bevy::input::gamepad::GamepadAxis { #[script_bindings( remote, name = "gamepad_button_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::GamepadButton { fn assert_receiver_is_total_eq( @@ -169,7 +172,8 @@ impl bevy::input::gamepad::GamepadButton { #[script_bindings( remote, name = "gamepad_settings_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::GamepadSettings { fn clone( @@ -185,7 +189,8 @@ impl bevy::input::gamepad::GamepadSettings { #[script_bindings( remote, name = "key_code_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::keyboard::KeyCode { fn assert_receiver_is_total_eq(_self: Ref) -> () { @@ -218,7 +223,8 @@ impl bevy::input::keyboard::KeyCode { #[script_bindings( remote, name = "mouse_button_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::mouse::MouseButton { fn assert_receiver_is_total_eq(_self: Ref) -> () { @@ -251,7 +257,8 @@ impl bevy::input::mouse::MouseButton { #[script_bindings( remote, name = "touch_input_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::touch::TouchInput { fn clone( @@ -277,7 +284,8 @@ impl bevy::input::touch::TouchInput { #[script_bindings( remote, name = "keyboard_focus_lost_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::keyboard::KeyboardFocusLost { fn assert_receiver_is_total_eq( @@ -312,7 +320,8 @@ impl bevy::input::keyboard::KeyboardFocusLost { #[script_bindings( remote, name = "keyboard_input_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::keyboard::KeyboardInput { fn assert_receiver_is_total_eq( @@ -347,7 +356,8 @@ impl bevy::input::keyboard::KeyboardInput { #[script_bindings( remote, name = "accumulated_mouse_motion_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::mouse::AccumulatedMouseMotion { fn clone( @@ -373,7 +383,8 @@ impl bevy::input::mouse::AccumulatedMouseMotion { #[script_bindings( remote, name = "accumulated_mouse_scroll_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::mouse::AccumulatedMouseScroll { fn clone( @@ -399,7 +410,8 @@ impl bevy::input::mouse::AccumulatedMouseScroll { #[script_bindings( remote, name = "mouse_button_input_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::mouse::MouseButtonInput { fn assert_receiver_is_total_eq( @@ -434,7 +446,8 @@ impl bevy::input::mouse::MouseButtonInput { #[script_bindings( remote, name = "mouse_motion_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::mouse::MouseMotion { fn clone( @@ -460,7 +473,8 @@ impl bevy::input::mouse::MouseMotion { #[script_bindings( remote, name = "mouse_wheel_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::mouse::MouseWheel { fn clone( @@ -486,7 +500,8 @@ impl bevy::input::mouse::MouseWheel { #[script_bindings( remote, name = "gamepad_axis_changed_event_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::GamepadAxisChangedEvent { fn clone( @@ -526,7 +541,8 @@ impl bevy::input::gamepad::GamepadAxisChangedEvent { #[script_bindings( remote, name = "gamepad_button_changed_event_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::GamepadButtonChangedEvent { fn clone( @@ -568,7 +584,8 @@ impl bevy::input::gamepad::GamepadButtonChangedEvent { #[script_bindings( remote, name = "gamepad_button_state_changed_event_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::GamepadButtonStateChangedEvent { fn assert_receiver_is_total_eq( @@ -617,7 +634,8 @@ impl bevy::input::gamepad::GamepadButtonStateChangedEvent { #[script_bindings( remote, name = "gamepad_connection_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::GamepadConnection { fn clone( @@ -643,7 +661,8 @@ impl bevy::input::gamepad::GamepadConnection { #[script_bindings( remote, name = "gamepad_connection_event_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::GamepadConnectionEvent { fn clone( @@ -697,7 +716,8 @@ impl bevy::input::gamepad::GamepadConnectionEvent { #[script_bindings( remote, name = "gamepad_event_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::GamepadEvent { fn clone( @@ -723,7 +743,8 @@ impl bevy::input::gamepad::GamepadEvent { #[script_bindings( remote, name = "gamepad_input_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::GamepadInput { fn assert_receiver_is_total_eq( @@ -758,7 +779,8 @@ impl bevy::input::gamepad::GamepadInput { #[script_bindings( remote, name = "gamepad_rumble_request_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::GamepadRumbleRequest { fn clone( @@ -784,7 +806,8 @@ impl bevy::input::gamepad::GamepadRumbleRequest { #[script_bindings( remote, name = "raw_gamepad_axis_changed_event_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::RawGamepadAxisChangedEvent { fn clone( @@ -824,7 +847,8 @@ impl bevy::input::gamepad::RawGamepadAxisChangedEvent { #[script_bindings( remote, name = "raw_gamepad_button_changed_event_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::RawGamepadButtonChangedEvent { fn clone( @@ -864,7 +888,8 @@ impl bevy::input::gamepad::RawGamepadButtonChangedEvent { #[script_bindings( remote, name = "raw_gamepad_event_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::RawGamepadEvent { fn clone( @@ -890,7 +915,8 @@ impl bevy::input::gamepad::RawGamepadEvent { #[script_bindings( remote, name = "pinch_gesture_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gestures::PinchGesture { fn clone( @@ -916,7 +942,8 @@ impl bevy::input::gestures::PinchGesture { #[script_bindings( remote, name = "rotation_gesture_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gestures::RotationGesture { fn clone( @@ -942,7 +969,8 @@ impl bevy::input::gestures::RotationGesture { #[script_bindings( remote, name = "double_tap_gesture_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gestures::DoubleTapGesture { fn clone( @@ -968,7 +996,8 @@ impl bevy::input::gestures::DoubleTapGesture { #[script_bindings( remote, name = "pan_gesture_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gestures::PanGesture { fn clone( @@ -994,7 +1023,8 @@ impl bevy::input::gestures::PanGesture { #[script_bindings( remote, name = "button_state_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::ButtonState { fn assert_receiver_is_total_eq(_self: Ref) -> () { @@ -1030,7 +1060,8 @@ impl bevy::input::ButtonState { #[script_bindings( remote, name = "button_settings_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::ButtonSettings { fn clone( @@ -1119,7 +1150,8 @@ impl bevy::input::gamepad::ButtonSettings { #[script_bindings( remote, name = "axis_settings_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::AxisSettings { /// Clamps the `raw_value` according to the `AxisSettings`. @@ -1270,7 +1302,8 @@ impl bevy::input::gamepad::AxisSettings { #[script_bindings( remote, name = "button_axis_settings_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::ButtonAxisSettings { fn clone( @@ -1302,7 +1335,8 @@ impl bevy::input::gamepad::ButtonAxisSettings { #[script_bindings( remote, name = "gamepad_rumble_intensity_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::gamepad::GamepadRumbleIntensity { fn clone( @@ -1348,7 +1382,8 @@ impl bevy::input::gamepad::GamepadRumbleIntensity { #[script_bindings( remote, name = "key_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::keyboard::Key { fn assert_receiver_is_total_eq(_self: Ref) -> () { @@ -1379,7 +1414,8 @@ impl bevy::input::keyboard::Key { #[script_bindings( remote, name = "native_key_code_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::keyboard::NativeKeyCode { fn assert_receiver_is_total_eq( @@ -1414,7 +1450,8 @@ impl bevy::input::keyboard::NativeKeyCode { #[script_bindings( remote, name = "native_key_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::keyboard::NativeKey { fn assert_receiver_is_total_eq(_self: Ref) -> () { @@ -1447,7 +1484,8 @@ impl bevy::input::keyboard::NativeKey { #[script_bindings( remote, name = "mouse_scroll_unit_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::mouse::MouseScrollUnit { fn assert_receiver_is_total_eq( @@ -1482,7 +1520,8 @@ impl bevy::input::mouse::MouseScrollUnit { #[script_bindings( remote, name = "touch_phase_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::touch::TouchPhase { fn assert_receiver_is_total_eq(_self: Ref) -> () { @@ -1515,7 +1554,8 @@ impl bevy::input::touch::TouchPhase { #[script_bindings( remote, name = "force_touch_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::input::touch::ForceTouch { fn clone( diff --git a/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_math.rs b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_math.rs index c9a4eb3108..6a65dc0527 100644 --- a/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_math.rs +++ b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_math.rs @@ -15,7 +15,8 @@ pub struct BevyMathScriptingPlugin; #[script_bindings( remote, name = "aspect_ratio_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::AspectRatio { fn clone(_self: Ref) -> Val { @@ -67,7 +68,8 @@ impl bevy::math::AspectRatio { #[script_bindings( remote, name = "compass_octant_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::CompassOctant { fn assert_receiver_is_total_eq(_self: Ref) -> () { @@ -98,7 +100,8 @@ impl bevy::math::CompassOctant { #[script_bindings( remote, name = "compass_quadrant_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::CompassQuadrant { fn assert_receiver_is_total_eq(_self: Ref) -> () { @@ -131,7 +134,8 @@ impl bevy::math::CompassQuadrant { #[script_bindings( remote, name = "isometry_2_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::Isometry2d { fn clone(_self: Ref) -> Val { @@ -268,7 +272,8 @@ impl bevy::math::Isometry2d { #[script_bindings( remote, name = "isometry_3_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::Isometry3d { fn clone(_self: Ref) -> Val { @@ -372,7 +377,8 @@ impl bevy::math::Isometry3d { #[script_bindings( remote, name = "ray_2_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::Ray2d { fn clone(_self: Ref) -> Val { @@ -431,7 +437,8 @@ impl bevy::math::Ray2d { #[script_bindings( remote, name = "ray_3_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::Ray3d { fn clone(_self: Ref) -> Val { @@ -490,7 +497,8 @@ impl bevy::math::Ray3d { #[script_bindings( remote, name = "rot_2_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::Rot2 { /// Returns the angle in radians needed to make `self` and `other` coincide. @@ -790,7 +798,8 @@ impl bevy::math::Rot2 { #[script_bindings( remote, name = "dir_2_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::prelude::Dir2 { /// Returns the inner [`Vec2`] @@ -960,7 +969,8 @@ impl bevy::math::prelude::Dir2 { #[script_bindings( remote, name = "dir_3_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::prelude::Dir3 { /// Returns the inner [`Vec3`] @@ -1101,7 +1111,8 @@ impl bevy::math::prelude::Dir3 { #[script_bindings( remote, name = "dir_3_a_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::prelude::Dir3A { /// Returns the inner [`Vec3A`] @@ -1213,7 +1224,8 @@ impl bevy::math::prelude::Dir3A { #[script_bindings( remote, name = "i_rect_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::prelude::IRect { /// Returns self as [`Rect`] (f32) @@ -1547,7 +1559,8 @@ impl bevy::math::prelude::IRect { #[script_bindings( remote, name = "rect_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::prelude::Rect { /// Returns self as [`IRect`] (i32) @@ -1890,7 +1903,8 @@ impl bevy::math::prelude::Rect { #[script_bindings( remote, name = "u_rect_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::prelude::URect { /// Returns self as [`IRect`] (i32) @@ -2224,13 +2238,15 @@ impl bevy::math::prelude::URect { #[script_bindings( remote, name = "affine_3_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::Affine3 {} #[script_bindings( remote, name = "aabb_2_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::bounding::Aabb2d { /// Computes the smallest [`BoundingCircle`] containing this [`Aabb2d`]. @@ -2282,7 +2298,8 @@ impl bevy::math::bounding::Aabb2d { #[script_bindings( remote, name = "bounding_circle_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::bounding::BoundingCircle { /// Computes the smallest [`Aabb2d`] containing this [`BoundingCircle`]. @@ -2339,7 +2356,8 @@ impl bevy::math::bounding::BoundingCircle { #[script_bindings( remote, name = "circle_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Circle { fn clone( @@ -2392,7 +2410,8 @@ impl bevy::math::primitives::Circle { #[script_bindings( remote, name = "annulus_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Annulus { fn clone( @@ -2455,7 +2474,8 @@ impl bevy::math::primitives::Annulus { #[script_bindings( remote, name = "arc_2_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Arc2d { /// Get the angle of the arc @@ -2607,7 +2627,8 @@ impl bevy::math::primitives::Arc2d { #[script_bindings( remote, name = "capsule_2_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Capsule2d { fn clone( @@ -2652,7 +2673,8 @@ impl bevy::math::primitives::Capsule2d { #[script_bindings( remote, name = "circular_sector_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::CircularSector { /// Get the angle of the sector @@ -2785,7 +2807,8 @@ impl bevy::math::primitives::CircularSector { #[script_bindings( remote, name = "circular_segment_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::CircularSegment { /// Get the angle of the segment @@ -2918,7 +2941,8 @@ impl bevy::math::primitives::CircularSegment { #[script_bindings( remote, name = "ellipse_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Ellipse { fn clone( @@ -2988,7 +3012,8 @@ impl bevy::math::primitives::Ellipse { #[script_bindings( remote, name = "line_2_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Line2d { fn clone( @@ -3014,7 +3039,8 @@ impl bevy::math::primitives::Line2d { #[script_bindings( remote, name = "plane_2_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Plane2d { fn clone( @@ -3052,7 +3078,8 @@ impl bevy::math::primitives::Plane2d { #[script_bindings( remote, name = "rectangle_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Rectangle { fn clone( @@ -3142,7 +3169,8 @@ impl bevy::math::primitives::Rectangle { #[script_bindings( remote, name = "regular_polygon_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::RegularPolygon { /// Get the radius of the circumcircle on which all vertices @@ -3252,7 +3280,8 @@ impl bevy::math::primitives::RegularPolygon { #[script_bindings( remote, name = "rhombus_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Rhombus { /// Get the radius of the circumcircle on which all vertices @@ -3337,7 +3366,8 @@ impl bevy::math::primitives::Rhombus { #[script_bindings( remote, name = "segment_2_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Segment2d { fn clone( @@ -3395,7 +3425,8 @@ impl bevy::math::primitives::Segment2d { #[script_bindings( remote, name = "triangle_2_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Triangle2d { fn clone( @@ -3469,7 +3500,8 @@ impl bevy::math::primitives::Triangle2d { #[script_bindings( remote, name = "aabb_3_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::bounding::Aabb3d { /// Computes the smallest [`BoundingSphere`] containing this [`Aabb3d`]. @@ -3495,7 +3527,8 @@ impl bevy::math::bounding::Aabb3d { #[script_bindings( remote, name = "bounding_sphere_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::bounding::BoundingSphere { /// Computes the smallest [`Aabb3d`] containing this [`BoundingSphere`]. @@ -3526,7 +3559,8 @@ impl bevy::math::bounding::BoundingSphere { #[script_bindings( remote, name = "sphere_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Sphere { fn clone( @@ -3579,7 +3613,8 @@ impl bevy::math::primitives::Sphere { #[script_bindings( remote, name = "cuboid_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Cuboid { fn clone( @@ -3674,7 +3709,8 @@ impl bevy::math::primitives::Cuboid { #[script_bindings( remote, name = "cylinder_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Cylinder { /// Get the base of the cylinder as a [`Circle`] @@ -3730,7 +3766,8 @@ impl bevy::math::primitives::Cylinder { #[script_bindings( remote, name = "capsule_3_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Capsule3d { fn clone( @@ -3776,7 +3813,8 @@ impl bevy::math::primitives::Capsule3d { #[script_bindings( remote, name = "cone_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Cone { /// Get the base of the cone as a [`Circle`] @@ -3838,7 +3876,8 @@ impl bevy::math::primitives::Cone { #[script_bindings( remote, name = "conical_frustum_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::ConicalFrustum { fn clone( @@ -3864,7 +3903,8 @@ impl bevy::math::primitives::ConicalFrustum { #[script_bindings( remote, name = "infinite_plane_3_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::InfinitePlane3d { fn clone( @@ -3948,7 +3988,8 @@ impl bevy::math::primitives::InfinitePlane3d { #[script_bindings( remote, name = "line_3_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Line3d { fn clone( @@ -3974,7 +4015,8 @@ impl bevy::math::primitives::Line3d { #[script_bindings( remote, name = "segment_3_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Segment3d { fn clone( @@ -4032,7 +4074,8 @@ impl bevy::math::primitives::Segment3d { #[script_bindings( remote, name = "torus_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Torus { fn clone( @@ -4083,7 +4126,8 @@ impl bevy::math::primitives::Torus { #[script_bindings( remote, name = "triangle_3_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Triangle3d { /// Get the centroid of the triangle. @@ -4178,7 +4222,8 @@ impl bevy::math::primitives::Triangle3d { #[script_bindings( remote, name = "ray_cast_2_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::bounding::RayCast2d { /// Get the distance of an intersection with an [`Aabb2d`], if any. @@ -4254,7 +4299,8 @@ impl bevy::math::bounding::RayCast2d { #[script_bindings( remote, name = "aabb_cast_2_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::bounding::AabbCast2d { /// Get the distance at which the [`Aabb2d`]s collide, if at all. @@ -4312,7 +4358,8 @@ impl bevy::math::bounding::AabbCast2d { #[script_bindings( remote, name = "bounding_circle_cast_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::bounding::BoundingCircleCast { /// Get the distance at which the [`BoundingCircle`]s collide, if at all. @@ -4370,7 +4417,8 @@ impl bevy::math::bounding::BoundingCircleCast { #[script_bindings( remote, name = "ray_cast_3_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::bounding::RayCast3d { /// Get the distance of an intersection with an [`Aabb3d`], if any. @@ -4432,7 +4480,8 @@ impl bevy::math::bounding::RayCast3d { #[script_bindings( remote, name = "aabb_cast_3_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::bounding::AabbCast3d { /// Get the distance at which the [`Aabb3d`]s collide, if at all. @@ -4474,7 +4523,8 @@ impl bevy::math::bounding::AabbCast3d { #[script_bindings( remote, name = "bounding_sphere_cast_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::bounding::BoundingSphereCast { fn clone( @@ -4516,7 +4566,8 @@ impl bevy::math::bounding::BoundingSphereCast { #[script_bindings( remote, name = "interval_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::curve::interval::Interval { /// Clamp the given `value` to lie within this interval. @@ -4620,7 +4671,8 @@ impl bevy::math::curve::interval::Interval { #[script_bindings( remote, name = "float_ord_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::FloatOrd { fn clone(_self: Ref) -> Val { @@ -4676,7 +4728,8 @@ impl bevy::math::FloatOrd { #[script_bindings( remote, name = "plane_3_d_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Plane3d { fn clone( @@ -4716,7 +4769,8 @@ impl bevy::math::primitives::Plane3d { #[script_bindings( remote, name = "tetrahedron_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::primitives::Tetrahedron { /// Get the centroid of the tetrahedron. @@ -4779,7 +4833,8 @@ impl bevy::math::primitives::Tetrahedron { #[script_bindings( remote, name = "ease_function_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::curve::easing::EaseFunction { fn clone( diff --git a/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_reflect.rs b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_reflect.rs index 83ad7639a1..303da037a7 100644 --- a/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_reflect.rs +++ b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_reflect.rs @@ -15,7 +15,8 @@ pub struct BevyReflectScriptingPlugin; #[script_bindings( remote, name = "atomic_bool_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl std::sync::atomic::AtomicBool { /// Consumes the atomic and returns the contained value. @@ -50,7 +51,8 @@ impl std::sync::atomic::AtomicBool { #[script_bindings( remote, name = "atomic_i_16_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl std::sync::atomic::AtomicI16 { /// Consumes the atomic and returns the contained value. @@ -84,7 +86,8 @@ impl std::sync::atomic::AtomicI16 { #[script_bindings( remote, name = "atomic_i_32_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl std::sync::atomic::AtomicI32 { /// Consumes the atomic and returns the contained value. @@ -118,7 +121,8 @@ impl std::sync::atomic::AtomicI32 { #[script_bindings( remote, name = "atomic_i_64_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl std::sync::atomic::AtomicI64 { /// Consumes the atomic and returns the contained value. @@ -152,7 +156,8 @@ impl std::sync::atomic::AtomicI64 { #[script_bindings( remote, name = "atomic_i_8_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl std::sync::atomic::AtomicI8 { /// Consumes the atomic and returns the contained value. @@ -186,7 +191,8 @@ impl std::sync::atomic::AtomicI8 { #[script_bindings( remote, name = "atomic_isize_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl std::sync::atomic::AtomicIsize { /// Consumes the atomic and returns the contained value. @@ -222,7 +228,8 @@ impl std::sync::atomic::AtomicIsize { #[script_bindings( remote, name = "atomic_u_16_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl std::sync::atomic::AtomicU16 { /// Consumes the atomic and returns the contained value. @@ -256,7 +263,8 @@ impl std::sync::atomic::AtomicU16 { #[script_bindings( remote, name = "atomic_u_32_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl std::sync::atomic::AtomicU32 { /// Consumes the atomic and returns the contained value. @@ -290,7 +298,8 @@ impl std::sync::atomic::AtomicU32 { #[script_bindings( remote, name = "atomic_u_64_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl std::sync::atomic::AtomicU64 { /// Consumes the atomic and returns the contained value. @@ -324,7 +333,8 @@ impl std::sync::atomic::AtomicU64 { #[script_bindings( remote, name = "atomic_u_8_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl std::sync::atomic::AtomicU8 { /// Consumes the atomic and returns the contained value. @@ -358,7 +368,8 @@ impl std::sync::atomic::AtomicU8 { #[script_bindings( remote, name = "atomic_usize_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl std::sync::atomic::AtomicUsize { /// Consumes the atomic and returns the contained value. @@ -394,7 +405,8 @@ impl std::sync::atomic::AtomicUsize { #[script_bindings( remote, name = "duration_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::utils::Duration { /// Computes the absolute difference between `self` and `other`. @@ -932,7 +944,8 @@ impl bevy::utils::Duration { #[script_bindings( remote, name = "instant_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::utils::Instant { /// # Panics @@ -1081,7 +1094,8 @@ impl bevy::utils::Instant { #[script_bindings( remote, name = "range_full_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl std::ops::RangeFull { fn assert_receiver_is_total_eq(_self: Ref) -> () { @@ -1109,7 +1123,8 @@ impl std::ops::RangeFull { #[script_bindings( remote, name = "quat_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::Quat { /// Returns true if the absolute difference of all elements between `self` and `rhs` @@ -1650,7 +1665,8 @@ impl bevy::math::Quat { #[script_bindings( remote, name = "vec_3_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::Vec3 { /// Returns a vector containing the absolute value of each element of `self`. @@ -2610,7 +2626,8 @@ impl bevy::math::Vec3 { #[script_bindings( remote, name = "i_vec_2_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::IVec2 { /// Returns a vector containing the absolute value of each element of `self`. @@ -3302,7 +3319,8 @@ impl bevy::math::IVec2 { #[script_bindings( remote, name = "i_vec_3_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::IVec3 { /// Returns a vector containing the absolute value of each element of `self`. @@ -3999,7 +4017,8 @@ impl bevy::math::IVec3 { #[script_bindings( remote, name = "i_vec_4_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::IVec4 { /// Returns a vector containing the absolute value of each element of `self`. @@ -4679,7 +4698,8 @@ impl bevy::math::IVec4 { #[script_bindings( remote, name = "i_64_vec_2_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::I64Vec2 { /// Returns a vector containing the absolute value of each element of `self`. @@ -5378,7 +5398,8 @@ impl bevy::math::I64Vec2 { #[script_bindings( remote, name = "i_64_vec_3_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::I64Vec3 { /// Returns a vector containing the absolute value of each element of `self`. @@ -6081,7 +6102,8 @@ impl bevy::math::I64Vec3 { #[script_bindings( remote, name = "i_64_vec_4_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::I64Vec4 { /// Returns a vector containing the absolute value of each element of `self`. @@ -6767,7 +6789,8 @@ impl bevy::math::I64Vec4 { #[script_bindings( remote, name = "u_vec_2_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::UVec2 { fn add( @@ -7331,7 +7354,8 @@ impl bevy::math::UVec2 { #[script_bindings( remote, name = "u_vec_3_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::UVec3 { fn add( @@ -7930,7 +7954,8 @@ impl bevy::math::UVec3 { #[script_bindings( remote, name = "u_vec_4_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::UVec4 { fn add( @@ -8512,7 +8537,8 @@ impl bevy::math::UVec4 { #[script_bindings( remote, name = "u_64_vec_2_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::U64Vec2 { fn add( @@ -9079,7 +9105,8 @@ impl bevy::math::U64Vec2 { #[script_bindings( remote, name = "u_64_vec_3_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::U64Vec3 { fn add( @@ -9682,7 +9709,8 @@ impl bevy::math::U64Vec3 { #[script_bindings( remote, name = "u_64_vec_4_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::U64Vec4 { fn add( @@ -10268,7 +10296,8 @@ impl bevy::math::U64Vec4 { #[script_bindings( remote, name = "vec_2_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::Vec2 { /// Returns a vector containing the absolute value of each element of `self`. @@ -11245,7 +11274,8 @@ impl bevy::math::Vec2 { #[script_bindings( remote, name = "vec_3_a_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::Vec3A { /// Returns a vector containing the absolute value of each element of `self`. @@ -12217,7 +12247,8 @@ impl bevy::math::Vec3A { #[script_bindings( remote, name = "vec_4_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::Vec4 { /// Returns a vector containing the absolute value of each element of `self`. @@ -13134,7 +13165,8 @@ impl bevy::math::Vec4 { #[script_bindings( remote, name = "b_vec_2_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::BVec2 { /// Returns true if all the elements are true, false otherwise. @@ -13206,7 +13238,8 @@ impl bevy::math::BVec2 { #[script_bindings( remote, name = "b_vec_3_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::BVec3 { /// Returns true if all the elements are true, false otherwise. @@ -13278,7 +13311,8 @@ impl bevy::math::BVec3 { #[script_bindings( remote, name = "b_vec_4_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::BVec4 { /// Returns true if all the elements are true, false otherwise. @@ -13350,7 +13384,8 @@ impl bevy::math::BVec4 { #[script_bindings( remote, name = "d_vec_2_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::DVec2 { /// Returns a vector containing the absolute value of each element of `self`. @@ -14332,7 +14367,8 @@ impl bevy::math::DVec2 { #[script_bindings( remote, name = "d_vec_3_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::DVec3 { /// Returns a vector containing the absolute value of each element of `self`. @@ -15302,7 +15338,8 @@ impl bevy::math::DVec3 { #[script_bindings( remote, name = "d_vec_4_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::DVec4 { /// Returns a vector containing the absolute value of each element of `self`. @@ -16223,7 +16260,8 @@ impl bevy::math::DVec4 { #[script_bindings( remote, name = "mat_2_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::Mat2 { /// Takes the absolute value of each element in `self` @@ -16524,7 +16562,8 @@ impl bevy::math::Mat2 { #[script_bindings( remote, name = "mat_3_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::Mat3 { /// Takes the absolute value of each element in `self` @@ -16981,7 +17020,8 @@ impl bevy::math::Mat3 { #[script_bindings( remote, name = "mat_3_a_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::Mat3A { /// Takes the absolute value of each element in `self` @@ -17440,7 +17480,8 @@ impl bevy::math::Mat3A { #[script_bindings( remote, name = "mat_4_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::Mat4 { /// Takes the absolute value of each element in `self` @@ -18215,7 +18256,8 @@ impl bevy::math::Mat4 { #[script_bindings( remote, name = "d_mat_2_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::DMat2 { /// Takes the absolute value of each element in `self` @@ -18495,7 +18537,8 @@ impl bevy::math::DMat2 { #[script_bindings( remote, name = "d_mat_3_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::DMat3 { /// Takes the absolute value of each element in `self` @@ -18932,7 +18975,8 @@ impl bevy::math::DMat3 { #[script_bindings( remote, name = "d_mat_4_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::DMat4 { /// Takes the absolute value of each element in `self` @@ -19659,7 +19703,8 @@ impl bevy::math::DMat4 { #[script_bindings( remote, name = "affine_2_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::Affine2 { /// Returns true if the absolute difference of all elements between `self` and `rhs` @@ -19894,7 +19939,8 @@ impl bevy::math::Affine2 { #[script_bindings( remote, name = "affine_3_a_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::Affine3A { /// Returns true if the absolute difference of all elements between `self` and `rhs` @@ -20252,7 +20298,8 @@ impl bevy::math::Affine3A { #[script_bindings( remote, name = "d_affine_2_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::DAffine2 { /// Returns true if the absolute difference of all elements between `self` and `rhs` @@ -20472,7 +20519,8 @@ impl bevy::math::DAffine2 { #[script_bindings( remote, name = "d_affine_3_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::DAffine3 { /// Returns true if the absolute difference of all elements between `self` and `rhs` @@ -20804,7 +20852,8 @@ impl bevy::math::DAffine3 { #[script_bindings( remote, name = "d_quat_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::DQuat { /// Returns true if the absolute difference of all elements between `self` and `rhs` @@ -21317,7 +21366,8 @@ impl bevy::math::DQuat { #[script_bindings( remote, name = "euler_rot_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::EulerRot { fn assert_receiver_is_total_eq(_self: Ref) -> () { @@ -21345,7 +21395,8 @@ impl bevy::math::EulerRot { #[script_bindings( remote, name = "b_vec_3_a_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::BVec3A { /// Returns true if all the elements are true, false otherwise. @@ -21410,7 +21461,8 @@ impl bevy::math::BVec3A { #[script_bindings( remote, name = "b_vec_4_a_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::math::BVec4A { /// Returns true if all the elements are true, false otherwise. @@ -21475,7 +21527,8 @@ impl bevy::math::BVec4A { #[script_bindings( remote, name = "smol_str_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl smol_str::SmolStr { fn clone(_self: Ref) -> Val { @@ -21512,7 +21565,8 @@ impl smol_str::SmolStr { #[script_bindings( remote, name = "uuid_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl uuid::Uuid { /// Returns a 128bit value containing the value. diff --git a/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_time.rs b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_time.rs index 2693af0abb..4802139580 100644 --- a/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_time.rs +++ b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_time.rs @@ -15,7 +15,8 @@ pub struct BevyTimeScriptingPlugin; #[script_bindings( remote, name = "fixed_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::time::prelude::Fixed { fn clone(_self: Ref) -> Val { @@ -29,7 +30,8 @@ impl bevy::time::prelude::Fixed { #[script_bindings( remote, name = "real_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::time::prelude::Real { fn clone(_self: Ref) -> Val { @@ -43,7 +45,8 @@ impl bevy::time::prelude::Real { #[script_bindings( remote, name = "timer_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::time::prelude::Timer { fn assert_receiver_is_total_eq(_self: Ref) -> () { @@ -408,7 +411,8 @@ impl bevy::time::prelude::Timer { #[script_bindings( remote, name = "timer_mode_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::time::prelude::TimerMode { fn assert_receiver_is_total_eq(_self: Ref) -> () { @@ -441,7 +445,8 @@ impl bevy::time::prelude::TimerMode { #[script_bindings( remote, name = "virtual_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::time::prelude::Virtual { fn clone( @@ -457,7 +462,8 @@ impl bevy::time::prelude::Virtual { #[script_bindings( remote, name = "stopwatch_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::time::Stopwatch { fn assert_receiver_is_total_eq(_self: Ref) -> () { diff --git a/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_transform.rs b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_transform.rs index a6bb246da4..33f27c9332 100644 --- a/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_transform.rs +++ b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_transform.rs @@ -15,7 +15,8 @@ pub struct BevyTransformScriptingPlugin; #[script_bindings( remote, name = "global_transform_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::transform::components::GlobalTransform { /// Returns the 3d affine transformation matrix as an [`Affine3A`]. @@ -379,7 +380,8 @@ impl bevy::transform::components::GlobalTransform { #[script_bindings( remote, name = "transform_functions", - bms_core_path = "bevy_mod_scripting_core" + bms_core_path = "bevy_mod_scripting_core", + generated )] impl bevy::transform::components::Transform { /// Equivalent to [`local_z()`][Transform::local_z] diff --git a/crates/bevy_mod_scripting_functions/src/core.rs b/crates/bevy_mod_scripting_functions/src/core.rs index 13d7c4d280..bcac621f01 100644 --- a/crates/bevy_mod_scripting_functions/src/core.rs +++ b/crates/bevy_mod_scripting_functions/src/core.rs @@ -43,6 +43,14 @@ pub fn register_bevy_bindings(app: &mut App) { unregistered )] impl World { + /// Returns either a `ScriptComponentRegistration` or `ScriptResourceRegistration` depending on the type of the type requested. + /// If the type is neither returns a `ScriptTypeRegistration`. + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `type_name`: The name of the type to retrieve. + /// Returns: + /// * `type`: The registration of the type, if it exists. fn get_type_by_name( ctxt: FunctionCallContext, type_name: String, @@ -63,6 +71,19 @@ impl World { } /// Retrieves the schedule with the given name, Also ensures the schedule is initialized before returning it. + /// + /// Schedules in bevy are "containers" for systems, each schedule runs separately and contains different systems. + /// + /// By default among others bevy contains the following schedules: + /// - `Update`: Runs every frame. + /// - `PostUpdate`: Runs after the `Update` schedule. + /// - `FixedUpdate`: Runs at a fixed rate. + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `name`: The name of the schedule to retrieve. + /// Returns: + /// * `schedule`: The schedule with the given name, if it exists fn get_schedule_by_name( ctxt: FunctionCallContext, name: String, @@ -80,6 +101,14 @@ impl World { Ok(Some(schedule.into())) } + /// Tries to retrieve the given component type on an entity. + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `entity`: The entity to retrieve the component from. + /// * `registration`: The component to retrieve. + /// Returns: + /// * `component`: The component on the entity, if it exists. fn get_component( ctxt: FunctionCallContext, entity: Val, @@ -91,6 +120,14 @@ impl World { Ok(val) } + /// Checks if the given entity has the given component. + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `entity`: The entity to check. + /// * `registration`: The component to check for. + /// Returns: + /// * `has_component`: Whether the entity has the component. fn has_component( ctxt: FunctionCallContext, entity: Val, @@ -101,6 +138,13 @@ impl World { world.has_component(*entity, registration.component_id()) } + /// Removes the given component from the entity. + /// Arguments: + /// * `ctxt`: The function call context. + /// * `entity`: The entity to remove the component from. + /// * `registration`: The component to remove. + /// Returns: + /// * `result`: Nothing if the component was removed successfully or didn't exist in the first place. fn remove_component( ctxt: FunctionCallContext, entity: Val, @@ -111,6 +155,12 @@ impl World { world.remove_component(*entity, registration.clone()) } + /// Retrieves the resource with the given registration. + /// Arguments: + /// * `ctxt`: The function call context. + /// * `registration`: The registration of the resource to retrieve. + /// Returns: + /// * `resource`: The resource, if it exists. fn get_resource( ctxt: FunctionCallContext, registration: Val, @@ -121,6 +171,13 @@ impl World { Ok(val) } + /// Checks if the world has the given resource. + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `registration`: The registration of the resource to check for. + /// Returns: + /// * `has_resource`: Whether the world has the resource. fn has_resource( ctxt: FunctionCallContext, registration: Val, @@ -130,6 +187,12 @@ impl World { world.has_resource(registration.resource_id()) } + /// Removes the given resource from the world. + /// Arguments: + /// * `ctxt`: The function call context. + /// * `registration`: The resource to remove. + /// Returns: + /// * `result`: Nothing if the resource was removed successfully or didn't exist in the first place. fn remove_resource( ctxt: FunctionCallContext, registration: Val, @@ -139,6 +202,12 @@ impl World { world.remove_resource(registration.into_inner()) } + /// Adds the given resource to the world. + /// Arguments: + /// * `ctxt`: The function call context. + /// * `registration`: The resource to add. + /// Returns: + /// * `result`: Nothing if the resource was added successfully. fn add_default_component( ctxt: FunctionCallContext, entity: Val, @@ -149,12 +218,27 @@ impl World { world.add_default_component(*entity, registration.clone()) } + /// Spawns a new entity and returns it + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// Returns: + /// * `entity`: The newly spawned entity fn spawn(ctxt: FunctionCallContext) -> Result, InteropError> { profiling::function_scope!("spawn"); let world = ctxt.world()?; Ok(Val(world.spawn()?)) } + /// Inserts the given component value into the provided entity + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `entity`: The entity to insert the component into. + /// * `registration`: The component registration of the component to insert. + /// * `value`: The value of the component to insert. Can be constructed using `construct` + /// Returns: + /// * `result`: Nothing if the component was inserted successfully. fn insert_component( ctxt: FunctionCallContext, entity: Val, @@ -166,6 +250,15 @@ impl World { world.insert_component(*entity, registration.into_inner(), value) } + /// Inserts the given children entities into the provided parent entity. + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `entity`: The parent entity to receive children + /// * `index`: The index to insert the children at + /// * `children`: The children entities to insert + /// Returns: + /// * `result`: Nothing if the children were inserted successfully. fn insert_children( ctxt: FunctionCallContext, entity: Val, @@ -186,6 +279,13 @@ impl World { ) } + /// Pushes the given children entities into the provided parent entity. + /// Arguments: + /// * `ctxt`: The function call context. + /// * `entity`: The parent entity to receive children + /// * `children`: The children entities to push + /// Returns: + /// * `result`: Nothing if the children were pushed successfully. fn push_children( ctxt: FunctionCallContext, entity: Val, @@ -199,6 +299,12 @@ impl World { ) } + /// Retrieves the children of the given entity. + /// Arguments: + /// * `ctxt`: The function call context. + /// * `entity`: The entity to retrieve the children of. + /// Returns: + /// * `children`: The children of the entity. fn get_children( ctxt: FunctionCallContext, entity: Val, @@ -209,40 +315,79 @@ impl World { Ok(children.into_iter().map(Val).collect::>()) } + /// Retrieves the parent of the given entity. + /// Arguments: + /// * `ctxt`: The function call context. + /// * `entity`: The entity to retrieve the parent of. + /// Returns: + /// * `parent`: The parent of the entity fn get_parent( ctxt: FunctionCallContext, - e: Val, + entity: Val, ) -> Result>, InteropError> { profiling::function_scope!("get_parent"); let world = ctxt.world()?; - let parent = world.get_parent(*e)?; + let parent = world.get_parent(*entity)?; Ok(parent.map(Val)) } - fn despawn(ctxt: FunctionCallContext, e: Val) -> Result<(), InteropError> { + /// Despawns the given entity. + /// Arguments: + /// * `ctxt`: The function call context. + /// * `entity`: The entity to despawn. + fn despawn(ctxt: FunctionCallContext, entity: Val) -> Result<(), InteropError> { profiling::function_scope!("despawn"); let world = ctxt.world()?; - world.despawn(*e) + world.despawn(*entity) } - fn despawn_descendants(ctxt: FunctionCallContext, e: Val) -> Result<(), InteropError> { + /// Despawn the descendants of the given entity. + /// Arguments: + /// * `ctxt`: The function call context. + /// * `entity`: The entity to despawn the descendants of. + /// Returns: + /// * `result`: Nothing if the descendants were despawned successfully. + fn despawn_descendants( + ctxt: FunctionCallContext, + entity: Val, + ) -> Result<(), InteropError> { profiling::function_scope!("despawn_descendants"); let world = ctxt.world()?; - world.despawn_descendants(*e) + world.despawn_descendants(*entity) } - fn despawn_recursive(ctxt: FunctionCallContext, e: Val) -> Result<(), InteropError> { + /// Despawns the entity and all its descendants. + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `entity`: The entity to despawn recursively. + /// Returns: + /// * `result`: Nothing if the entity and its descendants were despawned successfully. + fn despawn_recursive( + ctxt: FunctionCallContext, + entity: Val, + ) -> Result<(), InteropError> { profiling::function_scope!("despawn_recursive"); let world = ctxt.world()?; - world.despawn_recursive(*e) + world.despawn_recursive(*entity) } + /// Checks if the given entity exists. + /// Arguments: + /// * `ctxt`: The function call context. + /// * `entity`: The entity to check. + /// Returns: + /// * `has_entity`: Whether the entity exists. fn has_entity(ctxt: FunctionCallContext, e: Val) -> Result { profiling::function_scope!("has_entity"); let world = ctxt.world()?; world.has_entity(*e) } + /// Creates a new `ScriptQueryBuilder` which can be used to query the ECS. + /// + /// Returns: + /// * `query`: The new query builder. fn query() -> Result, InteropError> { profiling::function_scope!("query"); let query_builder = ScriptQueryBuilder::default(); @@ -290,6 +435,11 @@ impl World { Ok(Val(system)) } + /// Quits the program. + /// Arguments: + /// * `ctxt`: The function call context. + /// Returns: + /// * `result`: Nothing if the program was exited successfully. fn exit(ctxt: FunctionCallContext) -> Result<(), InteropError> { profiling::function_scope!("exit"); let world = ctxt.world()?; @@ -300,48 +450,81 @@ impl World { #[script_bindings( remote, bms_core_path = "bevy_mod_scripting_core", - name = "reflect_reference_functions" + name = "reflect_reference_functions", + core )] impl ReflectReference { /// If this type is an enum, will return the name of the variant it represents on the type. + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `reference`: The reference to get the variant name of. + /// Returns: + /// * `variant_name`: The name of the variant, if the reference is an enum. fn variant_name( ctxt: FunctionCallContext, - s: ReflectReference, + reference: ReflectReference, ) -> Result, InteropError> { profiling::function_scope!("variant_name"); let world = ctxt.world()?; - s.variant_name(world) + reference.variant_name(world) } /// Displays this reference without printing the exact contents. - fn display_ref(ctxt: FunctionCallContext, s: ReflectReference) -> Result { + /// + /// This is useful for debugging and logging. + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `reference`: The reference to display. + /// Returns: + /// * `display`: The display string. + fn display_ref( + ctxt: FunctionCallContext, + reference: ReflectReference, + ) -> Result { profiling::function_scope!("display_ref"); let world = ctxt.world()?; - Ok(s.display_with_world(world)) + Ok(reference.display_with_world(world)) } /// Displays the "value" of this reference + /// + /// This is useful for debugging and logging. + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `reference`: The reference to display. + /// Returns: + /// * `display`: The display string. fn display_value( ctxt: FunctionCallContext, - s: ReflectReference, + reference: ReflectReference, ) -> Result { profiling::function_scope!("display_value"); let world = ctxt.world()?; - Ok(s.display_value_with_world(world)) + Ok(reference.display_value_with_world(world)) } /// Gets and clones the value under the specified key if the underlying type is a map type. + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `reference`: The reference to index into. + /// * `key`: The key to index with. + /// Returns: + /// * `value`: The value at the key, if the reference is a map. fn map_get( ctxt: FunctionCallContext, - self_: ReflectReference, + reference: ReflectReference, key: ScriptValue, ) -> Result, InteropError> { profiling::function_scope!("map_get"); let world = ctxt.world()?; let key = >::from_script_ref( - self_.key_type_id(world.clone())?.ok_or_else(|| { + reference.key_type_id(world.clone())?.ok_or_else(|| { InteropError::unsupported_operation( - self_.tail_type_id(world.clone()).unwrap_or_default(), + reference.tail_type_id(world.clone()).unwrap_or_default(), Some(Box::new(key.clone())), "Could not get key type id. Are you trying to index into a type that's not a map?".to_owned(), ) @@ -349,7 +532,7 @@ impl ReflectReference { key, world.clone(), )?; - self_.with_reflect_mut(world.clone(), |s| match s.try_map_get(key.as_ref())? { + reference.with_reflect_mut(world.clone(), |s| match s.try_map_get(key.as_ref())? { Some(value) => { let reference = { let allocator = world.allocator(); @@ -367,9 +550,16 @@ impl ReflectReference { /// returns the concrete value. /// /// Does not support map types at the moment, for maps see `map_get` + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `reference`: The reference to index into. + /// * `key`: The key to index with. + /// Returns: + /// * `value`: The value at the key, if the reference is indexable. fn get( ctxt: FunctionCallContext, - mut self_: ReflectReference, + mut reference: ReflectReference, key: ScriptValue, ) -> Result { profiling::function_scope!("get"); @@ -377,71 +567,93 @@ impl ReflectReference { if ctxt.convert_to_0_indexed() { path.convert_to_0_indexed(); } - self_.index_path(path); + reference.index_path(path); let world = ctxt.world()?; - ReflectReference::into_script_ref(self_, world) + ReflectReference::into_script_ref(reference, world) } /// Sets the value under the specified path on the underlying value. + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `reference`: The reference to set the value on. + /// * `key`: The key to set the value at. + /// * `value`: The value to set. + /// Returns: + /// * `result`: Nothing if the value was set successfully. fn set( ctxt: FunctionCallContext, - self_: ScriptValue, + reference: ScriptValue, key: ScriptValue, value: ScriptValue, - ) -> Result { + ) -> Result<(), InteropError> { profiling::function_scope!("set"); - if let ScriptValue::Reference(mut self_) = self_ { + if let ScriptValue::Reference(mut self_) = reference { let world = ctxt.world()?; let mut path: ParsedPath = key.try_into()?; if ctxt.convert_to_0_indexed() { path.convert_to_0_indexed(); } self_.index_path(path); - let r: ScriptValue = self_ - .with_reflect_mut(world.clone(), |r| { - let target_type_id = r - .get_represented_type_info() - .map(|i| i.type_id()) - .or_fake_id(); - let other = >::from_script_ref( - target_type_id, - value, - world.clone(), - )?; - r.try_apply(other.as_partial_reflect()) - .map_err(|e| InteropError::external_error(Box::new(e)))?; - Ok::<_, InteropError>(()) - }) - .into(); - return Ok(r); + self_.with_reflect_mut(world.clone(), |r| { + let target_type_id = r + .get_represented_type_info() + .map(|i| i.type_id()) + .or_fake_id(); + let other = >::from_script_ref( + target_type_id, + value, + world.clone(), + )?; + r.try_apply(other.as_partial_reflect()) + .map_err(|e| InteropError::external_error(Box::new(e)))?; + Ok::<_, InteropError>(()) + })??; } - Ok(ScriptValue::Unit) + Ok(()) } /// Pushes the value into the reference, if the reference is an appropriate container type. + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `reference`: The reference to push the value into. + /// * `value`: The value to push. + /// Returns: + /// * `result`: Nothing if the value was pushed successfully. fn push( ctxt: FunctionCallContext, - s: ReflectReference, - v: ScriptValue, + reference: ReflectReference, + value: ScriptValue, ) -> Result<(), InteropError> { profiling::function_scope!("push"); let world = ctxt.world()?; - let target_type_id = s.element_type_id(world.clone())?.ok_or_else(|| { + let target_type_id = reference.element_type_id(world.clone())?.ok_or_else(|| { InteropError::unsupported_operation( - s.tail_type_id(world.clone()).unwrap_or_default(), - Some(Box::new(v.clone())), + reference.tail_type_id(world.clone()).unwrap_or_default(), + Some(Box::new(value.clone())), "Could not get element type id. Are you trying to insert elements into a type that's not a list?".to_owned(), ) })?; - let other = >::from_script_ref(target_type_id, v, world.clone())?; - s.with_reflect_mut(world, |s| s.try_push_boxed(other))? + let other = + >::from_script_ref(target_type_id, value, world.clone())?; + reference.with_reflect_mut(world, |s| s.try_push_boxed(other))? } /// Pops the value from the reference, if the reference is an appropriate container type. - fn pop(ctxt: FunctionCallContext, s: ReflectReference) -> Result { + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `reference`: The reference to pop the value from. + /// Returns: + /// * `value`: The value that was popped, if the reference supports popping. + fn pop( + ctxt: FunctionCallContext, + reference: ReflectReference, + ) -> Result { profiling::function_scope!("pop"); let world = ctxt.world()?; - let o = s.with_reflect_mut(world.clone(), |s| s.try_pop_boxed())??; + let o = reference.with_reflect_mut(world.clone(), |s| s.try_pop_boxed())??; let reference = { let allocator = world.allocator(); let mut allocator = allocator.write(); @@ -452,78 +664,108 @@ impl ReflectReference { } /// Inserts the value into the reference at the specified index, if the reference is an appropriate container type. + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `reference`: The reference to insert the value into. + /// * `key`: The index to insert the value at. + /// * `value`: The value to insert. + /// Returns: + /// * `result`: Nothing if the value was inserted successfully. fn insert( ctxt: FunctionCallContext, - s: ReflectReference, - k: ScriptValue, - v: ScriptValue, + reference: ReflectReference, + key: ScriptValue, + value: ScriptValue, ) -> Result<(), InteropError> { profiling::function_scope!("insert"); let world = ctxt.world()?; - let key_type_id = s.key_type_id(world.clone())?.ok_or_else(|| { + let key_type_id = reference.key_type_id(world.clone())?.ok_or_else(|| { InteropError::unsupported_operation( - s.tail_type_id(world.clone()).unwrap_or_default(), - Some(Box::new(k.clone())), + reference.tail_type_id(world.clone()).unwrap_or_default(), + Some(Box::new(key.clone())), "Could not get key type id. Are you trying to insert elements into a type that's not a map?".to_owned(), ) })?; - let mut key = >::from_script_ref(key_type_id, k, world.clone())?; + let mut key = >::from_script_ref(key_type_id, key, world.clone())?; if ctxt.convert_to_0_indexed() { key.convert_to_0_indexed_key(); } - let value_type_id = s.element_type_id(world.clone())?.ok_or_else(|| { + let value_type_id = reference.element_type_id(world.clone())?.ok_or_else(|| { InteropError::unsupported_operation( - s.tail_type_id(world.clone()).unwrap_or_default(), - Some(Box::new(v.clone())), + reference.tail_type_id(world.clone()).unwrap_or_default(), + Some(Box::new(value.clone())), "Could not get element type id. Are you trying to insert elements into a type that's not a map?".to_owned(), ) })?; - let value = >::from_script_ref(value_type_id, v, world.clone())?; + let value = + >::from_script_ref(value_type_id, value, world.clone())?; - s.with_reflect_mut(world, |s| s.try_insert_boxed(key, value))? + reference.with_reflect_mut(world, |s| s.try_insert_boxed(key, value))? } /// Clears the container, if the reference is an appropriate container type. - fn clear(ctxt: FunctionCallContext, s: ReflectReference) -> Result<(), InteropError> { + /// Arguments: + /// * `ctxt`: The function call context. + /// * `reference`: The reference to clear. + /// Returns: + /// * `result`: Nothing if the reference was cleared + fn clear(ctxt: FunctionCallContext, reference: ReflectReference) -> Result<(), InteropError> { profiling::function_scope!("clear"); let world = ctxt.world()?; - s.with_reflect_mut(world, |s| s.try_clear())? + reference.with_reflect_mut(world, |s| s.try_clear())? } /// Retrieves the length of the reference, if the reference is an appropriate container type. - fn len(ctxt: FunctionCallContext, s: ReflectReference) -> Result, InteropError> { + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `reference`: The reference to get the length of. + /// Returns: + /// * `len`: The length of the reference, if the reference is a container. + fn len( + ctxt: FunctionCallContext, + reference: ReflectReference, + ) -> Result, InteropError> { profiling::function_scope!("len"); let world = ctxt.world()?; - s.len(world) + reference.len(world) } /// Removes the value at the specified key from the reference, if the reference is an appropriate container type. + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `reference`: The reference to remove the value from. + /// * `key`: The key to remove the value at. + /// Returns: + /// * `result`: The removed value if any fn remove( ctxt: FunctionCallContext, - s: ReflectReference, - k: ScriptValue, + reference: ReflectReference, + key: ScriptValue, ) -> Result { profiling::function_scope!("remove"); let world = ctxt.world()?; - let key_type_id = s.key_type_id(world.clone())?.ok_or_else(|| { + let key_type_id = reference.key_type_id(world.clone())?.ok_or_else(|| { InteropError::unsupported_operation( - s.tail_type_id(world.clone()).unwrap_or_default(), - Some(Box::new(k.clone())), + reference.tail_type_id(world.clone()).unwrap_or_default(), + Some(Box::new(key.clone())), "Could not get key type id. Are you trying to remove elements from a type that's not a map?".to_owned(), ) })?; - let mut key = >::from_script_ref(key_type_id, k, world.clone())?; + let mut key = >::from_script_ref(key_type_id, key, world.clone())?; if ctxt.convert_to_0_indexed() { key.convert_to_0_indexed_key(); } - let removed = s.with_reflect_mut(world.clone(), |s| s.try_remove_boxed(key))??; + let removed = reference.with_reflect_mut(world.clone(), |s| s.try_remove_boxed(key))??; match removed { Some(removed) => { let reference = { @@ -540,14 +782,22 @@ impl ReflectReference { /// Iterates over the reference, if the reference is an appropriate container type. /// /// Returns an "next" iterator function. + /// + /// The iterator function should be called until it returns `nil` to signal the end of the iteration. + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `reference`: The reference to iterate over. + /// Returns: + /// * `iter`: The iterator function. fn iter( ctxt: FunctionCallContext, - s: ReflectReference, + reference: ReflectReference, ) -> Result { profiling::function_scope!("iter"); let world = ctxt.world()?; - let mut len = s.len(world.clone())?.unwrap_or_default(); - let mut infinite_iter = s.into_iter_infinite(); + let mut len = reference.len(world.clone())?.unwrap_or_default(); + let mut infinite_iter = reference.into_iter_infinite(); let iter_function = move || { // world is not thread safe, we can't capture it in the closure // or it will also be non-thread safe @@ -569,13 +819,19 @@ impl ReflectReference { } /// Lists the functions available on the reference. + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `reference`: The reference to list the functions of. + /// Returns: + /// * `functions`: The functions available on the reference. fn functions( ctxt: FunctionCallContext, - s: ReflectReference, + reference: ReflectReference, ) -> Result>, InteropError> { profiling::function_scope!("functions"); let world = ctxt.world()?; - let type_id = s.tail_type_id(world.clone())?.or_fake_id(); + let type_id = reference.tail_type_id(world.clone())?.or_fake_id(); let functions = world .get_functions_on_type(type_id) .into_iter() @@ -589,97 +845,165 @@ impl ReflectReference { #[script_bindings( remote, bms_core_path = "bevy_mod_scripting_core", - name = "script_type_registration_functions" + name = "script_type_registration_functions", + core )] impl ScriptTypeRegistration { - fn type_name(s: Ref) -> String { + /// Retrieves the name of the type. + /// + /// Arguments: + /// * `registration`: The type registration. + /// Returns: + /// * `type_name`: The name of the type. + fn type_name(registration: Ref) -> String { profiling::function_scope!("type_name"); - s.type_name().to_string() + registration.type_name().to_string() } - fn short_name(s: Ref) -> String { + /// Retrieves the short name of the type. + /// The short name is a more human-readable version of the type name. + /// Arguments: + /// * `registration`: The type registration. + /// Returns: + /// * `short_name`: The short name of the + fn short_name(registration: Ref) -> String { profiling::function_scope!("short_name"); - s.short_name().to_string() + registration.short_name().to_string() } } #[script_bindings( remote, bms_core_path = "bevy_mod_scripting_core", - name = "script_component_registration_functions" + name = "script_component_registration_functions", + core )] impl ScriptComponentRegistration { - fn type_name(s: Ref) -> &'static str { + /// Retrieves the name of the type. + /// + /// Arguments: + /// * `registration`: The type registration. + /// Returns: + /// * `type_name`: The name of the type. + fn type_name(registration: Ref) -> &'static str { profiling::function_scope!("type_name"); - s.type_registration().type_name() + registration.type_registration().type_name() } - fn short_name(s: Ref) -> &'static str { + /// Retrieves the short name of the type. + /// The short name is a more human-readable version of the type name. + /// Arguments: + /// * `registration`: The type registration. + /// Returns: + /// * `short_name`: The short name of the + fn short_name(registration: Ref) -> &'static str { profiling::function_scope!("short_name"); - s.type_registration().short_name() + registration.type_registration().short_name() } } #[script_bindings( remote, bms_core_path = "bevy_mod_scripting_core", - name = "script_resource_registration_functions" + name = "script_resource_registration_functions", + core )] impl ScriptResourceRegistration { - fn type_name(s: Ref) -> &'static str { + /// Retrieves the name of the type. + /// + /// Arguments: + /// * `registration`: The type registration. + /// Returns: + /// * `type_name`: The name of the type. + fn type_name(registration: Ref) -> &'static str { profiling::function_scope!("type_name"); - s.type_registration().type_name() + registration.type_registration().type_name() } - fn short_name(s: Ref) -> &'static str { + /// Retrieves the short name of the type. + /// The short name is a more human-readable version of the type name. + /// Arguments: + /// * `registration`: The type registration. + /// Returns: + /// * `short_name`: The short name of the + fn short_name(registration: Ref) -> &'static str { profiling::function_scope!("short_name"); - s.type_registration().short_name() + registration.type_registration().short_name() } } #[script_bindings( remote, bms_core_path = "bevy_mod_scripting_core", - name = "script_query_builder_functions" + name = "script_query_builder_functions", + core )] impl ScriptQueryBuilder { + /// Adds a component to be retrieved by the query + /// + /// Arguments: + /// * `query`: The query to add the component to + /// * `component`: The component to add + /// Returns: + /// * `query`: The query with the component added fn component( - s: Val, + query: Val, components: Val, ) -> Val { profiling::function_scope!("component"); - let mut builder = s.into_inner(); + let mut builder = query.into_inner(); builder.component(components.into_inner()); Val(builder) } + /// Adds a component to filter the query by. This component will NOT be retrieved. + /// + /// Arguments: + /// * `query`: The query to add the component to + /// * `component`: The component to filter by + /// Returns: + /// * `query`: The query with the component added fn with( - s: Val, + query: Val, with: Val, ) -> Val { profiling::function_scope!("with"); - let mut builder = s.into_inner(); + let mut builder = query.into_inner(); builder.with_component(with.into_inner()); Val(builder) } + /// Adds a component to filter the query by. This component will NOT be retrieved. + /// + /// Arguments: + /// * `query`: The query to add the component to + /// * `component`: The component to filter by + /// Returns: + /// * `query`: The query with the component added fn without( - s: Val, + query: Val, without: Val, ) -> Val { profiling::function_scope!("without"); - let mut builder = s.into_inner(); + let mut builder = query.into_inner(); builder.without_component(without.into_inner()); Val(builder) } + /// Builds the query and retrieves the entities and component references. + /// + /// Arguments: + /// * `ctxt`: The function call context. + /// * `query`: The query to build. + /// Returns: + /// * `result`: The entities and component references that match the query. fn build( ctxt: FunctionCallContext, - s: Val, + query: Val, ) -> Result>, InteropError> { profiling::function_scope!("build"); let world = ctxt.world()?; - let builder = s.into_inner(); + let builder = query.into_inner(); let result = world.query(builder)?; let result = result.into_iter().map(Val).collect::>(); Ok(result) @@ -689,57 +1013,73 @@ impl ScriptQueryBuilder { #[script_bindings( remote, bms_core_path = "bevy_mod_scripting_core", - name = "script_query_result_functions" + name = "script_query_result_functions", + core )] impl ScriptQueryResult { - fn entity(s: Ref) -> Val { + /// Retrieves the entity from the query result. + /// + /// Arguments: + /// * `query`: The query result to retrieve the entity from. + /// Returns: + /// * `entity`: The entity from the query result. + fn entity(query: Ref) -> Val { profiling::function_scope!("entity"); - Val::new(s.entity) + Val::new(query.entity) } - fn components(s: Ref) -> Vec { + /// Retrieves the components from the query result. + /// + /// These are ordered by the order they were added to the query. + /// + /// Arguments: + /// * `query`: The query result to retrieve the components from. + /// Returns: + /// * `components`: The components from the query result. + fn components(query: Ref) -> Vec { profiling::function_scope!("components"); - s.components.to_vec() + query.components.to_vec() } } #[script_bindings( remote, bms_core_path = "bevy_mod_scripting_core", - name = "reflect_schedule_functions" + name = "reflect_schedule_functions", + core )] impl ReflectSchedule { /// Retrieves all the systems in the schedule. /// /// Arguments: - /// * `self_`: The schedule to retrieve the systems from. + /// * `schedule`: The schedule to retrieve the systems from. /// Returns: /// * `systems`: The systems in the schedule. fn systems( ctxt: FunctionCallContext, - self_: Ref, + schedule: Ref, ) -> Result>, InteropError> { profiling::function_scope!("systems"); let world = ctxt.world()?; - let systems = world.systems(&self_); + let systems = world.systems(&schedule); Ok(systems?.into_iter().map(Into::into).collect()) } /// Retrieves the system with the given name in the schedule /// /// Arguments: - /// * `self_`: The schedule to retrieve the system from. + /// * `schedule`: The schedule to retrieve the system from. /// * `name`: The identifier or full path of the system to retrieve. /// Returns: /// * `system`: The system with the given name, if it exists. fn get_system_by_name( ctxt: FunctionCallContext, - self_: Ref, + schedule: Ref, name: String, ) -> Result>, InteropError> { profiling::function_scope!("system_by_name"); let world = ctxt.world()?; - let system = world.systems(&self_)?; + let system = world.systems(&schedule)?; Ok(system .into_iter() .find_map(|s| (s.identifier() == name || s.path() == name).then_some(s.into()))) @@ -751,19 +1091,19 @@ impl ReflectSchedule { /// /// Arguments: /// * `ctxt`: The function call context - /// * `self_`: The schedule to render. + /// * `schedule`: The schedule to render. /// Returns: /// * `dot`: The dot graph string. fn render_dot( ctxt: FunctionCallContext, - self_: Ref, + schedule: Ref, ) -> Result { profiling::function_scope!("render_dot"); let world = ctxt.world()?; world.with_resource(|schedules: &Schedules| { let schedule = schedules - .get(*self_.label()) - .ok_or_else(|| InteropError::missing_schedule(self_.identifier()))?; + .get(*schedule.label()) + .ok_or_else(|| InteropError::missing_schedule(schedule.identifier()))?; let mut graph = bevy_system_reflection::schedule_to_reflect_graph(schedule); graph.absorb_type_system_sets(); graph.sort(); @@ -776,42 +1116,51 @@ impl ReflectSchedule { #[script_bindings( remote, bms_core_path = "bevy_mod_scripting_core", - name = "reflect_system_functions" + name = "reflect_system_functions", + core )] impl ReflectSystem { /// Retrieves the identifier of the system /// Arguments: - /// * `self_`: The system to retrieve the identifier from. + /// * `system`: The system to retrieve the identifier from. /// Returns: /// * `identifier`: The identifier of the system, e.g. `my_system` - fn identifier(self_: Ref) -> String { + fn identifier(system: Ref) -> String { profiling::function_scope!("identifier"); - self_.identifier().to_string() + system.identifier().to_string() } /// Retrieves the full path of the system /// Arguments: - /// * `self_`: The system to retrieve the path from. + /// * `system`: The system to retrieve the path from. /// Returns: /// * `path`: The full path of the system, e.g. `my_crate::systems::my_system` - fn path(self_: Ref) -> String { + fn path(system: Ref) -> String { profiling::function_scope!("path"); - self_.path().to_string() + system.path().to_string() } } #[script_bindings( remote, bms_core_path = "bevy_mod_scripting_core", - name = "script_system_builder_functions" + name = "script_system_builder_functions", + core )] impl ScriptSystemBuilder { + /// Adds a query to the system builder. + /// + /// Arguments: + /// * `builder`: The system builder to add the query to. + /// * `query`: The query to add. + /// Returns: + /// * `builder`: The system builder with the query added. fn query( - self_: Val, + builder: Val, query: Val, ) -> Result, InteropError> { profiling::function_scope!("query"); - let mut builder = self_.into_inner(); + let mut builder = builder.into_inner(); builder.query(query.into_inner()); Ok(builder.into()) } @@ -819,28 +1168,28 @@ impl ScriptSystemBuilder { /// Requests the system have access to the given resource. The resource will be added to the /// list of arguments of the callback in the order they're provided. /// Arguments: - /// * `self_`: The system builder to add the resource to. + /// * `builder`: The system builder to add the resource to. /// * `resource`: The resource to add. /// Returns: /// * `builder`: The system builder with the resource added. fn resource( - self_: Val, + builder: Val, resource: Val, ) -> Val { profiling::function_scope!("resource"); - let mut builder = self_.into_inner(); + let mut builder = builder.into_inner(); builder.resource(resource.into_inner()); builder.into() } /// Specifies the system is to run exclusively, meaning it can access anything, but will not run in parallel with other systems. /// Arguments: - /// * `self_`: The system builder to make exclusive. + /// * `builder`: The system builder to make exclusive. /// Returns: /// * `builder`: The system builder that is now exclusive. - fn exclusive(self_: Val) -> Val { + fn exclusive(builder: Val) -> Val { profiling::function_scope!("exclusive"); - let mut builder = self_.into_inner(); + let mut builder = builder.into_inner(); builder.exclusive(true); builder.into() } @@ -850,16 +1199,16 @@ impl ScriptSystemBuilder { /// Note: this is an experimental feature, and the ordering might not work correctly for script initialized systems /// /// Arguments: - /// * `self_`: The system builder to add the dependency to. + /// * `builder`: The system builder to add the dependency to. /// * `system`: The system to run after. /// Returns: /// * `builder`: The system builder with the dependency added. fn after( - self_: Val, + builder: Val, system: Val, ) -> Val { profiling::function_scope!("after"); - let mut builder = self_.into_inner(); + let mut builder = builder.into_inner(); builder.after_system(system.into_inner()); Val(builder) } @@ -869,16 +1218,16 @@ impl ScriptSystemBuilder { /// Note: this is an experimental feature, and the ordering might not work correctly for script initialized systems /// /// Arguments: - /// * `self_`: The system builder to add the dependency to. + /// * `builder`: The system builder to add the dependency to. /// * `system`: The system to run before. /// Returns: /// * `builder`: The system builder with the dependency added. fn before( - self_: Val, + builder: Val, system: Val, ) -> Val { profiling::function_scope!("before"); - let mut builder = self_.into_inner(); + let mut builder = builder.into_inner(); builder.before_system(system.into_inner()); Val(builder) } diff --git a/crates/lad_backends/mdbook_lad_preprocessor/src/argument_visitor.rs b/crates/lad_backends/mdbook_lad_preprocessor/src/argument_visitor.rs index 9186a48d99..c170687517 100644 --- a/crates/lad_backends/mdbook_lad_preprocessor/src/argument_visitor.rs +++ b/crates/lad_backends/mdbook_lad_preprocessor/src/argument_visitor.rs @@ -1,5 +1,7 @@ //! Defines a visitor for function arguments of the `LAD` format. +use std::path::PathBuf; + use ladfile::{ArgumentVisitor, LadTypeId}; use crate::markdown::MarkdownBuilder; @@ -7,7 +9,8 @@ use crate::markdown::MarkdownBuilder; pub(crate) struct MarkdownArgumentVisitor<'a> { ladfile: &'a ladfile::LadFile, buffer: MarkdownBuilder, - linkifier: Box Option + 'static>, + linkifier: Box Option + 'static>, + pub raw_type_id_replacement: Option<&'static str>, } impl<'a> MarkdownArgumentVisitor<'a> { /// Create a new instance of the visitor @@ -18,12 +21,13 @@ impl<'a> MarkdownArgumentVisitor<'a> { ladfile, buffer: builder, linkifier: Box::new(|_, _| None), + raw_type_id_replacement: None, } } /// Create a new instance of the visitor with a custom linkifier function pub fn new_with_linkifier< - F: Fn(LadTypeId, &'a ladfile::LadFile) -> Option + 'static, + F: Fn(LadTypeId, &'a ladfile::LadFile) -> Option + 'static, >( ladfile: &'a ladfile::LadFile, linkifier: F, @@ -33,6 +37,12 @@ impl<'a> MarkdownArgumentVisitor<'a> { without } + /// Set the raw type id replacement + pub fn with_raw_type_id_replacement(mut self, replacement: &'static str) -> Self { + self.raw_type_id_replacement = Some(replacement); + self + } + pub fn build(mut self) -> String { self.buffer.build() } @@ -43,15 +53,17 @@ impl ArgumentVisitor for MarkdownArgumentVisitor<'_> { // Write identifier let generics = self.ladfile.get_type_generics(type_id); - let type_identifier = self.ladfile.get_type_identifier(type_id); + let type_identifier = self + .ladfile + .get_type_identifier(type_id, self.raw_type_id_replacement); if let Some(generics) = generics { self.buffer.text(type_identifier); self.buffer.text('<'); for (i, generic) in generics.iter().enumerate() { - self.visit_lad_type_id(&generic.type_id); if i > 0 { self.buffer.text(", "); } + self.visit_lad_type_id(&generic.type_id); } self.buffer.text('>'); } else { @@ -59,6 +71,9 @@ impl ArgumentVisitor for MarkdownArgumentVisitor<'_> { let link_value = (self.linkifier)(type_id.clone(), self.ladfile); let link_display = type_identifier; if let Some(link_value) = link_value { + // canonicalize to linux paths + let link_value = link_value.to_string_lossy().to_string().replace("\\", "/"); + self.buffer.link(link_display, link_value); } else { self.buffer.text(link_display); @@ -139,12 +154,18 @@ mod test { let mut visitor = MarkdownArgumentVisitor::new_with_linkifier(&ladfile, |type_id, ladfile| { - Some(format!("root/{}", ladfile.get_type_identifier(&type_id))) + Some( + PathBuf::from("root\\asd") + .join(ladfile.get_type_identifier(&type_id, None).to_string()), + ) }); let first_type_id = ladfile.types.first().unwrap().0; visitor.visit_lad_type_id(first_type_id); - assert_eq!(visitor.buffer.build(), "[EnumType](root/EnumType)"); + assert_eq!( + visitor.buffer.build(), + "StructType<[usize](root/asd/usize)>" + ); } #[test] @@ -155,13 +176,13 @@ mod test { let mut visitor = MarkdownArgumentVisitor::new(&ladfile); visitor.visit_lad_type_id(first_type_id); - assert_eq!(visitor.buffer.build(), "EnumType"); + assert_eq!(visitor.buffer.build(), "StructType"); visitor.buffer.clear(); let second_type_id = ladfile.types.iter().nth(1).unwrap().0; visitor.visit_lad_type_id(second_type_id); - assert_eq!(visitor.buffer.build(), "StructType"); + assert_eq!(visitor.buffer.build(), "EnumType"); } #[test] @@ -172,7 +193,7 @@ mod test { let mut visitor = MarkdownArgumentVisitor::new(&ladfile); visitor.visit(&LadTypeKind::Ref(first_type_id.clone())); - assert_eq!(visitor.buffer.build(), "EnumType"); + assert_eq!(visitor.buffer.build(), "StructType"); } #[test] @@ -183,7 +204,7 @@ mod test { let mut visitor = MarkdownArgumentVisitor::new(&ladfile); visitor.visit(&LadTypeKind::Mut(first_type_id.clone())); - assert_eq!(visitor.buffer.build(), "EnumType"); + assert_eq!(visitor.buffer.build(), "StructType"); } #[test] @@ -194,7 +215,7 @@ mod test { let mut visitor = MarkdownArgumentVisitor::new(&ladfile); visitor.visit(&LadTypeKind::Val(first_type_id.clone())); - assert_eq!(visitor.buffer.build(), "EnumType"); + assert_eq!(visitor.buffer.build(), "StructType"); } #[test] @@ -254,7 +275,7 @@ mod test { )); assert_eq!( visitor.buffer.build(), - "HashMap" + "HashMap | StructType | StructType>" ); } @@ -293,6 +314,6 @@ mod test { let first_type_id = ladfile.types.first().unwrap().0; visitor.visit(&LadTypeKind::Unknown(first_type_id.clone())); - assert_eq!(visitor.buffer.build(), "EnumType"); + assert_eq!(visitor.buffer.build(), "StructType"); } } diff --git a/crates/lad_backends/mdbook_lad_preprocessor/src/lib.rs b/crates/lad_backends/mdbook_lad_preprocessor/src/lib.rs index 9912e05376..4304945d20 100644 --- a/crates/lad_backends/mdbook_lad_preprocessor/src/lib.rs +++ b/crates/lad_backends/mdbook_lad_preprocessor/src/lib.rs @@ -1,8 +1,11 @@ //! The library crate for the mdbook LAD preprocessor. #![allow(missing_docs)] -use mdbook::{errors::Error, preprocess::Preprocessor}; -use sections::Section; +use mdbook::{ + errors::Error, + preprocess::{Preprocessor, PreprocessorContext}, +}; +use sections::{Section, SectionData}; mod argument_visitor; mod markdown; mod sections; @@ -27,6 +30,7 @@ impl LADPreprocessor { /// `parent` is the optional parent chapter reference, /// and `chapter_index` is the index of the chapter among its siblings. fn process_lad_chapter( + _context: &PreprocessorContext, chapter: &mdbook::book::Chapter, parent: Option<&mdbook::book::Chapter>, chapter_index: usize, @@ -38,10 +42,19 @@ impl LADPreprocessor { "Parsed LAD file: {}", serde_json::to_string_pretty(&ladfile).unwrap_or_default() ); - let new_chapter = Section::Summary { - ladfile: &ladfile, - title: Some(chapter_title), - } + + let parent_path = parent + .and_then(|p| p.path.clone()) + .unwrap_or_default() + .with_extension(""); + + let new_chapter = Section::new( + parent_path, + &ladfile, + SectionData::Summary { + title: Some(chapter_title), + }, + ) .into_chapter(parent, chapter_index); log::debug!( "New chapter: {}", @@ -58,7 +71,7 @@ impl Preprocessor for LADPreprocessor { fn run( &self, - _ctx: &mdbook::preprocess::PreprocessorContext, + context: &mdbook::preprocess::PreprocessorContext, mut book: mdbook::book::Book, ) -> mdbook::errors::Result { let mut errors = Vec::new(); @@ -75,6 +88,7 @@ impl Preprocessor for LADPreprocessor { if let mdbook::BookItem::Chapter(chapter) = item { if LADPreprocessor::is_lad_file(chapter) { match LADPreprocessor::process_lad_chapter( + context, chapter, Some(parent), idx, @@ -106,8 +120,16 @@ impl Preprocessor for LADPreprocessor { if !LADPreprocessor::is_lad_file(chapter) { return; } - - let new_chapter = match LADPreprocessor::process_lad_chapter(chapter, None, 0) { + let new_chapter = match LADPreprocessor::process_lad_chapter( + context, + chapter, + None, + chapter + .number + .clone() + .and_then(|n| n.0.last().map(|v| (*v) as usize)) + .unwrap_or_default(), + ) { Ok(new_chapter) => new_chapter, Err(e) => { errors.push(e); diff --git a/crates/lad_backends/mdbook_lad_preprocessor/src/markdown.rs b/crates/lad_backends/mdbook_lad_preprocessor/src/markdown.rs index 68dba62c70..4b69ee1afc 100644 --- a/crates/lad_backends/mdbook_lad_preprocessor/src/markdown.rs +++ b/crates/lad_backends/mdbook_lad_preprocessor/src/markdown.rs @@ -1,9 +1,9 @@ use std::borrow::Cow; /// Takes the first n characters from the markdown, without splitting any formatting. -pub(crate) fn markdown_substring(markdown: &str, length: usize) -> &str { +pub(crate) fn markdown_substring(markdown: &str, length: usize) -> String { if markdown.len() <= length { - return markdown; + return markdown.to_string(); } let mut end = length; for &(open, close) in &[("`", "`"), ("**", "**"), ("*", "*"), ("_", "_"), ("[", "]")] { @@ -27,11 +27,14 @@ pub(crate) fn markdown_substring(markdown: &str, length: usize) -> &str { } } } else { - return markdown; + return markdown.to_string(); } } } - &markdown[..end] + + let trimmed = markdown[..end].to_string(); + // append ... + format!("{}...", trimmed) } /// Escapes Markdown reserved characters in the given text. @@ -53,17 +56,17 @@ fn escape_markdown(text: &str, escape: bool) -> String { } /// Trait for converting elements into markdown strings. -pub trait IntoMarkdown { +pub trait IntoMarkdown: std::fmt::Debug { fn to_markdown(&self, builder: &mut MarkdownBuilder); } /// Comprehensive enum representing various Markdown constructs. -#[derive(Debug, Clone)] #[allow(dead_code)] +#[derive(Debug)] pub enum Markdown { Heading { level: u8, - text: String, + content: Box, }, Paragraph { text: String, @@ -77,7 +80,7 @@ pub enum Markdown { }, List { ordered: bool, - items: Vec, + items: Vec>, }, Quote(String), Image { @@ -85,14 +88,14 @@ pub enum Markdown { src: String, }, Link { - text: String, + text: Box, url: String, anchor: bool, }, HorizontalRule, Table { headers: Vec, - rows: Vec>, + rows: Vec>>, }, Raw(String), } @@ -108,6 +111,15 @@ impl Markdown { } } + pub fn space() -> Self { + Markdown::Paragraph { + text: " ".to_owned(), + bold: false, + italic: false, + code: false, + } + } + pub fn bold(self) -> Self { match self { Markdown::Paragraph { text, .. } => Markdown::Paragraph { @@ -148,12 +160,15 @@ impl Markdown { impl IntoMarkdown for Markdown { fn to_markdown(&self, builder: &mut MarkdownBuilder) { match self { - Markdown::Heading { level, text } => { + Markdown::Heading { level, content } => { // Clamp the header level to Markdown's 1-6. let clamped_level = level.clamp(&1, &6); let hashes = "#".repeat(*clamped_level as usize); - // Escape the text for Markdown - builder.append(&format!("{hashes} {text}")); + builder.append(&hashes); + builder.append(" "); + builder.with_tight_inline(|builder| { + content.to_markdown(builder); + }); } Markdown::Paragraph { text, @@ -196,19 +211,24 @@ impl IntoMarkdown for Markdown { builder.append(&format!("```{}\n{}\n```", lang, code)); } Markdown::List { ordered, items } => { - let list_output = items - .iter() - .enumerate() - .map(|(i, item)| { - if *ordered { - format!("{}. {}", i + 1, item) - } else { - format!("- {}", item) - } - }) - .collect::>() - .join("\n"); - builder.append(&list_output); + items.iter().enumerate().for_each(|(i, item)| { + if *ordered { + builder.append(&(i + 1).to_string()); + builder.append(". "); + builder.with_tight_inline(|builder| { + item.to_markdown(builder); + }); + } else { + builder.append("- "); + builder.with_tight_inline(|builder| { + item.to_markdown(builder); + }); + } + + if i < items.len() - 1 { + builder.append("\n"); + } + }); } Markdown::Quote(text) => { let quote_output = text @@ -228,6 +248,10 @@ impl IntoMarkdown for Markdown { } Markdown::Link { text, url, anchor } => { // anchors must be lowercase, only contain letters or dashes + builder.append("["); + builder.with_tight_inline(|builder| text.to_markdown(builder)); + builder.append("]("); + let url = if *anchor { // prefix with # format!( @@ -237,14 +261,11 @@ impl IntoMarkdown for Markdown { .replace(|c: char| !c.is_alphabetic(), "") ) } else { - url.clone() + url.clone().replace("\\", "/") }; - // Escape link text while leaving url untouched. - builder.append(&format!( - "[{}]({})", - escape_markdown(text, builder.escape), - url - )); + + builder.append(&url); + builder.append(")"); } Markdown::HorizontalRule => { builder.append("---"); @@ -254,51 +275,63 @@ impl IntoMarkdown for Markdown { return; } - // Generate a Markdown table: - // Header row: let header_line = format!("| {} |", headers.join(" | ")); + builder.append(&header_line); + builder.append("\n"); + // Separator row: let separator_line = format!( - "|{}|", + "|{}|\n", headers .iter() .map(|_| " --- ") .collect::>() .join("|") ); - // Rows: - let rows_lines = rows - .iter() - .map(|row| format!("| {} |", row.join(" | "))) - .collect::>() - .join("\n"); - builder.append(&format!( - "{}\n{}\n{}", - header_line, separator_line, rows_lines - )); + builder.append(&separator_line); + + for (row_idx, row) in rows.iter().enumerate() { + builder.append("| "); + for (i, cell) in row.iter().enumerate() { + builder.with_tight_inline(|builder| { + cell.to_markdown(builder); + }); + if i < row.len() - 1 { + builder.append(" | "); + } + } + builder.append(" |"); + if row_idx < rows.len() - 1 { + builder.append("\n"); + } + } } Markdown::Raw(text) => { builder.append(text); } } + builder.separate(); } } impl IntoMarkdown for &str { fn to_markdown(&self, builder: &mut MarkdownBuilder) { - builder.append(&escape_markdown(self, builder.escape)) + builder.append(&escape_markdown(self, builder.escape)); + builder.separate(); } } impl IntoMarkdown for String { fn to_markdown(&self, builder: &mut MarkdownBuilder) { - builder.append(&escape_markdown(self.as_ref(), builder.escape)) + builder.append(&escape_markdown(self.as_ref(), builder.escape)); + builder.separate(); } } impl IntoMarkdown for Cow<'_, str> { fn to_markdown(&self, builder: &mut MarkdownBuilder) { - builder.append(&escape_markdown(self.as_ref(), builder.escape)) + builder.append(&escape_markdown(self.as_ref(), builder.escape)); + builder.separate(); } } @@ -321,27 +354,19 @@ macro_rules! markdown_vec { impl IntoMarkdown for Vec { fn to_markdown(&self, builder: &mut MarkdownBuilder) { - for (i, item) in self.iter().enumerate() { + for item in self.iter() { item.to_markdown(builder); - if i < self.len() - 1 { - if builder.inline { - builder.append(builder.inline_separator); - } else { - builder.append("\n\n"); - } - } } } } /// Builder pattern for generating comprehensive Markdown documentation. /// Now also doubles as the accumulator for the generated markdown. -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct MarkdownBuilder { - elements: Vec, output: String, pub inline: bool, - pub inline_separator: &'static str, + pub tight_inline: bool, pub escape: bool, } @@ -349,21 +374,46 @@ pub struct MarkdownBuilder { impl MarkdownBuilder { /// Clears the builder's buffer pub fn clear(&mut self) { - self.elements.clear(); self.output.clear(); } + pub fn with_tight_inline(&mut self, f: F) { + let prev_inline = self.inline; + let prev_tight_inline = self.tight_inline; + self.tight_inline(); + f(self); + self.inline = prev_inline; + self.tight_inline = prev_tight_inline; + } + /// Creates a new MarkdownBuilder. pub fn new() -> Self { MarkdownBuilder { - elements: Vec::new(), output: String::new(), inline: false, - inline_separator: " ", + tight_inline: false, escape: true, } } + // inserts the correct separator + // this should be used after each element is added + pub fn separate(&mut self) { + self.output.push_str(self.separator()); + } + + fn separator(&self) -> &'static str { + if self.inline { + if self.tight_inline { + "" + } else { + " " + } + } else { + "\n\n" + } + } + /// Disables or enables the automatic escaping of Markdown reserved characters. /// by default it is enabled. /// @@ -376,6 +426,14 @@ impl MarkdownBuilder { /// Enables inline mode, which prevents newlines from being inserted for elements that support it pub fn inline(&mut self) -> &mut Self { self.inline = true; + self.tight_inline = false; + self + } + + /// Disables inline mode. + pub fn non_inline(&mut self) -> &mut Self { + self.inline = false; + self.tight_inline = false; self } @@ -383,7 +441,7 @@ impl MarkdownBuilder { /// Each element will simply be concatenated without any separator. pub fn tight_inline(&mut self) -> &mut Self { self.inline = true; - self.inline_separator = ""; + self.tight_inline = true; self } @@ -399,49 +457,54 @@ impl MarkdownBuilder { } /// Adds a heading element (Levels from 1-6). - pub fn heading(&mut self, level: u8, text: impl IntoMarkdown) -> &mut Self { - let mut builder = MarkdownBuilder::new(); - builder.inline(); - text.to_markdown(&mut builder); - let text = builder.build(); - - self.elements.push(Markdown::Heading { + pub fn heading(&mut self, level: u8, text: impl IntoMarkdown + 'static) -> &mut Self { + Markdown::Heading { level: level.min(6), - text, - }); + content: Box::new(text), + } + .to_markdown(self); + self + } + + /// Adds a raw markdown element + pub fn raw(&mut self, text: impl Into) -> &mut Self { + self.append(&text.into()); self } /// Adds a paragraph element. pub fn text(&mut self, text: impl Into) -> &mut Self { - self.elements.push(Markdown::Paragraph { + Markdown::Paragraph { text: text.into(), bold: false, italic: false, code: false, - }); + } + .to_markdown(self); self } /// Adds a bold element. pub fn bold(&mut self, text: impl Into) -> &mut Self { - self.elements.push(Markdown::Paragraph { + Markdown::Paragraph { text: text.into(), bold: true, italic: false, code: false, - }); + } + .to_markdown(self); self } /// Adds an italic element. pub fn italic(&mut self, text: impl Into) -> &mut Self { - self.elements.push(Markdown::Paragraph { + Markdown::Paragraph { text: text.into(), bold: false, italic: true, code: false, - }); + } + .to_markdown(self); self } @@ -451,82 +514,86 @@ impl MarkdownBuilder { language: Option>, code: impl Into, ) -> &mut Self { - self.elements.push(Markdown::CodeBlock { + Markdown::CodeBlock { language: language.map(|l| l.into()), code: code.into(), - }); + } + .to_markdown(self); self } /// Adds an inline code element. pub fn inline_code(&mut self, code: impl Into) -> &mut Self { - self.elements.push(Markdown::Paragraph { + Markdown::Paragraph { text: code.into(), bold: false, italic: false, code: true, - }); + } + .to_markdown(self); self } /// Adds a list element. - pub fn list(&mut self, ordered: bool, items: Vec) -> &mut Self { - let converted_items: Vec = items - .into_iter() - .map(|s| { - let mut builder = MarkdownBuilder::new(); - builder.inline(); - s.to_markdown(&mut builder); - builder.build() - }) - .collect(); - - self.elements.push(Markdown::List { + pub fn list(&mut self, ordered: bool, items: Vec) -> &mut Self { + Markdown::List { ordered, - items: converted_items, - }); + items: items + .into_iter() + .map(|i| Box::new(i) as Box) + .collect(), + } + .to_markdown(self); self } /// Adds a quote element. pub fn quote(&mut self, text: impl IntoMarkdown) -> &mut Self { let mut builder = MarkdownBuilder::new(); + builder.tight_inline(); text.to_markdown(&mut builder); - self.elements.push(Markdown::Quote(builder.build())); + Markdown::Quote(builder.build()).to_markdown(self); self } /// Adds an image element. pub fn image(&mut self, alt: impl Into, src: impl Into) -> &mut Self { - self.elements.push(Markdown::Image { + Markdown::Image { alt: alt.into(), src: src.into(), - }); + } + .to_markdown(self); self } /// Adds a link element. - pub fn link(&mut self, text: impl Into, url: impl Into) -> &mut Self { - self.elements.push(Markdown::Link { - text: text.into(), + pub fn link(&mut self, text: impl IntoMarkdown + 'static, url: impl Into) -> &mut Self { + Markdown::Link { + text: Box::new(text), url: url.into(), anchor: false, - }); + } + .to_markdown(self); self } - pub fn section_link(&mut self, text: impl Into, url: impl Into) -> &mut Self { - self.elements.push(Markdown::Link { - text: text.into(), + pub fn section_link( + &mut self, + text: impl IntoMarkdown + 'static, + url: impl Into, + ) -> &mut Self { + Markdown::Link { + text: Box::new(text), url: url.into(), anchor: true, - }); + } + .to_markdown(self); self } /// Adds a horizontal rule element. pub fn horizontal_rule(&mut self) -> &mut Self { - self.elements.push(Markdown::HorizontalRule); + Markdown::HorizontalRule.to_markdown(self); self } @@ -534,38 +601,31 @@ impl MarkdownBuilder { pub fn table(&mut self, f: impl FnOnce(&mut TableBuilder)) -> &mut Self { let mut builder = TableBuilder::new(); f(&mut builder); - self.elements.push(builder.build()); + log::info!("Table Builder: {builder:#?}"); + builder.build().to_markdown(self); self } /// Builds the markdown document as a single String by delegating the conversion /// of each element to its `into_markdown` implementation. pub fn build(&mut self) -> String { - let len = self.elements.len(); - for (i, element) in self.elements.clone().into_iter().enumerate() { - element.to_markdown(self); - if i < len - 1 { - if self.inline { - self.append(self.inline_separator); - } else { - self.append("\n\n"); - } - } - } + // replace inline placeholders with the characters they represent, + // at the same time remove multiple consecutive placeholders self.output.clone() } } impl IntoMarkdown for MarkdownBuilder { fn to_markdown(&self, builder: &mut MarkdownBuilder) { - *builder = self.clone() + builder.append(&self.output); } } /// Mini builder for constructing Markdown tables. +#[derive(Debug)] pub struct TableBuilder { headers: Vec, - rows: Vec>, + rows: Vec>>, } impl TableBuilder { @@ -584,17 +644,12 @@ impl TableBuilder { } /// Adds a row to the table. - pub fn row(&mut self, row: Vec) -> &mut Self { - let converted = row - .into_iter() - .map(|r| { - let mut builder = MarkdownBuilder::new(); - builder.inline(); - r.to_markdown(&mut builder); - builder.build() - }) - .collect(); - self.rows.push(converted); + pub fn row(&mut self, row: Vec) -> &mut Self { + self.rows.push( + row.into_iter() + .map(|r| Box::new(r) as Box) + .collect(), + ); self } @@ -632,7 +687,9 @@ mod tests { true, Vec::from_iter(vec![markdown_vec![ Markdown::new_paragraph("italic").italic(), + Markdown::space(), Markdown::new_paragraph("bold").bold(), + Markdown::space(), Markdown::new_paragraph("code").code(), ]]), ) @@ -649,6 +706,14 @@ mod tests { .row(markdown_vec![ "Row 2 Col 1", Markdown::new_paragraph("HashMap").code() + ]) + .row(markdown_vec![ + "Hello", + Markdown::Link { + text: Box::new("iam a link"), + url: "to a thing".to_owned(), + anchor: false + } ]); }) .build(); @@ -679,6 +744,7 @@ mod tests { | --- | --- | | Row 1 Col 1 | Row 1 Col 2 | | Row 2 Col 1 | `HashMap` | + | Hello | [iam a link](to a thing) | "#; let trimmed_indentation_expected = expected @@ -703,15 +769,15 @@ mod tests { // Test markdown_substring with simple 5–7 character inputs. let cases = vec![ // Inline code: "a`bcd`" → with len 3, substring "a`b" is extended to the full inline segment. - ("a`bcd`", 3, "a`bcd`"), + ("a`bcd`", 3, "a`bcd`..."), // Bold: "a**b**" → with len 3, substring "a**" is extended to "a**b**". - ("a**b**", 3, "a**b**"), + ("a**b**", 3, "a**b**..."), // Italic: "a*b*" → with len 1, substring "["a*", extended to "a*b*". - ("a*b*", 1, "a*b*"), + ("a*b*", 1, "a*b*..."), // Underscore: "a_b_" → with len 1, extended to "a_b_". - ("a_b_", 1, "a_b_"), + ("a_b_", 1, "a_b_..."), // Link-like: "[x](y)" → with len 1, extended to the next closing bracket. - ("[x](y)", 1, "[x](y)"), + ("[x](y)", 1, "[x](y)..."), ]; for (input, len, expected) in cases { assert_eq!( diff --git a/crates/lad_backends/mdbook_lad_preprocessor/src/sections.rs b/crates/lad_backends/mdbook_lad_preprocessor/src/sections.rs index 7d83ae8947..aefa59e2db 100644 --- a/crates/lad_backends/mdbook_lad_preprocessor/src/sections.rs +++ b/crates/lad_backends/mdbook_lad_preprocessor/src/sections.rs @@ -1,14 +1,14 @@ use crate::{ argument_visitor::MarkdownArgumentVisitor, - markdown::{markdown_substring, IntoMarkdown, Markdown, MarkdownBuilder}, + markdown::{markdown_substring, IntoMarkdown, Markdown, MarkdownBuilder, TableBuilder}, markdown_vec, }; use ladfile::{ - ArgumentVisitor, LadArgument, LadFile, LadFunction, LadInstance, LadType, LadTypeId, - LadTypeLayout, + ArgumentVisitor, LadArgument, LadBMSPrimitiveKind, LadFile, LadFunction, LadInstance, LadType, + LadTypeId, LadTypeKind, LadTypeLayout, }; -use mdbook::book::Chapter; -use std::{borrow::Cow, collections::HashSet}; +use mdbook::book::{Chapter, SectionNumber}; +use std::{borrow::Cow, collections::HashSet, path::PathBuf}; fn print_type(ladfile: &LadFile, type_: &LadTypeId) -> String { let mut visitor = MarkdownArgumentVisitor::new(ladfile); @@ -16,6 +16,17 @@ fn print_type(ladfile: &LadFile, type_: &LadTypeId) -> String { visitor.build() } +fn print_type_with_replacement( + ladfile: &LadFile, + type_: &LadTypeId, + raw_type_id_replacement: &'static str, +) -> String { + let mut visitor = + MarkdownArgumentVisitor::new(ladfile).with_raw_type_id_replacement(raw_type_id_replacement); + visitor.visit_lad_type_id(type_); + visitor.build() +} + fn build_escaped_visitor(arg_visitor: MarkdownArgumentVisitor<'_>) -> String { arg_visitor .build() @@ -24,29 +35,35 @@ fn build_escaped_visitor(arg_visitor: MarkdownArgumentVisitor<'_>) -> String { .replace("|", "\\|") } -/// Sections which convert to single markdown files -pub(crate) enum Section<'a> { +#[derive(Debug)] +pub(crate) enum SectionData<'a> { Summary { - ladfile: &'a ladfile::LadFile, title: Option, }, /// A link directory to all the types within the ladfile - TypeSummary { ladfile: &'a ladfile::LadFile }, + TypeSummary, /// A link directory to all global functions within the ladfile - FunctionSummary { ladfile: &'a ladfile::LadFile }, + FunctionSummary, /// A link directory to all global instances within the ladfile - InstancesSummary { ladfile: &'a ladfile::LadFile }, + InstancesSummary, TypeDetail { lad_type_id: &'a LadTypeId, lad_type: &'a LadType, - ladfile: &'a ladfile::LadFile, }, FunctionDetail { function: &'a LadFunction, - ladfile: &'a ladfile::LadFile, }, } +/// Sections which convert to single markdown files +#[derive(Debug)] +pub(crate) struct Section<'a> { + /// The path to the parent we can use for absolute links + pub parent_path: PathBuf, + pub ladfile: &'a LadFile, + pub data: SectionData<'a>, +} + /// Makes a filename safe to put in links pub fn linkify_filename(name: impl Into) -> String { name.into() @@ -57,6 +74,14 @@ pub fn linkify_filename(name: impl Into) -> String { } impl<'a> Section<'a> { + pub(crate) fn new(parent_path: PathBuf, ladfile: &'a LadFile, data: SectionData<'a>) -> Self { + Self { + ladfile, + data, + parent_path, + } + } + /// convert into a chapter, including children pub(crate) fn into_chapter(self, parent: Option<&Chapter>, index: usize) -> Chapter { let mut builder = MarkdownBuilder::new(); @@ -68,15 +93,20 @@ impl<'a> Section<'a> { None => &default_chapter, }; - let parent_path = parent.path.clone().unwrap_or_default().with_extension(""); + let parent_path = self.parent_path.clone(); + let parent_source_path = parent .source_path .clone() .unwrap_or_default() .with_extension(""); - let mut current_number = parent.number.clone().unwrap_or_default(); - current_number.push(index as u32); + let current_number = if let Some(mut parent_number) = parent.number.clone() { + parent_number.push(index as u32); + parent_number + } else { + SectionNumber(vec![index as u32]) + }; let mut chapter = Chapter { name: self.title(), @@ -100,174 +130,237 @@ impl<'a> Section<'a> { } pub(crate) fn title(&self) -> String { - match self { - Section::Summary { title, .. } => { + match &self.data { + SectionData::Summary { title, .. } => { title.as_deref().unwrap_or("Bindings Summary").to_owned() } - Section::TypeSummary { .. } => "Types".to_owned(), - Section::FunctionSummary { .. } => "Functions".to_owned(), - Section::InstancesSummary { .. } => "Globals".to_owned(), - Section::TypeDetail { - ladfile, - lad_type_id, - .. - } => print_type(ladfile, lad_type_id), - Section::FunctionDetail { function, .. } => function.identifier.to_string(), + SectionData::TypeSummary { .. } => "Types".to_owned(), + SectionData::FunctionSummary { .. } => "Functions".to_owned(), + SectionData::InstancesSummary { .. } => "Globals".to_owned(), + SectionData::TypeDetail { lad_type_id, .. } => print_type(self.ladfile, lad_type_id), + SectionData::FunctionDetail { function, .. } => function.identifier.to_string(), } } + pub(crate) fn is_code_heading(&self) -> bool { + matches!( + self.data, + SectionData::TypeDetail { .. } | SectionData::FunctionDetail { .. } + ) + } + pub(crate) fn file_name(&self) -> String { linkify_filename(self.title()) + ".md" } pub(crate) fn children(&self) -> Vec> { - match self { - Section::Summary { ladfile, .. } => { + let child_parent_path = self + .parent_path + .join(linkify_filename(self.title())) + .with_extension(""); + + match self.data { + SectionData::Summary { .. } => { vec![ - Section::InstancesSummary { ladfile }, - Section::FunctionSummary { ladfile }, - Section::TypeSummary { ladfile }, + Section::new( + child_parent_path.clone(), + self.ladfile, + SectionData::InstancesSummary, + ), + Section::new( + child_parent_path.clone(), + self.ladfile, + SectionData::FunctionSummary, + ), + Section::new( + child_parent_path.clone(), + self.ladfile, + SectionData::TypeSummary, + ), ] } - Section::TypeSummary { ladfile } => ladfile + SectionData::TypeSummary => self + .ladfile .types .iter() - .map(|(lad_type_id, lad_type)| Section::TypeDetail { - lad_type, - ladfile, - lad_type_id, + .map(|(lad_type_id, lad_type)| { + Section::new( + child_parent_path.clone(), + self.ladfile, + SectionData::TypeDetail { + lad_type, + lad_type_id, + }, + ) }) .collect(), - Section::FunctionSummary { ladfile } => { - let associated_functions = ladfile + SectionData::FunctionSummary => { + let associated_functions = self + .ladfile .types .iter() .flat_map(|t| &t.1.associated_functions) .collect::>(); - let non_associated_functions = ladfile + let non_associated_functions = self + .ladfile .functions .iter() .filter_map(|f| (!associated_functions.contains(f.0)).then_some(f.1)); non_associated_functions - .map(|function| Section::FunctionDetail { function, ladfile }) + .map(|function| { + Section::new( + child_parent_path.clone(), + self.ladfile, + SectionData::FunctionDetail { function }, + ) + }) .collect() } - Section::InstancesSummary { .. } => { + SectionData::InstancesSummary { .. } => { vec![] } - Section::TypeDetail { - lad_type, ladfile, .. - } => lad_type + SectionData::TypeDetail { lad_type, .. } => lad_type .associated_functions .iter() .filter_map(|f| { - let function = ladfile.functions.get(f)?; - Some(Section::FunctionDetail { function, ladfile }) + let function = self.ladfile.functions.get(f)?; + Some(Section::new( + child_parent_path.clone(), + self.ladfile, + SectionData::FunctionDetail { function }, + )) }) .collect(), - Section::FunctionDetail { .. } => vec![], + SectionData::FunctionDetail { .. } => vec![], } } pub(crate) fn section_items(&self) -> Vec { - match self { - Section::Summary { .. } => { - let mut builder = MarkdownBuilder::new(); - builder.heading(1, self.title()); - builder.heading(2, "Contents"); - builder.text("This is an automatically generated file, you'll find links to the contents below"); - builder.table(|builder| { - builder.headers(vec!["Section", "Contents"]); - builder.row(markdown_vec![ - Markdown::new_paragraph("Types").code(), - Markdown::Link { - text: "Describes all available binding types".into(), - url: format!("./{}/types.md", linkify_filename(self.title())), - anchor: false - } - ]); - builder.row(markdown_vec![ - Markdown::new_paragraph("Global Functions").code(), - Markdown::Link { - text: "Documents all the global functions present in the bindings" - .into(), - url: format!("./{}/functions.md", linkify_filename(self.title())), - anchor: false - } - ]); - builder.row(markdown_vec![ - Markdown::new_paragraph("Globals").code(), - Markdown::Link { - text: "Documents all global variables present in the bindings".into(), - url: format!("./{}/globals.md", linkify_filename(self.title())), - anchor: false - } - ]); - }); + match self.data { + SectionData::Summary { .. } => { + let title = self.title().clone(); + vec![SectionItem::Markdown { - markdown: Box::new(builder), + markdown: Box::new(move |builder| { + builder.heading(2, "Contents"); + builder.text("This is an automatically generated file, you'll find links to the contents below"); + builder.table(|builder| { + builder.headers(vec!["Section", "Contents"]); + builder.row(markdown_vec![ + Markdown::new_paragraph("Types").code(), + Markdown::Link { + text: Box::new("Describes all available binding types"), + url: format!("./{}/types.md", linkify_filename(title.clone())), + anchor: false + } + ]); + builder.row(markdown_vec![ + Markdown::new_paragraph("Global Functions").code(), + Markdown::Link { + text: + Box::new("Documents all the global functions present in the bindings"), + url: format!( + "./{}/functions.md", + linkify_filename(title.clone()) + ), + anchor: false + } + ]); + builder.row(markdown_vec![ + Markdown::new_paragraph("Globals").code(), + Markdown::Link { + text: Box::new("Documents all global variables present in the bindings"), + url: format!( + "./{}/globals.md", + linkify_filename(title.clone()) + ), + anchor: false + } + ]); + }); + }), }] } - Section::InstancesSummary { ladfile } => { - let instances = ladfile.globals.iter().collect::>(); - let types_directory = linkify_filename(Section::TypeSummary { ladfile }.title()); + SectionData::InstancesSummary => { + let instances = self.ladfile.globals.iter().collect::>(); + let types_directory = PathBuf::from("/").join(self.parent_path.join("types")); vec![SectionItem::InstancesSummary { instances, - ladfile, + ladfile: self.ladfile, types_directory, }] } - Section::TypeSummary { ladfile } => { - let types = ladfile.types.keys().collect::>(); + SectionData::TypeSummary => { + let types = self.ladfile.types.keys().collect::>(); vec![SectionItem::TypesSummary { types, - types_directory: linkify_filename(self.title()), - ladfile, + types_directory: self + .parent_path + .join(linkify_filename(self.title())) + .to_string_lossy() + .to_string(), + ladfile: self.ladfile, }] } - Section::FunctionSummary { ladfile } => { - let associated_functions = ladfile + SectionData::FunctionSummary => { + let associated_functions = self + .ladfile .types .iter() .flat_map(|t| &t.1.associated_functions) .collect::>(); - let non_associated_functions = ladfile + let non_associated_functions = self + .ladfile .functions .iter() .filter_map(|f| (!associated_functions.contains(f.0)).then_some(f.1)) .collect(); - - vec![SectionItem::FunctionsSummary { - functions: non_associated_functions, - functions_directory: "functions".to_owned(), - }] + vec![ + SectionItem::Markdown { + markdown: Box::new(|builder| { + builder.heading(2, "Non-Associated Functions"); + builder.text("Global functions that are not associated with any type and callable from anywhere in the script."); + }), + }, + SectionItem::FunctionsSummary { + functions: non_associated_functions, + functions_directory: "functions".to_owned(), + }, + ] } - Section::TypeDetail { - lad_type, ladfile, .. - } => { + SectionData::TypeDetail { lad_type, .. } => { let functions = lad_type .associated_functions .iter() - .filter_map(|i| ladfile.functions.get(i)) + .filter_map(|i| self.ladfile.functions.get(i)) .collect::>(); - vec![ SectionItem::Layout { layout: &lad_type.layout, }, SectionItem::Description { lad_type }, + SectionItem::Markdown { + markdown: Box::new(|builder| { + builder.heading(2, "Associated Functions"); + }), + }, SectionItem::FunctionsSummary { functions, functions_directory: linkify_filename(self.title()), }, ] } - Section::FunctionDetail { function, ladfile } => { - vec![SectionItem::FunctionDetails { function, ladfile }] + SectionData::FunctionDetail { function } => { + let types_directory = self.parent_path.join("../types"); + vec![SectionItem::FunctionDetails { + function, + ladfile: self.ladfile, + types_directory, + }] } } } @@ -275,7 +368,11 @@ impl<'a> Section<'a> { impl IntoMarkdown for Section<'_> { fn to_markdown(&self, builder: &mut MarkdownBuilder) { - builder.heading(1, self.title()); + if self.is_code_heading() { + builder.heading(1, Markdown::new_paragraph(self.title()).code()); + } else { + builder.heading(1, self.title()); + } for item in self.section_items() { item.to_markdown(builder); @@ -288,7 +385,7 @@ const NO_DOCS_STRING: &str = "No Documentation 🚧"; /// Items which combine markdown elements to build a section pub enum SectionItem<'a> { Markdown { - markdown: Box, + markdown: Box, }, Layout { layout: &'a LadTypeLayout, @@ -303,6 +400,7 @@ pub enum SectionItem<'a> { FunctionDetails { function: &'a LadFunction, ladfile: &'a ladfile::LadFile, + types_directory: PathBuf, }, TypesSummary { types: Vec<&'a LadTypeId>, @@ -312,14 +410,28 @@ pub enum SectionItem<'a> { InstancesSummary { ladfile: &'a ladfile::LadFile, instances: Vec<(&'a Cow<'static, str>, &'a LadInstance)>, - types_directory: String, + types_directory: PathBuf, }, } +impl std::fmt::Debug for SectionItem<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(match self { + SectionItem::Markdown { .. } => "Markdown", + SectionItem::Layout { .. } => "Layout", + SectionItem::Description { .. } => "Description", + SectionItem::FunctionsSummary { .. } => "FunctionsSummary", + SectionItem::FunctionDetails { .. } => "FunctionDetails", + SectionItem::TypesSummary { .. } => "TypesSummary", + SectionItem::InstancesSummary { .. } => "InstancesSummary", + }) + } +} + impl IntoMarkdown for SectionItem<'_> { fn to_markdown(&self, builder: &mut MarkdownBuilder) { match self { - SectionItem::Markdown { markdown } => markdown.to_markdown(builder), + SectionItem::Markdown { markdown } => (markdown)(builder), SectionItem::Layout { layout } => { // process the variants here let opaque = layout.for_each_variant( @@ -374,41 +486,28 @@ impl IntoMarkdown for SectionItem<'_> { functions, functions_directory: functions_path, } => { - builder.heading(2, "Functions"); + builder.text("For function details and documentation, click on the function link."); // make a table of functions as a quick reference, make them link to function details sub-sections builder.table(|builder| { builder.headers(vec!["Function", "Summary"]); for function in functions.iter() { - let mut first_col = function.identifier.to_string(); - first_col.push('('); - for (idx, arg) in function.arguments.iter().enumerate() { - first_col.push_str( - &arg.name - .as_ref() - .cloned() - .unwrap_or_else(|| Cow::Owned(format!("arg{}", idx))), - ); - if idx != function.arguments.len() - 1 { - first_col.push_str(", "); - } - } - first_col.push(')'); + let first_col = function.identifier.to_string(); // first line with content from documentation trimmed to 100 chars let second_col = function .documentation .as_deref() .map(|doc| markdown_substring(doc, 100)) - .unwrap_or_else(|| NO_DOCS_STRING); + .unwrap_or_else(|| NO_DOCS_STRING.to_string()); builder.row(markdown_vec![ - Markdown::new_paragraph(first_col).code(), Markdown::Link { - text: second_col.to_owned().replace("\n", " "), + text: Box::new(first_col), url: format!("./{}/{}.md", functions_path, function.identifier), anchor: false - } + }, + Markdown::new_paragraph(second_col.to_string().replace("\n", " ")), ]); } }); @@ -418,31 +517,37 @@ impl IntoMarkdown for SectionItem<'_> { types_directory, ladfile, } => { - builder.heading(2, "Types"); + builder.heading(2, "Available Types"); + builder.text("All registered reflect-able types which can be constructed and directly manipulated by scripts."); // make a table of types as a quick reference, make them link to type details sub-sections builder.table(|builder| { builder.headers(vec!["Type", "Summary"]); for type_ in types.iter() { - let printed_type = print_type(ladfile, type_); + let printed_type_for_url = print_type(ladfile, type_); + let printed_type_pretty = + print_type_with_replacement(ladfile, type_, "Unknown"); let documentation = ladfile.get_type_documentation(type_); // first line with content from documentation trimmed to 100 chars let second_col = documentation .map(|doc| markdown_substring(doc, 100)) - .unwrap_or_else(|| NO_DOCS_STRING); + .unwrap_or_else(|| NO_DOCS_STRING.to_string()); + + let mut link_builder = MarkdownBuilder::new(); + link_builder.tight_inline(); + link_builder.link( + Markdown::new_paragraph(printed_type_pretty).code(), + format!( + "/{types_directory}/{}.md", + linkify_filename(printed_type_for_url) + ), + ); builder.row(markdown_vec![ - Markdown::new_paragraph(printed_type.clone()).code(), - Markdown::Link { - text: second_col.to_owned().replace("\n", " "), - url: format!( - "./{types_directory}/{}.md", - linkify_filename(printed_type) - ), - anchor: false - } + link_builder, + Markdown::new_paragraph(second_col.replace("\n", " ")), ]); } }); @@ -467,7 +572,7 @@ impl IntoMarkdown for SectionItem<'_> { move |lad_type_id, ladfile| { let printed_type = linkify_filename(print_type(ladfile, &lad_type_id)); - Some(format!("./{types_directory}/{printed_type}.md")) + Some(types_directory.join(printed_type).with_extension("md")) }, ); arg_visitor.visit(&v.type_kind); @@ -500,7 +605,29 @@ impl IntoMarkdown for SectionItem<'_> { } }); } - SectionItem::FunctionDetails { function, ladfile } => { + SectionItem::FunctionDetails { + function, + ladfile, + types_directory, + } => { + // if the function takes in a FunctionCallContext argument, we notify that it's an impure function + // which potentially tries to access anything in the world + if function.arguments.iter().any(|a| { + matches!( + a.kind, + LadTypeKind::Primitive(LadBMSPrimitiveKind::FunctionCallContext) + ) + }) { + builder.raw( + r#" +
+ This function is impure, it might potentially try to access anything in the world. + If you are using it in the context of a script system, it might cause access errors. +
+ "#.trim(), + ); + } + // we don't escape this, this is already markdown builder.quote(Markdown::Raw( function @@ -511,50 +638,74 @@ impl IntoMarkdown for SectionItem<'_> { )); builder.heading(4, "Arguments"); - builder.list( - false, - function - .arguments - .iter() - .enumerate() - .map(|(idx, arg)| lad_argument_to_list_elem(idx, arg, ladfile)) - .collect(), - ); + let headers = vec!["Name", "Type", "Documentation"]; + builder.table(|builder| { + builder.headers(headers.clone()); + for (idx, arg) in function.arguments.iter().enumerate() { + build_lad_function_argument_row( + idx, + arg, + ladfile, + types_directory.clone(), + builder, + ); + } + }); builder.heading(4, "Returns"); - builder.list( - false, - vec![lad_argument_to_list_elem(0, &function.return_type, ladfile)], - ); + builder.table(|builder| { + builder.headers(headers.clone()); + build_lad_function_argument_row( + 0, + &function.return_type, + ladfile, + types_directory.clone(), + builder, + ) + }); } } } } -fn lad_argument_to_list_elem( +fn build_lad_function_argument_row( idx: usize, arg: &LadArgument, ladfile: &LadFile, -) -> impl IntoMarkdown { - let mut arg_visitor = MarkdownArgumentVisitor::new(ladfile); + types_directory: PathBuf, + builder: &mut TableBuilder, +) { + // we exclude function call context as it's not something scripts pass down + if matches!( + arg.kind, + LadTypeKind::Primitive(LadBMSPrimitiveKind::FunctionCallContext) + ) { + return; + } + + let types_directory = types_directory.to_owned(); + let mut arg_visitor = + MarkdownArgumentVisitor::new_with_linkifier(ladfile, move |lad_type_id, ladfile| { + let printed_type = linkify_filename(print_type(ladfile, &lad_type_id)); + Some(types_directory.join(printed_type).with_extension("md")) + }); arg_visitor.visit(&arg.kind); - let markdown = arg_visitor.build(); + let markdown = build_escaped_visitor(arg_visitor); let arg_name = arg .name .as_ref() .cloned() .unwrap_or_else(|| Cow::Owned(format!("arg{}", idx))); - markdown_vec![ + + builder.row(markdown_vec![ Markdown::new_paragraph(arg_name).bold(), - Markdown::new_paragraph(":"), - Markdown::new_paragraph(markdown).code(), - Markdown::new_paragraph("-"), + Markdown::Raw(markdown), Markdown::Raw( arg.documentation .as_deref() .unwrap_or(NO_DOCS_STRING) .to_owned() ) - ] + ]); } diff --git a/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad.md b/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad.md index b6b45e41d8..8cad7280a5 100644 --- a/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad.md +++ b/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad.md @@ -8,4 +8,5 @@ This is an automatically generated file, you'll find links to the contents below | --- | --- | | `Types` | [Describes all available binding types](./lad/types.md) | | `Global Functions` | [Documents all the global functions present in the bindings](./lad/functions.md) | -| `Globals` | [Documents all global variables present in the bindings](./lad/globals.md) | \ No newline at end of file +| `Globals` | [Documents all global variables present in the bindings](./lad/globals.md) | + diff --git a/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad/functions.md b/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad/functions.md index 547b97b243..da21640c96 100644 --- a/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad/functions.md +++ b/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad/functions.md @@ -1,7 +1,12 @@ # Functions -## Functions +## Non\-Associated Functions + +Global functions that are not associated with any type and callable from anywhere in the script\. + +For function details and documentation, click on the function link\. | Function | Summary | | --- | --- | -| `hello_world(arg1)` | [No Documentation 🚧](./functions/hello_world.md) | \ No newline at end of file +| [hello\_world](./functions/hello_world.md) | No Documentation 🚧 | + diff --git a/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad/functions/hello_world.md b/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad/functions/hello_world.md index 0d692dfbd3..47ce0b7268 100644 --- a/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad/functions/hello_world.md +++ b/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad/functions/hello_world.md @@ -1,11 +1,16 @@ -# hello\_world +# `hello_world` > No Documentation 🚧 #### Arguments -- **arg1** : `usize` \- No Documentation 🚧 +| Name | Type | Documentation | +| --- | --- | --- | +| **arg1** | [usize](parent/lad/functions/../types/usize.md) | No Documentation 🚧 | #### Returns -- **arg0** : `usize` \- No Documentation 🚧 \ No newline at end of file +| Name | Type | Documentation | +| --- | --- | --- | +| **arg0** | [usize](parent/lad/functions/../types/usize.md) | No Documentation 🚧 | + diff --git a/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad/globals.md b/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad/globals.md index d27fb52df9..55e506f43d 100644 --- a/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad/globals.md +++ b/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad/globals.md @@ -10,8 +10,8 @@ Instances containing actual accessible values\. | Instance | Type | | --- | --- | -| `my_non_static_instance` | Vec\<[UnitType](./types/unittype.md)\> | -| `map` | HashMap\<[String](./types/string.md), [String](./types/string.md) \| [String](./types/string.md)\> | +| `my_non_static_instance` | Vec\<[UnitType](/parent/lad/types/unittype.md)\> | +| `map` | HashMap\<[String](/parent/lad/types/string.md), [String](/parent/lad/types/string.md) \| [String](/parent/lad/types/string.md)\> | ### Static Instances @@ -19,4 +19,5 @@ Static type references, existing for the purpose of typed static function calls\ | Instance | Type | | --- | --- | -| `my_static_instance` | StructType\<[usize](./types/usize.md)\> | \ No newline at end of file +| `my_static_instance` | StructType\<[usize](/parent/lad/types/usize.md)\> | + diff --git a/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad/types.md b/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad/types.md index a591a784da..67240fe834 100644 --- a/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad/types.md +++ b/crates/lad_backends/mdbook_lad_preprocessor/tests/books/example_ladfile/expected/parent/lad/types.md @@ -1,10 +1,13 @@ # Types -## Types +## Available Types + +All registered reflect\-able types which can be constructed and directly manipulated by scripts\. | Type | Summary | | --- | --- | -| `EnumType` | [No Documentation 🚧](./types/enumtype.md) | -| `StructType` | [ I am a struct](./types/structtypeusize.md) | -| `TupleStructType` | [ I am a tuple test type](./types/tuplestructtype.md) | -| `UnitType` | [ I am a unit test type](./types/unittype.md) | \ No newline at end of file +| [`StructType`](/parent/lad/types/structtypeusize.md) | I am a struct | +| [`EnumType`](/parent/lad/types/enumtype.md) | No Documentation 🚧 | +| [`TupleStructType`](/parent/lad/types/tuplestructtype.md) | I am a tuple test type | +| [`UnitType`](/parent/lad/types/unittype.md) | I am a unit test type | + diff --git a/crates/ladfile/src/lib.rs b/crates/ladfile/src/lib.rs index 55ec97de25..93ad7518b6 100644 --- a/crates/ladfile/src/lib.rs +++ b/crates/ladfile/src/lib.rs @@ -52,7 +52,11 @@ impl LadFile { } /// Retrieves the best type identifier suitable for a type id. - pub fn get_type_identifier(&self, type_id: &LadTypeId) -> Cow<'static, str> { + pub fn get_type_identifier( + &self, + type_id: &LadTypeId, + raw_type_id_replacement: Option<&'static str>, + ) -> Cow<'static, str> { if let Some(primitive) = self.primitives.get(type_id) { return primitive.kind.lad_type_id().to_string().into(); } @@ -60,7 +64,13 @@ impl LadFile { self.types .get(type_id) .map(|t| t.identifier.clone().into()) - .unwrap_or_else(|| type_id.0.clone()) + .unwrap_or_else(|| { + if let Some(replacement) = raw_type_id_replacement { + replacement.into() + } else { + type_id.0.clone() + } + }) } /// Retrieves the generics of a type id if it is a generic type. @@ -441,8 +451,32 @@ pub struct LadType { /// The layout or kind of the type. pub layout: LadTypeLayout, + + /// If a type is marked as auto generated. Auto generated types might be treated differently by + /// backends which generate documentation or other files. For example they might be hidden or put in a separate section. + #[serde(default)] + pub generated: bool, + + /// An "importance" value. By default all types get a value of 1000. + /// A lower insignificance means the type is more important. + /// + /// Backends can use this value to determine the order in which types are displayed. + #[serde(default = "default_importance")] + pub insignificance: usize, } +/// The default importance value for a type. +pub fn default_importance() -> usize { + 1000 +} + +// /// A type importance value. +// pub struct Importance(pub usize) + +// impl Default for Importance { + +// } + #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] #[serde(untagged)] /// Description of a type layout in a LAD file. diff --git a/crates/ladfile/test_assets/test.lad.json b/crates/ladfile/test_assets/test.lad.json index 2b8686d392..10765db1e4 100644 --- a/crates/ladfile/test_assets/test.lad.json +++ b/crates/ladfile/test_assets/test.lad.json @@ -37,6 +37,37 @@ } }, "types": { + "ladfile_builder::test::StructType": { + "identifier": "StructType", + "crate": "ladfile_builder", + "path": "ladfile_builder::test::StructType", + "generics": [ + { + "type_id": "usize", + "name": "T" + } + ], + "documentation": " I am a struct", + "associated_functions": [ + "ladfile_builder::test::StructType::hello_world" + ], + "layout": { + "kind": "Struct", + "name": "StructType", + "fields": [ + { + "name": "field", + "type": "usize" + }, + { + "name": "field2", + "type": "usize" + } + ] + }, + "generated": false, + "insignificance": 1000 + }, "ladfile_builder::test::EnumType": { "identifier": "EnumType", "crate": "ladfile_builder", @@ -68,36 +99,9 @@ } ] } - ] - }, - "ladfile_builder::test::StructType": { - "identifier": "StructType", - "crate": "ladfile_builder", - "path": "ladfile_builder::test::StructType", - "generics": [ - { - "type_id": "usize", - "name": "T" - } ], - "documentation": " I am a struct", - "associated_functions": [ - "ladfile_builder::test::StructType::hello_world" - ], - "layout": { - "kind": "Struct", - "name": "StructType", - "fields": [ - { - "name": "field", - "type": "usize" - }, - { - "name": "field2", - "type": "usize" - } - ] - } + "generated": false, + "insignificance": 1000 }, "ladfile_builder::test::TupleStructType": { "identifier": "TupleStructType", @@ -115,7 +119,9 @@ "type": "String" } ] - } + }, + "generated": false, + "insignificance": 1000 }, "ladfile_builder::test::UnitType": { "identifier": "UnitType", @@ -125,7 +131,9 @@ "layout": { "kind": "Struct", "name": "UnitType" - } + }, + "generated": false, + "insignificance": 1000 } }, "functions": { diff --git a/crates/ladfile_builder/src/lib.rs b/crates/ladfile_builder/src/lib.rs index 9f0693fb3d..7c32b4d8b6 100644 --- a/crates/ladfile_builder/src/lib.rs +++ b/crates/ladfile_builder/src/lib.rs @@ -1,6 +1,7 @@ //! Parsing definitions for the LAD (Language Agnostic Decleration) file format. pub mod plugin; +use bevy::{ecs::world::World, utils::HashSet}; use bevy_mod_scripting_core::{ bindings::{ function::{ @@ -70,17 +71,24 @@ pub struct LadFileBuilder<'t> { type_id_mapping: HashMap, type_registry: &'t TypeRegistry, sorted: bool, + exclude_types_involving_unregistered_types: bool, } impl<'t> LadFileBuilder<'t> { - /// Create a new LAD file builder loaded with primitives. - pub fn new(type_registry: &'t TypeRegistry) -> Self { - let mut builder = Self { + /// Create a new LAD file builder without default primitives. + pub fn new_empty(type_registry: &'t TypeRegistry) -> Self { + Self { file: LadFile::new(), type_id_mapping: HashMap::new(), type_registry, sorted: false, - }; + exclude_types_involving_unregistered_types: false, + } + } + + /// Create a new LAD file builder loaded with primitives. + pub fn new(type_registry: &'t TypeRegistry) -> Self { + let mut builder = Self::new_empty(type_registry); builder .add_bms_primitive::("A boolean value") @@ -111,6 +119,13 @@ impl<'t> LadFileBuilder<'t> { builder } + /// Set whether types involving unregistered types should be excluded. + /// I.e. `HashMap` with T or V not being registered will be excluded. + pub fn set_exclude_including_unregistered(&mut self, exclude: bool) -> &mut Self { + self.exclude_types_involving_unregistered_types = exclude; + self + } + /// Set whether the LAD file should be sorted at build time. pub fn set_sorted(&mut self, sorted: bool) -> &mut Self { self.sorted = sorted; @@ -138,6 +153,24 @@ impl<'t> LadFileBuilder<'t> { self } + /// Mark a type as generated. + pub fn mark_generated(&mut self, type_id: TypeId) -> &mut Self { + let type_id = self.lad_id_from_type_id(type_id); + if let Some(t) = self.file.types.get_mut(&type_id) { + t.generated = true; + } + self + } + + /// Set the insignificance value of a type. + pub fn set_insignificance(&mut self, type_id: TypeId, importance: usize) -> &mut Self { + let type_id = self.lad_id_from_type_id(type_id); + if let Some(t) = self.file.types.get_mut(&type_id) { + t.insignificance = importance; + } + self + } + /// Add a global instance to the LAD file. /// /// Requires the type to be registered via [`Self::add_type`] or [`Self::add_type_info`] first to provide rich type information. @@ -181,6 +214,54 @@ impl<'t> LadFileBuilder<'t> { self } + /// Adds a global instance to the LAD file with a custom lad type kind. + pub fn add_instance_manually( + &mut self, + key: impl Into>, + is_static: bool, + type_kind: LadTypeKind, + ) -> &mut Self { + self.file.globals.insert( + key.into(), + LadInstance { + type_kind, + is_static, + }, + ); + self + } + + /// Adds a type which does not implement reflect to the list of types. + pub fn add_nonreflect_type( + &mut self, + crate_: Option<&str>, + documentation: &str, + ) -> &mut Self { + let path = std::any::type_name::().to_string(); + let identifier = path + .split("::") + .last() + .map(|o| o.to_owned()) + .unwrap_or_else(|| path.clone()); + + let lad_type_id = self.lad_id_from_type_id(std::any::TypeId::of::()); + self.file.types.insert( + lad_type_id, + LadType { + identifier, + crate_: crate_.map(|s| s.to_owned()), + path, + generics: vec![], + documentation: Some(documentation.trim().to_owned()), + associated_functions: vec![], + layout: LadTypeLayout::Opaque, + generated: false, + insignificance: default_importance(), + }, + ); + self + } + /// Add a type definition to the LAD file. /// /// Equivalent to calling [`Self::add_type_info`] with `T::type_info()`. @@ -215,6 +296,8 @@ impl<'t> LadFileBuilder<'t> { .map(|s| s.to_owned()), path: type_info.type_path_table().path().to_owned(), layout: self.lad_layout_from_type_info(type_info), + generated: false, + insignificance: default_importance(), }; self.file.types.insert(type_id, lad_type); self @@ -293,13 +376,53 @@ impl<'t> LadFileBuilder<'t> { self } + fn has_unknowns(&self, type_id: TypeId) -> bool { + if primitive_from_type_id(type_id).is_some() { + return false; + } + + let type_info = match self.type_registry.get_type_info(type_id) { + Some(info) => info, + None => return true, + }; + let inner_type_ids: Vec<_> = match type_info { + TypeInfo::Struct(struct_info) => { + struct_info.generics().iter().map(|g| g.type_id()).collect() + } + TypeInfo::TupleStruct(tuple_struct_info) => tuple_struct_info + .generics() + .iter() + .map(|g| g.type_id()) + .collect(), + TypeInfo::Tuple(tuple_info) => { + tuple_info.generics().iter().map(|g| g.type_id()).collect() + } + TypeInfo::List(list_info) => vec![list_info.item_ty().id()], + TypeInfo::Array(array_info) => vec![array_info.item_ty().id()], + TypeInfo::Map(map_info) => vec![map_info.key_ty().id(), map_info.value_ty().id()], + TypeInfo::Set(set_info) => vec![set_info.value_ty().id()], + TypeInfo::Enum(enum_info) => enum_info.generics().iter().map(|g| g.type_id()).collect(), + TypeInfo::Opaque(_) => vec![], + }; + + inner_type_ids.iter().any(|id| self.has_unknowns(*id)) + } + /// Build the finalized and optimized LAD file. pub fn build(&mut self) -> LadFile { let mut file = std::mem::replace(&mut self.file, LadFile::new()); - if self.sorted { - file.types.sort_keys(); - file.functions.sort_keys(); - file.primitives.sort_keys(); + + if self.exclude_types_involving_unregistered_types { + let mut to_remove = HashSet::new(); + for reg in self.type_registry.iter() { + let type_id = reg.type_id(); + if self.has_unknowns(type_id) { + to_remove.insert(self.lad_id_from_type_id(type_id)); + } + } + + // remove those type ids + file.types.retain(|id, _| !to_remove.contains(id)); } // associate functions on type namespaces with their types @@ -314,6 +437,39 @@ impl<'t> LadFileBuilder<'t> { } } + if self.sorted { + file.types.sort_by(|ak, av, bk, bv| { + let complexity_a: usize = av + .path + .char_indices() + .filter_map(|(_, c)| (c == '<' || c == ',').then_some(1)) + .sum(); + let complexity_b = bv + .path + .char_indices() + .filter_map(|(_, c)| (c == '<' || c == ',').then_some(1)) + .sum(); + + let has_functions_a = !av.associated_functions.is_empty(); + let has_functions_b = !bv.associated_functions.is_empty(); + + let ordered_by_name = ak.cmp(bk); + let ordered_by_generics_complexity = complexity_a.cmp(&complexity_b); + let ordered_by_generated = av.generated.cmp(&bv.generated); + let ordered_by_having_functions = has_functions_b.cmp(&has_functions_a); + let ordered_by_significance = av.insignificance.cmp(&bv.insignificance); + + ordered_by_significance + .then(ordered_by_having_functions) + .then(ordered_by_generics_complexity) + .then(ordered_by_name) + .then(ordered_by_generated) + }); + + file.functions.sort_keys(); + file.primitives.sort_keys(); + } + file } @@ -526,6 +682,11 @@ impl<'t> LadFileBuilder<'t> { } fn lad_id_from_type_id(&mut self, type_id: TypeId) -> LadTypeId { + // a special exception + if type_id == std::any::TypeId::of::() { + return LadTypeId::new_string_id("World".into()); + } + if let Some(lad_id) = self.type_id_mapping.get(&type_id) { return lad_id.clone(); } @@ -961,4 +1122,29 @@ mod test { let deserialized = parse_lad_file(&asset).unwrap(); assert_eq!(deserialized.version, "{{version}}"); } + + #[test] + fn test_nested_unregistered_generic_is_removed() { + let mut type_registry = TypeRegistry::default(); + + #[derive(Reflect)] + #[reflect(no_field_bounds, from_reflect = false)] + struct StructType { + #[reflect(ignore)] + phantom: std::marker::PhantomData, + } + + #[derive(Reflect)] + struct Blah; + + type_registry.register::>(); + + let lad_file = LadFileBuilder::new_empty(&type_registry) + .set_sorted(true) + .set_exclude_including_unregistered(true) + .add_type::>() + .build(); + + assert_eq!(lad_file.types.len(), 0); + } } diff --git a/crates/ladfile_builder/src/plugin.rs b/crates/ladfile_builder/src/plugin.rs index 1c6f5851d9..7f758a8dc9 100644 --- a/crates/ladfile_builder/src/plugin.rs +++ b/crates/ladfile_builder/src/plugin.rs @@ -7,12 +7,15 @@ use bevy::{ ecs::{ reflect::AppTypeRegistry, system::{Res, Resource}, + world::World, }, }; use bevy_mod_scripting_core::bindings::{ function::{namespace::Namespace, script_function::AppScriptFunctionRegistry}, globals::AppScriptGlobalsRegistry, + IntoNamespace, MarkAsCore, MarkAsGenerated, MarkAsSignificant, }; +use ladfile::{default_importance, LadTypeKind}; use crate::LadFileBuilder; @@ -33,6 +36,11 @@ pub struct LadFileSettings { /// The description to use for the LAD file, by default it's empty pub description: &'static str, + /// Whether to exclude types which are not registered. + /// + /// i.e. `HashMap` where `T` or `V` are not registered types + pub exclude_types_containing_unregistered: bool, + /// Whether to pretty print the output JSON. By default this is true (slay) pub pretty: bool, } @@ -43,17 +51,24 @@ impl Default for LadFileSettings { path: PathBuf::from("bindings.lad.json"), description: "", pretty: true, + exclude_types_containing_unregistered: true, } } } impl ScriptingDocgenPlugin { /// Create a new instance of the plugin with the given path - pub fn new(path: PathBuf, description: &'static str, pretty: bool) -> Self { + pub fn new( + path: PathBuf, + description: &'static str, + exclude_types_containing_unregistered: bool, + pretty: bool, + ) -> Self { Self(LadFileSettings { path, description, pretty, + exclude_types_containing_unregistered, }) } } @@ -71,8 +86,24 @@ pub fn generate_lad_file( let mut builder = LadFileBuilder::new(&type_registry); builder .set_description(settings.description) + .set_exclude_including_unregistered(settings.exclude_types_containing_unregistered) .set_sorted(true); + // process world as a special value + builder.add_nonreflect_type::( + Some("bevy_ecs"), + r#"The ECS world containing all Components, Resources and Systems. Main point of interaction with a Bevy App."#.trim(), + ); + + for (_, function) in function_registry.iter_namespace(World::into_namespace()) { + builder.add_function_info(function.info.clone()); + } + + builder.set_insignificance( + std::any::TypeId::of::(), + (default_importance() / 2) - 1, + ); + // first of all, iterate over all the types and register them for registration in type_registry.iter() { let type_info = registration.type_info(); @@ -84,6 +115,18 @@ pub fn generate_lad_file( builder.add_type_info(type_info); + if registration.contains::() { + builder.mark_generated(registration.type_id()); + } + + if registration.contains::() { + builder.set_insignificance(registration.type_id(), default_importance() / 2); + } + + if registration.contains::() { + builder.set_insignificance(registration.type_id(), default_importance() / 4); + } + // find functions on the namespace for (_, function) in function_registry.iter_namespace(Namespace::OnType(type_info.type_id())) @@ -98,12 +141,17 @@ pub fn generate_lad_file( } // find global instances - for (key, global) in global_registry.iter() { let type_info = global.type_information.clone(); builder.add_instance_dynamic(key.to_string(), global.maker.is_none(), type_info); } + // find global dummies + for (key, global) in global_registry.iter_dummies() { + let lad_type_id = builder.lad_id_from_type_id(global.type_id); + builder.add_instance_manually(key.to_string(), false, LadTypeKind::Val(lad_type_id)); + } + let file = builder.build(); let mut path = PathBuf::from("assets"); diff --git a/docs/generated_docs.html b/docs/generated_docs.html new file mode 100644 index 0000000000..e03efd0dd1 --- /dev/null +++ b/docs/generated_docs.html @@ -0,0 +1,237 @@ + + + + + + Generated Docs - Bevy Scripting + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+
+

Generated Docs

+

Contents

+

This is an automatically generated file, you'll find links to the contents below

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 9ca89fa9b6..cb80e83102 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -17,14 +17,7 @@ - [Introduction](./ScriptingReference/introduction.md) - [Constructing Arbitrary Types](./ScriptingReference/constructing-arbitrary-types.md) -- [Core Bindings](./ScriptingReference/core-api.md) - - [World](./ScriptingReference/world.md) - - [ReflectReference](./ScriptingReference/reflect-reference.md) - - [ScriptTypeRegistration](./ScriptingReference/script-type-registration.md) - - [ScriptComponentRegistration](./ScriptingReference/script-component-registration.md) - - [ScriptResourceRegistration](./ScriptingReference/script-resource-registration.md) - - [ScriptQueryBuilder](./ScriptingReference/script-query-builder.md) - - [ScriptQueryResult](./ScriptingReference/script-query-result.md) +- [Core Bindings](./ladfiles/bindings.lad.json) - [Core Callbacks](./ScriptingReference/core-callbacks.md) # Developing BMS @@ -34,8 +27,3 @@ - [New Languages](./Development/AddingLanguages/introduction.md) - [Evaluating Feasibility](./Development/AddingLanguages/evaluating-feasibility.md) - [Necessary Features](./Development/AddingLanguages/necessary-features.md) - -# LAD docs (WIP) - -- [Generated Docs](./ladfiles/bindings.lad.json) - diff --git a/docs/src/ScriptingReference/reflect-reference.md b/docs/src/ScriptingReference/reflect-reference.md deleted file mode 100644 index dca9880d0e..0000000000 --- a/docs/src/ScriptingReference/reflect-reference.md +++ /dev/null @@ -1,239 +0,0 @@ -# ReflectReference - -ReflectReferences are simply references to data living either in: -- A component -- A resource -- The allocator - -Reflect references contain a standard interface which operates over the reflection layer exposed by `Bevy` and also provides a way to call various dynamic functions registered on the underlying pointed to data. - -## display_ref - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ReflectReference` | The reference to display | - -Returns: - -| Return | Description | -| --- | --- | -| `String` | The reference in string format | - -```lua -print(ref:display_ref()) -print(ref) -``` - -## display_value - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ReflectReference` | The reference to display | - -Returns: - -| Return | Description | -| --- | --- | -| `String` | The value in string format | - -```lua -print(ref:display_value()) -``` - -## get -The index function, allows you to index into the reflect reference. - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `key` | `ScriptValue` | The key to get the value for | - -Returns: - -| Return | Description | -| --- | --- | -| `ScriptValue` | The value | - -```lua -local value = ref:get(key) --- same as -local value = ref.key -local value = ref[key] -local value = ref["key"] --- for tuple structs -local valye = ref._1 -``` - -## set - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `key` | `ScriptValue` | The key to set the value for | -| `value` | `ScriptValue` | The value to set | - -Returns: - -| Return | Description | -| --- | --- | -| `ScriptValue` | The result | - -```lua -ref:set(key, value) --- same as -ref.key = value -ref[key] = value -ref["key"] = value --- for tuple structs -ref._1 = value -``` - -## push -Generic push method, if the underlying type supports it, will push the value into the end of the reference. - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `value` | `ScriptValue` | The value to push | - -```lua -ref:push(value) -``` - -## pop -Generic pop method, if the underlying type supports it, will pop the value from the end of the reference. - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ReflectReference` | The reference to pop from | - -Returns: - -| Return | Description | -| --- | --- | -| `ScriptValue` | The popped value | - -```lua -local value = ref:pop() -``` - -## insert -Generic insert method, if the underlying type supports it, will insert the value at the key. - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `key` | `ScriptValue` | The key to insert the value for | -| `value` | `ScriptValue` | The value to insert | - -```lua -ref:insert(key, value) -``` - -## clear -Generic clear method, if the underlying type supports it, will clear the referenced container type. - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ReflectReference` | The reference to clear | - - -```lua -ref:clear() -``` - -## len -Generic length method, if the underlying type supports it, will return the length of the referenced container or length relevant to the type itself (number of fields etc.). - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ReflectReference` | The reference to get the length of | - -Returns: - -| Return | Description | -| --- | --- | -| `usize` | The length | - -```lua -length = ref:len() -``` - -## remove -Generic remove method, if the underlying type supports it, will remove the value at the key. - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `key` | `ScriptValue` | The key to remove the value for | - -Returns: - -| Return | Description | -| --- | --- | -| `ScriptValue` | The removed value | - -```lua -local value = ref:remove(key) -``` - -## iter -The iterator function, returns a function which can be called to iterate over the reference. - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ReflectReference` | The reference to iterate over | - -Returns: - -| Return | Description | -| --- | --- | -| `ScriptFunctionMut` | The iterator function | - -```lua -local iter = ref:iter() -local val = iter() -while val do - print(val) - next = iter() -end - --- same as -for val in pairs(ref) do - print(val) -end -``` - -## functions -Returns a list of functions that can be called on the reference. - -Returns: - -| Return | Description | -| --- | --- | -| `Vec` | The list of functions | - -```lua -local functions = ref:functions() -for _, func in ipairs(functions) do - print(func.name) - -end -``` \ No newline at end of file diff --git a/docs/src/ScriptingReference/script-component-registration.md b/docs/src/ScriptingReference/script-component-registration.md deleted file mode 100644 index c83fe416c9..0000000000 --- a/docs/src/ScriptingReference/script-component-registration.md +++ /dev/null @@ -1,39 +0,0 @@ -# ScriptComponentRegistration - -A reference to a component type's registration, in general think of this as a handle to a type. - -## type_name - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ScriptComponentRegistration` | The type registration as returned by `get_type_by_name` | - -Returns: - -| Return | Description | -| --- | --- | -| `String` | The type name | - -```lua -local name = MyType:type_name() -``` - -## short_name - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ScriptComponentRegistration` | The type registration as returned by `get_type_by_name` | - -Returns: - -| Return | Description | -| --- | --- | -| `String` | The short name | - -```lua -local name = MyType:short_name() -``` \ No newline at end of file diff --git a/docs/src/ScriptingReference/script-query-builder.md b/docs/src/ScriptingReference/script-query-builder.md deleted file mode 100644 index 7d4fcbd93e..0000000000 --- a/docs/src/ScriptingReference/script-query-builder.md +++ /dev/null @@ -1,83 +0,0 @@ -# ScriptQueryBuilder - -The query builder is used to build queries for entities with specific components. Can be used to interact with arbitrary entities in the world. - -## component - -Adds a component to the query, this will be accessible in the query results under the index corresponding to the index of this component in the query. - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ScriptQueryBuilder` | The query builder | -| `component` | `ScriptComponentRegistration` | The component to query for | - -Returns: - -| Return | Description | -| --- | --- | -| `ScriptQueryBuilder` | The updated query builder | - -```lua -query:component(MyType):component(MyOtherType) -``` - -## with - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ScriptQueryBuilder` | The query builder | -| `with` | `ScriptComponentRegistration` | The component to include in the query | - -Returns: - -| Return | Description | -| --- | --- | -| `ScriptQueryBuilder` | The updated query builder | - -```lua -query:with(MyType):with(MyOtherType) -``` - -## without - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ScriptQueryBuilder` | The query builder | -| `without` | `ScriptComponentRegistration` | The component to exclude from the query | - -Returns: - -| Return | Description | -| --- | --- | -| `ScriptQueryBuilder` | The updated query builder | - -```lua -query:without(MyType):without(MyOtherType) -``` - -## build - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ScriptQueryBuilder` | The query builder | - -Returns: - -| Return | Description | -| --- | --- | -| `Vec` | The query results | - -```lua -local results = query:build() -for _, result in pairs(results) do - print(result) -end -``` diff --git a/docs/src/ScriptingReference/script-query-result.md b/docs/src/ScriptingReference/script-query-result.md deleted file mode 100644 index f25e5d1c8d..0000000000 --- a/docs/src/ScriptingReference/script-query-result.md +++ /dev/null @@ -1,41 +0,0 @@ -# ScriptQueryResult - -The result of a query, built by the query builder. - -## entity - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ScriptQueryResult` | The query result | - -Returns: - -| Return | Description | -| --- | --- | -| `Entity` | The entity | - -```lua -local entity = result:entity() -``` - -## components - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ScriptQueryResult` | The query result | - -Returns: - -| Return | Description | -| --- | --- | -| `Vec` | The components | - -```lua -for _, component in pairs(result:components()) do - print(component) -end -``` \ No newline at end of file diff --git a/docs/src/ScriptingReference/script-resource-registration.md b/docs/src/ScriptingReference/script-resource-registration.md deleted file mode 100644 index 13e500f88b..0000000000 --- a/docs/src/ScriptingReference/script-resource-registration.md +++ /dev/null @@ -1,39 +0,0 @@ -# ScriptResourceRegistration - -A reference to a resource type's registration, in general think of this as a handle to a type. - -## type_name - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ScriptResourceRegistration` | The type registration as returned by `get_type_by_name` | - -Returns: - -| Return | Description | -| --- | --- | -| `String` | The type name | - -```lua -local name = MyType:type_name() -``` - -## short_name - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ScriptResourceRegistration` | The type registration as returned by `get_type_by_name` | - -Returns: - -| Return | Description | -| --- | --- | -| `String` | The short name | - -```lua -local name = MyType:short_name() -``` \ No newline at end of file diff --git a/docs/src/ScriptingReference/script-type-registration.md b/docs/src/ScriptingReference/script-type-registration.md deleted file mode 100644 index 1eb45d62d7..0000000000 --- a/docs/src/ScriptingReference/script-type-registration.md +++ /dev/null @@ -1,79 +0,0 @@ -# ScriptTypeRegistration - -A reference to a type registration, in general think of this as a handle to a type. - -## type_name - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` | - -Returns: - -| Return | Description | -| --- | --- | -| `String` | The type name | - -```lua -local name = MyType:type_name() -``` - -## short_name - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` | - -Returns: - -| Return | Description | -| --- | --- | -| `String` | The short name | - -```lua -local name = MyType:short_name() -``` - -## is_resource - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` | - -Returns: - -| Return | Description | -| --- | --- | -| `bool` | `true` if the type is a resource, otherwise `false` | - -```lua -if MyType:is_resource() then - print("MyType is a resource") -end -``` - -## is_component - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `s` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` | - -Returns: - -| Return | Description | -| --- | --- | -| `bool` | `true` if the type is a component, otherwise `false` | - -```lua -if MyType:is_component() then - print("MyType is a component") -end -``` diff --git a/docs/src/ScriptingReference/world.md b/docs/src/ScriptingReference/world.md deleted file mode 100644 index 967ebe36b1..0000000000 --- a/docs/src/ScriptingReference/world.md +++ /dev/null @@ -1,325 +0,0 @@ -## World - -The `World` is the entry point for interacting with `Bevy`. It is provided to scripts under either the `world` or `World` static variable. - -### get_type_by_name - -Returns either a `ScriptComponentRegistration` or `ScriptResourceRegistration` depending on the type of the type requested. If the type is neither returns a `ScriptTypeRegistration`. - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `type_name` | `String` | The name of the type to get, this can be either the short type name, i.e. `my_type` or the long name i.e. `my_crate::my_module::my_type` | - -Returns: - -| Return | Description | -| --- | --- | -| `Option` | The registration for the type if it exists, otherwise `None` | - -```lua -MyType = world.get_type_by_name("MyType") -if MyType == nil then - print("MyType not found") -end - --- OR -MyType = types.MyType -``` - -### get_component - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `entity` | `Entity` | The entity to get the component from | -| `registration` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` of the component | - -Returns: - -| Return | Description | -| --- | --- | -| `Option` | The reference to the component if it exists, otherwise `None` | - -```lua -local component = world.get_component(entity, MyType) -if component ~= nil then - print("found component:" .. component) -end -``` - -### has_component - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `entity` | `Entity` | The entity to check the component for | -| `registration` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` of the component | - -Returns: - -| Return | Description | -| --- | --- | -| `bool` | `true` if the entity has the component, otherwise `false` | - -```lua -if world.has_component(entity, MyType) then - print("Entity has MyType") -end -``` - -### remove_component - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `entity` | `Entity` | The entity to remove the component from | -| `registration` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` of the component | - -```lua -world.remove_component(entity, MyType) -``` - -### get_resource - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `registration` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` of the resource | - -Returns: - -| Return | Description | -| --- | --- | -| `Option` | The resource if it exists, otherwise `None` | - -```lua -local resource = world.get_resource(MyType) -if resource ~= nil then - print("found resource:" .. resource) -end -``` - -### has_resource - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `registration` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` of the resource | - -Returns: - -| Return | Description | -| --- | --- | -| `bool` | `true` if the resource exists, otherwise `false` | - -```lua -local hasResource = world.has_resource(MyType) -``` - -### remove_resource - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `registration` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` of the resource | - -```lua -world.remove_resource(MyType) -``` - -### add_default_component - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `entity` | `Entity` | The entity to add the component to | -| `registration` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` of the component | - -```lua -world.add_default_component(entity, MyType) -``` - -### insert_component - -Inserts or applies the given value to the component of the entity. If the component does not exist it will be added. - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `entity` | `Entity` | The entity to add the component to | -| `registration` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` of the component | -| `component` | `ReflectReference` | A reference to an existing component value to be inserted | - -```lua -local existingComponent = world.get_component(otherEntity, MyType) -world.insert_component(entity, MyType, existingComponent) -``` - - -### spawn - -Returns: - -| Return | Description | -| --- | --- | -| `Entity` | The spawned entity | - -```lua -local entity = world.spawn() -``` - -### insert_children - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `entity` | `Entity` | The parent entity | -| `index` | `usize` | The index to insert the children at | -| `children` | `Vec` | The children entities to insert | - -```lua -world.insert_children(parent, 1, {child1, child2}) -``` - -### push_children - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `entity` | `Entity` | The parent entity | -| `children` | `Vec` | The children entities to push | - - -```lua -world.push_children(parent, {child1, child2}) -``` - -### get_children - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `entity` | `Entity` | The parent entity | - -Returns: - -| Return | Description | -| --- | --- | -| `Vec` | The children entities | - -```lua -local children = world.get_children(parent) -for _, child in pairs(children) do - print("child: " .. child) -end -``` - -### get_parent - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `entity` | `Entity` | The child entity | - -Returns: - -| Return | Description | -| --- | --- | -| `Option` | The parent entity if it exists, otherwise `None` | - -```lua -local parent = world.get_parent(child) -if parent ~= nil then - print("parent: " .. parent) -end -``` - -### despawn - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `entity` | `Entity` | The entity to despawn | - -```lua -world.despawn(entity) -``` - -### despawn_descendants - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `entity` | `Entity` | The entity to despawn descendants of | - -```lua -world.despawn_descendants(entity) -``` - -### despawn_recursive - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `entity` | `Entity` | The entity to despawn recursively | - -```lua -world.despawn_recursive(entity) -``` - -### has_entity - -Arguments: - -| Argument | Type | Description | -| --- | --- | --- | -| `entity` | `Entity` | The entity to check | - -Returns: - -| Return | Description | -| --- | --- | -| `bool` | `true` if the entity exists, otherwise `false` | - -```lua -local exists = world.has_entity(entity) -if exists then - print("entity exists") -end -``` - -### query - -Returns: - -| Return | Description | -| --- | --- | -| `ScriptQueryBuilder` | The query builder | - -```lua -local queryBuilder = world.query() -``` - -### exit -Send the exit signal to the application, will gracefully shutdown the application. - -```lua -world.exit() -```