From fac74f1e519b5e8ac62161b54c01e3d196a653e4 Mon Sep 17 00:00:00 2001 From: makspll Date: Mon, 6 Jan 2025 12:46:20 +0000 Subject: [PATCH 01/21] fix: bugs to do with multiple languages being initialized --- Cargo.toml | 16 +- crates/bevy_mod_scripting_core/src/asset.rs | 77 +++++- .../bevy_mod_scripting_core/src/commands.rs | 51 ++-- crates/bevy_mod_scripting_core/src/lib.rs | 79 +++++- crates/bevy_mod_scripting_core/src/script.rs | 2 - crates/bevy_mod_scripting_core/src/systems.rs | 166 +++++++++---- .../bevy_mod_scripting_lua/src/lib.rs | 23 +- .../src/bindings/mod.rs | 1 + .../src/bindings/script_value.rs | 0 .../bevy_mod_scripting_rhai/src/lib.rs | 14 ++ .../bevy_mod_scripting_rune/src/lib.rs | 4 +- examples/{lua => }/game_of_life.rs | 32 ++- examples/rhai/game_of_life.rs | 224 ------------------ 13 files changed, 343 insertions(+), 346 deletions(-) create mode 100644 crates/languages/bevy_mod_scripting_rhai/src/bindings/mod.rs create mode 100644 crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs rename examples/{lua => }/game_of_life.rs (91%) delete mode 100644 examples/rhai/game_of_life.rs diff --git a/Cargo.toml b/Cargo.toml index d2a0e17d92..29b9699c15 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,11 +106,11 @@ inherits = "release" debug = true [[example]] -name = "game_of_life_lua" -path = "examples/lua/game_of_life.rs" -required-features = ["lua54", "bevy/file_watcher", "bevy/multi_threaded"] - -# [[example]] -# required-features = ["rhai", "bevy/file_watcher", "bevy/multi_threaded"] -# name = "game_of_life_rhai" -# path = "examples/rhai/game_of_life.rs" +name = "game_of_life" +path = "examples/game_of_life.rs" +required-features = [ + "lua54", + "rhai", + "bevy/file_watcher", + "bevy/multi_threaded", +] diff --git a/crates/bevy_mod_scripting_core/src/asset.rs b/crates/bevy_mod_scripting_core/src/asset.rs index 5fa3445efe..bbfe99fc10 100644 --- a/crates/bevy_mod_scripting_core/src/asset.rs +++ b/crates/bevy_mod_scripting_core/src/asset.rs @@ -10,18 +10,42 @@ use std::{ path::{Path, PathBuf}, }; +/// Represents a scripting language. Languages which compile into another language should use the target language as their language. +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub enum Language { + Rhai, + Lua, + Rune, + External(Cow<'static, str>), + /// Initial setting before being processed by the script synchronization systems + Unset, + /// Set if none of the asset path to language mappers match + Unknown, +} + +impl std::fmt::Display for Language { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Language::Rhai => "Rhai".fmt(f), + Language::Lua => "Lua".fmt(f), + Language::Rune => "Rune".fmt(f), + Language::External(cow) => cow.fmt(f), + Language::Unset => "Unset".fmt(f), + Language::Unknown => "Unknown".fmt(f), + } + } +} + /// Represents a script loaded into memory as an asset #[derive(Asset, TypePath, Clone)] pub struct ScriptAsset { pub content: Box<[u8]>, /// The virtual filesystem path of the asset, used to map to the script Id for asset backed scripts pub asset_path: PathBuf, - pub language: Cow<'static, str>, + pub language: Language, } pub struct ScriptAssetLoader { - /// Used to set the language of the script - pub language: Cow<'static, str>, /// The file extensions this loader should handle pub extensions: &'static [&'static str], /// preprocessor to run on the script before saving the content to an asset @@ -52,7 +76,7 @@ impl AssetLoader for ScriptAssetLoader { let asset = ScriptAsset { content: content.into_boxed_slice(), asset_path: load_context.path().to_owned(), - language: self.language.clone(), + language: Language::Unset, }; Ok(asset) } @@ -62,9 +86,24 @@ impl AssetLoader for ScriptAssetLoader { } } -#[derive(Clone, Copy, Resource)] +#[derive(Clone, Resource)] pub struct ScriptAssetSettings { pub script_id_mapper: AssetPathToScriptIdMapper, + pub script_language_mappers: Vec, +} + +impl ScriptAssetSettings { + pub fn select_script_language(&self, path: &Path) -> Language { + for mapper in &self.script_language_mappers { + let language = (mapper.map)(path); + match language { + Language::Unset | Language::Unknown => continue, + _ => return language, + } + } + + Language::Unknown + } } impl Default for ScriptAssetSettings { @@ -73,6 +112,9 @@ impl Default for ScriptAssetSettings { script_id_mapper: AssetPathToScriptIdMapper { map: (|path: &Path| path.to_string_lossy().into_owned().into()), }, + script_language_mappers: vec![AssetPathToLanguageMapper { + map: (|_: &Path| Language::Unset), + }], } } } @@ -83,22 +125,33 @@ pub struct AssetPathToScriptIdMapper { pub map: fn(&Path) -> ScriptId, } +#[derive(Clone, Copy)] +pub struct AssetPathToLanguageMapper { + pub map: fn(&Path) -> Language, +} + /// A cache of asset id's to their script id's. Necessary since when we drop an asset we won't have the ability to get the path from the asset. #[derive(Default, Debug, Resource)] -pub struct AssetIdToScriptIdMap { - pub map: HashMap, ScriptId>, +pub struct ScriptMetadataStore { + pub map: HashMap, ScriptMetadata>, +} + +#[derive(Debug, Clone)] +pub struct ScriptMetadata { + pub script_id: ScriptId, + pub language: Language, } -impl AssetIdToScriptIdMap { - pub fn insert(&mut self, id: AssetId, path: ScriptId) { - self.map.insert(id, path); +impl ScriptMetadataStore { + pub fn insert(&mut self, id: AssetId, meta: ScriptMetadata) { + self.map.insert(id, meta); } - pub fn get(&self, id: AssetId) -> Option<&ScriptId> { + pub fn get(&self, id: AssetId) -> Option<&ScriptMetadata> { self.map.get(&id) } - pub fn remove(&mut self, id: AssetId) -> Option { + pub fn remove(&mut self, id: AssetId) -> Option { self.map.remove(&id) } } diff --git a/crates/bevy_mod_scripting_core/src/commands.rs b/crates/bevy_mod_scripting_core/src/commands.rs index 86d289d30e..17eb7ce1a9 100644 --- a/crates/bevy_mod_scripting_core/src/commands.rs +++ b/crates/bevy_mod_scripting_core/src/commands.rs @@ -9,7 +9,7 @@ use crate::{ IntoScriptPluginParams, }; use bevy::{asset::Handle, ecs::world::Mut, log::debug, prelude::Command}; -use std::{any::type_name, marker::PhantomData}; +use std::marker::PhantomData; pub struct DeleteScript { pub id: ScriptId, @@ -62,9 +62,17 @@ impl Command for DeleteScript

{ &mut runtime_container.runtime, world, ) { - Ok(_) => {}, + Ok(_) => {} Err(e) => { - handle_script_errors(world, [e.with_context(format!("Running unload hook for script with id: {}. Runtime type: {}, Context type: {}", self.id, type_name::(), type_name::()))].into_iter()); + handle_script_errors( + world, + [e.with_context(format!( + "Running unload hook for script with id: {}. Language: {}", + self.id, + P::LANGUAGE + ))] + .into_iter(), + ); } } @@ -151,21 +159,13 @@ impl Command for CreateOrUpdateScript

{ let current_context_id = if let Some(id) = current_context_id { // reload existing context - let current_context = contexts.get_mut(id).unwrap(); - match (builder.reload)(&self.id, &self.content, current_context, &settings.context_initializers, &settings.context_pre_handling_initializers, world, &mut runtime.runtime) { - Ok(_) => {}, - Err(e) => { - handle_script_errors(world, [e.with_context(format!("Reloading script with id: {}. Runtime type: {}, Context type: {}", self.id, type_name::(), type_name::()))].into_iter()); - return; - } - }; id } else { let ctxt = (builder.load)(&self.id, &self.content, &settings.context_initializers, &settings.context_pre_handling_initializers, world, &mut runtime.runtime); match ctxt { Ok(ctxt) => contexts.insert(ctxt), Err(e) => { - handle_script_errors(world, [e.with_context(format!("Loading script with id: {}. Runtime type: {}, Context type: {}", self.id, type_name::(), type_name::()))].into_iter()); + handle_script_errors(world, [e.with_context(format!("Loading script with id: {}. Language: {}", self.id, P::LANGUAGE))].into_iter()); return; } } @@ -173,6 +173,18 @@ impl Command for CreateOrUpdateScript

{ if let Some(previous) = previous_context_id { + if let Some(previous_context_id) = contexts.get_mut(previous) { + match (builder.reload)(&self.id, &self.content, previous_context_id, &settings.context_initializers, &settings.context_pre_handling_initializers, world, &mut runtime.runtime) { + Ok(_) => {}, + Err(e) => { + handle_script_errors(world, [e.with_context(format!("Reloading script with id: {}. Language: {}", self.id, P::LANGUAGE))].into_iter()); + return; + } + }; + } else { + bevy::log::error!("Could not find previous context with id: {}. Could not reload script id: {}", previous, self.id); + } + if previous != current_context_id { debug!( "Script is being moved to a new context with id: {}, removing up old context.", @@ -183,12 +195,15 @@ impl Command for CreateOrUpdateScript

{ } } - let context = contexts.get_mut(current_context_id).expect("Context not found"); - match (runner)(vec![], bevy::ecs::entity::Entity::from_raw(0), &self.id, &OnScriptLoaded::into_callback_label(), context, &settings.context_pre_handling_initializers, &mut runtime.runtime, world) { - Ok(_) => {}, - Err(e) => { - handle_script_errors(world, [e.with_context(format!("Running initialization hook for script with id: {}. Runtime type: {}, Context type: {}", self.id, type_name::(), type_name::()))].into_iter()); - }, + if let Some(context) = contexts.get_mut(current_context_id) { + match (runner)(vec![], bevy::ecs::entity::Entity::from_raw(0), &self.id, &OnScriptLoaded::into_callback_label(), context, &settings.context_pre_handling_initializers, &mut runtime.runtime, world) { + Ok(_) => {}, + Err(e) => { + handle_script_errors(world, [e.with_context(format!("Running initialization hook for script with id: {}. Language: {}", self.id, P::LANGUAGE))].into_iter()); + }, + } + } else { + bevy::log::error!("Could not find context with id: {}. Could not run initialization hook for script id: {}. This may be because the script failed to load.", current_context_id, self.id); } // now we can insert the actual script diff --git a/crates/bevy_mod_scripting_core/src/lib.rs b/crates/bevy_mod_scripting_core/src/lib.rs index 450913eb9b..13e5bcef0f 100644 --- a/crates/bevy_mod_scripting_core/src/lib.rs +++ b/crates/bevy_mod_scripting_core/src/lib.rs @@ -1,7 +1,12 @@ #![allow(clippy::arc_with_non_send_sync)] +use std::sync::atomic::AtomicBool; + use crate::event::ScriptErrorEvent; -use asset::{AssetIdToScriptIdMap, ScriptAsset, ScriptAssetLoader, ScriptAssetSettings}; +use asset::{ + AssetPathToLanguageMapper, Language, ScriptAsset, ScriptAssetLoader, ScriptAssetSettings, + ScriptMetadataStore, +}; use bevy::prelude::*; use bindings::{ function::script_function::AppScriptFunctionRegistry, script_value::ScriptValue, @@ -18,7 +23,10 @@ use handler::{CallbackSettings, HandlerFn}; use runtime::{Runtime, RuntimeContainer, RuntimeInitializer, RuntimeSettings}; use script::Scripts; -use systems::{garbage_collector, initialize_runtime, sync_script_data}; +use systems::{ + garbage_collector, initialize_runtime, insert_script_metadata, remove_script_metadata, + sync_script_data, ScriptingSystemSet, +}; pub mod asset; pub mod bindings; @@ -37,8 +45,11 @@ pub mod world; /// Types which act like scripting plugins, by selecting a context and runtime /// Each individual combination of context and runtime has specific infrastructure built for it and does not interact with other scripting plugins pub trait IntoScriptPluginParams: 'static { + const LANGUAGE: Language; type C: Context; type R: Runtime; + + // fn supported_language() -> Language; } /// Bevy plugin enabling scripting within the bevy mod scripting framework @@ -53,6 +64,7 @@ pub struct ScriptingPlugin { pub context_builder: Option>, /// The context assigner for assigning contexts to scripts, if not provided default strategy of keeping each script in its own context is used pub context_assigner: Option>, + pub language_mapper: Option, } impl Default for ScriptingPlugin

@@ -66,6 +78,7 @@ where callback_handler: Default::default(), context_builder: Default::default(), context_assigner: Default::default(), + language_mapper: Default::default(), } } } @@ -77,10 +90,9 @@ impl Plugin for ScriptingPlugin

{ .init_resource::() .init_resource::() .init_resource::() - .init_resource::() + .init_resource::() .init_asset::() .register_asset_loader(ScriptAssetLoader { - language: "<>".into(), extensions: &[], preprocessor: None, }) @@ -98,14 +110,62 @@ impl Plugin for ScriptingPlugin

{ assigner: Some(self.context_assigner.clone().unwrap_or_default()), context_initializers: vec![], context_pre_handling_initializers: vec![], - }) - .add_systems(PostUpdate, (garbage_collector, sync_script_data::

)) - .add_systems(PostStartup, initialize_runtime::

); + }); + + register_script_plugin_systems::

(app); + register_systems(app); + + if let Some(language_mapper) = &self.language_mapper { + app.world_mut() + .resource_mut::() + .as_mut() + .script_language_mappers + .push(*language_mapper); + } register_types(app); } } +// One of registration of systems per bevy application +fn register_systems(app: &mut App) { + static INITIALIZED: AtomicBool = AtomicBool::new(false); + + if INITIALIZED.fetch_or(true, std::sync::atomic::Ordering::Relaxed) { + return; + } + + app.add_systems( + PostUpdate, + ( + (garbage_collector).in_set(ScriptingSystemSet::GarbageCollection), + (insert_script_metadata).in_set(ScriptingSystemSet::ScriptMetadataInsertion), + (remove_script_metadata).in_set(ScriptingSystemSet::ScriptMetadataRemoval), + ), + ) + .configure_sets( + PostUpdate, + ( + ScriptingSystemSet::ScriptMetadataInsertion.after(bevy::asset::TrackAssets), + ScriptingSystemSet::ScriptCommandDispatch + .after(ScriptingSystemSet::ScriptMetadataInsertion) + .before(ScriptingSystemSet::ScriptMetadataRemoval), + ), + ); +} + +/// Systems registered per-language +fn register_script_plugin_systems(app: &mut App) { + app.add_systems( + PostStartup, + (initialize_runtime::

).in_set(ScriptingSystemSet::RuntimeInitialization), + ) + .add_systems( + PostUpdate, + ((sync_script_data::

).in_set(ScriptingSystemSet::ScriptCommandDispatch),), + ); +} + /// Register all types that need to be accessed via reflection fn register_types(app: &mut App) { app.register_type::(); @@ -225,7 +285,7 @@ impl StoreDocumentation for App { #[cfg(test)] mod test { - use asset::AssetIdToScriptIdMap; + use asset::ScriptMetadataStore; use super::*; @@ -243,6 +303,7 @@ mod test { impl IntoScriptPluginParams for Plugin { type C = C; type R = R; + const LANGUAGE: Language = Language::Unset; } app.add_plugins(AssetPlugin::default()); @@ -258,6 +319,6 @@ mod test { .contains_resource::>()); assert!(app.world().contains_non_send::>()); assert!(app.world().contains_non_send::>()); - assert!(app.world().contains_resource::()); + assert!(app.world().contains_resource::()); } } diff --git a/crates/bevy_mod_scripting_core/src/script.rs b/crates/bevy_mod_scripting_core/src/script.rs index 0afcc20b26..8b17ebfca6 100644 --- a/crates/bevy_mod_scripting_core/src/script.rs +++ b/crates/bevy_mod_scripting_core/src/script.rs @@ -1,5 +1,3 @@ -//! Everything to do with the way scripts and their contexts are stored and handled. - use crate::{asset::ScriptAsset, context::ContextId}; use bevy::{asset::Handle, ecs::system::Resource, reflect::Reflect}; use std::{borrow::Cow, collections::HashMap, ops::Deref}; diff --git a/crates/bevy_mod_scripting_core/src/systems.rs b/crates/bevy_mod_scripting_core/src/systems.rs index 632a5ac8c2..78ce455590 100644 --- a/crates/bevy_mod_scripting_core/src/systems.rs +++ b/crates/bevy_mod_scripting_core/src/systems.rs @@ -1,5 +1,5 @@ use crate::{ - asset::{AssetIdToScriptIdMap, ScriptAsset, ScriptAssetSettings}, + asset::{ScriptAsset, ScriptAssetSettings, ScriptMetadata, ScriptMetadataStore}, bindings::{pretty_print::DisplayWithWorld, AppReflectAllocator, WorldAccessGuard, WorldGuard}, commands::{CreateOrUpdateScript, DeleteScript}, context::{ContextLoadingSettings, ScriptContexts}, @@ -13,6 +13,20 @@ use crate::{ use bevy::{ecs::system::SystemState, prelude::*}; use std::any::type_name; +#[derive(SystemSet, Hash, Debug, Eq, PartialEq, Clone)] +/// Labels for various BMS systems +pub enum ScriptingSystemSet { + // Post Setup processes + RuntimeInitialization, + + // Post Update processes + GarbageCollection, + + ScriptMetadataInsertion, + ScriptCommandDispatch, + ScriptMetadataRemoval, +} + /// Cleans up dangling script allocations pub fn garbage_collector(allocator: ResMut) { let mut allocator = allocator.write(); @@ -28,65 +42,118 @@ pub fn initialize_runtime( } } -/// Processes and reacts appropriately to script asset events, and queues commands to update the internal script state +/// Listens to `AssetEvent::Added` events and populates the script metadata store +pub fn insert_script_metadata( + mut events: EventReader>, + mut script_assets: ResMut>, + mut asset_path_map: ResMut, + settings: Res, +) { + for event in events.read() { + if let AssetEvent::Added { id } = event { + let asset = script_assets.get_mut(*id); + if let Some(asset) = asset { + let path = &asset.asset_path; + let converter = settings.script_id_mapper.map; + let script_id = converter(path); + + let language = settings.select_script_language(path); + asset.language = language.clone(); + let metadata = ScriptMetadata { + script_id, + language, + }; + + info!("Populating script metadata for script: {:?}:", metadata); + asset_path_map.insert(*id, metadata); + } else { + error!("A script was added but it's asset was not found, failed to compute metadata. This script will not be loaded. {}", id); + } + } + } +} + +/// Listens to [`AssetEvent::Removed`] events and removes the corresponding script metadata +pub fn remove_script_metadata( + mut events: EventReader>, + mut asset_path_map: ResMut, +) { + for event in events.read() { + if let AssetEvent::Removed { id } = event { + let previous = asset_path_map.remove(*id); + if let Some(previous) = previous { + info!("Removed script metadata for removed script: {:?}", previous); + } + } + } +} + +/// Listens to [`AssetEvent`] events and dispatches [`CreateOrUpdateScript`] and [`DeleteScript`] commands accordingly. +/// +/// Allows for hot-reloading of scripts. pub fn sync_script_data( mut events: EventReader>, script_assets: Res>, - asset_settings: Res, - mut asset_path_map: ResMut, + script_metadata: Res, mut commands: Commands, ) { for event in events.read() { - trace!("Received script asset event: {:?}", event); - let (id, remove) = match event { + trace!("{}: Received script asset event: {:?}", P::LANGUAGE, event); + match event { // emitted when a new script asset is loaded for the first time - AssetEvent::Added { id } => (id, false), - AssetEvent::Modified { id } => (id, false), - AssetEvent::Removed { id } => (id, true), - _ => continue, - }; - info!("Responding to script asset event: {:?}", event); - // get the path - let asset = script_assets.get(*id); - - let script_id = match asset_path_map.get(*id) { - Some(id) => id.clone(), - None => { - // we should only enter this branch for new assets - let asset = match asset { - Some(asset) => asset, + AssetEvent::Added { id } | AssetEvent::Modified { id } => { + let metadata = match script_metadata.get(*id) { + Some(m) => m, None => { - // this can happen if an asset is loaded and immediately unloaded, we can ignore this + error!( + "{}: Script metadata not found for script asset with id: {}. Cannot load script.", + P::LANGUAGE, + id + ); continue; } }; - let path = &asset.asset_path; - let converter = asset_settings.script_id_mapper.map; - let script_id = converter(path); - asset_path_map.insert(*id, script_id.clone()); + if metadata.language != P::LANGUAGE { + trace!( + "{}: Script asset with id: {} is for a different langauge than this sync system. Skipping.", + P::LANGUAGE, + metadata.script_id + ); + continue; + } - script_id - } - }; + info!( + "{}: Dispatching Creation command for script: {:?}", + P::LANGUAGE, + metadata + ); - if !remove { - let asset = match asset { - Some(asset) => asset, - None => { - // this can happen if an asset is loaded and immediately unloaded, we can ignore this - continue; + if let Some(asset) = script_assets.get(*id) { + commands.queue(CreateOrUpdateScript::

::new( + metadata.script_id.clone(), + asset.content.clone(), + Some(script_assets.reserve_handle().clone_weak()), + )); } - }; - info!("Creating or updating script with id: {}", script_id); - commands.queue(CreateOrUpdateScript::

::new( - script_id, - asset.content.clone(), - Some(script_assets.reserve_handle().clone_weak()), - )); - } else { - commands.queue(DeleteScript::

::new(script_id)); - } + } + AssetEvent::Removed { id } => { + let metadata = match script_metadata.get(*id) { + Some(m) => m, + None => { + error!( + "{}: Script metadata not found for script asset with id: {}. Cannot delete script.", + P::LANGUAGE, + id + ); + return; + } + }; + + commands.queue(DeleteScript::

::new(metadata.script_id.clone())); + } + _ => return, + }; } } @@ -198,11 +265,8 @@ pub fn event_handler( world, ) .map_err(|e| { - e.with_script(script.id.clone()).with_context(format!( - "Event handling for: Runtime {}, Context: {}", - type_name::(), - type_name::(), - )) + e.with_script(script.id.clone()) + .with_context(format!("Event handling for: Language: {}", P::LANGUAGE)) }); push_err_and_continue!(errors, handler_result) @@ -260,6 +324,8 @@ mod test { impl IntoScriptPluginParams for TestPlugin { type C = TestContext; type R = TestRuntime; + + const LANGUAGE: crate::asset::Language = crate::asset::Language::Unknown; } struct TestRuntime { diff --git a/crates/languages/bevy_mod_scripting_lua/src/lib.rs b/crates/languages/bevy_mod_scripting_lua/src/lib.rs index 0b904cd7a2..6b3bc6f672 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/lib.rs @@ -3,6 +3,7 @@ use bevy::{ ecs::{entity::Entity, world::World}, }; use bevy_mod_scripting_core::{ + asset::{AssetPathToLanguageMapper, Language}, bindings::{script_value::ScriptValue, WorldCallbackAccess}, context::{ContextBuilder, ContextInitializer, ContextPreHandlingInitializer}, error::ScriptError, @@ -24,6 +25,7 @@ pub mod bindings; impl IntoScriptPluginParams for LuaScriptingPlugin { type C = Lua; type R = (); + const LANGUAGE: Language = Language::Lua; } pub struct LuaScriptingPlugin { @@ -42,11 +44,21 @@ impl Default for LuaScriptingPlugin { load: lua_context_load, reload: lua_context_reload, }), + language_mapper: Some(AssetPathToLanguageMapper { + map: lua_language_mapper, + }), }, } } } +fn lua_language_mapper(path: &std::path::Path) -> Language { + match path.extension().and_then(|ext| ext.to_str()) { + Some("lua") => Language::Lua, + _ => Language::Unknown, + } +} + impl Plugin for LuaScriptingPlugin { fn build(&self, app: &mut bevy::prelude::App) { self.scripting_plugin.build(app); @@ -72,12 +84,7 @@ impl Plugin for LuaScriptingPlugin { fn cleanup(&self, app: &mut App) { // find all registered types, and insert dummy for calls - // let mut type_registry = app.world_mut().get_resource_or_init::(); - // let mut type_registry = type_registry.read(); - // type_registry.iter().map(|t| { - // t. - // }) app.add_context_initializer::(|_script_id, context: &mut Lua| { let world = context.get_world(); let type_registry = world.type_registry(); @@ -100,12 +107,6 @@ impl Plugin for LuaScriptingPlugin { } Ok(()) }); - - // let mut type_registry = app.world_mut().get_resource_mut().unwrap(); - - // we register up to two levels of nesting, if more are needed, the user will have to do this manually - // pre_register_common_containers(&mut type_registry); - // pre_register_common_containers(&mut type_registry); } } diff --git a/crates/languages/bevy_mod_scripting_rhai/src/bindings/mod.rs b/crates/languages/bevy_mod_scripting_rhai/src/bindings/mod.rs new file mode 100644 index 0000000000..881bf5524d --- /dev/null +++ b/crates/languages/bevy_mod_scripting_rhai/src/bindings/mod.rs @@ -0,0 +1 @@ +pub mod script_value; diff --git a/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs b/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/crates/languages/bevy_mod_scripting_rhai/src/lib.rs b/crates/languages/bevy_mod_scripting_rhai/src/lib.rs index e507c4aa05..dc06088ea1 100644 --- a/crates/languages/bevy_mod_scripting_rhai/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_rhai/src/lib.rs @@ -3,6 +3,7 @@ use bevy::{ ecs::{entity::Entity, world::World}, }; use bevy_mod_scripting_core::{ + asset::{AssetPathToLanguageMapper, Language}, bindings::{script_value::ScriptValue, WorldCallbackAccess}, context::{ContextBuilder, ContextInitializer, ContextPreHandlingInitializer}, error::ScriptError, @@ -13,6 +14,7 @@ use bevy_mod_scripting_core::{ use rhai::{CallFnOptions, Engine, FnPtr, Scope, AST}; pub use rhai; +pub mod bindings; pub type RhaiRuntime = Engine; @@ -24,6 +26,8 @@ pub struct RhaiScriptContext { impl IntoScriptPluginParams for RhaiScriptingPlugin { type C = RhaiScriptContext; type R = RhaiRuntime; + + const LANGUAGE: Language = Language::Rhai; } pub struct RhaiScriptingPlugin { @@ -42,11 +46,21 @@ impl Default for RhaiScriptingPlugin { load: rhai_context_load, reload: rhai_context_reload, }), + language_mapper: Some(AssetPathToLanguageMapper { + map: rhai_language_mapper, + }), }, } } } +fn rhai_language_mapper(path: &std::path::Path) -> Language { + match path.extension().and_then(|ext| ext.to_str()) { + Some("rhai") => Language::Rhai, + _ => Language::Unknown, + } +} + impl Plugin for RhaiScriptingPlugin { fn build(&self, app: &mut bevy::prelude::App) { self.scripting_plugin.build(app); diff --git a/crates/languages/bevy_mod_scripting_rune/src/lib.rs b/crates/languages/bevy_mod_scripting_rune/src/lib.rs index 8603087847..792ab054b5 100644 --- a/crates/languages/bevy_mod_scripting_rune/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_rune/src/lib.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use bevy_mod_scripting_core::{IntoScriptPluginParams, ScriptingPlugin}; +use bevy_mod_scripting_core::{asset::Language, IntoScriptPluginParams, ScriptingPlugin}; use rune::{ runtime::{Args, RuntimeContext}, Unit, Vm, @@ -19,6 +19,8 @@ pub type RuneRuntime = Vm; impl IntoScriptPluginParams for RuneScriptingPlugin { type C = RuneScriptContext; type R = RuneRuntime; + + const LANGUAGE: Language = Language::Rune; } pub struct RuneScriptingPlugin { diff --git a/examples/lua/game_of_life.rs b/examples/game_of_life.rs similarity index 91% rename from examples/lua/game_of_life.rs rename to examples/game_of_life.rs index 0487a48a87..2db4412cdb 100644 --- a/examples/lua/game_of_life.rs +++ b/examples/game_of_life.rs @@ -18,6 +18,7 @@ use bevy_mod_scripting_core::{ event::ScriptCallbackEvent, script::ScriptComponent, systems::event_handler, }; use bevy_mod_scripting_lua::LuaScriptingPlugin; +use bevy_mod_scripting_rhai::RhaiScriptingPlugin; use clap::Parser; // CONSOLE SETUP @@ -45,18 +46,19 @@ fn run_script_cmd( ) { if let Some(Ok(command)) = log.take() { match command { - GameOfLifeCommand::Start => { + GameOfLifeCommand::Start { language } => { // create an entity with the script component bevy::log::info!( "Starting game of life spawning entity with the game_of_life.lua script" ); - commands.spawn(ScriptComponent::new( - vec!["scripts/game_of_life.lua".into()], - )); + commands.spawn(ScriptComponent::new(vec![format!( + "scripts/game_of_life.{language}" + ) + .into()])); } GameOfLifeCommand::Stop => { // we can simply drop the handle, or manually delete, I'll just drop the handle - bevy::log::info!("Stopping game of life by dropping the handle to the script"); + bevy::log::info!("Stopping game of life by dropping the handles to all scripts"); // I am not mapping the handles to the script names, so I'll just clear the entire list loaded_scripts.0.clear(); @@ -75,9 +77,13 @@ fn run_script_cmd( #[command(name = "gol")] /// Controls the game of life pub enum GameOfLifeCommand { - /// Start the game of life by spawning an entity with the game_of_life.lua script - Start, - /// Stop the game of life by dropping a handle to the game_of_life.lua script + /// Start the game of life by spawning an entity with the game_of_life.{language} script + Start { + /// The language to use for the script, i.e. "lua" or "rhai" + #[clap(short, long, default_value = "lua")] + language: String, + }, + /// Stop the game of life by dropping a handle to the game_of_life script Stop, } @@ -87,6 +93,7 @@ fn game_of_life_app(app: &mut App) -> &mut App { .add_plugins(( // for scripting LuaScriptingPlugin::default(), + RhaiScriptingPlugin::default(), ScriptFunctionsPlugin, )) .register_type::() @@ -102,7 +109,9 @@ fn game_of_life_app(app: &mut App) -> &mut App { send_on_update.after(update_rendered_state), ( event_handler::, + event_handler::, event_handler::, + event_handler::, ) .after(send_on_update), ), @@ -146,9 +155,10 @@ pub fn load_script_assets( asset_server: Res, mut loaded_scripts: ResMut, ) { - loaded_scripts - .0 - .push(asset_server.load("scripts/game_of_life.lua")); + loaded_scripts.0.extend(vec![ + asset_server.load("scripts/game_of_life.lua"), + asset_server.load("scripts/game_of_life.rhai"), + ]); } pub fn register_script_functions(app: &mut App) -> &mut App { diff --git a/examples/rhai/game_of_life.rs b/examples/rhai/game_of_life.rs deleted file mode 100644 index 6ed07482dd..0000000000 --- a/examples/rhai/game_of_life.rs +++ /dev/null @@ -1,224 +0,0 @@ -use bevy::{ - diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, - image::ImageSampler, - prelude::*, - reflect::Reflect, - render::{ - render_asset::RenderAssetUsages, - render_resource::{Extent3d, TextureDimension, TextureFormat}, - }, - window::{PrimaryWindow, WindowResized}, -}; - -use bevy_mod_scripting::prelude::*; -use bevy_mod_scripting_rhai::rhai::packages::Package; -use bevy_script_api::rhai::{std::RegisterVecType, RegisterForeignRhaiType}; -use rhai_rand::RandomPackage; - -#[derive(Clone, Debug, Default, Reflect, Component)] -#[reflect(Component)] -pub struct LifeState { - pub cells: Vec, -} - -#[derive(Default)] -pub struct LifeAPI; - -impl APIProvider for LifeAPI { - type APITarget = Engine; - type ScriptContext = RhaiContext; - type DocTarget = RhaiDocFragment; - - fn attach_api(&mut self, api: &mut Self::APITarget) -> Result<(), ScriptError> { - api.register_vec_functions::(); - let random = RandomPackage::new(); - api.set_max_expr_depths(999, 999); - - // Load the package into the `Engine` - random.register_into_engine(api); - Ok(()) - } - - fn register_with_app(&self, app: &mut App) { - // this will resolve retrievals of this component to our custom rhai object - app.register_type::(); - app.register_type::(); - app.register_foreign_rhai_type::>(); - } -} - -#[derive(Reflect, Resource)] -#[reflect(Resource)] -pub struct Settings { - physical_grid_dimensions: (u32, u32), - display_grid_dimensions: (u32, u32), - border_thickness: u32, - live_color: u8, - dead_color: u8, -} - -impl Default for Settings { - fn default() -> Self { - Self { - border_thickness: 1, - live_color: 255u8, - dead_color: 0u8, - physical_grid_dimensions: (44, 25), - display_grid_dimensions: (0, 0), - } - } -} - -pub fn setup( - mut commands: Commands, - mut assets: ResMut>, - asset_server: Res, - settings: Res, -) { - let mut image = Image::new_fill( - Extent3d { - width: settings.physical_grid_dimensions.0, - height: settings.physical_grid_dimensions.1, - depth_or_array_layers: 1, - }, - TextureDimension::D2, - &[0u8], - TextureFormat::R8Unorm, - RenderAssetUsages::RENDER_WORLD | RenderAssetUsages::MAIN_WORLD, - ); - - image.sampler = ImageSampler::nearest(); - - let script_path = "scripts/game_of_life.rhai"; - - commands.spawn(Camera2d); - commands - .spawn(Sprite { - image: assets.add(image), - custom_size: Some(Vec2::new( - settings.display_grid_dimensions.0 as f32, - settings.display_grid_dimensions.1 as f32, - )), - color: Color::srgb(1.0, 0.388, 0.278), // TOMATO - ..Default::default() - }) - .insert(LifeState { - cells: vec![ - 0u8; - (settings.physical_grid_dimensions.0 * settings.physical_grid_dimensions.1) - as usize - ], - }) - .insert(ScriptCollection:: { - scripts: vec![Script::new( - script_path.to_owned(), - asset_server.load(script_path), - )], - }); -} - -pub fn sync_window_size( - mut resize_event: EventReader, - mut settings: ResMut, - mut query: Query<&mut Sprite, With>, - primary_windows: Query<&Window, With>, -) { - if let Some(e) = resize_event - .read() - .filter(|e| primary_windows.get(e.window).is_ok()) - .last() - { - let primary_window = primary_windows.get(e.window).unwrap(); - settings.display_grid_dimensions = ( - primary_window.physical_width(), - primary_window.physical_height(), - ); - - // resize all game's of life, retain aspect ratio and fit the entire game in the window - for mut sprite in query.iter_mut() { - let scale = if settings.physical_grid_dimensions.0 > settings.physical_grid_dimensions.1 - { - // horizontal is longer - settings.display_grid_dimensions.1 as f32 - / settings.physical_grid_dimensions.1 as f32 - } else { - // vertical is longer - settings.display_grid_dimensions.0 as f32 - / settings.physical_grid_dimensions.0 as f32 - }; - - sprite.custom_size = Some(Vec2::new( - (settings.physical_grid_dimensions.0 as f32) * scale, - (settings.physical_grid_dimensions.1 as f32) * scale, - )); - } - } -} - -/// Runs after LifeState components are updated, updates their rendered representation -pub fn update_rendered_state( - mut assets: ResMut>, - query: Query<(&LifeState, &Sprite)>, -) { - for (new_state, old_rendered_state) in query.iter() { - let old_rendered_state = assets - .get_mut(&old_rendered_state.image) - .expect("World is not setup correctly"); - - old_rendered_state.data = new_state.cells.clone(); - } -} - -/// Sends events allowing scripts to drive update logic -pub fn send_on_update(mut events: PriorityEventWriter>) { - events.send( - RhaiEvent { - hook_name: "on_update".to_owned(), - args: (), - recipients: Recipients::All, - }, - 1, - ) -} - -/// Sends initialization event -pub fn send_init(mut events: PriorityEventWriter>) { - events.send( - RhaiEvent { - hook_name: "init".to_owned(), - args: (), - recipients: Recipients::All, - }, - 0, - ) -} - -/// how often to step the simulation -const UPDATE_FREQUENCY: f64 = 1.0 / 30.0; - -fn main() -> std::io::Result<()> { - let mut app = App::new(); - - app.add_plugins(DefaultPlugins) - .insert_resource(Time::::from_seconds(UPDATE_FREQUENCY)) - .add_plugins(LogDiagnosticsPlugin::default()) - .add_plugins(FrameTimeDiagnosticsPlugin) - .add_plugins(ScriptingPlugin) - .init_resource::() - .add_systems(Startup, setup) - .add_systems(Startup, send_init) - .add_systems(Update, sync_window_size) - .add_systems(FixedUpdate, (update_rendered_state, send_on_update).chain()) - .add_systems( - FixedUpdate, - script_event_handler::, 0, 1>, - ) - .add_script_host::>(PostUpdate) - .add_api_provider::>(Box::new(RhaiBevyAPIProvider)) - .add_api_provider::>(Box::new(LifeAPI)) - .update_documentation::>(); - - app.run(); - - Ok(()) -} From 4aba668496bb46efad8dd0c88d5ec279f79c09a7 Mon Sep 17 00:00:00 2001 From: makspll Date: Wed, 8 Jan 2025 19:08:44 +0000 Subject: [PATCH 02/21] rhai re-implementation WIP --- .vscode/settings.json | 5 +- assets/scripts/game_of_life.rhai | 19 +-- check.sh | 3 +- crates/bevy_mod_scripting_core/src/asset.rs | 13 +- .../src/bindings/allocator.rs | 1 - .../src/bindings/function/from.rs | 19 +++ .../src/bindings/function/mod.rs | 9 +- .../src/bindings/function/script_function.rs | 2 +- .../bevy_mod_scripting_core/src/commands.rs | 51 +++---- crates/bevy_mod_scripting_core/src/handler.rs | 2 +- crates/bevy_mod_scripting_core/src/lib.rs | 67 +++++--- crates/bevy_mod_scripting_core/src/systems.rs | 39 +++-- .../bevy_mod_scripting_functions/Cargo.toml | 3 + .../bevy_mod_scripting_functions/src/lib.rs | 3 + .../src/test_functions.rs | 105 +++++++++++++ .../bevy_mod_scripting_lua/Cargo.toml | 3 +- .../bevy_mod_scripting_lua/src/lib.rs | 2 + .../bevy_mod_scripting_rhai/Cargo.toml | 14 ++ .../bevy_mod_scripting_rhai/src/lib.rs | 2 + .../tests/rhai_tests.rs | 144 ++++++++++++++++++ crates/test_utils/src/test_data.rs | 44 ++++-- crates/xtask/src/main.rs | 42 ++++- examples/game_of_life.rs | 3 +- 23 files changed, 486 insertions(+), 109 deletions(-) create mode 100644 crates/bevy_mod_scripting_functions/src/test_functions.rs create mode 100644 crates/languages/bevy_mod_scripting_rhai/tests/rhai_tests.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index ae2266a134..84e1df89b7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,7 +10,7 @@ }, "rust-analyzer.rustc.source": "discover", "rust-analyzer.linkedProjects": [ - "./crates/bevy_api_gen/Cargo.toml", + // "./crates/bevy_api_gen/Cargo.toml", "Cargo.toml", ], "rust-analyzer.check.invocationStrategy": "per_workspace", @@ -28,5 +28,8 @@ "rust-analyzer.runnables.extraArgs": [ "--profile=release-with-debug", ], + "rust-analyzer.cargo.features": [ + "bevy_mod_scripting_functions/test_functions" + ] // "rust-analyzer.semanticHighlighting.operator.enable": false } \ No newline at end of file diff --git a/assets/scripts/game_of_life.rhai b/assets/scripts/game_of_life.rhai index fee141bf8a..b388f01fa6 100644 --- a/assets/scripts/game_of_life.rhai +++ b/assets/scripts/game_of_life.rhai @@ -1,13 +1,14 @@ -fn init() { - let LifeState = world.get_type_by_name("LifeState"); - let life_state = world.get_component(entity,LifeState); - let cells = life_state.cells; +fn on_script_loaded() { + world.info("Game of Life script loaded"); + // let LifeState = world.get_type_by_name("LifeState"); + // let life_state = world.get_component(entity,LifeState); + // let cells = life_state.cells; - // set some cells alive - for x in 1..10000 { - let index = rand(0..cells.len()); - cells[index] = 255; - } + // // set some cells alive + // for x in 1..10000 { + // let index = rand(0..cells.len()); + // cells[index] = 255; + // } } fn on_update() { diff --git a/check.sh b/check.sh index 31a157ed1d..3042918ae1 100755 --- a/check.sh +++ b/check.sh @@ -6,5 +6,6 @@ CURRENT_DIR=$(basename "$PWD") if [[ "$CURRENT_DIR" == "bevy_api_gen" ]]; then cargo +nightly-2024-11-05 clippy --all-targets --message-format=json else - cargo clippy --workspace --all-targets --message-format=json --features="lua54 rhai rune bevy/file_watcher bevy/multi_threaded" + cargo xtask check --ide-mode + # cargo clippy --workspace --all-targets --message-format=json --features="lua54 rhai rune bevy/file_watcher bevy/multi_threaded " fi diff --git a/crates/bevy_mod_scripting_core/src/asset.rs b/crates/bevy_mod_scripting_core/src/asset.rs index bbfe99fc10..92a5a0dbf9 100644 --- a/crates/bevy_mod_scripting_core/src/asset.rs +++ b/crates/bevy_mod_scripting_core/src/asset.rs @@ -17,8 +17,6 @@ pub enum Language { Lua, Rune, External(Cow<'static, str>), - /// Initial setting before being processed by the script synchronization systems - Unset, /// Set if none of the asset path to language mappers match Unknown, } @@ -30,7 +28,6 @@ impl std::fmt::Display for Language { Language::Lua => "Lua".fmt(f), Language::Rune => "Rune".fmt(f), Language::External(cow) => cow.fmt(f), - Language::Unset => "Unset".fmt(f), Language::Unknown => "Unknown".fmt(f), } } @@ -42,9 +39,9 @@ pub struct ScriptAsset { pub content: Box<[u8]>, /// The virtual filesystem path of the asset, used to map to the script Id for asset backed scripts pub asset_path: PathBuf, - pub language: Language, } +#[derive(Default)] pub struct ScriptAssetLoader { /// The file extensions this loader should handle pub extensions: &'static [&'static str], @@ -76,7 +73,6 @@ impl AssetLoader for ScriptAssetLoader { let asset = ScriptAsset { content: content.into_boxed_slice(), asset_path: load_context.path().to_owned(), - language: Language::Unset, }; Ok(asset) } @@ -97,7 +93,7 @@ impl ScriptAssetSettings { for mapper in &self.script_language_mappers { let language = (mapper.map)(path); match language { - Language::Unset | Language::Unknown => continue, + Language::Unknown => continue, _ => return language, } } @@ -112,9 +108,7 @@ impl Default for ScriptAssetSettings { script_id_mapper: AssetPathToScriptIdMapper { map: (|path: &Path| path.to_string_lossy().into_owned().into()), }, - script_language_mappers: vec![AssetPathToLanguageMapper { - map: (|_: &Path| Language::Unset), - }], + script_language_mappers: vec![], } } } @@ -144,6 +138,7 @@ pub struct ScriptMetadata { impl ScriptMetadataStore { pub fn insert(&mut self, id: AssetId, meta: ScriptMetadata) { + // TODO: new generations of assets are not going to have the same ID as the old one self.map.insert(id, meta); } diff --git a/crates/bevy_mod_scripting_core/src/bindings/allocator.rs b/crates/bevy_mod_scripting_core/src/bindings/allocator.rs index 2499dd41b3..52b56edda1 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/allocator.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/allocator.rs @@ -195,7 +195,6 @@ impl ReflectAllocator { /// Runs a garbage collection pass on the allocations, removing any allocations which have no more strong references /// Needs to be run periodically to prevent memory leaks pub fn clean_garbage_allocations(&mut self) { - bevy::log::trace!("Cleaning garbage allocations"); self.allocations.retain(|k, _| Arc::strong_count(&k.0) > 1); } diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/from.rs b/crates/bevy_mod_scripting_core/src/bindings/function/from.rs index 383e4569f5..9cd2c77bb9 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/from.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/from.rs @@ -11,6 +11,8 @@ use std::{ path::PathBuf, }; +use super::script_function::DynamicScriptFunctionMut; + /// Describes the procedure for constructing a value of type `T` from a [`ScriptValue`]. /// /// The [`FromScript::This`] associated type is used to allow for the implementation of this trait to return @@ -387,3 +389,20 @@ where } } } + +impl FromScript for DynamicScriptFunctionMut { + type This<'w> = Self; + + fn from_script(value: ScriptValue, _: WorldGuard<'_>) -> Result, InteropError> + where + Self: Sized, + { + match value { + ScriptValue::Function(f) => Ok(f), + _ => Err(InteropError::value_mismatch( + std::any::TypeId::of::(), + value, + )), + } + } +} diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/mod.rs b/crates/bevy_mod_scripting_core/src/bindings/function/mod.rs index ae9f0f02b6..449b632b46 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/mod.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/mod.rs @@ -8,9 +8,7 @@ use script_function::{CallerContext, DynamicScriptFunction, DynamicScriptFunctio use crate::error::InteropError; -use super::{ - pretty_print::DisplayWithWorld, script_value::ScriptValue, WorldCallbackAccess, WorldGuard, -}; +use super::{script_value::ScriptValue, WorldCallbackAccess, WorldGuard}; /// Can be implemented for callables which require dynamic access to the world to be called. /// @@ -33,11 +31,6 @@ impl CallScriptFunction for DynamicScriptFunction { ) -> Result { let args = args.into_iter().collect::>(); let world_callback_access = WorldCallbackAccess::from_guard(world.clone()); - bevy::log::debug!( - "Calling function {} with args {:?}", - self.name(), - args.display_with_world(world.clone()) - ); // should we be inlining call errors into the return value? let return_val = self.call(context, world_callback_access, args); match return_val { diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs b/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs index 3eb7bf2275..0692d7b9ce 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs @@ -116,7 +116,7 @@ pub trait GetFunctionTypeDependencies { /// The caller context when calling a script function. /// Functions can choose to react to caller preferences such as converting 1-indexed numbers to 0-indexed numbers -#[derive(Clone, Copy, Debug, Reflect)] +#[derive(Clone, Copy, Debug, Reflect, Default)] #[reflect(opaque)] pub struct CallerContext { pub convert_to_0_indexed: bool, diff --git a/crates/bevy_mod_scripting_core/src/commands.rs b/crates/bevy_mod_scripting_core/src/commands.rs index 17eb7ce1a9..5eece951df 100644 --- a/crates/bevy_mod_scripting_core/src/commands.rs +++ b/crates/bevy_mod_scripting_core/src/commands.rs @@ -120,10 +120,6 @@ impl CreateOrUpdateScript

{ impl Command for CreateOrUpdateScript

{ fn apply(self, world: &mut bevy::prelude::World) { - debug!( - "CreateOrUpdateScript command applying to script_id: {}", - self.id - ); let settings = world .get_resource::>() .unwrap() @@ -148,24 +144,28 @@ impl Command for CreateOrUpdateScript

{ let mut script = scripts.scripts.get_mut(&self.id); let previous_context_id = script.as_ref().map(|s| s.context_id); debug!( - "CreateOrUpdateScript command applying with to (script_id: {}, previous_context_id: {:?})", + "{}: CreateOrUpdateScript command applying (script_id: {}, previous_context_id: {:?})", + P::LANGUAGE, self.id, previous_context_id ); // If None assign new context ID, otherwise assign the old one // If re-loading and different from the previous one, the old one will be removed let current_context_id = (assigner.assign)(script.as_deref(), &self.id, &self.content, &mut contexts); - debug!("Context assigned: {:?}", current_context_id); + + debug!("{}: New context assigned?: {:?}", P::LANGUAGE, current_context_id.is_none() || current_context_id != previous_context_id); let current_context_id = if let Some(id) = current_context_id { // reload existing context id } else { + let log_context = format!("{}: Loading script: {}", P::LANGUAGE, self.id); + bevy::log::info!("{}", log_context); let ctxt = (builder.load)(&self.id, &self.content, &settings.context_initializers, &settings.context_pre_handling_initializers, world, &mut runtime.runtime); match ctxt { Ok(ctxt) => contexts.insert(ctxt), Err(e) => { - handle_script_errors(world, [e.with_context(format!("Loading script with id: {}. Language: {}", self.id, P::LANGUAGE))].into_iter()); + handle_script_errors(world, [e.with_context(log_context)].into_iter()); return; } } @@ -174,22 +174,21 @@ impl Command for CreateOrUpdateScript

{ if let Some(previous) = previous_context_id { if let Some(previous_context_id) = contexts.get_mut(previous) { + let log_context = format!("{}: Reloading script: {}.", P::LANGUAGE, self.id); + bevy::log::info!("{}", log_context); match (builder.reload)(&self.id, &self.content, previous_context_id, &settings.context_initializers, &settings.context_pre_handling_initializers, world, &mut runtime.runtime) { Ok(_) => {}, Err(e) => { - handle_script_errors(world, [e.with_context(format!("Reloading script with id: {}. Language: {}", self.id, P::LANGUAGE))].into_iter()); + handle_script_errors(world, [e.with_context(log_context)].into_iter()); return; } }; } else { - bevy::log::error!("Could not find previous context with id: {}. Could not reload script id: {}", previous, self.id); + bevy::log::error!("{}: Could not find previous context with id: {}. Could not reload script: {}", P::LANGUAGE, previous, self.id); } if previous != current_context_id { - debug!( - "Script is being moved to a new context with id: {}, removing up old context.", - current_context_id - ); + bevy::log::info!("{}: Unloading script with id: {}. As it was assigned to a new context", P::LANGUAGE, self.id); script.as_deref_mut().unwrap().context_id = current_context_id; (assigner.remove)(previous, script.unwrap(), &mut contexts); } @@ -199,24 +198,22 @@ impl Command for CreateOrUpdateScript

{ match (runner)(vec![], bevy::ecs::entity::Entity::from_raw(0), &self.id, &OnScriptLoaded::into_callback_label(), context, &settings.context_pre_handling_initializers, &mut runtime.runtime, world) { Ok(_) => {}, Err(e) => { - handle_script_errors(world, [e.with_context(format!("Running initialization hook for script with id: {}. Language: {}", self.id, P::LANGUAGE))].into_iter()); + handle_script_errors(world, [e.with_context(format!("{}: Running initialization hook for script with id: {}", P::LANGUAGE, self.id))].into_iter()); }, } + + // we only want to insert the script if a context is present, otherwise something went wrong + scripts.scripts.insert( + self.id.clone(), + Script { + id: self.id, + asset: self.asset, + context_id: current_context_id, + }, + ); } else { - bevy::log::error!("Could not find context with id: {}. Could not run initialization hook for script id: {}. This may be because the script failed to load.", current_context_id, self.id); + bevy::log::error!("{}: Context loading failed for script: {}. Did not run on_script_loaded hook",P::LANGUAGE ,self.id); } - - // now we can insert the actual script - scripts.scripts.insert( - self.id.clone(), - Script { - id: self.id, - asset: self.asset, - context_id: current_context_id, - }, - ); - - // finally we trigger on_script_loaded }); world.insert_resource(settings); world.insert_non_send_resource(runtime); diff --git a/crates/bevy_mod_scripting_core/src/handler.rs b/crates/bevy_mod_scripting_core/src/handler.rs index fdc6784b09..dff84c585a 100644 --- a/crates/bevy_mod_scripting_core/src/handler.rs +++ b/crates/bevy_mod_scripting_core/src/handler.rs @@ -16,7 +16,7 @@ pub type HandlerFn

= fn( pre_handling_initializers: &[ContextPreHandlingInitializer

], runtime: &mut

::R, world: &mut World, -) -> Result<(), ScriptError>; +) -> Result; /// A resource that holds the settings for the callback handler for a specific combination of type parameters #[derive(Resource)] diff --git a/crates/bevy_mod_scripting_core/src/lib.rs b/crates/bevy_mod_scripting_core/src/lib.rs index 13e5bcef0f..adb8310717 100644 --- a/crates/bevy_mod_scripting_core/src/lib.rs +++ b/crates/bevy_mod_scripting_core/src/lib.rs @@ -65,6 +65,11 @@ pub struct ScriptingPlugin { /// The context assigner for assigning contexts to scripts, if not provided default strategy of keeping each script in its own context is used pub context_assigner: Option>, pub language_mapper: Option, + + /// initializers for the contexts, run when loading the script + pub context_initializers: Vec>, + /// initializers for the contexts run every time before handling events + pub context_pre_handling_initializers: Vec>, } impl Default for ScriptingPlugin

@@ -79,25 +84,15 @@ where context_builder: Default::default(), context_assigner: Default::default(), language_mapper: Default::default(), + context_initializers: Default::default(), + context_pre_handling_initializers: Default::default(), } } } impl Plugin for ScriptingPlugin

{ fn build(&self, app: &mut bevy::prelude::App) { - app.add_event::() - .add_event::() - .init_resource::() - .init_resource::() - .init_resource::() - .init_resource::() - .init_asset::() - .register_asset_loader(ScriptAssetLoader { - extensions: &[], - preprocessor: None, - }) - .insert_resource(self.runtime_settings.as_ref().cloned().unwrap_or_default()) - .init_resource::() + app.insert_resource(self.runtime_settings.as_ref().cloned().unwrap_or_default()) .insert_non_send_resource::>(RuntimeContainer { runtime: (self.runtime_builder)(), }) @@ -113,7 +108,7 @@ impl Plugin for ScriptingPlugin

{ }); register_script_plugin_systems::

(app); - register_systems(app); + once_per_app_init(app); if let Some(language_mapper) = &self.language_mapper { app.world_mut() @@ -124,17 +119,55 @@ impl Plugin for ScriptingPlugin

{ } register_types(app); + + for initializer in self.context_initializers.iter() { + app.add_context_initializer::

(*initializer); + } + + for initializer in self.context_pre_handling_initializers.iter() { + app.add_context_pre_handling_initializer::

(*initializer); + } } } -// One of registration of systems per bevy application -fn register_systems(app: &mut App) { +impl ScriptingPlugin

{ + /// Adds a context initializer to the plugin + pub fn add_context_initializer(&mut self, initializer: ContextInitializer

) -> &mut Self { + self.context_initializers.push(initializer); + self + } + + /// Adds a context pre-handling initializer to the plugin + pub fn add_context_pre_handling_initializer( + &mut self, + initializer: ContextPreHandlingInitializer

, + ) -> &mut Self { + self.context_pre_handling_initializers.push(initializer); + self + } +} + +// One of registration of things that need to be done only once per app +fn once_per_app_init(app: &mut App) { static INITIALIZED: AtomicBool = AtomicBool::new(false); if INITIALIZED.fetch_or(true, std::sync::atomic::Ordering::Relaxed) { return; } + app.add_event::() + .add_event::() + .init_resource::() + .init_resource::() + .init_resource::() + .init_resource::() + .init_asset::() + .init_resource::() + .register_asset_loader(ScriptAssetLoader { + extensions: &[], + preprocessor: None, + }); + app.add_systems( PostUpdate, ( @@ -303,7 +336,7 @@ mod test { impl IntoScriptPluginParams for Plugin { type C = C; type R = R; - const LANGUAGE: Language = Language::Unset; + const LANGUAGE: Language = Language::Unknown; } app.add_plugins(AssetPlugin::default()); diff --git a/crates/bevy_mod_scripting_core/src/systems.rs b/crates/bevy_mod_scripting_core/src/systems.rs index 78ce455590..5dcdf98d63 100644 --- a/crates/bevy_mod_scripting_core/src/systems.rs +++ b/crates/bevy_mod_scripting_core/src/systems.rs @@ -45,25 +45,23 @@ pub fn initialize_runtime( /// Listens to `AssetEvent::Added` events and populates the script metadata store pub fn insert_script_metadata( mut events: EventReader>, - mut script_assets: ResMut>, + script_assets: Res>, mut asset_path_map: ResMut, settings: Res, ) { for event in events.read() { if let AssetEvent::Added { id } = event { - let asset = script_assets.get_mut(*id); + let asset = script_assets.get(*id); if let Some(asset) = asset { let path = &asset.asset_path; let converter = settings.script_id_mapper.map; let script_id = converter(path); let language = settings.select_script_language(path); - asset.language = language.clone(); let metadata = ScriptMetadata { script_id, language, }; - info!("Populating script metadata for script: {:?}:", metadata); asset_path_map.insert(*id, metadata); } else { @@ -124,9 +122,10 @@ pub fn sync_script_data( } info!( - "{}: Dispatching Creation command for script: {:?}", + "{}: Dispatching Creation/Modification command for script: {:?}. Asset Id: {}", P::LANGUAGE, - metadata + metadata, + id ); if let Some(asset) = script_assets.get(*id) { @@ -150,6 +149,12 @@ pub fn sync_script_data( } }; + info!( + "{}: Dispatching Deletion command for script: {:?}. Asset Id: {}", + P::LANGUAGE, + metadata, + id + ); commands.queue(DeleteScript::

::new(metadata.script_id.clone())); } _ => return, @@ -180,8 +185,6 @@ pub fn event_handler( Query<(Entity, Ref)>, )>, ) { - trace!("Handling events with label `{}`", L::into_callback_label()); - let mut runtime_container = world .remove_non_send_resource::>() .unwrap_or_else(|| { @@ -249,10 +252,16 @@ pub fn event_handler( continue; } }; - let ctxt = script_contexts - .contexts - .get_mut(&script.context_id) - .unwrap(); + + let ctxt = match script_contexts.contexts.get_mut(&script.context_id) { + Some(ctxt) => ctxt, + None => { + // if we don't have a context for the script, it's either: + // 1. a script for a different language, in which case we ignore it + // 2. something went wrong. This should not happen though and it's best we ignore this + continue; + } + }; let handler_result = (handler)( event.args.clone(), @@ -269,7 +278,7 @@ pub fn event_handler( .with_context(format!("Event handling for: Language: {}", P::LANGUAGE)) }); - push_err_and_continue!(errors, handler_result) + let _ = push_err_and_continue!(errors, handler_result); } } } @@ -387,7 +396,7 @@ mod test { |args, entity, script, _, ctxt, _, runtime, _| { ctxt.invocations.extend(args); runtime.invocations.push((entity, script.clone())); - Ok(()) + Ok(ScriptValue::Unit) }, runtime, contexts, @@ -474,7 +483,7 @@ mod test { |args, entity, script, _, ctxt, _, runtime, _| { ctxt.invocations.extend(args); runtime.invocations.push((entity, script.clone())); - Ok(()) + Ok(ScriptValue::Unit) }, runtime, contexts, diff --git a/crates/bevy_mod_scripting_functions/Cargo.toml b/crates/bevy_mod_scripting_functions/Cargo.toml index c694f946a1..01f607802b 100644 --- a/crates/bevy_mod_scripting_functions/Cargo.toml +++ b/crates/bevy_mod_scripting_functions/Cargo.toml @@ -14,6 +14,7 @@ readme = "readme.md" [features] core_functions = [] bevy_bindings = [] +test_functions = ["test_utils", "regex"] [dependencies] @@ -33,3 +34,5 @@ bevy = { workspace = true, features = [ uuid = "1.11" smol_str = "0.2.2" bevy_mod_scripting_core = { workspace = true } +test_utils = { workspace = true, optional = true } +regex = { version = "1.11", optional = true } diff --git a/crates/bevy_mod_scripting_functions/src/lib.rs b/crates/bevy_mod_scripting_functions/src/lib.rs index 3a446b9e7d..5fbe0a3eac 100644 --- a/crates/bevy_mod_scripting_functions/src/lib.rs +++ b/crates/bevy_mod_scripting_functions/src/lib.rs @@ -3,6 +3,9 @@ use ::bevy::prelude::*; pub mod bevy_bindings; pub mod core; +#[cfg(feature = "test_functions")] +pub mod test_functions; + pub mod namespaced_register; pub use core::*; diff --git a/crates/bevy_mod_scripting_functions/src/test_functions.rs b/crates/bevy_mod_scripting_functions/src/test_functions.rs new file mode 100644 index 0000000000..94039590ff --- /dev/null +++ b/crates/bevy_mod_scripting_functions/src/test_functions.rs @@ -0,0 +1,105 @@ +use std::sync::Arc; + +use crate::NamespaceBuilder; +use bevy::{ + prelude::{Entity, World}, + reflect::{Reflect, TypeRegistration}, +}; +use bevy_mod_scripting_core::{ + bindings::{ + access_map::ReflectAccessId, + function::{ + script_function::{CallerContext, DynamicScriptFunctionMut}, + CallScriptFunction, + }, + pretty_print::DisplayWithWorld, + ReflectReference, ScriptTypeRegistration, WorldCallbackAccess, + }, + error::InteropError, +}; +use test_utils::test_data::EnumerateTestComponents; + +pub fn register_test_functions(world: &mut World) { + NamespaceBuilder::::new_unregistered(world) + .register("_get_mock_type", |s: WorldCallbackAccess| { + let world = s.try_read().unwrap(); + #[derive(Reflect)] + struct Dummy; + let reg = + ScriptTypeRegistration::new(Arc::new(TypeRegistration::of::()), None, None); + let allocator = world.allocator(); + let mut allocator = allocator.write(); + ReflectReference::new_allocated(reg, &mut allocator) + }) + .register( + "_get_entity_with_test_component", + |s: WorldCallbackAccess, name: String| { + let world = s.try_read().unwrap(); + World::enumerate_test_components() + .iter() + .find(|(n, _, _)| n.contains(&name)) + .map(|(_, _, c)| { + let allocator = world.allocator(); + let mut allocator = allocator.write(); + + ReflectReference::new_allocated( + c.unwrap_or(Entity::from_raw(9999)), + &mut allocator, + ) + }) + }, + ) + .register( + "_assert_throws", + |s: WorldCallbackAccess, mut f: DynamicScriptFunctionMut, reg: String| { + let world = s.try_read().unwrap(); + + let result = + f.call_script_function(vec![], world.clone(), CallerContext::default()); + let err = match result { + Ok(_) => { + return Err(InteropError::external_error( + "Expected function to throw error, but it did not.".into(), + )) + } + Err(e) => e.display_with_world(world.clone()), + }; + + let regex = regex::Regex::new(®).unwrap(); + if regex.is_match(&err) { + Ok(()) + } else { + Err(InteropError::external_error( + format!( + "Expected error message to match the regex: \n{}\n\nBut got:\n{}", + regex.as_str(), + err + ) + .into(), + )) + } + }, + ) + .register( + "_set_write_access", + |s: WorldCallbackAccess, ref_: ReflectReference| { + let world = s.try_read().unwrap(); + + world + .claim_write_access(ReflectAccessId::for_reference(ref_.base.base_id).unwrap()); + }, + ) + .register( + "_set_read_access", + |s: WorldCallbackAccess, ref_: ReflectReference| { + let world = s.try_read().unwrap(); + + world.claim_read_access(ReflectAccessId::for_reference(ref_.base.base_id).unwrap()); + }, + ) + .register("_claim_global_access", |s: WorldCallbackAccess| { + let world = s.try_read().unwrap(); + + world.claim_global_access(); + }); +} diff --git a/crates/languages/bevy_mod_scripting_lua/Cargo.toml b/crates/languages/bevy_mod_scripting_lua/Cargo.toml index c277aa298b..0625d7df19 100644 --- a/crates/languages/bevy_mod_scripting_lua/Cargo.toml +++ b/crates/languages/bevy_mod_scripting_lua/Cargo.toml @@ -39,7 +39,8 @@ path = "src/lib.rs" [dependencies] bevy = { workspace = true, default-features = false } bevy_mod_scripting_core = { workspace = true, features = ["mlua_impls"] } -bevy_mod_scripting_functions = { workspace = true, features = [] } +bevy_mod_scripting_functions = { workspace = true, features = [ +], default-features = false } mlua = { workspace = true, features = ["vendored", "send", "macros"] } parking_lot = "0.12.1" uuid = "1.1" diff --git a/crates/languages/bevy_mod_scripting_lua/src/lib.rs b/crates/languages/bevy_mod_scripting_lua/src/lib.rs index 6b3bc6f672..088e908997 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/lib.rs @@ -47,6 +47,8 @@ impl Default for LuaScriptingPlugin { language_mapper: Some(AssetPathToLanguageMapper { map: lua_language_mapper, }), + context_initializers: Default::default(), + context_pre_handling_initializers: Default::default(), }, } } diff --git a/crates/languages/bevy_mod_scripting_rhai/Cargo.toml b/crates/languages/bevy_mod_scripting_rhai/Cargo.toml index ee0604f420..9fd764301f 100644 --- a/crates/languages/bevy_mod_scripting_rhai/Cargo.toml +++ b/crates/languages/bevy_mod_scripting_rhai/Cargo.toml @@ -19,3 +19,17 @@ path = "src/lib.rs" bevy = { workspace = true, default-features = false } rhai = { workspace = true, features = ["sync"] } bevy_mod_scripting_core = { workspace = true, features = ["rhai_impls"] } +bevy_mod_scripting_functions = { workspace = true, features = [ +], default-features = false } + +[dev-dependencies] +bevy_mod_scripting_functions = { workspace = true, features = [ + "test_functions", +] } +test_utils = { workspace = true } +libtest-mimic = "0.8" +regex = "1.11" + +[[test]] +name = "rhai_tests" +harness = false diff --git a/crates/languages/bevy_mod_scripting_rhai/src/lib.rs b/crates/languages/bevy_mod_scripting_rhai/src/lib.rs index dc06088ea1..83d1040b6a 100644 --- a/crates/languages/bevy_mod_scripting_rhai/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_rhai/src/lib.rs @@ -49,6 +49,8 @@ impl Default for RhaiScriptingPlugin { language_mapper: Some(AssetPathToLanguageMapper { map: rhai_language_mapper, }), + context_initializers: Default::default(), + context_pre_handling_initializers: Default::default(), }, } } diff --git a/crates/languages/bevy_mod_scripting_rhai/tests/rhai_tests.rs b/crates/languages/bevy_mod_scripting_rhai/tests/rhai_tests.rs new file mode 100644 index 0000000000..df5325a954 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_rhai/tests/rhai_tests.rs @@ -0,0 +1,144 @@ +use bevy::{ + app::App, + asset::AssetPlugin, + prelude::{Children, Entity, HierarchyPlugin, Parent, World}, + reflect::{Reflect, TypeRegistration}, +}; +use bevy_mod_scripting_core::{ + bindings::{ + access_map::ReflectAccessId, pretty_print::DisplayWithWorld, script_value::ScriptValue, + ReflectReference, ScriptTypeRegistration, WorldAccessGuard, + }, + context::ContextLoadingSettings, + error::ScriptError, + event::CallbackLabel, +}; +use bevy_mod_scripting_functions::ScriptFunctionsPlugin; +use bevy_mod_scripting_rhai::{RhaiScriptContext, RhaiScriptingPlugin}; +use libtest_mimic::{Arguments, Failed, Trial}; +use rhai::Engine; +use std::{ + fs::{self, DirEntry}, + io, panic, + path::{Path, PathBuf}, + sync::Arc, +}; +use test_utils::test_data::{setup_integration_test, setup_world, EnumerateTestComponents}; + +/// Initializes world for tests +fn init_app() -> App { + let mut app = setup_integration_test(|_, _| {}); + + app.add_plugins(RhaiScriptingPlugin::default()) + .add_plugins(ScriptFunctionsPlugin); + + app.finish(); + app.cleanup(); + + app +} + +struct Test { + code: String, + path: PathBuf, +} + +impl Test { + fn execute(self) -> Result<(), Failed> { + // let lua = Lua::new(); + // set file information + let mut app = init_app(); + app.add_systems(schedule, systems) + + // let mut lua = lua_context_load( + // &(self.name()).into(), + // self.code.as_bytes(), + // &context_settings.context_initializers, + // &context_settings.context_pre_handling_initializers, + // app.world_mut(), + // &mut (), + // ) + // .map_err(|e| { + // let world = app.world_mut(); + // let world = WorldAccessGuard::new(world); + // let msg = e.display_with_world(Arc::new(world)); + // Failed::from(msg) + // })?; + + // lua_handler( + // vec![ScriptValue::Unit], + // Entity::from_raw(1), + // &(self.name()).into(), + // &CallbackLabel::new("on_test").ok_or("invalid callback label")?, + // &mut lua, + // &context_settings.context_pre_handling_initializers, + // &mut (), + // app.world_mut(), + // ) + // .map_err(|e| { + // let world = app.world_mut(); + // let world = WorldAccessGuard::new(world); + // let msg = e.display_with_world(Arc::new(world)); + // Failed::from(msg) + // })?; + + Ok(()) + } + + fn name(&self) -> String { + format!( + "lua_test - {}", + self.path + .to_string_lossy() + .split(&format!("tests{}data", std::path::MAIN_SEPARATOR)) + .last() + .unwrap() + ) + } +} + +fn visit_dirs(dir: &Path, cb: &mut dyn FnMut(&DirEntry)) -> io::Result<()> { + if dir.is_dir() { + for entry in fs::read_dir(dir)? { + let entry = entry?; + let path = entry.path(); + if path.is_dir() { + visit_dirs(&path, cb)?; + } else { + cb(&entry); + } + } + } else { + panic!("Not a directory: {:?}", dir); + } + Ok(()) +} + +fn discover_all_tests() -> Vec { + let workspace_root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let test_root = workspace_root.join("tests").join("data"); + let mut test_files = Vec::new(); + visit_dirs(&test_root, &mut |entry| { + let path = entry.path(); + let code = fs::read_to_string(&path).unwrap(); + test_files.push(Test { code, path }); + }) + .unwrap(); + + test_files +} + +// run this with `cargo test --features lua54 --package bevy_mod_scripting_lua --test lua_tests` +// or filter using the prefix "lua test -" +fn main() { + // Parse command line arguments + let args = Arguments::from_args(); + + // Create a list of tests and/or benchmarks (in this case: two dummy tests). + let tests = discover_all_tests() + .into_iter() + .map(|t| Trial::test(t.name(), move || t.execute())); + + // Run all tests and exit the application appropriatly. + libtest_mimic::run(&args, tests.collect()).exit(); +} diff --git a/crates/test_utils/src/test_data.rs b/crates/test_utils/src/test_data.rs index c052f09504..ad0d06e4a3 100644 --- a/crates/test_utils/src/test_data.rs +++ b/crates/test_utils/src/test_data.rs @@ -4,6 +4,8 @@ use std::sync::{Arc, RwLock}; use bevy::ecs::{component::*, world::World}; use bevy::prelude::*; use bevy::reflect::*; +use bevy::render::settings::{RenderCreation, WgpuSettings}; +use bevy::render::RenderPlugin; /// Test component with Reflect and ReflectComponent registered #[derive(Component, Reflect, PartialEq, Eq, Debug)] @@ -225,11 +227,7 @@ impl_test_component_ids!( ] ); -/// Initializes a default world with a set of test components and resources with various properties and implemantations. -pub fn setup_world(init: F) -> World { - let mut world = World::default(); - - // find the number of ComponentId's registered, fill it up until we hit the offset +fn init_world(world: &mut World, init: F) { while world.components().len() < TEST_COMPONENT_ID_START { unsafe { world.register_component_with_descriptor(ComponentDescriptor::new_with_layout( @@ -241,18 +239,42 @@ pub fn setup_world(init: F) -> World { }; } - let mut type_registry = TypeRegistry::new(); - init_all_components(&mut world, &mut type_registry); + let type_registry = world.get_resource_or_init::().clone(); + let mut type_registry_guard = type_registry.0.write(); + init_all_components(world, &mut type_registry_guard); + init(world, &mut type_registry_guard); +} - init(&mut world, &mut type_registry); +fn setup_app(init: F) -> App { + let mut app = App::new(); + let world = app.world_mut(); - world.insert_resource(AppTypeRegistry(TypeRegistryArc { - internal: Arc::new(RwLock::new(type_registry)), - })); + init_world(world, init); + app +} +/// Initializes a default world with a set of test components and resources with various properties and implemantations. +pub fn setup_world(init: F) -> World { + let mut world = World::default(); + init_world(&mut world, init); world } +/// Initializes a headless app with the standard testing setup and the given plugin. +pub fn setup_integration_test(init: F) -> App { + // first setup all normal test components and resources + let mut app = setup_app(init); + + app.add_plugins(DefaultPlugins.set(RenderPlugin { + synchronous_pipeline_compilation: true, + render_creation: RenderCreation::Automatic(WgpuSettings { + backends: None, + ..default() + }), + })); + app +} + #[cfg(test)] mod test { use super::*; diff --git a/crates/xtask/src/main.rs b/crates/xtask/src/main.rs index 101d86cf23..24c29e8c2f 100644 --- a/crates/xtask/src/main.rs +++ b/crates/xtask/src/main.rs @@ -187,7 +187,15 @@ enum Xtasks { /// Build the main workspace only Build, /// Build the main workspace, apply all prefferred lints - Check, + Check { + #[clap( + long, + short, + default_value = "false", + help = "Run in the expected format for rust-analyzer's override check command" + )] + ide_mode: bool, + }, /// Build the rust crates.io docs as well as any other docs Docs { /// Open in browser @@ -209,7 +217,7 @@ impl Xtasks { fn run(self, features: Features) -> Result<()> { match self { Xtasks::Build => Self::build(features), - Xtasks::Check => Self::check(features), + Xtasks::Check { ide_mode } => Self::check(features, ide_mode), Xtasks::Docs { open, no_rust_docs } => Self::docs(open, no_rust_docs), Xtasks::Test => Self::test(features), Xtasks::CiCheck => Self::cicd(), @@ -223,7 +231,8 @@ impl Xtasks { } fn get_cargo_profile() -> Option { - Some(std::env::var("BMS_CARGO_PROFILE").unwrap_or_default()) + let val = std::env::var("BMS_CARGO_PROFILE").ok(); + val.filter(|v| !v.is_empty()) } fn cargo_metadata() -> Result { @@ -350,16 +359,26 @@ impl Xtasks { Ok(()) } - fn check(features: Features) -> Result<()> { + fn check_main_workspace(features: Features, ide_mode: bool) -> Result<()> { // start with cargo clippy + let mut clippy_args = Vec::default(); + if ide_mode { + clippy_args.push("--message-format=json"); + } + clippy_args.extend(vec!["--all-targets", "--", "-D", "warnings"]); + Self::run_workspace_command( "clippy", "Failed to run clippy", features, - vec!["--all-targets", "--", "-D", "warnings"], + clippy_args, None, )?; + if ide_mode { + return Ok(()); + } + // run cargo fmt checks Self::run_system_command( "cargo", @@ -371,6 +390,17 @@ impl Xtasks { Ok(()) } + fn check_codegen_crate(features: Features, ide_mode: bool) -> Result<()> { + // set the working directory to the codegen crate + let codegen_dir = Self::relative_workspace_dir(Path::join("crates", "bevy_api_gen"))?; + Ok(()) + } + + fn check(features: Features, ide_mode: bool) -> Result<()> { + check_main_workspace(features, ide_mode)?; + Ok(()) + } + fn docs(open: bool, no_rust_docs: bool) -> Result<()> { // find [package.metadata."docs.rs"] key in Cargo.toml if !no_rust_docs { @@ -561,7 +591,7 @@ impl Xtasks { // run lints let all_features = Features::all_features(); - Self::check(all_features.clone())?; + Self::check(all_features.clone(), false)?; // run docs Self::docs(false, false)?; diff --git a/examples/game_of_life.rs b/examples/game_of_life.rs index 2db4412cdb..583525491b 100644 --- a/examples/game_of_life.rs +++ b/examples/game_of_life.rs @@ -49,7 +49,8 @@ fn run_script_cmd( GameOfLifeCommand::Start { language } => { // create an entity with the script component bevy::log::info!( - "Starting game of life spawning entity with the game_of_life.lua script" + "Starting game of life spawning entity with the game_of_life.{} script", + language ); commands.spawn(ScriptComponent::new(vec![format!( "scripts/game_of_life.{language}" From 9c8a03237228cf1565e8622a3b18dd8bd910861c Mon Sep 17 00:00:00 2001 From: makspll Date: Wed, 8 Jan 2025 23:43:37 +0000 Subject: [PATCH 03/21] feat: switch vscode to xtask --- .vscode/settings.json | 11 +- check.sh | 12 +- .../bevy_mod_scripting_core/src/commands.rs | 2 +- .../bevy_mod_scripting_lua/src/lib.rs | 12 +- .../src/bindings/script_value.rs | 1 + .../bevy_mod_scripting_rhai/src/lib.rs | 12 +- .../tests/rhai_tests.rs | 48 +- crates/test_utils/src/test_data.rs | 1 - crates/xtask/src/main.rs | 60 +- log.out | 841 ------------------ 10 files changed, 91 insertions(+), 909 deletions(-) delete mode 100644 log.out diff --git a/.vscode/settings.json b/.vscode/settings.json index 84e1df89b7..ce5ba1c1a8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,11 +10,10 @@ }, "rust-analyzer.rustc.source": "discover", "rust-analyzer.linkedProjects": [ - // "./crates/bevy_api_gen/Cargo.toml", + "./crates/bevy_api_gen/Cargo.toml", "Cargo.toml", ], - "rust-analyzer.check.invocationStrategy": "per_workspace", - "rust-analyzer.check.invocationLocation": "workspace", + "rust-analyzer.check.invocationStrategy": "once", "rust-analyzer.check.overrideCommand": [ "/home/makspll/git/bevy_mod_scripting/check.sh" ], @@ -28,8 +27,8 @@ "rust-analyzer.runnables.extraArgs": [ "--profile=release-with-debug", ], - "rust-analyzer.cargo.features": [ - "bevy_mod_scripting_functions/test_functions" - ] + // "rust-analyzer.cargo.features": [ + // "bevy_mod_scripting_functions/test_functions" + // ] // "rust-analyzer.semanticHighlighting.operator.enable": false } \ No newline at end of file diff --git a/check.sh b/check.sh index 3042918ae1..6f8685c45e 100755 --- a/check.sh +++ b/check.sh @@ -1,11 +1,3 @@ #!/bin/bash -unset RUSTUP_TOOLCHAIN -CURRENT_DIR=$(basename "$PWD") - - -if [[ "$CURRENT_DIR" == "bevy_api_gen" ]]; then - cargo +nightly-2024-11-05 clippy --all-targets --message-format=json -else - cargo xtask check --ide-mode - # cargo clippy --workspace --all-targets --message-format=json --features="lua54 rhai rune bevy/file_watcher bevy/multi_threaded " -fi +cd "$(dirname "$0")" +cargo xtask check --ide-mode diff --git a/crates/bevy_mod_scripting_core/src/commands.rs b/crates/bevy_mod_scripting_core/src/commands.rs index 5eece951df..ac548f78ab 100644 --- a/crates/bevy_mod_scripting_core/src/commands.rs +++ b/crates/bevy_mod_scripting_core/src/commands.rs @@ -152,7 +152,7 @@ impl Command for CreateOrUpdateScript

{ // If None assign new context ID, otherwise assign the old one // If re-loading and different from the previous one, the old one will be removed let current_context_id = (assigner.assign)(script.as_deref(), &self.id, &self.content, &mut contexts); - + debug!("{}: New context assigned?: {:?}", P::LANGUAGE, current_context_id.is_none() || current_context_id != previous_context_id); let current_context_id = if let Some(id) = current_context_id { diff --git a/crates/languages/bevy_mod_scripting_lua/src/lib.rs b/crates/languages/bevy_mod_scripting_lua/src/lib.rs index 088e908997..3c98bad7f8 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/lib.rs @@ -174,7 +174,7 @@ pub fn lua_handler( pre_handling_initializers: &[ContextPreHandlingInitializer], _: &mut (), world: &mut bevy::ecs::world::World, -) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { +) -> Result { with_world(world, context, |context| { pre_handling_initializers .iter() @@ -183,7 +183,7 @@ pub fn lua_handler( let handler: Function = match context.globals().raw_get(callback_label.as_ref()) { Ok(handler) => handler, // not subscribed to this event type - Err(_) => return Ok(()), + Err(_) => return Ok(ScriptValue::Unit), }; let input = MultiValue::from_vec( @@ -192,17 +192,17 @@ pub fn lua_handler( .collect::>()?, ); - handler.call::<()>(input)?; - Ok(()) + let out = handler.call::(input)?; + Ok(out.into()) }) } /// Safely scopes world access for a lua context to the given closure's scope -pub fn with_world Result<(), ScriptError>>( +pub fn with_world Result>( world: &mut World, context: &mut Lua, f: F, -) -> Result<(), ScriptError> { +) -> Result { WorldCallbackAccess::with_callback_access(world, |guard| { context .globals() diff --git a/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs b/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs index e69de29bb2..8b13789179 100644 --- a/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs +++ b/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs @@ -0,0 +1 @@ + diff --git a/crates/languages/bevy_mod_scripting_rhai/src/lib.rs b/crates/languages/bevy_mod_scripting_rhai/src/lib.rs index 83d1040b6a..7e867627dc 100644 --- a/crates/languages/bevy_mod_scripting_rhai/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_rhai/src/lib.rs @@ -132,7 +132,7 @@ pub fn rhai_callback_handler( pre_handling_initializers: &[ContextPreHandlingInitializer], runtime: &mut RhaiRuntime, world: &mut World, -) -> Result<(), ScriptError> { +) -> Result { with_world(world, context, |context| { pre_handling_initializers .iter() @@ -144,27 +144,27 @@ pub fn rhai_callback_handler( .is_none() { // not subscribed to this handler - return Ok(()); + return Ok(ScriptValue::Unit); }; // we want the call to be able to impact the scope let options = CallFnOptions::new().rewind_scope(false); - runtime.call_fn_with_options( + let out = runtime.call_fn_with_options::( options, &mut context.scope, &context.ast, callback.as_ref(), args, )?; - Ok(()) + Ok(out) }) } -pub fn with_world Result<(), ScriptError>>( +pub fn with_world Result>( world: &mut World, context: &mut RhaiScriptContext, f: F, -) -> Result<(), ScriptError> { +) -> Result { WorldCallbackAccess::with_callback_access(world, |guard| { context.scope.push("world", guard.clone()); f(context) diff --git a/crates/languages/bevy_mod_scripting_rhai/tests/rhai_tests.rs b/crates/languages/bevy_mod_scripting_rhai/tests/rhai_tests.rs index df5325a954..d73f101f4c 100644 --- a/crates/languages/bevy_mod_scripting_rhai/tests/rhai_tests.rs +++ b/crates/languages/bevy_mod_scripting_rhai/tests/rhai_tests.rs @@ -1,42 +1,26 @@ -use bevy::{ - app::App, - asset::AssetPlugin, - prelude::{Children, Entity, HierarchyPlugin, Parent, World}, - reflect::{Reflect, TypeRegistration}, -}; -use bevy_mod_scripting_core::{ - bindings::{ - access_map::ReflectAccessId, pretty_print::DisplayWithWorld, script_value::ScriptValue, - ReflectReference, ScriptTypeRegistration, WorldAccessGuard, - }, - context::ContextLoadingSettings, - error::ScriptError, - event::CallbackLabel, -}; -use bevy_mod_scripting_functions::ScriptFunctionsPlugin; -use bevy_mod_scripting_rhai::{RhaiScriptContext, RhaiScriptingPlugin}; +// use bevy::app::App; +// use bevy_mod_scripting_functions::ScriptFunctionsPlugin; +// use bevy_mod_scripting_rhai::RhaiScriptingPlugin; use libtest_mimic::{Arguments, Failed, Trial}; -use rhai::Engine; use std::{ fs::{self, DirEntry}, io, panic, path::{Path, PathBuf}, - sync::Arc, }; -use test_utils::test_data::{setup_integration_test, setup_world, EnumerateTestComponents}; +// use test_utils::test_data::setup_integration_test; -/// Initializes world for tests -fn init_app() -> App { - let mut app = setup_integration_test(|_, _| {}); +// Initializes world for tests +// fn init_app() -> App { +// let mut app = setup_integration_test(|_, _| {}); - app.add_plugins(RhaiScriptingPlugin::default()) - .add_plugins(ScriptFunctionsPlugin); +// app.add_plugins(RhaiScriptingPlugin::default()) +// .add_plugins(ScriptFunctionsPlugin); - app.finish(); - app.cleanup(); +// app.finish(); +// app.cleanup(); - app -} +// app +// } struct Test { code: String, @@ -45,10 +29,12 @@ struct Test { impl Test { fn execute(self) -> Result<(), Failed> { + println!("Running test: {}", self.name()); + println!("Code: {}", self.code); // let lua = Lua::new(); // set file information - let mut app = init_app(); - app.add_systems(schedule, systems) + // let mut app = init_app(); + // app.add_systems(schedule, systems); // let mut lua = lua_context_load( // &(self.name()).into(), diff --git a/crates/test_utils/src/test_data.rs b/crates/test_utils/src/test_data.rs index ad0d06e4a3..7cdc12c292 100644 --- a/crates/test_utils/src/test_data.rs +++ b/crates/test_utils/src/test_data.rs @@ -1,5 +1,4 @@ use std::alloc::Layout; -use std::sync::{Arc, RwLock}; use bevy::ecs::{component::*, world::World}; use bevy::prelude::*; diff --git a/crates/xtask/src/main.rs b/crates/xtask/src/main.rs index 24c29e8c2f..8229edaef1 100644 --- a/crates/xtask/src/main.rs +++ b/crates/xtask/src/main.rs @@ -175,6 +175,15 @@ struct App { subcmd: Xtasks, } +#[derive(Debug, Clone, Default, strum::EnumString)] +#[strum(serialize_all = "snake_case")] +enum CheckKind { + #[default] + All, + Main, + Codegen, +} + #[derive(Debug, clap::Subcommand)] #[clap( name = "xtask", @@ -195,6 +204,15 @@ enum Xtasks { help = "Run in the expected format for rust-analyzer's override check command" )] ide_mode: bool, + + #[clap( + long, + short, + default_value = "all", + value_parser=clap::value_parser!(CheckKind), + help = "The kind of check to perform", + )] + kind: CheckKind, }, /// Build the rust crates.io docs as well as any other docs Docs { @@ -217,7 +235,7 @@ impl Xtasks { fn run(self, features: Features) -> Result<()> { match self { Xtasks::Build => Self::build(features), - Xtasks::Check { ide_mode } => Self::check(features, ide_mode), + Xtasks::Check { ide_mode, kind } => Self::check(features, ide_mode, kind), Xtasks::Docs { open, no_rust_docs } => Self::docs(open, no_rust_docs), Xtasks::Test => Self::test(features), Xtasks::CiCheck => Self::cicd(), @@ -361,7 +379,7 @@ impl Xtasks { fn check_main_workspace(features: Features, ide_mode: bool) -> Result<()> { // start with cargo clippy - let mut clippy_args = Vec::default(); + let mut clippy_args = vec![]; if ide_mode { clippy_args.push("--message-format=json"); } @@ -390,14 +408,42 @@ impl Xtasks { Ok(()) } - fn check_codegen_crate(features: Features, ide_mode: bool) -> Result<()> { + fn check_codegen_crate(_ide_mode: bool) -> Result<()> { // set the working directory to the codegen crate - let codegen_dir = Self::relative_workspace_dir(Path::join("crates", "bevy_api_gen"))?; + // let crates_path = Self::relative_workspace_dir(PathBuf::from("crates"))?; + // let codegen_crate_path = crates_path.join("bevy_api_gen"); + + // let mut clippy_args = vec!["+nightly-2024-12-15", "clippy"]; + // if ide_mode { + // clippy_args.push("--message-format=json"); + // } + // clippy_args.extend(vec!["--all-targets", "--", "-D", "warnings"]); + + // Self::run_system_command( + // "cargo", + // "Failed to run clippy on codegen crate", + // clippy_args, + // Some(&codegen_crate_path), + // )?; + + // TODO: for now do nothing, it's difficult to get rust analyzer to accept the nightly version + Ok(()) } - fn check(features: Features, ide_mode: bool) -> Result<()> { - check_main_workspace(features, ide_mode)?; + fn check(features: Features, ide_mode: bool, kind: CheckKind) -> Result<()> { + match kind { + CheckKind::All => { + Self::check_main_workspace(features.clone(), ide_mode)?; + Self::check_codegen_crate(ide_mode)?; + } + CheckKind::Main => { + Self::check_main_workspace(features, ide_mode)?; + } + CheckKind::Codegen => { + Self::check_codegen_crate(ide_mode)?; + } + } Ok(()) } @@ -591,7 +637,7 @@ impl Xtasks { // run lints let all_features = Features::all_features(); - Self::check(all_features.clone(), false)?; + Self::check(all_features.clone(), false, CheckKind::Main)?; // run docs Self::docs(false, false)?; diff --git a/log.out b/log.out deleted file mode 100644 index f16c4b42a2..0000000000 --- a/log.out +++ /dev/null @@ -1,841 +0,0 @@ -warning: unused import: `Args` - --> crates/bevy_mod_scripting_core/src/lib.rs:14:15 - | -14 | use handler::{Args, CallbackSettings, HandlerFn}; - | ^^^^ - | - = note: `#[warn(unused_imports)]` on by default - -warning: unused import: `utils::BoxedFuture` - --> crates/bevy_mod_scripting_core/src/asset.rs:10:5 - | -10 | utils::BoxedFuture, - | ^^^^^^^^^^^^^^^^^^ - -warning: unused import: `AtomicUsize` - --> crates/bevy_mod_scripting_core/src/bindings/access_map.rs:2:32 - | -2 | sync::atomic::{AtomicBool, AtomicUsize}, - | ^^^^^^^^^^^ - -warning: unused imports: `Map` and `try_result::TryResult` - --> crates/bevy_mod_scripting_core/src/bindings/access_map.rs:10:15 - | -10 | use dashmap::{try_result::TryResult, DashMap, Entry, Map}; - | ^^^^^^^^^^^^^^^^^^^^^ ^^^ - -warning: unused imports: `any::TypeId`, `borrow::Cow`, `ops::Deref`, and `sync::Arc` - --> crates/bevy_mod_scripting_core/src/bindings/function/mod.rs:1:11 - | -1 | use std::{any::TypeId, borrow::Cow, ops::Deref, sync::Arc}; - | ^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^ - -warning: unused imports: `ReflectReference` and `downcast_into_value` - --> crates/bevy_mod_scripting_core/src/bindings/function/from_ref.rs:6:44 - | -6 | bindings::{function::from::FromScript, ReflectReference, WorldGuard}, - | ^^^^^^^^^^^^^^^^ -7 | downcast_into_value, - | ^^^^^^^^^^^^^^^^^^^ - -warning: unused import: `Path` - --> crates/bevy_mod_scripting_core/src/bindings/function/into.rs:4:12 - | -4 | path::{Path, PathBuf}, - | ^^^^ - -warning: unused imports: `GetTypeRegistration` and `ReflectRef` - --> crates/bevy_mod_scripting_core/src/bindings/function/into.rs:7:21 - | -7 | use bevy::reflect::{GetTypeRegistration, PartialReflect, ReflectRef}; - | ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ - -warning: unused import: `any::TypeId` - --> crates/bevy_mod_scripting_core/src/bindings/function/into_ref.rs:1:11 - | -1 | use std::{any::TypeId, ffi::OsString, path::PathBuf}; - | ^^^^^^^^^^^ - -warning: unused imports: `AppFunctionRegistry`, `DynamicFunction`, `FunctionInfo`, `IntoFunction`, `PartialReflect`, `TypeRegistration`, `TypedFunction`, and `World` - --> crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs:11:15 - | -11 | prelude::{AppFunctionRegistry, IntoFunction, Reflect, Resource, World}, - | ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^ -12 | reflect::{ -13 | func::{args::GetOwnership, DynamicFunction, FunctionError, FunctionInfo, TypedFunction}, - | ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^^ -14 | FromReflect, GetTypeRegistration, PartialReflect, TypePath, TypeRegistration, TypeRegistry, - | ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ - -warning: unused imports: `ArgInfo`, `ArgList`, `ArgValue`, `Arg`, `DynamicFunction`, `FunctionInfo`, `FunctionResult`, `Ownership`, `PartialReflect`, and `Return` - --> crates/bevy_mod_scripting_core/src/bindings/function/mod.rs:11:16 - | -11 | args::{Arg, ArgInfo, Ownership}, - | ^^^ ^^^^^^^ ^^^^^^^^^ -12 | ArgList, ArgValue, DynamicFunction, FunctionInfo, FunctionResult, Return, - | ^^^^^^^ ^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^ -13 | }, -14 | PartialReflect, - | ^^^^^^^^^^^^^^ - -warning: unused imports: `FlattenError`, `InteropErrorInner`, `PartialReflectExt`, `ReturnValExt`, `ScriptError`, and `ScriptResult` - --> crates/bevy_mod_scripting_core/src/bindings/function/mod.rs:19:13 - | -19 | error::{FlattenError, InteropError, InteropErrorInner, ScriptError, ScriptResult}, - | ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^ -20 | reflection_extensions::{PartialReflectExt, ReturnValExt}, - | ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ - -warning: unused imports: `ReflectBase`, `ReflectReference`, `WorldAccessGuard`, `access_map::ReflectAccessId`, and `pretty_print::DisplayWithWorld` - --> crates/bevy_mod_scripting_core/src/bindings/function/mod.rs:24:5 - | -24 | access_map::ReflectAccessId, pretty_print::DisplayWithWorld, script_value::ScriptValue, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -25 | ReflectBase, ReflectReference, WorldAccessGuard, WorldCallbackAccess, WorldGuard, - | ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ - -warning: unused imports: `CONCURRENT_WORLD_ACCESS_MSG` and `STALE_WORLD_MSG` - --> crates/bevy_mod_scripting_core/src/bindings/query.rs:3:16 - | -3 | bindings::{CONCURRENT_WORLD_ACCESS_MSG, STALE_WORLD_MSG}, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ - -warning: unused imports: `WorldAccessGuard` and `WorldCallbackAccess` - --> crates/bevy_mod_scripting_core/src/bindings/reference.rs:9:5 - | -9 | WorldAccessGuard, WorldCallbackAccess, WorldGuard, - | ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ - -warning: unused import: `ScriptResult` - --> crates/bevy_mod_scripting_core/src/bindings/reference.rs:14:33 - | -14 | prelude::{ReflectAllocator, ScriptResult}, - | ^^^^^^^^^^^^ - -warning: unused imports: `ArgValue`, `ReflectFromReflect`, `ReflectMut`, `ReflectPathError`, `ReflectRef`, and `args::ArgInfo` - --> crates/bevy_mod_scripting_core/src/bindings/reference.rs:26:16 - | -26 | func::{args::ArgInfo, ArgValue}, - | ^^^^^^^^^^^^^ ^^^^^^^^ -27 | ParsedPath, PartialReflect, Reflect, ReflectFromPtr, ReflectFromReflect, ReflectMut, - | ^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ -28 | ReflectPath, ReflectPathError, ReflectRef, TypeData, - | ^^^^^^^^^^^^^^^^ ^^^^^^^^^^ - -warning: unused import: `itertools::Either` - --> crates/bevy_mod_scripting_core/src/bindings/reference.rs:31:5 - | -31 | use itertools::Either; - | ^^^^^^^^^^^^^^^^^ - -warning: unused import: `sync::Arc` - --> crates/bevy_mod_scripting_core/src/bindings/reference.rs:32:36 - | -32 | use std::{any::TypeId, fmt::Debug, sync::Arc}; - | ^^^^^^^^^ - -warning: unused imports: `CStr`, `CString`, `OsStr`, `OsString`, `PathBuf`, `Path`, `TypeId`, and `type_name` - --> crates/bevy_mod_scripting_core/src/bindings/script_value/mod.rs:2:11 - | -2 | any::{type_name, TypeId}, - | ^^^^^^^^^ ^^^^^^ -3 | borrow::Cow, -4 | ffi::{CStr, CString, OsStr, OsString}, - | ^^^^ ^^^^^^^ ^^^^^ ^^^^^^^^ -5 | path::{Path, PathBuf}, - | ^^^^ ^^^^^^^ - -warning: unused imports: `Access`, `DynamicEnum`, `DynamicList`, `DynamicTuple`, `DynamicVariant`, `PartialReflect`, `ReflectFromReflect`, and `TypeData` - --> crates/bevy_mod_scripting_core/src/bindings/script_value/mod.rs:9:5 - | -9 | Access, DynamicEnum, DynamicList, DynamicTuple, DynamicVariant, OffsetAccess, ParsedPath, - | ^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^^^ -10 | PartialReflect, Reflect, ReflectFromReflect, TypeData, - | ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^ ^^^^^^^^ - -warning: unused imports: `InteropErrorInner`, `PartialReflectExt`, `ScriptError`, `ScriptResult`, `TypeIdExtensions`, and `TypeInfoExtensions` - --> crates/bevy_mod_scripting_core/src/bindings/script_value/mod.rs:14:27 - | -14 | error::{InteropError, InteropErrorInner, ScriptError, ScriptResult}, - | ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^ -15 | reflection_extensions::{PartialReflectExt, TypeIdExtensions, TypeInfoExtensions}, - | ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^ - -warning: unused imports: `DynamicScriptFunction`, `WorldGuard`, and `pretty_print::DisplayWithWorld` - --> crates/bevy_mod_scripting_core/src/bindings/script_value/mod.rs:19:33 - | -19 | function::script_function::{DynamicScriptFunction, DynamicScriptFunctionMut}, - | ^^^^^^^^^^^^^^^^^^^^^ -20 | pretty_print::DisplayWithWorld, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -21 | ReflectReference, WorldGuard, - | ^^^^^^^^^^ - -warning: unused imports: `AtomicUsize`, `Ordering`, `marker::PhantomData`, and `mem` - --> crates/bevy_mod_scripting_core/src/bindings/world.rs:11:5 - | -11 | marker::PhantomData, - | ^^^^^^^^^^^^^^^^^^^ -12 | mem, - | ^^^ -... -15 | atomic::{AtomicUsize, Ordering}, - | ^^^^^^^^^^^ ^^^^^^^^ - -warning: unused imports: `TypeRegistry` and `utils::HashMap` - --> crates/bevy_mod_scripting_core/src/bindings/world.rs:33:19 - | -33 | TypePath, TypeRegistry, TypeRegistryArc, - | ^^^^^^^^^^^^ -34 | }, -35 | utils::HashMap, - | ^^^^^^^^^^^^^^ - -warning: unused import: `smallvec::SmallVec` - --> crates/bevy_mod_scripting_core/src/bindings/world.rs:38:5 - | -38 | use smallvec::SmallVec; - | ^^^^^^^^^^^^^^^^^^ - -warning: unused imports: `ReflectAllocator`, `ScriptError`, `ScriptResult`, and `bindings::ReflectAllocationId` - --> crates/bevy_mod_scripting_core/src/bindings/world.rs:41:5 - | -41 | bindings::ReflectAllocationId, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -42 | error::InteropError, -43 | prelude::{ReflectAllocator, ScriptError, ScriptResult}, - | ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^ - -warning: unused imports: `Context` and `Runtime` - --> crates/bevy_mod_scripting_core/src/commands.rs:7:15 - | -7 | context::{Context, ContextLoadingSettings, ScriptContexts}, - | ^^^^^^^ -8 | prelude::{Runtime, RuntimeContainer}, - | ^^^^^^^ - -warning: unused import: `Runtime` - --> crates/bevy_mod_scripting_core/src/context.rs:6:15 - | -6 | prelude::{Runtime, ScriptError}, - | ^^^^^^^ - -warning: unused import: `borrow::Cow` - --> crates/bevy_mod_scripting_core/src/error.rs:3:5 - | -3 | borrow::Cow, - | ^^^^^^^^^^^ - -warning: unused imports: `ApplyError`, `FunctionInfo`, `ReflectPathError`, and `args::ArgInfo` - --> crates/bevy_mod_scripting_core/src/error.rs:14:16 - | -14 | func::{args::ArgInfo, FunctionError, FunctionInfo}, - | ^^^^^^^^^^^^^ ^^^^^^^^^^^^ -15 | ApplyError, PartialReflect, Reflect, ReflectPathError, - | ^^^^^^^^^^ ^^^^^^^^^^^^^^^^ - -warning: unused import: `thiserror::Error` - --> crates/bevy_mod_scripting_core/src/error.rs:18:5 - | -18 | use thiserror::Error; - | ^^^^^^^^^^^^^^^^ - -warning: unused imports: `ReflectAllocationId` and `ReflectBase` - --> crates/bevy_mod_scripting_core/src/error.rs:24:9 - | -24 | ReflectAllocationId, ReflectBase, ReflectBaseType, ReflectReference, - | ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ - -warning: unused import: `handler::Args` - --> crates/bevy_mod_scripting_core/src/event.rs:3:33 - | -3 | use crate::{error::ScriptError, handler::Args, prelude::ScriptValue, script::ScriptId}; - | ^^^^^^^^^^^^^ - -warning: unused imports: `Context` and `runtime::Runtime` - --> crates/bevy_mod_scripting_core/src/handler.rs:4:15 - | -4 | context::{Context, ContextPreHandlingInitializer}, - | ^^^^^^^ -... -7 | runtime::Runtime, - | ^^^^^^^^^^^^^^^^ - -warning: unused imports: `CStr`, `CString`, `OsStr`, `OsString`, `PathBuf`, `Path`, and `borrow::Cow` - --> crates/bevy_mod_scripting_core/src/reflection_extensions.rs:3:5 - | -3 | borrow::Cow, - | ^^^^^^^^^^^ -4 | cmp::max, -5 | ffi::{CStr, CString, OsStr, OsString}, - | ^^^^ ^^^^^^^ ^^^^^ ^^^^^^^^ -6 | ops::Sub, -7 | path::{Path, PathBuf}, - | ^^^^ ^^^^^^^ - -warning: unused imports: `WorldAccessGuard` and `script_value::ScriptValue` - --> crates/bevy_mod_scripting_core/src/reflection_extensions.rs:19:41 - | -19 | pretty_print::DisplayWithWorld, script_value::ScriptValue, ReflectReference, - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -20 | WorldAccessGuard, WorldGuard, - | ^^^^^^^^^^^^^^^^ - -warning: unused imports: `Args`, `Context`, `ReflectAllocator`, `Runtime`, and `ScriptResult` - --> crates/bevy_mod_scripting_core/src/systems.rs:6:48 - | -6 | bindings::{pretty_print::DisplayWithWorld, ReflectAllocator, WorldAccessGuard, WorldGuard}, - | ^^^^^^^^^^^^^^^^ -7 | commands::{CreateOrUpdateScript, DeleteScript}, -8 | context::{Context, ContextLoadingSettings, ScriptContexts}, - | ^^^^^^^ -9 | error::{ScriptError, ScriptResult}, - | ^^^^^^^^^^^^ -10 | event::{IntoCallbackLabel, ScriptCallbackEvent, ScriptErrorEvent}, -11 | handler::{Args, CallbackSettings}, - | ^^^^ -12 | prelude::{AppReflectAllocator, RuntimeSettings}, -13 | runtime::{Runtime, RuntimeContainer}, - | ^^^^^^^ - -warning: unused import: `AsyncReadExt` - --> crates/bevy_mod_scripting_core/src/asset.rs:7:33 - | -7 | asset::{Asset, AssetLoader, AsyncReadExt}, - | ^^^^^^^^^^^^ - -warning: unused import: `std::io::Read` - --> crates/bevy_mod_scripting_core/src/bindings/allocator.rs:8:5 - | -8 | use std::io::Read; - | ^^^^^^^^^^^^^ - -warning: unused import: `Reflect` - --> crates/bevy_mod_scripting_core/src/bindings/allocator.rs:2:37 - | -2 | use bevy::reflect::{PartialReflect, Reflect}; - | ^^^^^^^ - -warning: unused import: `Any` - --> crates/bevy_mod_scripting_core/src/bindings/allocator.rs:4:16 - | -4 | use std::any::{Any, TypeId}; - | ^^^ - -warning: unused import: `GetTypeRegistration` - --> crates/bevy_mod_scripting_core/src/bindings/function/from.rs:6:34 - | -6 | use bevy::reflect::{FromReflect, GetTypeRegistration, Reflect}; - | ^^^^^^^^^^^^^^^^^^^ - -warning: unused import: `itertools::Itertools` - --> crates/bevy_mod_scripting_core/src/reflection_extensions.rs:15:5 - | -15 | use itertools::Itertools; - | ^^^^^^^^^^^^^^^^^^^^ - -warning: unused import: `pretty_print::DisplayWithWorld` - --> crates/bevy_mod_scripting_core/src/reflection_extensions.rs:19:9 - | -19 | pretty_print::DisplayWithWorld, script_value::ScriptValue, ReflectReference, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: unused import: `TypeData` - --> crates/bevy_mod_scripting_core/src/reflection_extensions.rs:13:17 - | -13 | ReflectMut, TypeData, TypeInfo, - | ^^^^^^^^ - -warning: unused import: `FromType` - --> crates/bevy_mod_scripting_core/src/reflection_extensions.rs:12:32 - | -12 | func::Return, FromReflect, FromType, List, PartialReflect, Reflect, ReflectFromReflect, - | ^^^^^^^^ - -warning: unused import: `AccessMapKey` - --> crates/bevy_mod_scripting_core/src/bindings/reference.rs:8:18 - | -8 | access_map::{AccessMapKey, ReflectAccessId}, - | ^^^^^^^^^^^^ - -warning: unused import: `pretty_print::DisplayWithWorld` - --> crates/bevy_mod_scripting_core/src/bindings/reference.rs:12:16 - | -12 | bindings::{pretty_print::DisplayWithWorld, ReflectAllocationId}, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: unused import: `List` - --> crates/bevy_mod_scripting_core/src/reflection_extensions.rs:12:42 - | -12 | func::Return, FromReflect, FromType, List, PartialReflect, Reflect, ReflectFromReflect, - | ^^^^ - -warning: unused import: `TypeData` - --> crates/bevy_mod_scripting_core/src/bindings/reference.rs:28:52 - | -28 | ReflectPath, ReflectPathError, ReflectRef, TypeData, - | ^^^^^^^^ - -warning: unused import: `str::FromStr` - --> crates/bevy_mod_scripting_core/src/reflection_extensions.rs:8:5 - | -8 | str::FromStr, - | ^^^^^^^^^^^^ - -warning: unused import: `ops::Sub` - --> crates/bevy_mod_scripting_core/src/reflection_extensions.rs:6:5 - | -6 | ops::Sub, - | ^^^^^^^^ - -warning: unused import: `ops::Deref` - --> crates/bevy_mod_scripting_core/src/bindings/world.rs:13:5 - | -13 | ops::Deref, - | ^^^^^^^^^^ - -warning: unused import: `DerefMut` - --> crates/bevy_mod_scripting_core/src/error.rs:5:18 - | -5 | ops::{Deref, DerefMut}, - | ^^^^^^^^ - -warning: unused import: `func::args::FromArg` - --> crates/bevy_mod_scripting_core/src/bindings/world.rs:32:9 - | -32 | func::args::FromArg, std_traits::ReflectDefault, ParsedPath, PartialReflect, Reflect, - | ^^^^^^^^^^^^^^^^^^^ - -warning: unused import: `PartialReflect` - --> crates/bevy_mod_scripting_core/src/bindings/world.rs:32:70 - | -32 | func::args::FromArg, std_traits::ReflectDefault, ParsedPath, PartialReflect, Reflect, - | ^^^^^^^^^^^^^^ - -warning: unused import: `TypePath` - --> crates/bevy_mod_scripting_core/src/bindings/world.rs:33:9 - | -33 | TypePath, TypeRegistry, TypeRegistryArc, - | ^^^^^^^^ - -warning: unused import: `reflection_extensions::TypeIdExtensions` - --> crates/bevy_mod_scripting_core/src/bindings/world.rs:44:5 - | -44 | reflection_extensions::TypeIdExtensions, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: unused variable: `value` - --> crates/bevy_mod_scripting_core/src/bindings/function/from.rs:37:20 - | -37 | fn from_script(value: ScriptValue, _world: WorldGuard) -> Result { - | ^^^^^ help: if this is intentional, prefix it with an underscore: `_value` - | - = note: `#[warn(unused_variables)]` on by default - -warning: unused variable: `v` - --> crates/bevy_mod_scripting_core/src/bindings/script_value/mod.rs:151:32 - | -151 | ScriptValue::Float(v) => { - | ^ help: if this is intentional, prefix it with an underscore: `_v` - -warning: unused variable: `e` - --> crates/bevy_mod_scripting_core/src/bindings/world.rs:701:27 - | -701 | .map_err(|e| InteropError::missing_entity(entity))?; - | ^ help: if this is intentional, prefix it with an underscore: `_e` - -warning: unused variable: `e` - --> crates/bevy_mod_scripting_core/src/bindings/world.rs:777:27 - | -777 | .map_err(|e| InteropError::missing_entity(entity))?; - | ^ help: if this is intentional, prefix it with an underscore: `_e` - -warning: function `map_key_to_concrete` is never used - --> crates/bevy_mod_scripting_core/src/bindings/reference.rs:465:4 - | -465 | fn map_key_to_concrete(key: &str, key_type_id: TypeId) -> Option> { - | ^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(dead_code)]` on by default - -warning: constant `STALE_WORLD_MSG` is never used - --> crates/bevy_mod_scripting_core/src/bindings/world.rs:116:18 - | -116 | pub(crate) const STALE_WORLD_MSG: &str = "Tried to access world via stale reference"; - | ^^^^^^^^^^^^^^^ - -warning: constant `CONCURRENT_WORLD_ACCESS_MSG` is never used - --> crates/bevy_mod_scripting_core/src/bindings/world.rs:117:18 - | -117 | pub(crate) const CONCURRENT_WORLD_ACCESS_MSG: &str = - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: constant `CONCURRENT_ACCESS_MSG` is never used - --> crates/bevy_mod_scripting_core/src/bindings/world.rs:119:18 - | -119 | pub(crate) const CONCURRENT_ACCESS_MSG: &str = - | ^^^^^^^^^^^^^^^^^^^^^ - -warning: bounds on generic parameters in type aliases are not enforced - --> crates/bevy_mod_scripting_core/src/context.rs:55:32 - | -55 | pub type ContextInitializer = - | ^^^^^^^^^^^^^^^^^^^^^^ will not be checked at usage sites of the type alias - | - = note: this is a known limitation of the type checker that may be lifted in a future edition. - see issue #112792 for more information - = note: `#[warn(type_alias_bounds)]` on by default -help: remove this bound - | -55 - pub type ContextInitializer = -55 + pub type ContextInitializer

= - | -help: fully qualify this associated type - | -56 | fn(&ScriptId, &mut

::C) -> Result<(), ScriptError>; - | + +++++++++++++++ - -warning: bounds on generic parameters in type aliases are not enforced - --> crates/bevy_mod_scripting_core/src/context.rs:58:43 - | -58 | pub type ContextPreHandlingInitializer = - | ^^^^^^^^^^^^^^^^^^^^^^ will not be checked at usage sites of the type alias - | - = note: this is a known limitation of the type checker that may be lifted in a future edition. - see issue #112792 for more information -help: remove this bound - | -58 - pub type ContextPreHandlingInitializer = -58 + pub type ContextPreHandlingInitializer

= - | -help: fully qualify this associated type - | -59 | fn(&ScriptId, Entity, &mut

::C) -> Result<(), ScriptError>; - | + +++++++++++++++ - -warning: bounds on generic parameters in type aliases are not enforced - --> crates/bevy_mod_scripting_core/src/handler.rs:15:23 - | -15 | pub type HandlerFn = fn( - | ^^^^^^^^^^^^^^^^^^^^^^ will not be checked at usage sites of the type alias - | - = note: this is a known limitation of the type checker that may be lifted in a future edition. - see issue #112792 for more information -help: remove this bound - | -15 - pub type HandlerFn = fn( -15 + pub type HandlerFn

= fn( - | -help: fully qualify this associated type - | -20 | context: &mut

::C, - | + +++++++++++++++ -help: fully qualify this associated type - | -22 | runtime: &mut

::R, - | + +++++++++++++++ - -warning: bounds on generic parameters in type aliases are not enforced - --> crates/bevy_mod_scripting_core/src/runtime.rs:11:32 - | -11 | pub type RuntimeInitializer = fn(&mut P::R); - | ^^^^^^^^^^^^^^^^^^^^^^ will not be checked at usage sites of the type alias - | - = note: this is a known limitation of the type checker that may be lifted in a future edition. - see issue #112792 for more information -help: remove this bound - | -11 - pub type RuntimeInitializer = fn(&mut P::R); -11 + pub type RuntimeInitializer

= fn(&mut P::R); - | -help: fully qualify this associated type - | -11 | pub type RuntimeInitializer = fn(&mut

::R); - | + +++++++++++++++ - -warning: `bevy_mod_scripting_core` (lib) generated 71 warnings (run `cargo fix --lib -p bevy_mod_scripting_core` to apply 38 suggestions) -warning: unused import: `std::borrow::Cow` - --> crates/bevy_mod_scripting_functions/src/core.rs:2:5 - | -2 | use std::borrow::Cow; - | ^^^^^^^^^^^^^^^^ - | - = note: `#[warn(unused_imports)]` on by default - -warning: unused imports: `FunctionRegistryArc`, `FunctionRegistry`, and `GetTypeRegistration` - --> crates/bevy_mod_scripting_functions/src/core.rs:7:43 - | -7 | func::{FunctionRegistrationError, FunctionRegistry, FunctionRegistryArc}, GetTypeRegistration, ParsedPath - | ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ - -warning: unused imports: `GetFunctionTypeDependencies`, `Mut`, `ScriptFunction`, and `WorldAccessGuard` - --> crates/bevy_mod_scripting_functions/src/core.rs:13:16 - | -13 | from::{Mut, Ref, Val}, - | ^^^ -... -16 | script_function::{CallerContext, GetFunctionTypeDependencies, ScriptFunction, ScriptFunctionMut}, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ -... -21 | ScriptTypeRegistration, WorldAccessGuard, WorldCallbackAccess, - | ^^^^^^^^^^^^^^^^ - -warning: unused import: `InteropErrorInner` - --> crates/bevy_mod_scripting_functions/src/core.rs:23:27 - | -23 | use error::{InteropError, InteropErrorInner}; - | ^^^^^^^^^^^^^^^^^ - -warning: unused imports: `AppFunctionRegistry`, `DynamicFunction`, `FunctionRegistrationError`, `FunctionRegistry`, and `IntoFunction` - --> crates/bevy_mod_scripting_functions/src/namespaced_register.rs:4:15 - | -4 | prelude::{AppFunctionRegistry, AppTypeRegistry, IntoFunction, World}, - | ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ -5 | reflect::func::{DynamicFunction, FunctionRegistrationError, FunctionRegistry}, - | ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ - -warning: unused variable: `s` - --> crates/bevy_mod_scripting_functions/src/core.rs:145:14 - | -145 | |s: WorldCallbackAccess, components: Vec>| { - | ^ help: if this is intentional, prefix it with an underscore: `_s` - | - = note: `#[warn(unused_variables)]` on by default - -warning: unused variable: `idx` - --> crates/bevy_mod_scripting_functions/src/core.rs:313:32 - | -313 | let (next_ref, idx) = infinite_iter.next_ref(); - | ^^^ help: if this is intentional, prefix it with an underscore: `_idx` - -warning: variable does not need to be mutable - --> crates/bevy_mod_scripting_functions/src/namespaced_register.rs:152:21 - | -152 | let mut type_registry = self.world.get_resource_or_init::(); - | ----^^^^^^^^^^^^^ - | | - | help: remove this `mut` - | - = note: `#[warn(unused_mut)]` on by default - -warning: `bevy_mod_scripting_functions` (lib) generated 8 warnings (run `cargo fix --lib -p bevy_mod_scripting_functions` to apply 6 suggestions) -warning: unexpected `cfg` condition value: `teal` - --> crates/languages/bevy_mod_scripting_lua/src/util.rs:16:11 - | -16 | #[cfg(all(feature = "teal", debug_assertions))] - | ^^^^^^^^^^^^^^^^ - | - = note: expected values for `feature` are: `lua51`, `lua52`, `lua53`, `lua54`, `luajit`, `luajit52`, `luau`, `mlua_async`, `mlua_macros`, `mlua_serialize`, and `unsafe_lua_modules` - = help: consider adding `teal` as a feature in `Cargo.toml` - = note: see for more information about checking conditional configuration - = note: `#[warn(unexpected_cfgs)]` on by default - -warning: unexpected `cfg` condition value: `teal` - --> crates/languages/bevy_mod_scripting_lua/src/util.rs:32:34 - | -32 | #[cfg(all(not(debug_assertions), feature = "teal"))] - | ^^^^^^^^^^^^^^^^ - | - = note: expected values for `feature` are: `lua51`, `lua52`, `lua53`, `lua54`, `luajit`, `luajit52`, `luau`, `mlua_async`, `mlua_macros`, `mlua_serialize`, and `unsafe_lua_modules` - = help: consider adding `teal` as a feature in `Cargo.toml` - = note: see for more information about checking conditional configuration - -warning: unexpected `cfg` condition value: `teal` - --> crates/languages/bevy_mod_scripting_lua/src/util.rs:48:11 - | -48 | #[cfg(not(feature = "teal"))] - | ^^^^^^^^^^^^^^^^ - | - = note: expected values for `feature` are: `lua51`, `lua52`, `lua53`, `lua54`, `luajit`, `luajit52`, `luau`, `mlua_async`, `mlua_macros`, `mlua_serialize`, and `unsafe_lua_modules` - = help: consider adding `teal` as a feature in `Cargo.toml` - = note: see for more information about checking conditional configuration - -warning: unused imports: `DerefMut` and `Deref` - --> crates/languages/bevy_mod_scripting_lua/src/util.rs:1:16 - | -1 | use std::ops::{Deref, DerefMut}; - | ^^^^^ ^^^^^^^^ - | - = note: `#[warn(unused_imports)]` on by default - -warning: unused imports: `AppTypeRegistry`, `FromType`, `GetTypeRegistration`, `Mut`, `PartialReflect`, `Startup`, `TypePath`, and `impl_reflect` - --> crates/languages/bevy_mod_scripting_lua/src/lib.rs:3:24 - | -3 | app::{App, Plugin, Startup}, - | ^^^^^^^ -4 | ecs::{entity::Entity, world::World}, -5 | prelude::{AppTypeRegistry, Mut}, - | ^^^^^^^^^^^^^^^ ^^^ -6 | reflect::{impl_reflect, FromType, GetTypeRegistration, PartialReflect, Reflect, TypePath}, - | ^^^^^^^^^^^^ ^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^ - -warning: unused imports: `IntoCallbackLabel`, `ReflectAllocator`, `ReflectReference`, `handler::Args`, and `systems::event_handler` - --> crates/languages/bevy_mod_scripting_lua/src/lib.rs:10:36 - | -10 | script_value::ScriptValue, ReflectAllocator, ReflectReference, WorldCallbackAccess, - | ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ -... -14 | event::{CallbackLabel, IntoCallbackLabel}, - | ^^^^^^^^^^^^^^^^^ -15 | handler::Args, - | ^^^^^^^^^^^^^ -... -18 | systems::event_handler, - | ^^^^^^^^^^^^^^^^^^^^^^ - -warning: unused import: `LuaWorld` - --> crates/languages/bevy_mod_scripting_lua/src/lib.rs:27:23 - | -27 | world::{GetWorld, LuaWorld}, - | ^^^^^^^^ - -warning: unused import: `IntoLuaMulti` - --> crates/languages/bevy_mod_scripting_lua/src/lib.rs:30:22 - | -30 | use mlua::{Function, IntoLuaMulti, Lua}; - | ^^^^^^^^^^^^ - -warning: unused imports: `CStr`, `CString`, `OsStr`, `OsString`, `PathBuf`, `Path`, `borrow::Cow`, and `sync::Arc` - --> crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs:3:5 - | -3 | borrow::Cow, - | ^^^^^^^^^^^ -4 | error::Error, -5 | ffi::{CStr, CString, OsStr, OsString}, - | ^^^^ ^^^^^^^ ^^^^^ ^^^^^^^^ -6 | path::{Path, PathBuf}, - | ^^^^ ^^^^^^^ -7 | sync::Arc, - | ^^^^^^^^^ - -warning: unused imports: `OffsetAccess`, `ParsedPath`, `ReflectFromReflect`, `func::DynamicFunction`, `prelude::AppFunctionRegistry`, `reflect::AppTypeRegistry`, and `world::Mut` - --> crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs:11:11 - | -11 | ecs::{reflect::AppTypeRegistry, world::Mut}, - | ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ -12 | prelude::AppFunctionRegistry, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -13 | reflect::{ -14 | func::DynamicFunction, OffsetAccess, ParsedPath, PartialReflect, ReflectFromReflect, - | ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^ - -warning: unused imports: `CallerContext`, `Either`, `ReflectAllocator`, `ReflectRefIter`, `ReflectReferencePrinter`, `ScriptError`, `ScriptResult`, `TypeIdSource`, and `WorldCallbackAccess` - --> crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs:20:58 - | -20 | script_function::{AppScriptFunctionRegistry, CallerContext, DynamicScriptFunction}, - | ^^^^^^^^^^^^^ -... -23 | pretty_print::{DisplayWithWorld, ReflectReferencePrinter}, - | ^^^^^^^^^^^^^^^^^^^^^^^ -24 | script_value::ScriptValue, -25 | ReflectAllocator, ReflectRefIter, ReflectReference, ReflectionPathExt, TypeIdSource, - | ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^ -26 | WorldCallbackAccess, WorldGuard, - | ^^^^^^^^^^^^^^^^^^^ -27 | }, -28 | error::{InteropError, ScriptError, ScriptResult}, - | ^^^^^^^^^^^ ^^^^^^^^^^^^ -29 | reflection_extensions::{PartialReflectExt, TypeIdExtensions}, -30 | Either, - | ^^^^^^ - -warning: unused import: `Value` - --> crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs:33:75 - | -33 | use mlua::{Function, IntoLua, Lua, MetaMethod, UserData, UserDataMethods, Value, Variadic}; - | ^^^^^ - -warning: unused import: `world::LuaWorld` - --> crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs:40:57 - | -40 | use crate::bindings::{script_value::lua_caller_context, world::LuaWorld}; - | ^^^^^^^^^^^^^^^ - -warning: unused imports: `ReflectBase` and `ReflectReference` - --> crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs:6:5 - | -6 | ReflectBase, ReflectReference, - | ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ - -warning: unused imports: `IntoLuaMulti` and `MultiValue` - --> crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs:8:30 - | -8 | use mlua::{FromLua, IntoLua, IntoLuaMulti, MultiValue, Value, Variadic}; - | ^^^^^^^^^^^^ ^^^^^^^^^^ - -warning: unused imports: `component::ComponentId`, `reflect::AppTypeRegistry`, and `world::Mut` - --> crates/languages/bevy_mod_scripting_lua/src/bindings/world.rs:3:17 - | -3 | use bevy::ecs::{component::ComponentId, reflect::AppTypeRegistry, world::Mut}; - | ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ - -warning: unused imports: `AppFunctionRegistry`, `Entity`, and `World` - --> crates/languages/bevy_mod_scripting_lua/src/bindings/world.rs:4:21 - | -4 | use bevy::prelude::{AppFunctionRegistry, Entity, World}; - | ^^^^^^^^^^^^^^^^^^^ ^^^^^^ ^^^^^ - -warning: unused imports: `ReflectReference`, `ScriptTypeRegistration`, and `error::ScriptError` - --> crates/languages/bevy_mod_scripting_lua/src/bindings/world.rs:9:16 - | -9 | bindings::{ReflectReference, ScriptTypeRegistration, WorldAccessGuard, WorldCallbackAccess}, - | ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^ -10 | error::ScriptError, - | ^^^^^^^^^^^^^^^^^^ - -warning: unused imports: `GetNamespacedFunction` and `Namespace` - --> crates/languages/bevy_mod_scripting_lua/src/bindings/world.rs:12:57 - | -12 | use bevy_mod_scripting_functions::namespaced_register::{GetNamespacedFunction, Namespace}; - | ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^ - -warning: unused imports: `MetaMethod`, `UserDataFields`, `UserDataMethods`, `Value`, and `Variadic` - --> crates/languages/bevy_mod_scripting_lua/src/bindings/world.rs:13:12 - | -13 | use mlua::{MetaMethod, UserData, UserDataFields, UserDataMethods, Value, Variadic}; - | ^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^ ^^^^^^^^ - -warning: unused import: `super::script_value::LuaScriptValue` - --> crates/languages/bevy_mod_scripting_lua/src/bindings/world.rs:15:5 - | -15 | use super::script_value::LuaScriptValue; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: unused import: `Any` - --> crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs:2:11 - | -2 | any::{Any, TypeId}, - | ^^^ - -warning: unused import: `error::Error` - --> crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs:4:5 - | -4 | error::Error, - | ^^^^^^^^^^^^ - -warning: unused import: `PartialReflect` - --> crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs:14:58 - | -14 | func::DynamicFunction, OffsetAccess, ParsedPath, PartialReflect, ReflectFromReflect, - | ^^^^^^^^^^^^^^ - -warning: unused import: `ReflectionPathExt` - --> crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs:25:61 - | -25 | ReflectAllocator, ReflectRefIter, ReflectReference, ReflectionPathExt, TypeIdSource, - | ^^^^^^^^^^^^^^^^^ - -warning: unused import: `PartialReflectExt` - --> crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs:29:29 - | -29 | reflection_extensions::{PartialReflectExt, TypeIdExtensions}, - | ^^^^^^^^^^^^^^^^^ - -warning: unused import: `Reflect` - --> crates/languages/bevy_mod_scripting_lua/src/lib.rs:6:76 - | -6 | reflect::{impl_reflect, FromType, GetTypeRegistration, PartialReflect, Reflect, TypePath}, - | ^^^^^^^ - -warning: `bevy_mod_scripting_lua` (lib) generated 27 warnings (run `cargo fix --lib -p bevy_mod_scripting_lua` to apply 18 suggestions) - Compiling bevy_mod_scripting v0.9.0-alpha.1 (/home/makspll/git/bevy_mod_scripting) From 25c3bc774b1f0a6f1791bfeddc3c6935e9c40d5e Mon Sep 17 00:00:00 2001 From: makspll Date: Thu, 9 Jan 2025 23:00:03 +0000 Subject: [PATCH 04/21] re-write lua tests to use common integration test framework --- .vscode/settings.json | 2 +- Cargo.toml | 8 +- crates/bevy_mod_scripting_core/src/context.rs | 4 + crates/bevy_mod_scripting_core/src/lib.rs | 22 +- crates/bevy_mod_scripting_core/src/systems.rs | 6 + .../bevy_mod_scripting_functions/src/lib.rs | 7 + .../src/test_functions.rs | 29 +- .../bevy_mod_scripting_lua/Cargo.toml | 11 +- .../src/bindings/script_value.rs | 2 +- .../bevy_mod_scripting_lua/src/lib.rs | 3 +- .../data/access/aliasing_global_access.lua | 11 - .../tests/data/access/aliasing_write.lua | 11 - .../component_no_component_data.lua | 2 +- .../component_with_component_data.lua | 2 +- .../missing_resource_returns_nil.lua | 2 +- .../empty_entity_mock_component_is_false.lua | 2 +- .../data/has_component/no_component_data.lua | 2 +- .../has_component/with_component_data.lua | 2 +- ...issing_resource_mock_resource_is_false.lua | 2 +- .../query_returns_all_entities_matching.lua | 2 +- .../no_component_data_errors.lua | 2 +- .../with_component_data_removes_component.lua | 2 +- .../no_resource_data_errors.lua | 2 +- .../bevy_mod_scripting_lua/tests/lua_tests.rs | 250 ++++-------------- .../bevy_mod_scripting_rhai/src/lib.rs | 5 +- .../bevy_mod_scripting_rune/src/lib.rs | 4 + .../Cargo.toml | 15 ++ .../src/lib.rs | 113 ++++++++ crates/test_utils/src/test_data.rs | 10 +- crates/xtask/src/main.rs | 192 ++++++++++---- 30 files changed, 382 insertions(+), 345 deletions(-) delete mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/access/aliasing_global_access.lua delete mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/access/aliasing_write.lua create mode 100644 crates/script_integration_test_harness/Cargo.toml create mode 100644 crates/script_integration_test_harness/src/lib.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index ce5ba1c1a8..3979afae44 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,7 +10,7 @@ }, "rust-analyzer.rustc.source": "discover", "rust-analyzer.linkedProjects": [ - "./crates/bevy_api_gen/Cargo.toml", + // "./crates/bevy_api_gen/Cargo.toml", "Cargo.toml", ], "rust-analyzer.check.invocationStrategy": "once", diff --git a/Cargo.toml b/Cargo.toml index 29b9699c15..78b2da0de2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,11 +60,14 @@ bevy_mod_scripting_functions = { workspace = true } [workspace.dependencies] bevy = { version = "0.15.0", default-features = false } bevy_mod_scripting_core = { path = "crates/bevy_mod_scripting_core", version = "0.9.0-alpha.2" } -bevy_mod_scripting_functions = { path = "crates/bevy_mod_scripting_functions", version = "0.9.0-alpha.2" } -test_utils = { path = "crates/test_utils" } +bevy_mod_scripting_functions = { path = "crates/bevy_mod_scripting_functions", version = "0.9.0-alpha.2", default-features = false } mlua = { version = "0.10" } rhai = { version = "1.20.1" } +# test utilities +script_integration_test_harness = { path = "crates/script_integration_test_harness" } +test_utils = { path = "crates/test_utils" } + [dev-dependencies] bevy = { workspace = true, default-features = true } clap = { version = "4.1", features = ["derive"] } @@ -82,6 +85,7 @@ members = [ "crates/test_utils", "crates/bevy_mod_scripting_functions", "crates/xtask", + "crates/script_integration_test_harness", ] resolver = "2" exclude = ["crates/bevy_api_gen", "crates/macro_tests"] diff --git a/crates/bevy_mod_scripting_core/src/context.rs b/crates/bevy_mod_scripting_core/src/context.rs index b548f62355..2b04b335aa 100644 --- a/crates/bevy_mod_scripting_core/src/context.rs +++ b/crates/bevy_mod_scripting_core/src/context.rs @@ -66,9 +66,13 @@ pub type ContextPreHandlingInitializer

= #[derive(Resource)] pub struct ContextLoadingSettings { + /// Defines the strategy used to load and reload contexts pub loader: Option>, + /// Defines the strategy used to assign contexts to scripts pub assigner: Option>, + /// Initializers run once after creating a context but before executing it for the first time pub context_initializers: Vec>, + /// Initializers run every time before executing or loading a script pub context_pre_handling_initializers: Vec>, } diff --git a/crates/bevy_mod_scripting_core/src/lib.rs b/crates/bevy_mod_scripting_core/src/lib.rs index adb8310717..98cc9a6aa6 100644 --- a/crates/bevy_mod_scripting_core/src/lib.rs +++ b/crates/bevy_mod_scripting_core/src/lib.rs @@ -1,7 +1,3 @@ -#![allow(clippy::arc_with_non_send_sync)] - -use std::sync::atomic::AtomicBool; - use crate::event::ScriptErrorEvent; use asset::{ AssetPathToLanguageMapper, Language, ScriptAsset, ScriptAssetLoader, ScriptAssetSettings, @@ -49,13 +45,13 @@ pub trait IntoScriptPluginParams: 'static { type C: Context; type R: Runtime; + fn build_runtime() -> Self::R; + // fn supported_language() -> Language; } /// Bevy plugin enabling scripting within the bevy mod scripting framework pub struct ScriptingPlugin { - /// Callback for initiating the runtime - pub runtime_builder: fn() -> P::R, /// Settings for the runtime pub runtime_settings: Option>, /// The handler used for executing callbacks in scripts @@ -78,7 +74,6 @@ where { fn default() -> Self { Self { - runtime_builder: P::R::default, runtime_settings: Default::default(), callback_handler: Default::default(), context_builder: Default::default(), @@ -94,7 +89,7 @@ impl Plugin for ScriptingPlugin

{ fn build(&self, app: &mut bevy::prelude::App) { app.insert_resource(self.runtime_settings.as_ref().cloned().unwrap_or_default()) .insert_non_send_resource::>(RuntimeContainer { - runtime: (self.runtime_builder)(), + runtime: P::build_runtime(), }) .init_non_send_resource::>() .insert_resource::>(CallbackSettings { @@ -149,12 +144,15 @@ impl ScriptingPlugin

{ // One of registration of things that need to be done only once per app fn once_per_app_init(app: &mut App) { - static INITIALIZED: AtomicBool = AtomicBool::new(false); + #[derive(Resource)] + struct BMSInitialized; - if INITIALIZED.fetch_or(true, std::sync::atomic::Ordering::Relaxed) { + if app.world().contains_resource::() { return; } + app.insert_resource(BMSInitialized); + app.add_event::() .add_event::() .init_resource::() @@ -337,6 +335,10 @@ mod test { type C = C; type R = R; const LANGUAGE: Language = Language::Unknown; + + fn build_runtime() -> Self::R { + R + } } app.add_plugins(AssetPlugin::default()); diff --git a/crates/bevy_mod_scripting_core/src/systems.rs b/crates/bevy_mod_scripting_core/src/systems.rs index 5dcdf98d63..57b29c144b 100644 --- a/crates/bevy_mod_scripting_core/src/systems.rs +++ b/crates/bevy_mod_scripting_core/src/systems.rs @@ -335,6 +335,12 @@ mod test { type R = TestRuntime; const LANGUAGE: crate::asset::Language = crate::asset::Language::Unknown; + + fn build_runtime() -> Self::R { + TestRuntime { + invocations: vec![], + } + } } struct TestRuntime { diff --git a/crates/bevy_mod_scripting_functions/src/lib.rs b/crates/bevy_mod_scripting_functions/src/lib.rs index 5fbe0a3eac..9339559249 100644 --- a/crates/bevy_mod_scripting_functions/src/lib.rs +++ b/crates/bevy_mod_scripting_functions/src/lib.rs @@ -1,4 +1,5 @@ use ::bevy::prelude::*; +use test_functions::register_test_functions; #[cfg(feature = "bevy_bindings")] pub mod bevy_bindings; pub mod core; @@ -17,5 +18,11 @@ impl Plugin for ScriptFunctionsPlugin { fn build(&self, app: &mut App) { register_bevy_bindings(app); register_core_functions(app); + #[cfg(feature = "test_functions")] + register_test_functions(app); + + // TODO: if bevy ever does this itself we should remove this + app.world_mut().register_component::(); + app.world_mut().register_component::(); } } diff --git a/crates/bevy_mod_scripting_functions/src/test_functions.rs b/crates/bevy_mod_scripting_functions/src/test_functions.rs index 94039590ff..43f54fc136 100644 --- a/crates/bevy_mod_scripting_functions/src/test_functions.rs +++ b/crates/bevy_mod_scripting_functions/src/test_functions.rs @@ -2,12 +2,12 @@ use std::sync::Arc; use crate::NamespaceBuilder; use bevy::{ + app::App, prelude::{Entity, World}, reflect::{Reflect, TypeRegistration}, }; use bevy_mod_scripting_core::{ bindings::{ - access_map::ReflectAccessId, function::{ script_function::{CallerContext, DynamicScriptFunctionMut}, CallScriptFunction, @@ -19,7 +19,8 @@ use bevy_mod_scripting_core::{ }; use test_utils::test_data::EnumerateTestComponents; -pub fn register_test_functions(world: &mut World) { +pub fn register_test_functions(world: &mut App) { + let world = world.world_mut(); NamespaceBuilder::::new_unregistered(world) .register("_get_mock_type", |s: WorldCallbackAccess| { let world = s.try_read().unwrap(); @@ -79,27 +80,5 @@ pub fn register_test_functions(world: &mut World) { )) } }, - ) - .register( - "_set_write_access", - |s: WorldCallbackAccess, ref_: ReflectReference| { - let world = s.try_read().unwrap(); - - world - .claim_write_access(ReflectAccessId::for_reference(ref_.base.base_id).unwrap()); - }, - ) - .register( - "_set_read_access", - |s: WorldCallbackAccess, ref_: ReflectReference| { - let world = s.try_read().unwrap(); - - world.claim_read_access(ReflectAccessId::for_reference(ref_.base.base_id).unwrap()); - }, - ) - .register("_claim_global_access", |s: WorldCallbackAccess| { - let world = s.try_read().unwrap(); - - world.claim_global_access(); - }); + ); } diff --git a/crates/languages/bevy_mod_scripting_lua/Cargo.toml b/crates/languages/bevy_mod_scripting_lua/Cargo.toml index 0625d7df19..977db69ed3 100644 --- a/crates/languages/bevy_mod_scripting_lua/Cargo.toml +++ b/crates/languages/bevy_mod_scripting_lua/Cargo.toml @@ -39,8 +39,7 @@ path = "src/lib.rs" [dependencies] bevy = { workspace = true, default-features = false } bevy_mod_scripting_core = { workspace = true, features = ["mlua_impls"] } -bevy_mod_scripting_functions = { workspace = true, features = [ -], default-features = false } +bevy_mod_scripting_functions = { workspace = true, features = [] } mlua = { workspace = true, features = ["vendored", "send", "macros"] } parking_lot = "0.12.1" uuid = "1.1" @@ -48,7 +47,13 @@ smol_str = "0.2.2" smallvec = "1.13" [dev-dependencies] -test_utils = { workspace = true } +# test_utils = { workspace = true } +script_integration_test_harness = { workspace = true } +bevy_mod_scripting_functions = { workspace = true, features = [ + "core_functions", + "bevy_bindings", + "test_functions", +] } libtest-mimic = "0.8" regex = "1.11" diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs index 946710bc27..7b1d5459af 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs @@ -57,7 +57,7 @@ impl FromLua for LuaScriptValue { } ScriptValue::List(vec) } - // Value::Function(function) => todo!(), + Value::Function(_) => todo!("Function FromLua is not implemented yet"), // Value::Thread(thread) => todo!(), Value::UserData(ud) => { let ud = ud.borrow::().map_err(|e| { diff --git a/crates/languages/bevy_mod_scripting_lua/src/lib.rs b/crates/languages/bevy_mod_scripting_lua/src/lib.rs index 3c98bad7f8..e6add60283 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/lib.rs @@ -26,6 +26,8 @@ impl IntoScriptPluginParams for LuaScriptingPlugin { type C = Lua; type R = (); const LANGUAGE: Language = Language::Lua; + + fn build_runtime() -> Self::R {} } pub struct LuaScriptingPlugin { @@ -37,7 +39,6 @@ impl Default for LuaScriptingPlugin { LuaScriptingPlugin { scripting_plugin: ScriptingPlugin { context_assigner: None, - runtime_builder: Default::default, runtime_settings: None, callback_handler: Some(lua_handler), context_builder: Some(ContextBuilder:: { diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/access/aliasing_global_access.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/access/aliasing_global_access.lua deleted file mode 100644 index 8cd7334081..0000000000 --- a/crates/languages/bevy_mod_scripting_lua/tests/data/access/aliasing_global_access.lua +++ /dev/null @@ -1,11 +0,0 @@ -local entity = Entity.from_raw(9999); -_claim_global_access(); - -if pcall(function() - entity:eq(entity) -end) -then - error("Aliasing access did not panick") -else - -- all good -end diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/access/aliasing_write.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/access/aliasing_write.lua deleted file mode 100644 index 85de5ee344..0000000000 --- a/crates/languages/bevy_mod_scripting_lua/tests/data/access/aliasing_write.lua +++ /dev/null @@ -1,11 +0,0 @@ -local entity = Entity.from_raw(9999); -_claim_write_access(entity); - -if pcall(function() - entity:eq(entity) -end) -then - error("Aliasing access did not panick") -else - -- all good -end diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/get_component/component_no_component_data.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/get_component/component_no_component_data.lua index 683e536205..d938e9d3f1 100644 --- a/crates/languages/bevy_mod_scripting_lua/tests/data/get_component/component_no_component_data.lua +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/get_component/component_no_component_data.lua @@ -1,5 +1,5 @@ local component = world.get_type_by_name("CompWithDefault") -local entity = _get_entity_with_test_component("CompWithDefault") +local entity = world._get_entity_with_test_component("CompWithDefault") local retrieved = world.get_component(entity, component) assert(retrieved ~= nil, "Component was not found") diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/get_component/component_with_component_data.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/get_component/component_with_component_data.lua index 886a6e6c39..5bfb7b7da3 100644 --- a/crates/languages/bevy_mod_scripting_lua/tests/data/get_component/component_with_component_data.lua +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/get_component/component_with_component_data.lua @@ -1,5 +1,5 @@ local component = world.get_type_by_name("TestComponent") -local entity = _get_entity_with_test_component("TestComponent") +local entity = world._get_entity_with_test_component("TestComponent") local retrieved = world.get_component(entity, component) assert(retrieved ~= nil, "Component was not found") diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/get_resource/missing_resource_returns_nil.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/get_resource/missing_resource_returns_nil.lua index 055d05d8f7..d2bc48168b 100644 --- a/crates/languages/bevy_mod_scripting_lua/tests/data/get_resource/missing_resource_returns_nil.lua +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/get_resource/missing_resource_returns_nil.lua @@ -1,2 +1,2 @@ -local type = _get_mock_type() +local type = world._get_mock_type() assert(world.get_resource(type) == nil, "Resource should not exist") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/has_component/empty_entity_mock_component_is_false.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/has_component/empty_entity_mock_component_is_false.lua index 1de4c06d18..226f87e549 100644 --- a/crates/languages/bevy_mod_scripting_lua/tests/data/has_component/empty_entity_mock_component_is_false.lua +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/has_component/empty_entity_mock_component_is_false.lua @@ -1,4 +1,4 @@ local entity = world.spawn() -local type = _get_mock_type() +local type = world._get_mock_type() assert(world.has_component(entity, type) == false, "Entity should not have component") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/has_component/no_component_data.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/has_component/no_component_data.lua index edbeae9fa9..129328bafc 100644 --- a/crates/languages/bevy_mod_scripting_lua/tests/data/has_component/no_component_data.lua +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/has_component/no_component_data.lua @@ -1,3 +1,3 @@ -local entity = _get_entity_with_test_component("CompWithDefault") +local entity = world._get_entity_with_test_component("CompWithDefault") local component = world.get_type_by_name("CompWithDefault") assert(world.has_component(entity, component) == true, "Component was not found") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/has_component/with_component_data.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/has_component/with_component_data.lua index 059137873d..6df4760557 100644 --- a/crates/languages/bevy_mod_scripting_lua/tests/data/has_component/with_component_data.lua +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/has_component/with_component_data.lua @@ -1,3 +1,3 @@ -local entity = _get_entity_with_test_component("TestComponent") +local entity = world._get_entity_with_test_component("TestComponent") local component = world.get_type_by_name("TestComponent") assert(world.has_component(entity, component) == true, "Component was not found") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/has_resource/missing_resource_mock_resource_is_false.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/has_resource/missing_resource_mock_resource_is_false.lua index 1917bb89e1..c15064fa39 100644 --- a/crates/languages/bevy_mod_scripting_lua/tests/data/has_resource/missing_resource_mock_resource_is_false.lua +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/has_resource/missing_resource_mock_resource_is_false.lua @@ -1,2 +1,2 @@ -local type = _get_mock_type() +local type = world._get_mock_type() assert(world.has_resource(type) == false, "Resource should not exist") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/query/query_returns_all_entities_matching.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/query/query_returns_all_entities_matching.lua index 5a3e83b055..527085cac6 100644 --- a/crates/languages/bevy_mod_scripting_lua/tests/data/query/query_returns_all_entities_matching.lua +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/query/query_returns_all_entities_matching.lua @@ -1,7 +1,7 @@ local entity_a = world.spawn() local entity_b = world.spawn() local entity_c = world.spawn() -local entity_d = _get_entity_with_test_component("CompWithFromWorldAndComponentData") +local entity_d = world._get_entity_with_test_component("CompWithFromWorldAndComponentData") local component_with = world.get_type_by_name("CompWithFromWorldAndComponentData") local component_without = world.get_type_by_name("CompWithDefaultAndComponentData") diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/remove_component/no_component_data_errors.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/remove_component/no_component_data_errors.lua index 5a2cdb58d0..0dc5c2d780 100644 --- a/crates/languages/bevy_mod_scripting_lua/tests/data/remove_component/no_component_data_errors.lua +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/remove_component/no_component_data_errors.lua @@ -1,5 +1,5 @@ -local entity = _get_entity_with_test_component("CompWithDefault") +local entity = world._get_entity_with_test_component("CompWithDefault") local component = world.get_type_by_name("CompWithDefault") assert_throws(function () diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/remove_component/with_component_data_removes_component.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/remove_component/with_component_data_removes_component.lua index 43d6dfd7e2..90ca6bd08f 100644 --- a/crates/languages/bevy_mod_scripting_lua/tests/data/remove_component/with_component_data_removes_component.lua +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/remove_component/with_component_data_removes_component.lua @@ -1,5 +1,5 @@ -local entity = _get_entity_with_test_component("TestComponent") +local entity = world._get_entity_with_test_component("TestComponent") local component = world.get_type_by_name("TestComponent") world.remove_component(entity, component) assert(world.has_component(entity, component) == false, "Component was not removed") diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/remove_resource/no_resource_data_errors.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/remove_resource/no_resource_data_errors.lua index 2f7b85ebff..b9b7a766f1 100644 --- a/crates/languages/bevy_mod_scripting_lua/tests/data/remove_resource/no_resource_data_errors.lua +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/remove_resource/no_resource_data_errors.lua @@ -1,5 +1,5 @@ -local type = _get_mock_type() +local type = world._get_mock_type() assert_throws(function () world.remove_resource(type) diff --git a/crates/languages/bevy_mod_scripting_lua/tests/lua_tests.rs b/crates/languages/bevy_mod_scripting_lua/tests/lua_tests.rs index 356c56ba80..b6456012f7 100644 --- a/crates/languages/bevy_mod_scripting_lua/tests/lua_tests.rs +++ b/crates/languages/bevy_mod_scripting_lua/tests/lua_tests.rs @@ -1,167 +1,13 @@ -use bevy::{ - app::App, - asset::AssetPlugin, - prelude::{Children, Entity, HierarchyPlugin, Parent, World}, - reflect::{Reflect, TypeRegistration}, -}; -use bevy_mod_scripting_core::{ - bindings::{ - access_map::ReflectAccessId, pretty_print::DisplayWithWorld, script_value::ScriptValue, - ReflectReference, ScriptTypeRegistration, WorldAccessGuard, - }, - context::ContextLoadingSettings, - error::ScriptError, - event::CallbackLabel, -}; -use bevy_mod_scripting_functions::ScriptFunctionsPlugin; -use bevy_mod_scripting_lua::{ - bindings::{reference::LuaReflectReference, world::GetWorld}, - lua_context_load, lua_handler, LuaScriptingPlugin, -}; +use bevy_mod_scripting_core::{bindings::pretty_print::DisplayWithWorld, error::ScriptError, AddContextInitializer}; +use bevy_mod_scripting_lua::{bindings::world::GetWorld, LuaScriptingPlugin}; use libtest_mimic::{Arguments, Failed, Trial}; -use mlua::{Function, Lua}; +use mlua::{Function, Lua, MultiValue}; +use script_integration_test_harness::execute_integration_test; use std::{ fs::{self, DirEntry}, io, panic, path::{Path, PathBuf}, - sync::Arc, }; -use test_utils::test_data::{setup_world, EnumerateTestComponents}; - -/// Initializes world for tests -fn init_app() -> App { - let mut app = App::new(); - - let world = setup_world(|_, _| {}); - - *app.world_mut() = world; - - // we probably should cut down some fat in here, but it's fast enough so meh - app.add_plugins(AssetPlugin::default()) - .add_plugins(HierarchyPlugin) - .add_plugins(LuaScriptingPlugin::default()) - .add_plugins(ScriptFunctionsPlugin); - - // for some reason hierarchy plugin doesn't register the children component - app.world_mut().register_component::(); - app.world_mut().register_component::(); - app.finish(); - app.cleanup(); - - app -} - -fn init_lua_test_utils(_script_name: &str, lua: &mut Lua) -> Result<(), ScriptError> { - let _get_mock_type = lua - .create_function(|l, ()| { - let world = l.get_world(); - #[derive(Reflect)] - struct Dummy; - let reg = - ScriptTypeRegistration::new(Arc::new(TypeRegistration::of::()), None, None); - let allocator = world.allocator(); - let mut allocator = allocator.write(); - let reference = ReflectReference::new_allocated(reg, &mut allocator); - Ok(LuaReflectReference::from(reference)) - }) - .unwrap(); - - let _get_entity_with_test_component = lua - .create_function(|l, s: String| { - let world = l.get_world(); - - Ok(World::enumerate_test_components() - .iter() - .find(|(name, _, _)| name.contains(&s)) - .map(|(_, _, c)| { - let allocator = world.allocator(); - let mut allocator = allocator.write(); - - let reference = ReflectReference::new_allocated( - c.unwrap_or(Entity::from_raw(9999)), - &mut allocator, - ); - LuaReflectReference::from(reference) - })) - }) - .unwrap(); - - let assert_throws = lua - .create_function(|lua, (f, regex): (Function, String)| { - let world = lua.get_world(); - - let result = f.call::<()>(()); - let err = match result { - Ok(_) => { - return Err(mlua::Error::RuntimeError( - "Expected function to throw error, but it did not.".into(), - )) - } - Err(e) => ScriptError::from_mlua_error(e).display_with_world(world), - }; - - let regex = regex::Regex::new(®ex).unwrap(); - if regex.is_match(&err) { - Ok(()) - } else { - Err(mlua::Error::RuntimeError(format!( - "Expected error message to match the regex: \n{}\n\nBut got:\n{}", - regex.as_str(), - err - ))) - } - }) - .unwrap(); - - let set_write_access = lua - .create_function(|lua, val: LuaReflectReference| { - let world = lua.get_world(); - let inner: ReflectReference = val.into(); - - world.claim_write_access(ReflectAccessId::for_reference(inner.base.base_id).unwrap()); - Ok(()) - }) - .unwrap(); - - let set_read_access = lua - .create_function(|lua, val: LuaReflectReference| { - let world = lua.get_world(); - let inner: ReflectReference = val.into(); - - world.claim_read_access(ReflectAccessId::for_reference(inner.base.base_id).unwrap()); - Ok(()) - }) - .unwrap(); - - let claim_whole_world_access = lua - .create_function(|lua, ()| { - let world = lua.get_world(); - world.claim_global_access(); - Ok(()) - }) - .unwrap(); - - let globals = lua.globals(); - globals - .set( - "_get_entity_with_test_component", - _get_entity_with_test_component, - ) - .unwrap(); - - globals.set("assert_throws", assert_throws).unwrap(); - - globals.set("_get_mock_type", _get_mock_type).unwrap(); - - globals - .set("_claim_write_access", set_write_access) - .unwrap(); - globals.set("_claim_read_access", set_read_access).unwrap(); - globals - .set("_claim_global_access", claim_whole_world_access) - .unwrap(); - Ok(()) -} struct Test { code: String, @@ -170,55 +16,57 @@ struct Test { impl Test { fn execute(self) -> Result<(), Failed> { - // let lua = Lua::new(); - // set file information - let mut app = init_app(); - let mut context_settings: ContextLoadingSettings = app - .world_mut() - .remove_resource() - .ok_or("could not find context loading settings")?; - context_settings - .context_initializers - .push(init_lua_test_utils); - - let mut lua = lua_context_load( - &(self.name()).into(), + execute_integration_test::( + |world, type_registry| { + let _ = world; + let _ = type_registry; + }, + |app| { + app.add_plugins(LuaScriptingPlugin::default()); + app.add_context_initializer::(|_,ctxt: &mut Lua| { + let globals = ctxt.globals(); + globals.set( + "assert_throws", + ctxt.create_function(|lua, (f, reg): (Function, String)| { + let world = lua.get_world(); + let result = f.call::<()>(MultiValue::new()); + let err = match result { + Ok(_) => { + return Err(mlua::Error::external( + "Expected function to throw error, but it did not.", + )) + } + Err(e) => + ScriptError::from_mlua_error(e).display_with_world(world) + , + }; + + let regex = regex::Regex::new(®).unwrap(); + if regex.is_match(&err) { + Ok(()) + } else { + Err(mlua::Error::external( + format!( + "Expected error message to match the regex: \n{}\n\nBut got:\n{}", + regex.as_str(), + err + ), + )) + } + })?, + )?; + Ok(()) + }); + }, + self.path.as_os_str().to_str().unwrap(), self.code.as_bytes(), - &context_settings.context_initializers, - &context_settings.context_pre_handling_initializers, - app.world_mut(), - &mut (), - ) - .map_err(|e| { - let world = app.world_mut(); - let world = WorldAccessGuard::new(world); - let msg = e.display_with_world(Arc::new(world)); - Failed::from(msg) - })?; - - lua_handler( - vec![ScriptValue::Unit], - Entity::from_raw(1), - &(self.name()).into(), - &CallbackLabel::new("on_test").ok_or("invalid callback label")?, - &mut lua, - &context_settings.context_pre_handling_initializers, - &mut (), - app.world_mut(), ) - .map_err(|e| { - let world = app.world_mut(); - let world = WorldAccessGuard::new(world); - let msg = e.display_with_world(Arc::new(world)); - Failed::from(msg) - })?; - - Ok(()) + .map_err(Failed::from) } fn name(&self) -> String { format!( - "lua_test - {}", + "script_test - lua - {}", self.path .to_string_lossy() .split(&format!("tests{}data", std::path::MAIN_SEPARATOR)) diff --git a/crates/languages/bevy_mod_scripting_rhai/src/lib.rs b/crates/languages/bevy_mod_scripting_rhai/src/lib.rs index 7e867627dc..7a16b8606b 100644 --- a/crates/languages/bevy_mod_scripting_rhai/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_rhai/src/lib.rs @@ -28,6 +28,10 @@ impl IntoScriptPluginParams for RhaiScriptingPlugin { type R = RhaiRuntime; const LANGUAGE: Language = Language::Rhai; + + fn build_runtime() -> Self::R { + RhaiRuntime::new() + } } pub struct RhaiScriptingPlugin { @@ -38,7 +42,6 @@ impl Default for RhaiScriptingPlugin { fn default() -> Self { RhaiScriptingPlugin { scripting_plugin: ScriptingPlugin { - runtime_builder: RhaiRuntime::new, runtime_settings: None, callback_handler: Some(rhai_callback_handler), context_assigner: None, diff --git a/crates/languages/bevy_mod_scripting_rune/src/lib.rs b/crates/languages/bevy_mod_scripting_rune/src/lib.rs index 792ab054b5..4835a2ab0e 100644 --- a/crates/languages/bevy_mod_scripting_rune/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_rune/src/lib.rs @@ -21,6 +21,10 @@ impl IntoScriptPluginParams for RuneScriptingPlugin { type R = RuneRuntime; const LANGUAGE: Language = Language::Rune; + + fn build_runtime() -> Self::R { + todo!() + } } pub struct RuneScriptingPlugin { diff --git a/crates/script_integration_test_harness/Cargo.toml b/crates/script_integration_test_harness/Cargo.toml new file mode 100644 index 0000000000..7c8f2f1c74 --- /dev/null +++ b/crates/script_integration_test_harness/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "script_integration_test_harness" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] +bevy = { workspace = true } +test_utils = { workspace = true } +bevy_mod_scripting_core = { workspace = true } +bevy_mod_scripting_functions = { workspace = true, features = [ + "bevy_bindings", + "core_functions", + "test_functions", +] } diff --git a/crates/script_integration_test_harness/src/lib.rs b/crates/script_integration_test_harness/src/lib.rs new file mode 100644 index 0000000000..5f43e75d6e --- /dev/null +++ b/crates/script_integration_test_harness/src/lib.rs @@ -0,0 +1,113 @@ +use bevy::{ + app::App, + prelude::{Entity, World}, + reflect::TypeRegistry, +}; +use bevy_mod_scripting_core::{ + bindings::{ + pretty_print::DisplayWithWorld, script_value::ScriptValue, WorldAccessGuard, WorldGuard, + }, + context::ContextLoadingSettings, + event::{IntoCallbackLabel, OnScriptLoaded}, + handler::CallbackSettings, + runtime::RuntimeSettings, + IntoScriptPluginParams, +}; +use bevy_mod_scripting_functions::ScriptFunctionsPlugin; +use test_utils::test_data::setup_integration_test; + +pub fn execute_integration_test< + P: IntoScriptPluginParams, + F: FnOnce(&mut World, &mut TypeRegistry), + G: FnOnce(&mut App), +>( + init: F, + init_app: G, + script_id: &str, + code: &[u8], +) -> Result<(), String> { + let mut app = setup_integration_test(init); + + app.add_plugins(ScriptFunctionsPlugin); + init_app(&mut app); + + app.cleanup(); + app.finish(); + + let context_settings: ContextLoadingSettings

= app + .world_mut() + .remove_resource() + .ok_or("could not find context loading settings") + .unwrap(); + + let callback_settings: CallbackSettings

= app + .world_mut() + .remove_resource() + .ok_or("could not find callback settings") + .unwrap(); + + let runtime_settings: RuntimeSettings

= app + .world_mut() + .remove_resource() + .ok_or("could not find runtime settings") + .unwrap(); + + let mut runtime = P::build_runtime(); + runtime_settings + .initializers + .iter() + .for_each(|initializer| { + (initializer)(&mut runtime); + }); + + // load the context as normal + let mut loaded_context = (context_settings.loader.unwrap().load)( + &(script_id.to_owned()).into(), + code, + &context_settings.context_initializers, + &context_settings.context_pre_handling_initializers, + app.world_mut(), + &mut runtime, + ) + .map_err(|e| { + let world = app.world_mut(); + let world = WorldAccessGuard::new(world); + e.display_with_world(WorldGuard::new(world)) + })?; + + // call on_script_loaded as normal + let val = (callback_settings.callback_handler.unwrap())( + vec![], + Entity::from_raw(0), + &(script_id.to_owned()).into(), + &OnScriptLoaded::into_callback_label(), + &mut loaded_context, + &context_settings.context_pre_handling_initializers, + &mut runtime, + app.world_mut(), + ) + .map_err(|e| e.display_with_world(WorldGuard::new(WorldAccessGuard::new(app.world_mut()))))?; + + if let ScriptValue::Error(e) = val { + return Err(e.display_with_world(WorldGuard::new(WorldAccessGuard::new(app.world_mut())))); + } + + // call on_test callback + let val = (callback_settings.callback_handler.unwrap())( + vec![], + Entity::from_raw(0), + &(script_id.to_owned()).into(), + &"on_test".into(), + &mut loaded_context, + &context_settings.context_pre_handling_initializers, + &mut runtime, + app.world_mut(), + ) + .map_err(|e| e.display_with_world(WorldGuard::new(WorldAccessGuard::new(app.world_mut()))))?; + + if let ScriptValue::Error(e) = val { + return Err(e.display_with_world(WorldGuard::new(WorldAccessGuard::new(app.world_mut())))); + } + + Ok(()) +} diff --git a/crates/test_utils/src/test_data.rs b/crates/test_utils/src/test_data.rs index 7cdc12c292..c869c48b87 100644 --- a/crates/test_utils/src/test_data.rs +++ b/crates/test_utils/src/test_data.rs @@ -3,8 +3,6 @@ use std::alloc::Layout; use bevy::ecs::{component::*, world::World}; use bevy::prelude::*; use bevy::reflect::*; -use bevy::render::settings::{RenderCreation, WgpuSettings}; -use bevy::render::RenderPlugin; /// Test component with Reflect and ReflectComponent registered #[derive(Component, Reflect, PartialEq, Eq, Debug)] @@ -264,13 +262,7 @@ pub fn setup_integration_test(init: F) // first setup all normal test components and resources let mut app = setup_app(init); - app.add_plugins(DefaultPlugins.set(RenderPlugin { - synchronous_pipeline_compilation: true, - render_creation: RenderCreation::Automatic(WgpuSettings { - backends: None, - ..default() - }), - })); + app.add_plugins((MinimalPlugins, AssetPlugin::default(), HierarchyPlugin)); app } diff --git a/crates/xtask/src/main.rs b/crates/xtask/src/main.rs index 8229edaef1..a30d7c851a 100644 --- a/crates/xtask/src/main.rs +++ b/crates/xtask/src/main.rs @@ -175,7 +175,7 @@ struct App { subcmd: Xtasks, } -#[derive(Debug, Clone, Default, strum::EnumString)] +#[derive(Debug, Clone, Default, strum::EnumString, strum::VariantNames)] #[strum(serialize_all = "snake_case")] enum CheckKind { #[default] @@ -184,6 +184,25 @@ enum CheckKind { Codegen, } +impl CheckKind { + fn to_placeholder() -> clap::builder::Str { + format!("[{}]", CheckKind::VARIANTS.join("|")).into() + } +} + +#[derive(Debug, Clone, strum::EnumString, strum::VariantNames)] +#[strum(serialize_all = "snake_case")] +enum Macro { + /// Integration tests for all script plugins + ScriptTests, +} + +impl Macro { + pub fn to_placeholder() -> clap::builder::Str { + format!("[{}]", Macro::VARIANTS.join("|")).into() + } +} + #[derive(Debug, clap::Subcommand)] #[clap( name = "xtask", @@ -191,6 +210,16 @@ enum CheckKind { about = "A set of xtasks for managing the project. Run 'cargo xtask init' to get started." )] enum Xtasks { + /// Set of tasks with predefined settings for running a combination of the other commands + Macros { + #[clap( + required = true, + value_parser=clap::value_parser!(Macro), + value_name=Macro::to_placeholder(), + help = "The macro to run" + )] + macro_name: Macro, + }, /// Performs first time local-development environment setup Init, /// Build the main workspace only @@ -210,6 +239,7 @@ enum Xtasks { short, default_value = "all", value_parser=clap::value_parser!(CheckKind), + value_name=CheckKind::to_placeholder(), help = "The kind of check to perform", )] kind: CheckKind, @@ -226,7 +256,19 @@ enum Xtasks { no_rust_docs: bool, }, /// Build the main workspace, and then run all tests - Test, + Test { + /// Run tests containing the given name only + #[clap(long, short)] + name: Option, + + /// Run tests in the given package only + #[clap(long, short)] + package: Option, + + /// Run tests without coverage + #[clap(long, short)] + no_coverage: bool, + }, /// Perform a full check as it would be done in CI CiCheck, } @@ -237,9 +279,21 @@ impl Xtasks { Xtasks::Build => Self::build(features), Xtasks::Check { ide_mode, kind } => Self::check(features, ide_mode, kind), Xtasks::Docs { open, no_rust_docs } => Self::docs(open, no_rust_docs), - Xtasks::Test => Self::test(features), + Xtasks::Test { + name, + package, + no_coverage, + } => Self::test(features, name, package, no_coverage), Xtasks::CiCheck => Self::cicd(), Xtasks::Init => Self::init(), + Xtasks::Macros { macro_name } => match macro_name { + Macro::ScriptTests => Self::test( + Features::all_features(), + Some("script_test".to_owned()), + None, + true, + ), + }, } } @@ -511,20 +565,39 @@ impl Xtasks { Ok(()) } - fn test(features: Features) -> Result<()> { + fn test( + features: Features, + package: Option, + name: Option, + no_coverage: bool, + ) -> Result<()> { // run cargo test with instrumentation - std::env::set_var("CARGO_INCREMENTAL", "0"); - Self::append_rustflags("-Cinstrument-coverage"); - let target_dir = std::env::var("CARGO_TARGET_DIR").unwrap_or_else(|_| "target".to_owned()); - let coverage_dir = std::path::PathBuf::from(target_dir).join("coverage"); - let coverage_file = coverage_dir.join("cargo-test-%p-%m.profraw"); + if !no_coverage { + std::env::set_var("CARGO_INCREMENTAL", "0"); + Self::append_rustflags("-Cinstrument-coverage"); - // clear coverage directory - assert!(coverage_dir != std::path::Path::new("/")); - let _ = std::fs::remove_dir_all(coverage_dir); + let target_dir = + std::env::var("CARGO_TARGET_DIR").unwrap_or_else(|_| "target".to_owned()); + let coverage_dir = std::path::PathBuf::from(target_dir).join("coverage"); + let coverage_file = coverage_dir.join("cargo-test-%p-%m.profraw"); - std::env::set_var("LLVM_PROFILE_FILE", coverage_file); + // clear coverage directory + assert!(coverage_dir != std::path::Path::new("/")); + let _ = std::fs::remove_dir_all(coverage_dir); + + std::env::set_var("LLVM_PROFILE_FILE", coverage_file); + } + + let mut test_args = vec![]; + if let Some(package) = package { + test_args.push("--package".to_owned()); + test_args.push(package); + } + + if let Some(name) = name { + test_args.push(name); + } Self::run_workspace_command( "test", @@ -535,51 +608,54 @@ impl Xtasks { )?; // generate coverage report and lcov file - Self::run_system_command( - "grcov", - "Generating html coverage report", - vec![ - ".", - "--binary-path", - "./target/debug/deps/", - "-s", - ".", - "-t", - "html", - "--branch", - "--ignore-not-existing", - "--ignore", - "../*", - "--ignore", - "/*", - "-o", - "target/coverage/html", - ], - None, - )?; + if !no_coverage { + Self::run_system_command( + "grcov", + "Generating html coverage report", + vec![ + ".", + "--binary-path", + "./target/debug/deps/", + "-s", + ".", + "-t", + "html", + "--branch", + "--ignore-not-existing", + "--ignore", + "../*", + "--ignore", + "/*", + "-o", + "target/coverage/html", + ], + None, + )?; - Self::run_system_command( - "grcov", - "Failed to generate coverage report", - vec![ - ".", - "--binary-path", - "./target/debug/deps/", - "-s", - ".", - "-t", - "lcov", - "--branch", - "--ignore-not-existing", - "--ignore", - "../*", - "--ignore", - "/*", - "-o", - "target/coverage/lcov.info", - ], - None, - ) + Self::run_system_command( + "grcov", + "Failed to generate coverage report", + vec![ + ".", + "--binary-path", + "./target/debug/deps/", + "-s", + ".", + "-t", + "lcov", + "--branch", + "--ignore-not-existing", + "--ignore", + "../*", + "--ignore", + "/*", + "-o", + "target/coverage/lcov.info", + ], + None, + )?; + } + Ok(()) } fn cicd() -> Result<()> { @@ -645,7 +721,7 @@ impl Xtasks { info!("All checks passed, running tests"); // run tests - Self::test(all_features)?; + Self::test(all_features, None, None, false)?; Ok(()) } From 1c0fd630a00d3003fc07f18e59002e52da119dd3 Mon Sep 17 00:00:00 2001 From: makspll Date: Thu, 9 Jan 2025 23:05:51 +0000 Subject: [PATCH 05/21] setup rhai tests --- .../bevy_mod_scripting_lua/Cargo.toml | 1 - .../bevy_mod_scripting_rhai/Cargo.toml | 4 +- .../missing_type_returns_nothing.rhai | 1 + .../registered_type_returns_correct_type.rhai | 15 +++ .../tests/rhai_tests.rs | 107 ++++++++---------- 5 files changed, 68 insertions(+), 60 deletions(-) create mode 100644 crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/missing_type_returns_nothing.rhai create mode 100644 crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/registered_type_returns_correct_type.rhai diff --git a/crates/languages/bevy_mod_scripting_lua/Cargo.toml b/crates/languages/bevy_mod_scripting_lua/Cargo.toml index 977db69ed3..505a2c1f3f 100644 --- a/crates/languages/bevy_mod_scripting_lua/Cargo.toml +++ b/crates/languages/bevy_mod_scripting_lua/Cargo.toml @@ -47,7 +47,6 @@ smol_str = "0.2.2" smallvec = "1.13" [dev-dependencies] -# test_utils = { workspace = true } script_integration_test_harness = { workspace = true } bevy_mod_scripting_functions = { workspace = true, features = [ "core_functions", diff --git a/crates/languages/bevy_mod_scripting_rhai/Cargo.toml b/crates/languages/bevy_mod_scripting_rhai/Cargo.toml index 9fd764301f..153894de3a 100644 --- a/crates/languages/bevy_mod_scripting_rhai/Cargo.toml +++ b/crates/languages/bevy_mod_scripting_rhai/Cargo.toml @@ -23,10 +23,12 @@ bevy_mod_scripting_functions = { workspace = true, features = [ ], default-features = false } [dev-dependencies] +script_integration_test_harness = { workspace = true } bevy_mod_scripting_functions = { workspace = true, features = [ + "core_functions", + "bevy_bindings", "test_functions", ] } -test_utils = { workspace = true } libtest-mimic = "0.8" regex = "1.11" diff --git a/crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/missing_type_returns_nothing.rhai b/crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/missing_type_returns_nothing.rhai new file mode 100644 index 0000000000..054a6f0e06 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/missing_type_returns_nothing.rhai @@ -0,0 +1 @@ +assert(world.get_type_by_name('UnregisteredType') == (), 'Unregistered type was found') diff --git a/crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/registered_type_returns_correct_type.rhai b/crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/registered_type_returns_correct_type.rhai new file mode 100644 index 0000000000..3ee1a0a08f --- /dev/null +++ b/crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/registered_type_returns_correct_type.rhai @@ -0,0 +1,15 @@ +local type = world.get_type_by_name('TestComponent') + +local expected = { + type_name = 'test_utils::test_data::TestComponent', + short_name = 'TestComponent', +} + +local received = { + type_name = type:type_name(), + short_name = type:short_name(), +} + +assert(type != (), 'Type not found') +assert(received.type_name == expected.type_name, 'type_name mismatch, expected: ' .. expected.type_name .. ', got: ' .. received.type_name) +assert(received.short_name == expected.short_name, 'short_name mismatch, expected: ' .. expected.short_name .. ', got: ' .. received.short_name) diff --git a/crates/languages/bevy_mod_scripting_rhai/tests/rhai_tests.rs b/crates/languages/bevy_mod_scripting_rhai/tests/rhai_tests.rs index d73f101f4c..fd553c2652 100644 --- a/crates/languages/bevy_mod_scripting_rhai/tests/rhai_tests.rs +++ b/crates/languages/bevy_mod_scripting_rhai/tests/rhai_tests.rs @@ -1,26 +1,11 @@ -// use bevy::app::App; -// use bevy_mod_scripting_functions::ScriptFunctionsPlugin; -// use bevy_mod_scripting_rhai::RhaiScriptingPlugin; +use bevy_mod_scripting_rhai::RhaiScriptingPlugin; use libtest_mimic::{Arguments, Failed, Trial}; +use script_integration_test_harness::execute_integration_test; use std::{ fs::{self, DirEntry}, io, panic, path::{Path, PathBuf}, }; -// use test_utils::test_data::setup_integration_test; - -// Initializes world for tests -// fn init_app() -> App { -// let mut app = setup_integration_test(|_, _| {}); - -// app.add_plugins(RhaiScriptingPlugin::default()) -// .add_plugins(ScriptFunctionsPlugin); - -// app.finish(); -// app.cleanup(); - -// app -// } struct Test { code: String, @@ -29,51 +14,57 @@ struct Test { impl Test { fn execute(self) -> Result<(), Failed> { - println!("Running test: {}", self.name()); - println!("Code: {}", self.code); - // let lua = Lua::new(); - // set file information - // let mut app = init_app(); - // app.add_systems(schedule, systems); - - // let mut lua = lua_context_load( - // &(self.name()).into(), - // self.code.as_bytes(), - // &context_settings.context_initializers, - // &context_settings.context_pre_handling_initializers, - // app.world_mut(), - // &mut (), - // ) - // .map_err(|e| { - // let world = app.world_mut(); - // let world = WorldAccessGuard::new(world); - // let msg = e.display_with_world(Arc::new(world)); - // Failed::from(msg) - // })?; - - // lua_handler( - // vec![ScriptValue::Unit], - // Entity::from_raw(1), - // &(self.name()).into(), - // &CallbackLabel::new("on_test").ok_or("invalid callback label")?, - // &mut lua, - // &context_settings.context_pre_handling_initializers, - // &mut (), - // app.world_mut(), - // ) - // .map_err(|e| { - // let world = app.world_mut(); - // let world = WorldAccessGuard::new(world); - // let msg = e.display_with_world(Arc::new(world)); - // Failed::from(msg) - // })?; - - Ok(()) + execute_integration_test::( + |world, type_registry| { + let _ = world; + let _ = type_registry; + }, + |app| { + app.add_plugins(RhaiScriptingPlugin::default()); + // app.add_context_initializer::(|_,ctxt: &mut Lua| { + // let globals = ctxt.globals(); + // globals.set( + // "assert_throws", + // ctxt.create_function(|lua, (f, reg): (Function, String)| { + // let world = lua.get_world(); + // let result = f.call::<()>(MultiValue::new()); + // let err = match result { + // Ok(_) => { + // return Err(mlua::Error::external( + // "Expected function to throw error, but it did not.", + // )) + // } + // Err(e) => + // ScriptError::from_mlua_error(e).display_with_world(world) + // , + // }; + + // let regex = regex::Regex::new(®).unwrap(); + // if regex.is_match(&err) { + // Ok(()) + // } else { + // Err(mlua::Error::external( + // format!( + // "Expected error message to match the regex: \n{}\n\nBut got:\n{}", + // regex.as_str(), + // err + // ), + // )) + // } + // })?, + // )?; + // Ok(()) + // }); + }, + self.path.as_os_str().to_str().unwrap(), + self.code.as_bytes(), + ) + .map_err(Failed::from) } fn name(&self) -> String { format!( - "lua_test - {}", + "script_test - lua - {}", self.path .to_string_lossy() .split(&format!("tests{}data", std::path::MAIN_SEPARATOR)) From 5b34eea1ab6822f79f23bba30c220b2991184db7 Mon Sep 17 00:00:00 2001 From: makspll Date: Thu, 9 Jan 2025 23:18:39 +0000 Subject: [PATCH 06/21] add assertions --- .../missing_type_returns_nothing.rhai | 3 ++- .../tests/rhai_tests.rs | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/missing_type_returns_nothing.rhai b/crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/missing_type_returns_nothing.rhai index 054a6f0e06..ea44877a9e 100644 --- a/crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/missing_type_returns_nothing.rhai +++ b/crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/missing_type_returns_nothing.rhai @@ -1 +1,2 @@ -assert(world.get_type_by_name('UnregisteredType') == (), 'Unregistered type was found') +assert(false); +assert(world.get_type_by_name("UnregisteredType") == (), "Unregistered type was found"); diff --git a/crates/languages/bevy_mod_scripting_rhai/tests/rhai_tests.rs b/crates/languages/bevy_mod_scripting_rhai/tests/rhai_tests.rs index fd553c2652..48f81176fe 100644 --- a/crates/languages/bevy_mod_scripting_rhai/tests/rhai_tests.rs +++ b/crates/languages/bevy_mod_scripting_rhai/tests/rhai_tests.rs @@ -1,5 +1,7 @@ +use bevy_mod_scripting_core::AddRuntimeInitializer; use bevy_mod_scripting_rhai::RhaiScriptingPlugin; use libtest_mimic::{Arguments, Failed, Trial}; +use rhai::Dynamic; use script_integration_test_harness::execute_integration_test; use std::{ fs::{self, DirEntry}, @@ -21,6 +23,28 @@ impl Test { }, |app| { app.add_plugins(RhaiScriptingPlugin::default()); + app.add_runtime_initializer::(|runtime| { + runtime.register_fn("assert", |a: Dynamic, b: &str| { + if !a.is::() { + panic!("Expected a boolean value, but got {:?}", a); + } + if !a.as_bool().unwrap() { + panic!("Assertion failed. {}", b); + } + }); + }); + + app.add_runtime_initializer::(|runtime| { + runtime.register_fn("assert", |a: Dynamic| { + if !a.is::() { + panic!("Expected a boolean value, but got {:?}", a); + } + if !a.as_bool().unwrap() { + panic!("Assertion failed"); + } + }); + }); + // app.add_context_initializer::(|_,ctxt: &mut Lua| { // let globals = ctxt.globals(); // globals.set( From 2491f5414d36f20b4914aeb9ccacd32a34026d00 Mon Sep 17 00:00:00 2001 From: makspll Date: Thu, 9 Jan 2025 23:42:24 +0000 Subject: [PATCH 07/21] start writing marshalling code for rhai --- .../src/bindings/script_value.rs | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs b/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs index 8b13789179..d272c62087 100644 --- a/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs +++ b/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs @@ -1 +1,53 @@ +use std::str::FromStr; +use bevy_mod_scripting_core::{bindings::script_value::ScriptValue, error::InteropError}; +use rhai::{Dynamic, EvalAltResult}; + +pub trait IntoDynamic { + fn into_dynamic(self) -> Result>; +} + +impl IntoDynamic for ScriptValue { + fn into_dynamic(self) -> Result> { + Ok(match self { + ScriptValue::Unit => Dynamic::UNIT, + ScriptValue::Bool(b) => Dynamic::from_bool(b), + ScriptValue::Integer(i) => Dynamic::from_int(i), + ScriptValue::Float(f) => Dynamic::from_float(f), + ScriptValue::String(cow) => Dynamic::from_str(&cow).map_err(|_| { + EvalAltResult::ErrorSystem( + "error in converting string to rhai value".to_owned(), + InteropError::unsupported_operation( + None, + Some(Box::new(cow.clone())), + "string to rhai value".to_owned(), + ) + .into(), + ) + })?, + ScriptValue::List(_vec) => todo!(), + ScriptValue::Reference(_reflect_reference) => todo!(), + ScriptValue::Function(_dynamic_script_function_mut) => todo!(), + ScriptValue::Error(_interop_error) => todo!(), + }) + } +} + +pub trait FromDynamic: Sized { + fn from_dynamic(dynamic: Dynamic) -> Result>; +} + +impl FromDynamic for ScriptValue { + fn from_dynamic(dynamic: Dynamic) -> Result> { + match dynamic { + d if d.is_unit() => Ok(ScriptValue::Unit), + d if d.is_bool() => Ok(ScriptValue::Bool(d.as_bool().unwrap())), + d if d.is_int() => Ok(ScriptValue::Integer(d.as_int().unwrap())), + d if d.is_float() => Ok(ScriptValue::Float(d.as_float().unwrap())), + d if d.is_string() => Ok(ScriptValue::String( + d.into_immutable_string().unwrap().to_string().into(), + )), + _ => todo!(), + } + } +} From 5fb07761718ccc76bac7ed88b7b73bc02284f2a6 Mon Sep 17 00:00:00 2001 From: makspll Date: Sat, 11 Jan 2025 12:02:32 +0000 Subject: [PATCH 08/21] move world pointers to thread locals --- .../src/bindings/world.rs | 46 +++++ crates/bevy_mod_scripting_core/src/lib.rs | 1 - crates/bevy_mod_scripting_core/src/world.rs | 158 ------------------ .../src/bindings/reference.rs | 64 ++++--- .../src/bindings/script_value.rs | 7 +- .../src/bindings/world.rs | 56 ++----- .../bevy_mod_scripting_lua/src/lib.rs | 64 ++++--- .../bevy_mod_scripting_lua/tests/lua_tests.rs | 8 +- .../src/bindings/mod.rs | 1 + .../src/bindings/reference.rs | 49 ++++++ .../bevy_mod_scripting_rhai/src/lib.rs | 12 +- 11 files changed, 191 insertions(+), 275 deletions(-) delete mode 100644 crates/bevy_mod_scripting_core/src/world.rs create mode 100644 crates/languages/bevy_mod_scripting_rhai/src/bindings/reference.rs diff --git a/crates/bevy_mod_scripting_core/src/bindings/world.rs b/crates/bevy_mod_scripting_core/src/bindings/world.rs index 613adab29c..99b40a6f24 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/world.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/world.rs @@ -24,6 +24,7 @@ use bevy::{ }; use std::{ any::TypeId, + cell::RefCell, fmt::Debug, sync::{Arc, Weak}, time::Duration, @@ -946,6 +947,51 @@ impl WorldAccessGuard<'_> { } } +/// Utility type for accessing the world in a callback +pub trait WorldContainer { + type Error: Debug; + /// Sets the world to the given value + fn set_world(&mut self, world: WorldCallbackAccess) -> Result<(), Self::Error>; + + /// Gets the world, use [`WorldContainer::try_get_world`] if you want to handle errors with retrieving the world + /// # Panics + /// - if the world has not been set + /// - if the world has been dropped + fn get_world(&self) -> WorldGuard<'static> { + self.try_get_world().expect("World not set, or expired") + } + + /// Tries to get the world + fn try_get_world(&self) -> Result>, Self::Error>; +} + +/// A world container that stores the world in a thread local +pub struct ThreadWorldContainer; + +thread_local! { + static WORLD_CALLBACK_ACCESS: RefCell> = const { RefCell::new(None) }; +} + +impl WorldContainer for ThreadWorldContainer { + type Error = InteropError; + + fn set_world(&mut self, world: WorldCallbackAccess) -> Result<(), Self::Error> { + WORLD_CALLBACK_ACCESS.with(|w| { + w.replace(Some(world)); + }); + Ok(()) + } + + fn try_get_world(&self) -> Result>, Self::Error> { + WORLD_CALLBACK_ACCESS.with(|w| { + w.borrow() + .as_ref() + .map(|w| w.try_read()) + .ok_or_else(InteropError::missing_world) + })? + } +} + // #[cfg(test)] // mod test { // use crate::bindings::ScriptTypeRegistration; diff --git a/crates/bevy_mod_scripting_core/src/lib.rs b/crates/bevy_mod_scripting_core/src/lib.rs index 98cc9a6aa6..b596ce2a7a 100644 --- a/crates/bevy_mod_scripting_core/src/lib.rs +++ b/crates/bevy_mod_scripting_core/src/lib.rs @@ -36,7 +36,6 @@ pub mod reflection_extensions; pub mod runtime; pub mod script; pub mod systems; -pub mod world; /// Types which act like scripting plugins, by selecting a context and runtime /// Each individual combination of context and runtime has specific infrastructure built for it and does not interact with other scripting plugins diff --git a/crates/bevy_mod_scripting_core/src/world.rs b/crates/bevy_mod_scripting_core/src/world.rs deleted file mode 100644 index 2dee3cc48a..0000000000 --- a/crates/bevy_mod_scripting_core/src/world.rs +++ /dev/null @@ -1,158 +0,0 @@ -use bevy::prelude::World; -use parking_lot::{ - MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard, -}; -use std::ops::Deref; -use std::sync::Arc; - -/// Pointer to a bevy world, safely allows multiple access via RwLock -/// -/// If the original [WorldPointerGuard] that created this pointer is dropped, -/// the `read` and `write` methods will panic, and the "try" variants will -/// return `None`. -#[derive(Debug, Clone)] -pub struct WorldPointer(Arc>>); - -/// Guarded pointer to a bevy world, can be used to `clone` additional -/// [WorldPointer]s for safe access. -/// -/// # Safety -/// The original `&mut World` used to create this guard _must not_ be used after -/// the guard is created in order for the cloned [WorldPointer]s to be safe. -/// -/// On [Drop], it will "take back" access to the `&mut World`, preventing the -/// `WorldPointer`s from invoking UB. -#[derive(Debug)] -pub struct WorldPointerGuard(WorldPointer); - -impl Deref for WorldPointerGuard { - type Target = WorldPointer; - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -unsafe impl Send for WorldPointer {} -unsafe impl Sync for WorldPointer {} - -impl WorldPointerGuard { - /// Creates a new world pointer. - /// # Safety - /// The original `&mut World` must not be used while this guard is in scope. - /// The [World] may only be accessed through this guard or one of its cloned - /// [WorldPointer]s. - #[allow(clippy::arc_with_non_send_sync)] - pub unsafe fn new(world: &mut World) -> Self { - WorldPointerGuard(WorldPointer(Arc::new(RwLock::new(Some(world))))) - } -} - -impl Drop for WorldPointerGuard { - fn drop(&mut self) { - // Being explicit about the types here to make sure we're getting things - // correct. - let world_ptr: &WorldPointer = &self.0; - let _: Option<*mut World> = RwLock::write(&world_ptr.0).take(); - } -} - -impl WorldPointer { - /// Returns a read guard which can be used for immutable world access. - /// - /// Panics if the pointer is already locked or has gone out of scope. - pub fn read(&self) -> MappedRwLockReadGuard { - self.try_read().expect("concurrent read/write world access") - } - - /// Returns a write guard which can be used for mutable world access. - /// - /// Panics if the pointer is already locked or has gone out of scope. - pub fn write(&self) -> MappedRwLockWriteGuard { - self.try_write() - .expect("concurrent read/write world access") - } - - /// Returns a read guard which can be used for immutable world access. - /// - /// Returns `None` if the pointer is already locked or has gone out of - /// scope. - pub fn try_read(&self) -> Option> { - self.try_read_inner(false) - } - - /// Returns a write guard which can be used for mutable world access. - /// - /// Returns `None` if the pointer is already locked or has gone out of - /// scope. - pub fn try_write(&self) -> Option> { - self.try_write_inner(false) - } - - /// Returns a read guard which can be used for immutable world access. - /// - /// Panics if the pointer has gone out of scope. May block if another thread - /// holds the lock. - pub fn read_blocking(&self) -> MappedRwLockReadGuard { - self.try_read_blocking() - .expect("the world pointer is out of scope") - } - - /// Returns a write guard which can be used for mutable world access. - /// - /// Panics if the pointer has gone out of scope. May block if another thread - /// holds the lock. - pub fn write_blocking(&self) -> MappedRwLockWriteGuard { - self.try_write_blocking() - .expect("the world pointer is out of scope") - } - - /// Returns a read guard which can be used for immutable world access. - /// - /// Returns `None` if has gone out of scope. May block if another thread - /// holds the lock. - pub fn try_read_blocking(&self) -> Option> { - self.try_read_inner(true) - } - - /// Returns a write guard which can be used for mutable world access. - /// - /// Returns `None` if has gone out of scope. May block if another thread - /// holds the lock. - pub fn try_write_blocking(&self) -> Option> { - self.try_write_inner(true) - } - - fn try_read_inner(&self, blocking: bool) -> Option> { - let guard = if blocking { - self.0.read() - } else { - self.0.try_read()? - }; - // Check if the inner pointer is there so we can invert the `Option`. - if guard.is_none() { - return None; - } - - Some(RwLockReadGuard::map( - guard, - |ptr: &Option<*mut World>| unsafe { &*ptr.unwrap() }, - )) - } - - fn try_write_inner(&self, blocking: bool) -> Option> { - let guard = if blocking { - self.0.write() - } else { - self.0.try_write()? - }; - // Check if the inner pointer is there so we can invert the `Option`. - if guard.is_none() { - return None; - } - - Some(RwLockWriteGuard::map( - guard, - |ptr: &mut Option<*mut World>| unsafe { &mut *ptr.unwrap() }, - )) - } -} diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs index 8b26442240..d34b431fbf 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs @@ -1,5 +1,5 @@ -use std::any::TypeId; - +use super::script_value::LuaScriptValue; +use crate::bindings::script_value::lua_caller_context; use bevy_mod_scripting_core::{ bindings::{ function::{ @@ -8,20 +8,14 @@ use bevy_mod_scripting_core::{ }, pretty_print::DisplayWithWorld, script_value::ScriptValue, - ReflectReference, WorldGuard, + ReflectReference, ThreadWorldContainer, WorldContainer, WorldGuard, }, error::InteropError, reflection_extensions::TypeIdExtensions, }; -use bevy_mod_scripting_functions::namespaced_register::{GetNamespacedFunction, Namespace}; +use bevy_mod_scripting_functions::{namespaced_register::Namespace, GetNamespacedFunction}; use mlua::{Function, IntoLua, Lua, MetaMethod, UserData, UserDataMethods, Variadic}; - -use super::{ - // proxy::{LuaProxied, LuaValProxy}, - script_value::LuaScriptValue, - world::GetWorld, -}; -use crate::bindings::script_value::lua_caller_context; +use std::any::TypeId; /// Lua UserData wrapper for [`bevy_mod_scripting_core::bindings::ReflectReference`]. /// Acts as a lua reflection interface. Any value which is registered in the type registry can be interacted with using this type. @@ -51,8 +45,8 @@ fn lookup_function(lua: &Lua, key: &str, type_id: TypeId) -> Option| { - let world = lua.get_world(); + lua.create_function_mut(move |_lua, args: Variadic| { + let world = ThreadWorldContainer.get_world(); let out = function.call_script_function( args.into_iter().map(Into::into), world, @@ -72,8 +66,12 @@ fn lookup_function_typed( lookup_function(lua, key, type_id) } -fn lookup_dynamic_function(lua: &Lua, key: &str, type_id: TypeId) -> Option { - let function_registry = lua +fn lookup_dynamic_function( + _lua: &Lua, + key: &str, + type_id: TypeId, +) -> Option { + let function_registry = ThreadWorldContainer .get_world() .with_resource(|registry: &AppScriptFunctionRegistry| registry.clone()); let registry = function_registry.read(); @@ -92,11 +90,11 @@ fn lookup_dynamic_function_typed( } fn iter_dynamic_function_overloads( - lua: &Lua, + _lua: &Lua, key: &str, type_id: TypeId, ) -> impl Iterator { - let registry = lua + let registry = ThreadWorldContainer .get_world() .with_resource(|registry: &AppScriptFunctionRegistry| registry.clone()); let registry = registry.read(); @@ -136,7 +134,7 @@ impl UserData for LuaReflectReference { m.add_meta_function( MetaMethod::Index, |lua, (self_, key): (LuaReflectReference, LuaScriptValue)| { - let world = lua.get_world(); + let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let type_id = self_.tail_type_id(world.clone())?.or_fake_id(); @@ -177,7 +175,7 @@ impl UserData for LuaReflectReference { .expect("No 'set' function registered for a ReflectReference") .call_script_function( vec![ScriptValue::Reference(self_), key, value], - lua.get_world(), + ThreadWorldContainer.get_world(), lua_caller_context(Some(std::any::TypeId::of::())), )?; @@ -188,7 +186,7 @@ impl UserData for LuaReflectReference { m.add_meta_function( MetaMethod::Sub, |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { - let world = lua.get_world(); + let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); @@ -200,7 +198,7 @@ impl UserData for LuaReflectReference { m.add_meta_function( MetaMethod::Add, |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { - let world = lua.get_world(); + let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); @@ -212,7 +210,7 @@ impl UserData for LuaReflectReference { m.add_meta_function( MetaMethod::Mul, |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { - let world = lua.get_world(); + let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); @@ -224,7 +222,7 @@ impl UserData for LuaReflectReference { m.add_meta_function( MetaMethod::Div, |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { - let world = lua.get_world(); + let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); @@ -236,7 +234,7 @@ impl UserData for LuaReflectReference { m.add_meta_function( MetaMethod::Mod, |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { - let world = lua.get_world(); + let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); @@ -246,7 +244,7 @@ impl UserData for LuaReflectReference { ); m.add_meta_function(MetaMethod::Unm, |lua, self_: LuaReflectReference| { - let world = lua.get_world(); + let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_)]; @@ -256,7 +254,7 @@ impl UserData for LuaReflectReference { m.add_meta_function( MetaMethod::Pow, |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { - let world = lua.get_world(); + let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); @@ -268,7 +266,7 @@ impl UserData for LuaReflectReference { m.add_meta_function( MetaMethod::Eq, |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { - let world = lua.get_world(); + let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); @@ -280,7 +278,7 @@ impl UserData for LuaReflectReference { m.add_meta_function( MetaMethod::Lt, |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { - let world = lua.get_world(); + let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); @@ -289,8 +287,8 @@ impl UserData for LuaReflectReference { }, ); - m.add_meta_function(MetaMethod::Len, |lua, self_: LuaScriptValue| { - let world = lua.get_world(); + m.add_meta_function(MetaMethod::Len, |_lua, self_: LuaScriptValue| { + let world = ThreadWorldContainer.get_world(); let script_value: ScriptValue = self_.into(); Ok(match script_value { ScriptValue::Reference(r) => r.len(world)?, @@ -308,7 +306,7 @@ impl UserData for LuaReflectReference { m.add_meta_function(MetaMethod::Pairs, |l, s: LuaReflectReference| { let mut iter_func = lookup_dynamic_function_typed::(l, "iter") .expect("No iter function registered"); - let world = l.get_world(); + let world = ThreadWorldContainer.get_world(); Ok(LuaScriptValue::from(iter_func.call_script_function( vec![ScriptValue::Reference(s.into())], @@ -318,7 +316,7 @@ impl UserData for LuaReflectReference { }); m.add_meta_function(MetaMethod::ToString, |lua, self_: LuaReflectReference| { - let world = lua.get_world(); + let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let mut display_func = @@ -357,7 +355,7 @@ impl UserData for LuaStaticReflectReference { return func?.into_lua(lua); } }; - let world = lua.get_world(); + let world = ThreadWorldContainer.get_world(); Err( InteropError::missing_function(type_id, key.display_with_world(world.clone())) .into(), diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs index 7b1d5459af..257a08ef93 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs @@ -6,10 +6,11 @@ use std::{ use bevy_mod_scripting_core::bindings::{ function::{script_function::CallerContext, CallScriptFunction}, script_value::ScriptValue, + ThreadWorldContainer, WorldContainer, }; use mlua::{FromLua, IntoLua, Value, Variadic}; -use super::{reference::LuaReflectReference, world::GetWorld}; +use super::reference::LuaReflectReference; #[derive(Debug, Clone)] pub struct LuaScriptValue(ScriptValue); @@ -100,8 +101,8 @@ impl IntoLua for LuaScriptValue { ScriptValue::Reference(r) => LuaReflectReference::from(r).into_lua(lua)?, ScriptValue::Error(script_error) => return Err(mlua::Error::external(script_error)), ScriptValue::Function(mut function) => lua - .create_function_mut(move |lua, args: Variadic| { - let world = lua.get_world(); + .create_function_mut(move |_lua, args: Variadic| { + let world = ThreadWorldContainer.get_world(); let out = function.call_script_function( args.into_iter().map(Into::into), world, diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/world.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/world.rs index b04a900b2d..a4185deb74 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/bindings/world.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/world.rs @@ -1,45 +1,21 @@ -use std::sync::Arc; +// use std::sync::Arc; -use bevy_mod_scripting_core::bindings::WorldGuard; -use bevy_mod_scripting_core::bindings::{WorldAccessGuard, WorldCallbackAccess}; -use bevy_mod_scripting_core::error::InteropError; -use mlua::UserData; +// use bevy_mod_scripting_core::bindings::WorldCallbackAccess; +// use mlua::UserData; -#[derive(Clone, Debug, mlua::FromLua)] -pub struct LuaWorld(pub WorldCallbackAccess); +// #[derive(Clone, Debug, mlua::FromLua)] +// pub struct LuaWorld(pub WorldCallbackAccess); -impl LuaWorld { - pub fn world_callback_access(self) -> WorldCallbackAccess { - self.0.clone() - } -} +// impl LuaWorld { +// pub fn world_callback_access(self) -> WorldCallbackAccess { +// self.0.clone() +// } +// } -impl UserData for LuaWorld {} +// impl UserData for LuaWorld {} -impl From<&LuaWorld> for WorldCallbackAccess { - fn from(value: &LuaWorld) -> Self { - value.0.clone() - } -} - -pub trait GetWorld { - fn get_world(&self) -> WorldGuard<'static>; - fn try_get_world(&self) -> Result>, mlua::Error>; -} - -impl GetWorld for mlua::Lua { - fn try_get_world(&self) -> Result>, mlua::Error> { - let access = self - .app_data_ref::() - .ok_or_else(InteropError::missing_world)?; - - let world = access.try_read()?; - - Ok(world) - } - - fn get_world(&self) -> WorldGuard<'static> { - self.try_get_world() - .expect("global 'world' did not exist or was invalid. Cannot retrieve world") - } -} +// impl From<&LuaWorld> for WorldCallbackAccess { +// fn from(value: &LuaWorld) -> Self { +// value.0.clone() +// } +// } diff --git a/crates/languages/bevy_mod_scripting_lua/src/lib.rs b/crates/languages/bevy_mod_scripting_lua/src/lib.rs index e6add60283..af7d39601e 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/lib.rs @@ -4,19 +4,19 @@ use bevy::{ }; use bevy_mod_scripting_core::{ asset::{AssetPathToLanguageMapper, Language}, - bindings::{script_value::ScriptValue, WorldCallbackAccess}, + bindings::{ + script_value::ScriptValue, ThreadWorldContainer, WorldCallbackAccess, WorldContainer, + }, context::{ContextBuilder, ContextInitializer, ContextPreHandlingInitializer}, error::ScriptError, event::CallbackLabel, reflection_extensions::PartialReflectExt, script::ScriptId, - AddContextInitializer, AddContextPreHandlingInitializer, IntoScriptPluginParams, - ScriptingPlugin, + AddContextInitializer, IntoScriptPluginParams, ScriptingPlugin, }; use bindings::{ reference::{LuaReflectReference, LuaStaticReflectReference}, script_value::LuaScriptValue, - world::GetWorld, }; pub use mlua; use mlua::{Function, IntoLua, Lua, MultiValue}; @@ -48,8 +48,31 @@ impl Default for LuaScriptingPlugin { language_mapper: Some(AssetPathToLanguageMapper { map: lua_language_mapper, }), - context_initializers: Default::default(), - context_pre_handling_initializers: Default::default(), + context_initializers: vec![|_script_id, context| { + context + .globals() + .set( + "world", + LuaStaticReflectReference(std::any::TypeId::of::()), + ) + .map_err(ScriptError::from_mlua_error)?; + Ok(()) + }], + context_pre_handling_initializers: vec![|script_id, entity, context| { + let world = ThreadWorldContainer.get_world(); + context + .globals() + .set( + "entity", + LuaReflectReference(::allocate(Box::new(entity), world)), + ) + .map_err(ScriptError::from_mlua_error)?; + context + .globals() + .set("script_id", script_id) + .map_err(ScriptError::from_mlua_error)?; + Ok(()) + }], }, } } @@ -65,31 +88,13 @@ fn lua_language_mapper(path: &std::path::Path) -> Language { impl Plugin for LuaScriptingPlugin { fn build(&self, app: &mut bevy::prelude::App) { self.scripting_plugin.build(app); - // register_lua_values(app); - app.add_context_pre_handling_initializer::( - |script_id, entity, context: &mut Lua| { - let world = context.get_world(); - context - .globals() - .set( - "entity", - LuaReflectReference(::allocate(Box::new(entity), world)), - ) - .map_err(ScriptError::from_mlua_error)?; - context - .globals() - .set("script_id", script_id) - .map_err(ScriptError::from_mlua_error)?; - Ok(()) - }, - ); } fn cleanup(&self, app: &mut App) { // find all registered types, and insert dummy for calls app.add_context_initializer::(|_script_id, context: &mut Lua| { - let world = context.get_world(); + let world = ThreadWorldContainer.get_world(); let type_registry = world.type_registry(); let type_registry = type_registry.read(); @@ -205,14 +210,7 @@ pub fn with_world Result>( f: F, ) -> Result { WorldCallbackAccess::with_callback_access(world, |guard| { - context - .globals() - .set( - "world", - LuaStaticReflectReference(std::any::TypeId::of::()), - ) - .map_err(ScriptError::from_mlua_error)?; - context.set_app_data(guard.clone()); + ThreadWorldContainer.set_world(guard.clone())?; f(context) }) } diff --git a/crates/languages/bevy_mod_scripting_lua/tests/lua_tests.rs b/crates/languages/bevy_mod_scripting_lua/tests/lua_tests.rs index b6456012f7..95c12a946f 100644 --- a/crates/languages/bevy_mod_scripting_lua/tests/lua_tests.rs +++ b/crates/languages/bevy_mod_scripting_lua/tests/lua_tests.rs @@ -1,5 +1,5 @@ -use bevy_mod_scripting_core::{bindings::pretty_print::DisplayWithWorld, error::ScriptError, AddContextInitializer}; -use bevy_mod_scripting_lua::{bindings::world::GetWorld, LuaScriptingPlugin}; +use bevy_mod_scripting_core::{bindings::{pretty_print::DisplayWithWorld, ThreadWorldContainer, WorldContainer}, error::ScriptError, AddContextInitializer}; +use bevy_mod_scripting_lua::LuaScriptingPlugin; use libtest_mimic::{Arguments, Failed, Trial}; use mlua::{Function, Lua, MultiValue}; use script_integration_test_harness::execute_integration_test; @@ -27,8 +27,8 @@ impl Test { let globals = ctxt.globals(); globals.set( "assert_throws", - ctxt.create_function(|lua, (f, reg): (Function, String)| { - let world = lua.get_world(); + ctxt.create_function(|_lua, (f, reg): (Function, String)| { + let world = ThreadWorldContainer.get_world(); let result = f.call::<()>(MultiValue::new()); let err = match result { Ok(_) => { diff --git a/crates/languages/bevy_mod_scripting_rhai/src/bindings/mod.rs b/crates/languages/bevy_mod_scripting_rhai/src/bindings/mod.rs index 881bf5524d..7f3ef78fa8 100644 --- a/crates/languages/bevy_mod_scripting_rhai/src/bindings/mod.rs +++ b/crates/languages/bevy_mod_scripting_rhai/src/bindings/mod.rs @@ -1 +1,2 @@ +pub mod reference; pub mod script_value; diff --git a/crates/languages/bevy_mod_scripting_rhai/src/bindings/reference.rs b/crates/languages/bevy_mod_scripting_rhai/src/bindings/reference.rs new file mode 100644 index 0000000000..c790a14ed1 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_rhai/src/bindings/reference.rs @@ -0,0 +1,49 @@ +use std::ops::{Deref, DerefMut}; + +use bevy_mod_scripting_core::bindings::{ReflectReference, ThreadWorldContainer, WorldContainer}; +use rhai::{CustomType, Dynamic}; + +#[derive(Clone, Debug, PartialEq)] +pub struct RhaiReflectReference(pub ReflectReference); + +impl AsRef for RhaiReflectReference { + fn as_ref(&self) -> &ReflectReference { + &self.0 + } +} + +impl From for RhaiReflectReference { + fn from(value: ReflectReference) -> Self { + RhaiReflectReference(value) + } +} + +impl From for ReflectReference { + fn from(value: RhaiReflectReference) -> Self { + value.0 + } +} + +impl Deref for RhaiReflectReference { + type Target = ReflectReference; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for RhaiReflectReference { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl CustomType for RhaiReflectReference { + fn build(mut builder: rhai::TypeBuilder) { + builder + .with_name(std::any::type_name::()) + .with_indexer_get(|_obj: &mut Self, _index: Dynamic| { + let _world = ThreadWorldContainer.get_world(); + }); + } +} diff --git a/crates/languages/bevy_mod_scripting_rhai/src/lib.rs b/crates/languages/bevy_mod_scripting_rhai/src/lib.rs index 7a16b8606b..e7acadef85 100644 --- a/crates/languages/bevy_mod_scripting_rhai/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_rhai/src/lib.rs @@ -4,7 +4,9 @@ use bevy::{ }; use bevy_mod_scripting_core::{ asset::{AssetPathToLanguageMapper, Language}, - bindings::{script_value::ScriptValue, WorldCallbackAccess}, + bindings::{ + script_value::ScriptValue, ThreadWorldContainer, WorldCallbackAccess, WorldContainer, + }, context::{ContextBuilder, ContextInitializer, ContextPreHandlingInitializer}, error::ScriptError, event::CallbackLabel, @@ -53,7 +55,11 @@ impl Default for RhaiScriptingPlugin { map: rhai_language_mapper, }), context_initializers: Default::default(), - context_pre_handling_initializers: Default::default(), + context_pre_handling_initializers: vec![|_script, _entity, context| { + let world = ThreadWorldContainer.get_world(); + context.scope.push("world", world); + Ok(()) + }], }, } } @@ -169,7 +175,7 @@ pub fn with_world Result f: F, ) -> Result { WorldCallbackAccess::with_callback_access(world, |guard| { - context.scope.push("world", guard.clone()); + ThreadWorldContainer.set_world(guard.clone())?; f(context) }) } From d7514815975062b80baad2cea7224aef146617c2 Mon Sep 17 00:00:00 2001 From: makspll Date: Sat, 11 Jan 2025 13:49:58 +0000 Subject: [PATCH 09/21] move namespace stuff into core --- crates/bevy_api_gen/templates/header.tera | 2 +- .../src/bindings/function/mod.rs | 1 + .../src/bindings/function/namespace.rs} | 8 +- .../src/bindings/function/script_function.rs | 70 +++++++++--- .../src/bevy_bindings/bevy_reflect.rs | 2 +- .../bevy_mod_scripting_functions/src/core.rs | 2 +- .../bevy_mod_scripting_functions/src/lib.rs | 3 - .../src/test_functions.rs | 2 +- .../src/bindings/reference.rs | 34 +++++- .../src/bindings/script_value.rs | 101 +++++++++++++++++- 10 files changed, 194 insertions(+), 31 deletions(-) rename crates/{bevy_mod_scripting_functions/src/namespaced_register.rs => bevy_mod_scripting_core/src/bindings/function/namespace.rs} (98%) diff --git a/crates/bevy_api_gen/templates/header.tera b/crates/bevy_api_gen/templates/header.tera index cdab05cad8..435722a94a 100644 --- a/crates/bevy_api_gen/templates/header.tera +++ b/crates/bevy_api_gen/templates/header.tera @@ -14,7 +14,7 @@ use bevy_mod_scripting_core::{ StoreDocumentation, bindings::{ ReflectReference, - function::from::{Ref, Mut, Val} + function::{from::{Ref, Mut, Val}, namespace::{NamespaceBuilder}} } }; {% if args.self_is_bms_lua %} diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/mod.rs b/crates/bevy_mod_scripting_core/src/bindings/function/mod.rs index 449b632b46..dd2529cc05 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/mod.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/mod.rs @@ -2,6 +2,7 @@ pub mod from; pub mod from_ref; pub mod into; pub mod into_ref; +pub mod namespace; pub mod script_function; use script_function::{CallerContext, DynamicScriptFunction, DynamicScriptFunctionMut}; diff --git a/crates/bevy_mod_scripting_functions/src/namespaced_register.rs b/crates/bevy_mod_scripting_core/src/bindings/function/namespace.rs similarity index 98% rename from crates/bevy_mod_scripting_functions/src/namespaced_register.rs rename to crates/bevy_mod_scripting_core/src/bindings/function/namespace.rs index 6a8ee66997..8def2c700a 100644 --- a/crates/bevy_mod_scripting_functions/src/namespaced_register.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/namespace.rs @@ -1,11 +1,11 @@ +use crate::bindings::function::script_function::{ + AppScriptFunctionRegistry, DynamicScriptFunction, GetFunctionTypeDependencies, ScriptFunction, + ScriptFunctionRegistry, +}; use bevy::{ prelude::{AppTypeRegistry, World}, reflect::GetTypeRegistration, }; -use bevy_mod_scripting_core::bindings::function::script_function::{ - AppScriptFunctionRegistry, DynamicScriptFunction, GetFunctionTypeDependencies, ScriptFunction, - ScriptFunctionRegistry, -}; use std::{any::TypeId, borrow::Cow, marker::PhantomData}; pub trait RegisterNamespacedFunction { diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs b/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs index 0692d7b9ce..17217b2047 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs @@ -123,11 +123,29 @@ pub struct CallerContext { pub self_type: Option, } +#[derive(Clone, Debug, PartialEq, Default)] +pub struct FunctionInfo { + pub name: Cow<'static, str>, + pub on_type: Option, +} + +impl FunctionInfo { + /// The name of the function + pub fn name(&self) -> &Cow<'static, str> { + &self.name + } + + /// If the function is namespaced to a specific type, this will return the type id of that type + pub fn on_type(&self) -> Option { + self.on_type + } +} + /// The Script Function equivalent for dynamic functions. Currently unused #[derive(Clone, Reflect)] #[reflect(opaque)] pub struct DynamicScriptFunction { - name: Cow<'static, str>, + pub info: FunctionInfo, // TODO: info about the function, this is hard right now because of non 'static lifetimes in wrappers, we can't use TypePath etc func: Arc< dyn Fn(CallerContext, WorldCallbackAccess, Vec) -> ScriptValue @@ -139,14 +157,14 @@ pub struct DynamicScriptFunction { impl PartialEq for DynamicScriptFunction { fn eq(&self, other: &Self) -> bool { - self.name == other.name + self.info == other.info } } #[derive(Clone, Reflect)] #[reflect(opaque)] pub struct DynamicScriptFunctionMut { - name: Cow<'static, str>, + pub info: FunctionInfo, func: Arc< RwLock< // I'd rather consume an option or something instead of having the RWLock but I just wanna get this release out @@ -160,7 +178,7 @@ pub struct DynamicScriptFunctionMut { impl PartialEq for DynamicScriptFunctionMut { fn eq(&self, other: &Self) -> bool { - self.name == other.name + self.info == other.info } } @@ -175,12 +193,25 @@ impl DynamicScriptFunction { } pub fn name(&self) -> &Cow<'static, str> { - &self.name + &self.info.name } pub fn with_name>>(self, name: N) -> Self { Self { - name: name.into(), + info: FunctionInfo { + name: name.into(), + ..self.info + }, + func: self.func, + } + } + + pub fn with_on_type(self, on_type: Option) -> Self { + Self { + info: FunctionInfo { + on_type, + ..self.info + }, func: self.func, } } @@ -188,7 +219,7 @@ impl DynamicScriptFunction { impl DynamicScriptFunctionMut { pub fn call( - &mut self, + &self, context: CallerContext, world: WorldCallbackAccess, args: Vec, @@ -198,12 +229,25 @@ impl DynamicScriptFunctionMut { } pub fn name(&self) -> &Cow<'static, str> { - &self.name + &self.info.name } pub fn with_name>>(self, name: N) -> Self { Self { - name: name.into(), + info: FunctionInfo { + name: name.into(), + ..self.info + }, + func: self.func, + } + } + + pub fn with_on_type(self, on_type: Option) -> Self { + Self { + info: FunctionInfo { + on_type, + ..self.info + }, func: self.func, } } @@ -234,9 +278,10 @@ where { fn from(fn_: F) -> Self { DynamicScriptFunction { - name: std::any::type_name::().into(), + info: FunctionInfo::default(), func: Arc::new(fn_), } + .with_name(std::any::type_name::()) } } @@ -249,9 +294,10 @@ where { fn from(fn_: F) -> Self { DynamicScriptFunctionMut { - name: std::any::type_name::().into(), + info: FunctionInfo::default(), func: Arc::new(RwLock::new(fn_)), } + .with_name(std::any::type_name::()) } } @@ -301,7 +347,7 @@ impl ScriptFunctionRegistry { self.register_overload(name, func); } - pub fn register_overload(&mut self, name: impl Into>, func: F) + fn register_overload(&mut self, name: impl Into>, func: F) where F: ScriptFunction<'static, M>, { 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 2104e1c9a1..db22129bd5 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 @@ -4,7 +4,7 @@ #![cfg_attr(rustfmt, rustfmt_skip)] use bevy_mod_scripting_core::{ AddContextInitializer, StoreDocumentation, - bindings::{ReflectReference, function::from::{Ref, Mut, Val}}, + bindings::{ReflectReference, function::{namespace::NamespaceBuilder,from::{Ref, Mut, Val}}}, }; use crate::*; pub struct BevyReflectScriptingPlugin; diff --git a/crates/bevy_mod_scripting_functions/src/core.rs b/crates/bevy_mod_scripting_functions/src/core.rs index 15b160cb7d..749d3a58a3 100644 --- a/crates/bevy_mod_scripting_functions/src/core.rs +++ b/crates/bevy_mod_scripting_functions/src/core.rs @@ -1,6 +1,5 @@ //! Contains functions defined by the [`bevy_mod_scripting_core`] crate -use crate::NamespaceBuilder; use bevy::{ prelude::*, reflect::{func::FunctionRegistrationError, ParsedPath}, @@ -12,6 +11,7 @@ use bindings::{ from::{Ref, Val}, from_ref::FromScriptRef, into_ref::IntoScriptRef, + namespace::NamespaceBuilder, script_function::{CallerContext, ScriptFunctionMut}, }, pretty_print::DisplayWithWorld, diff --git a/crates/bevy_mod_scripting_functions/src/lib.rs b/crates/bevy_mod_scripting_functions/src/lib.rs index 9339559249..387f4314ed 100644 --- a/crates/bevy_mod_scripting_functions/src/lib.rs +++ b/crates/bevy_mod_scripting_functions/src/lib.rs @@ -7,10 +7,7 @@ pub mod core; #[cfg(feature = "test_functions")] pub mod test_functions; -pub mod namespaced_register; - pub use core::*; -pub use namespaced_register::*; pub struct ScriptFunctionsPlugin; diff --git a/crates/bevy_mod_scripting_functions/src/test_functions.rs b/crates/bevy_mod_scripting_functions/src/test_functions.rs index 43f54fc136..b1a11786c1 100644 --- a/crates/bevy_mod_scripting_functions/src/test_functions.rs +++ b/crates/bevy_mod_scripting_functions/src/test_functions.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use crate::NamespaceBuilder; use bevy::{ app::App, prelude::{Entity, World}, @@ -9,6 +8,7 @@ use bevy::{ use bevy_mod_scripting_core::{ bindings::{ function::{ + namespace::NamespaceBuilder, script_function::{CallerContext, DynamicScriptFunctionMut}, CallScriptFunction, }, diff --git a/crates/languages/bevy_mod_scripting_rhai/src/bindings/reference.rs b/crates/languages/bevy_mod_scripting_rhai/src/bindings/reference.rs index c790a14ed1..2ce21a6e6f 100644 --- a/crates/languages/bevy_mod_scripting_rhai/src/bindings/reference.rs +++ b/crates/languages/bevy_mod_scripting_rhai/src/bindings/reference.rs @@ -1,7 +1,15 @@ -use std::ops::{Deref, DerefMut}; - -use bevy_mod_scripting_core::bindings::{ReflectReference, ThreadWorldContainer, WorldContainer}; -use rhai::{CustomType, Dynamic}; +use super::script_value::FromDynamic; +use bevy_mod_scripting_core::bindings::{ + function::script_function::{AppScriptFunctionRegistry, DynamicScriptFunction}, + script_value::ScriptValue, + ReflectReference, ThreadWorldContainer, WorldContainer, WorldGuard, +}; +use bevy_mod_scripting_functions::{GetNamespacedFunction, Namespace}; +use rhai::{CustomType, Dynamic, EvalAltResult}; +use std::{ + any::TypeId, + ops::{Deref, DerefMut}, +}; #[derive(Clone, Debug, PartialEq)] pub struct RhaiReflectReference(pub ReflectReference); @@ -38,12 +46,30 @@ impl DerefMut for RhaiReflectReference { } } +fn lookup_dynamic_function( + world: WorldGuard, + name: &str, + on: TypeId, +) -> Option { + let registry = world.with_resource(|registry: &AppScriptFunctionRegistry| registry.clone()); + let registry = registry.read(); + + registry + .get_namespaced_function(name.to_string(), Namespace::OnType(on)) + .cloned() +} + impl CustomType for RhaiReflectReference { fn build(mut builder: rhai::TypeBuilder) { builder .with_name(std::any::type_name::()) .with_indexer_get(|_obj: &mut Self, _index: Dynamic| { let _world = ThreadWorldContainer.get_world(); + let key: ScriptValue = ScriptValue::from_dynamic(_index)?; + if let ScriptValue::String(key) = key { + // lookup function + } + Ok::<_, Box>(()) }); } } diff --git a/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs b/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs index d272c62087..26df6bfd05 100644 --- a/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs +++ b/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs @@ -1,7 +1,100 @@ -use std::str::FromStr; +use std::{any::TypeId, str::FromStr, sync::Arc}; -use bevy_mod_scripting_core::{bindings::script_value::ScriptValue, error::InteropError}; -use rhai::{Dynamic, EvalAltResult}; +use bevy_mod_scripting_core::{ + bindings::{ + function::script_function::{ + CallerContext, DynamicScriptFunction, DynamicScriptFunctionMut, + }, + script_value::ScriptValue, + ThreadWorldContainer, WorldCallbackAccess, WorldContainer, + }, + error::InteropError, +}; +use rhai::{ + plugin::{PluginFunc, RhaiFunc}, + Dynamic, EvalAltResult, +}; + +fn rhai_caller_context(self_type: Option) -> CallerContext { + CallerContext { + convert_to_0_indexed: false, + self_type, + } +} + +struct FuncWrapper(DynamicScriptFunction); +struct FuncMutWrapper(DynamicScriptFunctionMut); + +impl PluginFunc for FuncWrapper { + fn call( + &self, + _context: Option, + _args: &mut [&mut Dynamic], + ) -> rhai::plugin::RhaiResult { + let convert_args = _args + .iter_mut() + .map(|arg| ScriptValue::from_dynamic(arg.clone())) + .collect::, _>>()?; + + let out = self.0.call( + rhai_caller_context(self.0.info.on_type()), + WorldCallbackAccess::from_guard(ThreadWorldContainer.get_world()), + convert_args, + ); + + out.into_dynamic() + } + + fn is_method_call(&self) -> bool { + // TODO: is this correct? do we care if it's a method call? + false + } + + fn has_context(&self) -> bool { + false + } +} + +impl PluginFunc for FuncMutWrapper { + fn call( + &self, + _context: Option, + _args: &mut [&mut Dynamic], + ) -> rhai::plugin::RhaiResult { + let convert_args = _args + .iter_mut() + .map(|arg| ScriptValue::from_dynamic(arg.clone())) + .collect::, _>>()?; + + let out = self.0.call( + rhai_caller_context(self.0.info.on_type()), + WorldCallbackAccess::from_guard(ThreadWorldContainer.get_world()), + convert_args, + ); + + out.into_dynamic() + } + + fn is_method_call(&self) -> bool { + false + } + + fn has_context(&self) -> bool { + false + } +} + +pub(crate) fn to_rhai_fn(func: DynamicScriptFunction) -> RhaiFunc { + RhaiFunc::Plugin { + func: Arc::new(FuncWrapper(func)), + } +} + +pub(crate) fn to_rhai_fn_mut(func: DynamicScriptFunctionMut) -> RhaiFunc { + RhaiFunc::Plugin { + func: Arc::new(FuncMutWrapper(func)), + } +} pub trait IntoDynamic { fn into_dynamic(self) -> Result>; @@ -27,7 +120,7 @@ impl IntoDynamic for ScriptValue { })?, ScriptValue::List(_vec) => todo!(), ScriptValue::Reference(_reflect_reference) => todo!(), - ScriptValue::Function(_dynamic_script_function_mut) => todo!(), + ScriptValue::Function(func) => Dynamic::from(to_rhai_fn_mut(func)), ScriptValue::Error(_interop_error) => todo!(), }) } From 2b2a4514089b51eb906a36eed1adcf750fa4a3c7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 11 Jan 2025 13:54:02 +0000 Subject: [PATCH 10/21] chore(codegen): update bevy bindings (#195) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../src/bevy_bindings/bevy_core.rs | 8 +- .../src/bevy_bindings/bevy_ecs.rs | 156 +- .../src/bevy_bindings/bevy_hierarchy.rs | 28 +- .../src/bevy_bindings/bevy_input.rs | 492 +- .../src/bevy_bindings/bevy_math.rs | 1004 ++-- .../src/bevy_bindings/bevy_reflect.rs | 5064 +++++++++-------- .../src/bevy_bindings/bevy_time.rs | 74 +- .../src/bevy_bindings/bevy_transform.rs | 98 +- 8 files changed, 3486 insertions(+), 3438 deletions(-) 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 e66a541e86..40d8b76363 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 @@ -6,7 +6,13 @@ use super::bevy_ecs::*; use super::bevy_reflect::*; use bevy_mod_scripting_core::{ AddContextInitializer, StoreDocumentation, - bindings::{ReflectReference, function::from::{Ref, Mut, Val}}, + bindings::{ + ReflectReference, + function::{ + from::{Ref, Mut, Val}, + namespace::NamespaceBuilder, + }, + }, }; use crate::*; pub struct BevyCoreScriptingPlugin; 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 6dfeb8d0a1..6187685017 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 @@ -5,7 +5,13 @@ use super::bevy_reflect::*; use bevy_mod_scripting_core::{ AddContextInitializer, StoreDocumentation, - bindings::{ReflectReference, function::from::{Ref, Mut, Val}}, + bindings::{ + ReflectReference, + function::{ + from::{Ref, Mut, Val}, + namespace::NamespaceBuilder, + }, + }, }; use crate::*; pub struct BevyEcsScriptingPlugin; @@ -13,29 +19,6 @@ impl ::bevy::app::Plugin for BevyEcsScriptingPlugin { fn build(&self, app: &mut ::bevy::prelude::App) { let mut world = app.world_mut(); NamespaceBuilder::<::bevy::ecs::entity::Entity>::new(world) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) - .register( - "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, - ) .register( "from_raw", |index: u32| { @@ -85,12 +68,45 @@ impl ::bevy::app::Plugin for BevyEcsScriptingPlugin { .into(); output }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, ); NamespaceBuilder::<::bevy::ecs::world::OnAdd>::new(world); NamespaceBuilder::<::bevy::ecs::world::OnInsert>::new(world); NamespaceBuilder::<::bevy::ecs::world::OnRemove>::new(world); NamespaceBuilder::<::bevy::ecs::world::OnReplace>::new(world); NamespaceBuilder::<::bevy::ecs::component::ComponentId>::new(world) + .register( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .into(); + output + }, + ) .register( "eq", | @@ -114,16 +130,6 @@ impl ::bevy::app::Plugin for BevyEcsScriptingPlugin { output }, ) - .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( - &_self, - ) - .into(); - output - }, - ) .register( "new", |index: usize| { @@ -145,6 +151,29 @@ impl ::bevy::app::Plugin for BevyEcsScriptingPlugin { }, ); NamespaceBuilder::<::bevy::ecs::component::Tick>::new(world) + .register( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .into(); + output + }, + ) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) .register( "new", |tick: u32| { @@ -188,39 +217,26 @@ impl ::bevy::app::Plugin for BevyEcsScriptingPlugin { }, ) .register( - "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, - ) - .register( - "assert_receiver_is_total_eq", + "clone", |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( + let output: Val = ::clone( &_self, ) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::ecs::component::ComponentTicks>::new(world) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, - ); - NamespaceBuilder::<::bevy::ecs::component::ComponentTicks>::new(world) + ) .register( "is_added", | @@ -276,18 +292,21 @@ impl ::bevy::app::Plugin for BevyEcsScriptingPlugin { .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::ecs::identifier::Identifier>::new(world) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) .into(); output }, - ); - NamespaceBuilder::<::bevy::ecs::identifier::Identifier>::new(world) + ) .register( "clone", |_self: Ref| { @@ -337,19 +356,6 @@ impl ::bevy::app::Plugin for BevyEcsScriptingPlugin { .into(); output }, - ) - .register( - "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, ); NamespaceBuilder::<::bevy::ecs::entity::EntityHash>::new(world) .register( 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 efb3bc53a7..a47dda82c9 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 @@ -7,7 +7,13 @@ use super::bevy_reflect::*; use super::bevy_core::*; use bevy_mod_scripting_core::{ AddContextInitializer, StoreDocumentation, - bindings::{ReflectReference, function::from::{Ref, Mut, Val}}, + bindings::{ + ReflectReference, + function::{ + from::{Ref, Mut, Val}, + namespace::NamespaceBuilder, + }, + }, }; use crate::*; pub struct BevyHierarchyScriptingPlugin; @@ -32,16 +38,6 @@ impl ::bevy::app::Plugin for BevyHierarchyScriptingPlugin { }, ); NamespaceBuilder::<::bevy::hierarchy::prelude::Parent>::new(world) - .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( - &_self, - ) - .into(); - output - }, - ) .register( "eq", | @@ -54,6 +50,16 @@ impl ::bevy::app::Plugin for BevyHierarchyScriptingPlugin { .into(); output }, + ) + .register( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .into(); + output + }, ); NamespaceBuilder::<::bevy::hierarchy::HierarchyEvent>::new(world) .register( 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 85c1f1ba6b..f26675ec8f 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 @@ -8,7 +8,13 @@ use super::bevy_core::*; use super::bevy_math::*; use bevy_mod_scripting_core::{ AddContextInitializer, StoreDocumentation, - bindings::{ReflectReference, function::from::{Ref, Mut, Val}}, + bindings::{ + ReflectReference, + function::{ + from::{Ref, Mut, Val}, + namespace::NamespaceBuilder, + }, + }, }; use crate::*; pub struct BevyInputScriptingPlugin; @@ -79,6 +85,16 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { }, ); NamespaceBuilder::<::bevy::input::gamepad::GamepadAxis>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "assert_receiver_is_total_eq", |_self: Ref| { @@ -101,16 +117,6 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .into(); output }, - ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, ); NamespaceBuilder::<::bevy::input::gamepad::GamepadButton>::new(world) .register( @@ -158,16 +164,6 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { }, ); NamespaceBuilder::<::bevy::input::keyboard::KeyCode>::new(world) - .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( - &_self, - ) - .into(); - output - }, - ) .register( "eq", | @@ -190,12 +186,22 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .into(); output }, + ) + .register( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .into(); + output + }, ); NamespaceBuilder::<::bevy::input::mouse::MouseButton>::new(world) .register( - "assert_receiver_is_total_eq", + "clone", |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( + let output: Val = ::clone( &_self, ) .into(); @@ -203,9 +209,9 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { }, ) .register( - "clone", + "assert_receiver_is_total_eq", |_self: Ref| { - let output: Val = ::clone( + let output: () = ::assert_receiver_is_total_eq( &_self, ) .into(); @@ -260,16 +266,6 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { output }, ) - .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( - &_self, - ) - .into(); - output - }, - ) .register( "eq", | @@ -282,18 +278,18 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .into(); output }, - ); - NamespaceBuilder::<::bevy::input::keyboard::KeyboardInput>::new(world) + ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( &_self, ) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::input::keyboard::KeyboardInput>::new(world) .register( "eq", | @@ -316,18 +312,18 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .into(); output }, - ); - NamespaceBuilder::<::bevy::input::mouse::AccumulatedMouseMotion>::new(world) + ) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::input::mouse::AccumulatedMouseMotion>::new(world) .register( "eq", | @@ -340,18 +336,18 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .into(); output }, - ); - NamespaceBuilder::<::bevy::input::mouse::AccumulatedMouseScroll>::new(world) + ) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::input::mouse::AccumulatedMouseScroll>::new(world) .register( "eq", | @@ -364,12 +360,22 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .into(); output }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, ); NamespaceBuilder::<::bevy::input::mouse::MouseButtonInput>::new(world) .register( - "assert_receiver_is_total_eq", + "clone", |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( + let output: Val = ::clone( &_self, ) .into(); @@ -377,9 +383,9 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { }, ) .register( - "clone", + "assert_receiver_is_total_eq", |_self: Ref| { - let output: Val = ::clone( + let output: () = ::assert_receiver_is_total_eq( &_self, ) .into(); @@ -424,6 +430,16 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { }, ); NamespaceBuilder::<::bevy::input::mouse::MouseWheel>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "eq", | @@ -436,28 +452,8 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .into(); output }, - ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, ); NamespaceBuilder::<::bevy::input::gamepad::GamepadAxisChangedEvent>::new(world) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) .register( "eq", | @@ -470,18 +466,18 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .into(); output }, - ); - NamespaceBuilder::<::bevy::input::gamepad::GamepadButtonChangedEvent>::new(world) + ) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::input::gamepad::GamepadButtonChangedEvent>::new(world) .register( "eq", | @@ -494,10 +490,32 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .into(); output }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, ); NamespaceBuilder::< ::bevy::input::gamepad::GamepadButtonStateChangedEvent, >::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val< + bevy::input::gamepad::GamepadButtonStateChangedEvent, + > = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "eq", | @@ -520,18 +538,6 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .into(); output }, - ) - .register( - "clone", - |_self: Ref| { - let output: Val< - bevy::input::gamepad::GamepadButtonStateChangedEvent, - > = ::clone( - &_self, - ) - .into(); - output - }, ); NamespaceBuilder::<::bevy::input::gamepad::GamepadConnection>::new(world) .register( @@ -559,19 +565,9 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { ); NamespaceBuilder::<::bevy::input::gamepad::GamepadConnectionEvent>::new(world) .register( - "connected", - |_self: Ref| { - let output: bool = bevy::input::gamepad::GamepadConnectionEvent::connected( - &_self, - ) - .into(); - output - }, - ) - .register( - "disconnected", + "clone", |_self: Ref| { - let output: bool = bevy::input::gamepad::GamepadConnectionEvent::disconnected( + let output: Val = ::clone( &_self, ) .into(); @@ -592,26 +588,26 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { }, ) .register( - "clone", + "connected", |_self: Ref| { - let output: Val = ::clone( + let output: bool = bevy::input::gamepad::GamepadConnectionEvent::connected( &_self, ) .into(); output }, - ); - NamespaceBuilder::<::bevy::input::gamepad::GamepadEvent>::new(world) + ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( + "disconnected", + |_self: Ref| { + let output: bool = bevy::input::gamepad::GamepadConnectionEvent::disconnected( &_self, ) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::input::gamepad::GamepadEvent>::new(world) .register( "eq", | @@ -624,18 +620,18 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .into(); output }, - ); - NamespaceBuilder::<::bevy::input::gamepad::GamepadInput>::new(world) + ) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::input::gamepad::GamepadInput>::new(world) .register( "eq", | @@ -649,6 +645,16 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { output }, ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "assert_receiver_is_total_eq", |_self: Ref| { @@ -699,18 +705,6 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { NamespaceBuilder::< ::bevy::input::gamepad::RawGamepadButtonChangedEvent, >::new(world) - .register( - "clone", - |_self: Ref| { - let output: Val< - bevy::input::gamepad::RawGamepadButtonChangedEvent, - > = ::clone( - &_self, - ) - .into(); - output - }, - ) .register( "eq", | @@ -723,6 +717,18 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .into(); output }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val< + bevy::input::gamepad::RawGamepadButtonChangedEvent, + > = ::clone( + &_self, + ) + .into(); + output + }, ); NamespaceBuilder::<::bevy::input::gamepad::RawGamepadEvent>::new(world) .register( @@ -773,16 +779,6 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { }, ); NamespaceBuilder::<::bevy::input::gestures::RotationGesture>::new(world) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) .register( "eq", | @@ -795,36 +791,22 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .into(); output }, - ); - NamespaceBuilder::<::bevy::input::gestures::DoubleTapGesture>::new(world) - .register( - "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, ) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, ); - NamespaceBuilder::<::bevy::input::gestures::PanGesture>::new(world) + NamespaceBuilder::<::bevy::input::gestures::DoubleTapGesture>::new(world) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); @@ -834,37 +816,41 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .register( "eq", | - _self: Ref, - other: Ref| + _self: Ref, + other: Ref| { - let output: bool = >::eq(&_self, &other) .into(); output }, ); - NamespaceBuilder::<::bevy::input::ButtonState>::new(world) + NamespaceBuilder::<::bevy::input::gestures::PanGesture>::new(world) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) .into(); output }, ) .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( + "clone", + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::input::ButtonState>::new(world) .register( "eq", | @@ -878,6 +864,16 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { output }, ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "is_pressed", |_self: Ref| { @@ -885,8 +881,28 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .into(); output }, + ) + .register( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .into(); + output + }, ); NamespaceBuilder::<::bevy::input::gamepad::ButtonSettings>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "is_pressed", |_self: Ref, value: f32| { @@ -951,16 +967,6 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { output }, ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) .register( "eq", | @@ -1107,16 +1113,6 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { output }, ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) .register( "eq", | @@ -1129,6 +1125,16 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .into(); output }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, ); NamespaceBuilder::<::bevy::input::gamepad::ButtonAxisSettings>::new(world) .register( @@ -1168,19 +1174,6 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { output }, ) - .register( - "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, - ) .register( "weak_motor", |intensity: f32| { @@ -1200,18 +1193,21 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .into(); output }, - ); - NamespaceBuilder::<::bevy::input::keyboard::Key>::new(world) + ) .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( - &_self, - ) + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::input::keyboard::Key>::new(world) .register( "clone", |_self: Ref| { @@ -1234,17 +1230,30 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .into(); output }, - ); - NamespaceBuilder::<::bevy::input::keyboard::NativeKeyCode>::new(world) + ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( &_self, ) .into(); output }, + ); + NamespaceBuilder::<::bevy::input::keyboard::NativeKeyCode>::new(world) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, ) .register( "assert_receiver_is_total_eq", @@ -1257,14 +1266,11 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { }, ) .register( - "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = >::eq(&_self, &other) + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, @@ -1305,9 +1311,9 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { ); NamespaceBuilder::<::bevy::input::mouse::MouseScrollUnit>::new(world) .register( - "assert_receiver_is_total_eq", + "clone", |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( + let output: Val = ::clone( &_self, ) .into(); @@ -1315,9 +1321,9 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { }, ) .register( - "clone", + "assert_receiver_is_total_eq", |_self: Ref| { - let output: Val = ::clone( + let output: () = ::assert_receiver_is_total_eq( &_self, ) .into(); @@ -1338,6 +1344,19 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { }, ); NamespaceBuilder::<::bevy::input::touch::TouchPhase>::new(world) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) .register( "clone", |_self: Ref| { @@ -1357,19 +1376,6 @@ impl ::bevy::app::Plugin for BevyInputScriptingPlugin { .into(); output }, - ) - .register( - "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, ); NamespaceBuilder::<::bevy::input::touch::ForceTouch>::new(world) .register( 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 2d1c322ff1..6558273b9a 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 @@ -5,7 +5,13 @@ use super::bevy_reflect::*; use bevy_mod_scripting_core::{ AddContextInitializer, StoreDocumentation, - bindings::{ReflectReference, function::from::{Ref, Mut, Val}}, + bindings::{ + ReflectReference, + function::{ + from::{Ref, Mut, Val}, + namespace::NamespaceBuilder, + }, + }, }; use crate::*; pub struct BevyMathScriptingPlugin; @@ -13,16 +19,6 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { fn build(&self, app: &mut ::bevy::prelude::App) { let mut world = app.world_mut(); NamespaceBuilder::<::bevy::math::AspectRatio>::new(world) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) .register( "eq", | @@ -36,6 +32,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "ratio", |_self: Ref| { @@ -78,9 +84,9 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { ); NamespaceBuilder::<::bevy::math::CompassOctant>::new(world) .register( - "clone", + "assert_receiver_is_total_eq", |_self: Ref| { - let output: Val = ::clone( + let output: () = ::assert_receiver_is_total_eq( &_self, ) .into(); @@ -101,9 +107,9 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ) .register( - "assert_receiver_is_total_eq", + "clone", |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( + let output: Val = ::clone( &_self, ) .into(); @@ -111,6 +117,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ); NamespaceBuilder::<::bevy::math::CompassQuadrant>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "eq", | @@ -133,16 +149,6 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, - ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, ); NamespaceBuilder::<::bevy::math::Isometry2d>::new(world) .register( @@ -187,6 +193,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) .register( "clone", |_self: Ref| { @@ -210,16 +226,6 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) - .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) .register( "eq", |_self: Ref, other: Ref| { @@ -231,6 +237,26 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ); NamespaceBuilder::<::bevy::math::Isometry3d>::new(world) + .register( + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "mul", | @@ -244,6 +270,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) .register( "from_xyz", |x: f32, y: f32, z: f32| { @@ -276,38 +312,18 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::Ray2d>::new(world) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, ) - .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, - ); - NamespaceBuilder::<::bevy::math::Ray2d>::new(world) .register( "eq", |_self: Ref, other: Ref| { @@ -317,18 +333,18 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::Ray3d>::new(world) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, - ); - NamespaceBuilder::<::bevy::math::Ray3d>::new(world) + ) .register( "eq", |_self: Ref, other: Ref| { @@ -338,41 +354,8 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, - ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, ); NamespaceBuilder::<::bevy::math::Rot2>::new(world) - .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, - ) - .register( - "mul", - | - _self: Val, - direction: Val| - { - let output: Val = >::mul(_self.into_inner(), direction.into_inner()) - .into(); - output - }, - ) .register( "mul", |_self: Val, rhs: Val| { @@ -598,6 +581,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) + .register( + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) .register( "clone", |_self: Ref| { @@ -607,6 +600,19 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, + ) + .register( + "mul", + | + _self: Val, + direction: Val| + { + let output: Val = >::mul(_self.into_inner(), direction.into_inner()) + .into(); + output + }, ); NamespaceBuilder::<::bevy::math::prelude::Dir2>::new(world) .register( @@ -619,16 +625,6 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) .register( "eq", | @@ -746,28 +742,18 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, - ); - NamespaceBuilder::<::bevy::math::prelude::Dir3>::new(world) + ) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, - ) - .register( - "neg", - |_self: Val| { - let output: Val = ::neg( - _self.into_inner(), - ) - .into(); - output - }, - ) + ); + NamespaceBuilder::<::bevy::math::prelude::Dir3>::new(world) .register( "eq", | @@ -818,35 +804,68 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, - ); - NamespaceBuilder::<::bevy::math::prelude::Dir3A>::new(world) + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "neg", - |_self: Val| { - let output: Val = ::neg( + |_self: Val| { + let output: Val = ::neg( _self.into_inner(), ) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::prelude::Dir3A>::new(world) .register( - "from_xyz_unchecked", - |x: f32, y: f32, z: f32| { - let output: Val = bevy::math::prelude::Dir3A::from_xyz_unchecked( - x, - y, - z, + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, ) .into(); output }, ) .register( - "slerp", + "eq", | - _self: Val, - rhs: Val, + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) + .register( + "from_xyz_unchecked", + |x: f32, y: f32, z: f32| { + let output: Val = bevy::math::prelude::Dir3A::from_xyz_unchecked( + x, + y, + z, + ) + .into(); + output + }, + ) + .register( + "slerp", + | + _self: Val, + rhs: Val, s: f32| { let output: Val = bevy::math::prelude::Dir3A::slerp( @@ -869,52 +888,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), ) .into(); output }, - ) - .register( - "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, ); NamespaceBuilder::<::bevy::math::prelude::IRect>::new(world) - .register( - "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, - ) - .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( - &_self, - ) - .into(); - output - }, - ) .register( "new", |x0: i32, y0: i32, x1: i32, y1: i32| { @@ -1018,6 +1001,29 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, + ) + .register( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .into(); + output + }, + ) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, ); NamespaceBuilder::<::bevy::math::prelude::Rect>::new(world) .register( @@ -1152,6 +1158,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ); NamespaceBuilder::<::bevy::math::prelude::URect>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "new", |x0: u32, y0: u32, x1: u32, y1: u32| { @@ -1246,16 +1262,6 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) - .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( - &_self, - ) - .into(); - output - }, - ) .register( "eq", | @@ -1270,9 +1276,9 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ) .register( - "clone", + "assert_receiver_is_total_eq", |_self: Ref| { - let output: Val = ::clone( + let output: () = ::assert_receiver_is_total_eq( &_self, ) .into(); @@ -1282,9 +1288,9 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { NamespaceBuilder::<::bevy::math::Affine3>::new(world); NamespaceBuilder::<::bevy::math::bounding::Aabb2d>::new(world) .register( - "bounding_circle", + "clone", |_self: Ref| { - let output: Val = bevy::math::bounding::Aabb2d::bounding_circle( + let output: Val = ::clone( &_self, ) .into(); @@ -1292,9 +1298,9 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ) .register( - "clone", + "bounding_circle", |_self: Ref| { - let output: Val = ::clone( + let output: Val = bevy::math::bounding::Aabb2d::bounding_circle( &_self, ) .into(); @@ -1302,16 +1308,6 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ); NamespaceBuilder::<::bevy::math::bounding::BoundingCircle>::new(world) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) .register( "radius", |_self: Ref| { @@ -1331,18 +1327,18 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, - ); - NamespaceBuilder::<::bevy::math::primitives::Circle>::new(world) + ) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::primitives::Circle>::new(world) .register( "eq", | @@ -1373,6 +1369,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, ); NamespaceBuilder::<::bevy::math::primitives::Annulus>::new(world) .register( @@ -1426,6 +1432,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ); NamespaceBuilder::<::bevy::math::primitives::Arc2d>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "new", |radius: f32, half_angle: f32| { @@ -1548,18 +1564,31 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, + ); + NamespaceBuilder::<::bevy::math::primitives::Capsule2d>::new(world) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, ) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, - ); - NamespaceBuilder::<::bevy::math::primitives::Capsule2d>::new(world) + ) .register( "new", |radius: f32, length: f32| { @@ -1580,31 +1609,21 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::primitives::CircularSector>::new(world) .register( "eq", | - _self: Ref, - other: Ref| + _self: Ref, + other: Ref| { - let output: bool = >::eq(&_self, &other) .into(); output }, ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ); - NamespaceBuilder::<::bevy::math::primitives::CircularSector>::new(world) .register( "clone", |_self: Ref| { @@ -1615,19 +1634,6 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) - .register( - "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, - ) .register( "new", |radius: f32, angle: f32| { @@ -1754,11 +1760,14 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { ); NamespaceBuilder::<::bevy::math::primitives::CircularSegment>::new(world) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) .into(); output }, @@ -1887,43 +1896,17 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) - .register( - "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, - ); - NamespaceBuilder::<::bevy::math::primitives::Ellipse>::new(world) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, - ) - .register( - "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, - ) + ); + NamespaceBuilder::<::bevy::math::primitives::Ellipse>::new(world) .register( "new", |half_width: f32, half_height: f32| { @@ -1970,6 +1953,29 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, ); NamespaceBuilder::<::bevy::math::primitives::Line2d>::new(world) .register( @@ -1996,6 +2002,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ); NamespaceBuilder::<::bevy::math::primitives::Plane2d>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "eq", | @@ -2008,30 +2024,17 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::primitives::Rectangle>::new(world) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, - ); - NamespaceBuilder::<::bevy::math::primitives::Rectangle>::new(world) - .register( - "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, ) .register( "new", @@ -2054,30 +2057,20 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ); - NamespaceBuilder::<::bevy::math::primitives::RegularPolygon>::new(world) .register( "eq", | - _self: Ref, - other: Ref| + _self: Ref, + other: Ref| { - let output: bool = >::eq(&_self, &other) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::primitives::RegularPolygon>::new(world) .register( "new", |circumradius: f32, sides: u32| { @@ -2159,6 +2152,19 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) .register( "clone", |_self: Ref| { @@ -2170,6 +2176,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ); NamespaceBuilder::<::bevy::math::primitives::Rhombus>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "eq", | @@ -2183,16 +2199,6 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) .register( "new", |horizontal_diagonal: f32, vertical_diagonal: f32| { @@ -2264,16 +2270,6 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) .register( "new", |direction: Val, length: f32| { @@ -2284,21 +2280,18 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, - ); - NamespaceBuilder::<::bevy::math::primitives::Triangle2d>::new(world) + ) .register( - "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = >::eq(&_self, &other) + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::primitives::Triangle2d>::new(world) .register( "clone", |_self: Ref| { @@ -2358,12 +2351,25 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, + ) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, ); NamespaceBuilder::<::bevy::math::bounding::Aabb3d>::new(world) .register( - "bounding_sphere", + "clone", |_self: Ref| { - let output: Val = bevy::math::bounding::Aabb3d::bounding_sphere( + let output: Val = ::clone( &_self, ) .into(); @@ -2371,9 +2377,9 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ) .register( - "clone", + "bounding_sphere", |_self: Ref| { - let output: Val = ::clone( + let output: Val = bevy::math::bounding::Aabb3d::bounding_sphere( &_self, ) .into(); @@ -2382,9 +2388,9 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { ); NamespaceBuilder::<::bevy::math::bounding::BoundingSphere>::new(world) .register( - "radius", + "clone", |_self: Ref| { - let output: f32 = bevy::math::bounding::BoundingSphere::radius( + let output: Val = ::clone( &_self, ) .into(); @@ -2392,9 +2398,9 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ) .register( - "aabb_3d", + "radius", |_self: Ref| { - let output: Val = bevy::math::bounding::BoundingSphere::aabb_3d( + let output: f32 = bevy::math::bounding::BoundingSphere::radius( &_self, ) .into(); @@ -2402,9 +2408,9 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ) .register( - "clone", + "aabb_3d", |_self: Ref| { - let output: Val = ::clone( + let output: Val = bevy::math::bounding::BoundingSphere::aabb_3d( &_self, ) .into(); @@ -2425,6 +2431,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "new", |radius: f32| { @@ -2442,18 +2458,21 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::primitives::Cuboid>::new(world) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) .into(); output }, - ); - NamespaceBuilder::<::bevy::math::primitives::Cuboid>::new(world) + ) .register( "new", |x_length: f32, y_length: f32, z_length: f32| { @@ -2470,21 +2489,8 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { "from_length", |length: f32| { let output: Val = bevy::math::primitives::Cuboid::from_length( - length, - ) - .into(); - output - }, - ) - .register( - "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = >::eq(&_self, &other) + length, + ) .into(); output }, @@ -2500,6 +2506,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ); NamespaceBuilder::<::bevy::math::primitives::Cylinder>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "new", |radius: f32, height: f32| { @@ -2539,16 +2555,6 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) .register( "eq", | @@ -2564,20 +2570,22 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { ); NamespaceBuilder::<::bevy::math::primitives::Capsule3d>::new(world) .register( - "new", - |radius: f32, length: f32| { - let output: Val = bevy::math::primitives::Capsule3d::new( - radius, - length, - ) + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) .into(); output }, ) .register( - "to_cylinder", + "clone", |_self: Ref| { - let output: Val = bevy::math::primitives::Capsule3d::to_cylinder( + let output: Val = ::clone( &_self, ) .into(); @@ -2585,22 +2593,20 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ) .register( - "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = >::eq(&_self, &other) + "new", + |radius: f32, length: f32| { + let output: Val = bevy::math::primitives::Capsule3d::new( + radius, + length, + ) .into(); output }, ) .register( - "clone", + "to_cylinder", |_self: Ref| { - let output: Val = ::clone( + let output: Val = bevy::math::primitives::Capsule3d::to_cylinder( &_self, ) .into(); @@ -2608,6 +2614,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ); NamespaceBuilder::<::bevy::math::primitives::Cone>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "new", |radius: f32, height: f32| { @@ -2653,16 +2669,6 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) .register( "eq", | @@ -2677,16 +2683,6 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ); NamespaceBuilder::<::bevy::math::primitives::ConicalFrustum>::new(world) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) .register( "eq", | @@ -2699,18 +2695,18 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, - ); - NamespaceBuilder::<::bevy::math::primitives::InfinitePlane3d>::new(world) + ) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::primitives::InfinitePlane3d>::new(world) .register( "eq", | @@ -2723,6 +2719,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, ); NamespaceBuilder::<::bevy::math::primitives::Line3d>::new(world) .register( @@ -2749,6 +2755,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ); NamespaceBuilder::<::bevy::math::primitives::Segment3d>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "new", |direction: Val, length: f32| { @@ -2772,28 +2788,8 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, - ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, ); NamespaceBuilder::<::bevy::math::primitives::Torus>::new(world) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) .register( "new", |inner_radius: f32, outer_radius: f32| { @@ -2821,6 +2817,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "eq", | @@ -2885,6 +2891,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "eq", | @@ -2897,18 +2913,18 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::bounding::RayCast2d>::new(world) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, - ); - NamespaceBuilder::<::bevy::math::bounding::RayCast2d>::new(world) + ) .register( "from_ray", |ray: Val, max: f32| { @@ -2947,28 +2963,8 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, - ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, ); NamespaceBuilder::<::bevy::math::bounding::AabbCast2d>::new(world) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) .register( "from_ray", | @@ -2998,6 +2994,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, ); NamespaceBuilder::<::bevy::math::bounding::BoundingCircleCast>::new(world) .register( @@ -3183,6 +3189,19 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { output }, ) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) .register( "start", |_self: Val| { @@ -3278,21 +3297,18 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::FloatOrd>::new(world) .register( "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = , other: Ref| { + let output: bool = >::eq(&_self, &other) .into(); output }, - ); - NamespaceBuilder::<::bevy::math::FloatOrd>::new(world) + ) .register( "clone", |_self: Ref| { @@ -3352,16 +3368,6 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, - ) - .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, ); NamespaceBuilder::<::bevy::math::primitives::Plane3d>::new(world) .register( @@ -3422,16 +3428,6 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { }, ); NamespaceBuilder::<::bevy::math::curve::easing::EaseFunction>::new(world) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) .register( "eq", | @@ -3444,6 +3440,16 @@ impl ::bevy::app::Plugin for BevyMathScriptingPlugin { .into(); output }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, ); } } 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 db22129bd5..a6b8b9bed4 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 @@ -4,7 +4,13 @@ #![cfg_attr(rustfmt, rustfmt_skip)] use bevy_mod_scripting_core::{ AddContextInitializer, StoreDocumentation, - bindings::{ReflectReference, function::{namespace::NamespaceBuilder,from::{Ref, Mut, Val}}}, + bindings::{ + ReflectReference, + function::{ + from::{Ref, Mut, Val}, + namespace::NamespaceBuilder, + }, + }, }; use crate::*; pub struct BevyReflectScriptingPlugin; @@ -700,61 +706,41 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { ); NamespaceBuilder::<::bevy::math::Quat>::new(world) .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) .into(); output }, ) .register( - "add", + "mul", |_self: Val, rhs: Val| { - let output: Val = >::add(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "eq", - |_self: Ref, rhs: Ref| { - let output: bool = = >::eq(&_self, &rhs) - .into(); - output - }, - ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + >>::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( "mul", - |_self: Val, rhs: Val| { - let output: Val = , rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "mul", - |_self: Val, rhs: f32| { - let output: Val = >::mul(_self.into_inner(), rhs) + "eq", + |_self: Ref, rhs: Ref| { + let output: bool = >::eq(&_self, &rhs) .into(); output }, @@ -769,36 +755,6 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) - .register( - "neg", - |_self: Val| { - let output: Val = ::neg( - _self.into_inner(), - ) - .into(); - output - }, - ) - .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "div", - |_self: Val, rhs: f32| { - let output: Val = >::div(_self.into_inner(), rhs) - .into(); - output - }, - ) .register( "from_xyzw", |x: f32, y: f32, z: f32, w: f32| { @@ -1213,84 +1169,144 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { .into(); output }, + ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: f32| { + let output: Val = >::mul(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: f32| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, ); NamespaceBuilder::<::bevy::math::Vec3>::new(world) .register( - "sub", + "add", + |_self: Val, rhs: Ref| { + let output: Val = >::add(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "div", |_self: Val, rhs: f32| { - let output: Val = = >::sub(_self.into_inner(), rhs) + >>::div(_self.into_inner(), rhs) .into(); output }, ) .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = , other: Ref| { + let output: bool = >::mul(_self.into_inner(), rhs.into_inner()) + >>::eq(&_self, &other) .into(); output }, ) .register( - "add", - |_self: Val, rhs: Val| { - let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, ) .register( "rem", - |_self: Val, rhs: Ref| { + |_self: Val, rhs: f32| { let output: Val = >::rem(_self.into_inner(), &rhs) + f32, + >>::rem(_self.into_inner(), rhs) .into(); output }, ) .register( - "sub", - |_self: Val, rhs: Ref| { - let output: Val = >::sub(_self.into_inner(), &rhs) + "div", + |_self: Val, rhs: Val| { + let output: Val = >::div(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "div", - |_self: Val, rhs: Ref| { - let output: Val = >::div(_self.into_inner(), &rhs) + "sub", + |_self: Val, rhs: Val| { + let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( "mul", - |_self: Val, rhs: Ref| { + |_self: Val, rhs: f32| { let output: Val = >::mul(_self.into_inner(), &rhs) + f32, + >>::mul(_self.into_inner(), rhs) .into(); output }, ) .register( - "neg", - |_self: Val| { - let output: Val = ::neg( - _self.into_inner(), - ) + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -1305,6 +1321,46 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) + .register( + "rem", + |_self: Val, rhs: Val| { + let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: Ref| { + let output: Val = >::rem(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: Ref| { + let output: Val = >::sub(_self.into_inner(), &rhs) + .into(); + output + }, + ) .register( "new", |x: f32, y: f32, z: f32| { @@ -2106,126 +2162,46 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) - .register( - "add", + "div", |_self: Val, rhs: Ref| { - let output: Val = = >::add(_self.into_inner(), &rhs) + >>::div(_self.into_inner(), &rhs) .into(); output }, ) .register( "sub", - |_self: Val, rhs: Val| { - let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "div", - |_self: Val, rhs: f32| { - let output: Val = >::div(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "div", - |_self: Val, rhs: Val| { - let output: Val = >::div(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "rem", - |_self: Val, rhs: f32| { - let output: Val = >::rem(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "mul", |_self: Val, rhs: f32| { - let output: Val = = >::mul(_self.into_inner(), rhs) + >>::sub(_self.into_inner(), rhs) .into(); output }, ) .register( - "rem", + "add", |_self: Val, rhs: Val| { - let output: Val = = >::rem(_self.into_inner(), rhs.into_inner()) + >>::add(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = >::eq(&_self, &other) + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) .into(); output }, ); NamespaceBuilder::<::bevy::math::IVec2>::new(world) - .register( - "sub", - |_self: Val, rhs: i32| { - let output: Val = >::sub(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "div", - |_self: Val, rhs: Ref| { - let output: Val = >::div(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) .register( "new", |x: i32, y: i32| { @@ -2754,11 +2730,11 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "rem", - |_self: Val, rhs: Val| { - let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) .into(); output }, @@ -2774,41 +2750,21 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "sub", - |_self: Val, rhs: Ref| { - let output: Val = >::sub(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "neg", - |_self: Val| { - let output: Val = ::neg( - _self.into_inner(), - ) - .into(); - output - }, - ) - .register( - "rem", + "div", |_self: Val, rhs: Ref| { - let output: Val = = >::rem(_self.into_inner(), &rhs) + >>::div(_self.into_inner(), &rhs) .into(); output }, ) .register( - "div", + "add", |_self: Val, rhs: i32| { - let output: Val = = >::div(_self.into_inner(), rhs) + >>::add(_self.into_inner(), rhs) .into(); output }, @@ -2824,31 +2780,31 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "sub", + "rem", |_self: Val, rhs: Val| { - let output: Val = = >::sub(_self.into_inner(), rhs.into_inner()) + >>::rem(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "add", + "sub", |_self: Val, rhs: Ref| { - let output: Val = = >::add(_self.into_inner(), &rhs) + >>::sub(_self.into_inner(), &rhs) .into(); output }, ) .register( "add", - |_self: Val, rhs: i32| { + |_self: Val, rhs: Val| { let output: Val = >::add(_self.into_inner(), rhs) + bevy::math::IVec2, + >>::add(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -2865,10 +2821,30 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { ) .register( "add", - |_self: Val, rhs: Val| { + |_self: Val, rhs: Ref| { let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + &bevy::math::IVec2, + >>::add(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: i32| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) .into(); output }, @@ -2894,76 +2870,56 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + "rem", + |_self: Val, rhs: Ref| { + let output: Val = >::rem(_self.into_inner(), &rhs) .into(); output }, ) - .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( - &_self, - ) - .into(); - output - }, - ); - NamespaceBuilder::<::bevy::math::IVec3>::new(world) .register( "sub", - |_self: Val, rhs: Ref| { - let output: Val = >::sub(_self.into_inner(), &rhs) + |_self: Val, rhs: i32| { + let output: Val = >::sub(_self.into_inner(), rhs) .into(); output }, ) .register( - "div", - |_self: Val, rhs: i32| { - let output: Val = >::div(_self.into_inner(), rhs) + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, ) .register( - "rem", - |_self: Val, rhs: i32| { - let output: Val = >::rem(_self.into_inner(), rhs) + "sub", + |_self: Val, rhs: Val| { + let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( "mul", - |_self: Val, rhs: Val| { - let output: Val = , rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, - ) - .register( - "rem", - |_self: Val, rhs: Val| { - let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) + ); + NamespaceBuilder::<::bevy::math::IVec3>::new(world) .register( "new", |x: i32, y: i32, z: i32| { @@ -3502,21 +3458,21 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "mul", - |_self: Val, rhs: i32| { - let output: Val = >::mul(_self.into_inner(), rhs) + "add", + |_self: Val, rhs: Ref| { + let output: Val = >::add(_self.into_inner(), &rhs) .into(); output }, ) .register( - "div", + "rem", |_self: Val, rhs: Val| { - let output: Val = = >::div(_self.into_inner(), rhs.into_inner()) + >>::rem(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -3542,11 +3498,51 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "sub", + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: Ref| { + let output: Val = >::div(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "rem", |_self: Val, rhs: i32| { - let output: Val = = >::sub(_self.into_inner(), rhs) + >>::rem(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: Ref| { + let output: Val = >::sub(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -3562,11 +3558,11 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + "div", + |_self: Val, rhs: i32| { + let output: Val = >::div(_self.into_inner(), rhs) .into(); output }, @@ -3582,30 +3578,30 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "add", + "sub", |_self: Val, rhs: i32| { - let output: Val = = >::add(_self.into_inner(), rhs) + >>::sub(_self.into_inner(), rhs) .into(); output }, ) .register( - "add", - |_self: Val, rhs: Ref| { - let output: Val = >::add(_self.into_inner(), &rhs) + "div", + |_self: Val, rhs: Val| { + let output: Val = >::div(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "neg", - |_self: Val| { - let output: Val = ::neg( - _self.into_inner(), + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, ) .into(); output @@ -3613,10 +3609,10 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { ) .register( "mul", - |_self: Val, rhs: Ref| { + |_self: Val, rhs: i32| { let output: Val = >::mul(_self.into_inner(), &rhs) + i32, + >>::mul(_self.into_inner(), rhs) .into(); output }, @@ -3632,11 +3628,21 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "div", + "add", + |_self: Val, rhs: i32| { + let output: Val = >::add(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "mul", |_self: Val, rhs: Ref| { - let output: Val = = >::div(_self.into_inner(), &rhs) + >>::mul(_self.into_inner(), &rhs) .into(); output }, @@ -3644,24 +3650,64 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { NamespaceBuilder::<::bevy::math::IVec4>::new(world) .register( "rem", - |_self: Val, rhs: i32| { + |_self: Val, rhs: Ref| { let output: Val = >::rem(_self.into_inner(), rhs) + &bevy::math::IVec4, + >>::rem(_self.into_inner(), &rhs) .into(); output }, ) .register( - "neg", - |_self: Val| { - let output: Val = ::neg( - _self.into_inner(), + "mul", + |_self: Val, rhs: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, ) .into(); output }, ) + .register( + "add", + |_self: Val, rhs: i32| { + let output: Val = >::add(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) .register( "new", |x: i32, y: i32, z: i32, w: i32| { @@ -4184,31 +4230,31 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "sub", - |_self: Val, rhs: i32| { - let output: Val = >::sub(_self.into_inner(), rhs) + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) .into(); output }, ) .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( - &_self, - ) + "div", + |_self: Val, rhs: Ref| { + let output: Val = >::div(_self.into_inner(), &rhs) .into(); output }, ) .register( - "add", - |_self: Val, rhs: Ref| { - let output: Val = >::add(_self.into_inner(), &rhs) + "rem", + |_self: Val, rhs: i32| { + let output: Val = >::rem(_self.into_inner(), rhs) .into(); output }, @@ -4224,31 +4270,21 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "rem", - |_self: Val, rhs: Val| { - let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "mul", + "sub", |_self: Val, rhs: Val| { - let output: Val = = >::mul(_self.into_inner(), rhs.into_inner()) + >>::sub(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "add", - |_self: Val, rhs: Val| { - let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) .into(); output }, @@ -4264,136 +4300,66 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + "div", + |_self: Val, rhs: Val| { + let output: Val = >::div(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( "rem", - |_self: Val, rhs: Ref| { + |_self: Val, rhs: Val| { let output: Val = >::rem(_self.into_inner(), &rhs) + bevy::math::IVec4, + >>::rem(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = >::eq(&_self, &other) + "add", + |_self: Val, rhs: Ref| { + let output: Val = >::add(_self.into_inner(), &rhs) .into(); output }, ) .register( - "mul", + "sub", |_self: Val, rhs: Ref| { - let output: Val = = >::mul(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "add", - |_self: Val, rhs: i32| { - let output: Val = >::add(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "sub", - |_self: Val, rhs: Val| { - let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "div", - |_self: Val, rhs: Ref| { - let output: Val = >::div(_self.into_inner(), &rhs) + >>::sub(_self.into_inner(), &rhs) .into(); output }, ) .register( "sub", - |_self: Val, rhs: Ref| { + |_self: Val, rhs: i32| { let output: Val = >::sub(_self.into_inner(), &rhs) + i32, + >>::sub(_self.into_inner(), rhs) .into(); output }, ) .register( - "div", - |_self: Val, rhs: Val| { - let output: Val = >::div(_self.into_inner(), rhs.into_inner()) + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, ); NamespaceBuilder::<::bevy::math::I64Vec2>::new(world) - .register( - "sub", - |_self: Val, rhs: i64| { - let output: Val = >::sub(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "rem", - |_self: Val, rhs: i64| { - let output: Val = >::rem(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "add", - |_self: Val, rhs: Ref| { - let output: Val = >::add(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "div", - |_self: Val, rhs: Val| { - let output: Val = >::div(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) .register( "rem", |_self: Val, rhs: Ref| { @@ -4404,76 +4370,6 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) - .register( - "add", - |_self: Val, rhs: i64| { - let output: Val = >::add(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "mul", - |_self: Val, rhs: Ref| { - let output: Val = >::mul(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "div", - |_self: Val, rhs: Ref| { - let output: Val = >::div(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "neg", - |_self: Val| { - let output: Val = ::neg( - _self.into_inner(), - ) - .into(); - output - }, - ) - .register( - "sub", - |_self: Val, rhs: Ref| { - let output: Val = >::sub(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( - &_self, - ) - .into(); - output - }, - ) - .register( - "sub", - |_self: Val, rhs: Val| { - let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) .register( "new", |x: i64, y: i64| { @@ -5009,26 +4905,6 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) - .register( - "add", - |_self: Val, rhs: Val| { - let output: Val = >::add(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "rem", - |_self: Val, rhs: Val| { - let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) .register( "eq", |_self: Ref, other: Ref| { @@ -5039,16 +4915,6 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) - .register( - "div", - |_self: Val, rhs: i64| { - let output: Val = >::div(_self.into_inner(), rhs) - .into(); - output - }, - ) .register( "mul", |_self: Val, rhs: i64| { @@ -5060,11 +4926,21 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "mul", + "sub", |_self: Val, rhs: Val| { - let output: Val = = >::mul(_self.into_inner(), rhs.into_inner()) + >>::sub(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: Ref| { + let output: Val = >::add(_self.into_inner(), &rhs) .into(); output }, @@ -5078,64 +4954,154 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { .into(); output }, - ); - NamespaceBuilder::<::bevy::math::I64Vec3>::new(world) + ) .register( - "rem", - |_self: Val, rhs: i64| { - let output: Val = >::rem(_self.into_inner(), rhs) + "div", + |_self: Val, rhs: Ref| { + let output: Val = >::div(_self.into_inner(), &rhs) .into(); output }, ) .register( "sub", - |_self: Val, rhs: Ref| { - let output: Val = , rhs: Ref| { + let output: Val = >::sub(_self.into_inner(), &rhs) .into(); output }, ) .register( - "sub", - |_self: Val, rhs: i64| { - let output: Val = >::sub(_self.into_inner(), rhs) + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) .into(); output }, ) .register( - "rem", - |_self: Val, rhs: Ref| { - let output: Val = >::rem(_self.into_inner(), &rhs) + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + "div", + |_self: Val, rhs: i64| { + let output: Val = >::div(_self.into_inner(), rhs) .into(); output }, ) .register( - "div", - |_self: Val, rhs: Val| { - let output: Val = >::div(_self.into_inner(), rhs.into_inner()) + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: i64| { + let output: Val = >::add(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: i64| { + let output: Val = >::rem(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: Val| { + let output: Val = >::div(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: i64| { + let output: Val = >::sub(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: Val| { + let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::I64Vec3>::new(world) + .register( + "div", + |_self: Val, rhs: i64| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: Ref| { + let output: Val = >::sub(_self.into_inner(), &rhs) .into(); output }, @@ -5690,21 +5656,41 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "add", - |_self: Val, rhs: Ref| { - let output: Val = >::add(_self.into_inner(), &rhs) + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "add", + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul", |_self: Val, rhs: i64| { - let output: Val = = >::add(_self.into_inner(), rhs) + >>::mul(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) .into(); output }, @@ -5730,61 +5716,61 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "div", + "add", |_self: Val, rhs: i64| { - let output: Val = = >::div(_self.into_inner(), rhs) + >>::add(_self.into_inner(), rhs) .into(); output }, ) .register( - "div", - |_self: Val, rhs: Ref| { - let output: Val = >::div(_self.into_inner(), &rhs) + "sub", + |_self: Val, rhs: i64| { + let output: Val = >::sub(_self.into_inner(), rhs) .into(); output }, ) .register( - "neg", - |_self: Val| { - let output: Val = ::neg( - _self.into_inner(), - ) + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) .into(); output }, ) .register( - "sub", + "div", |_self: Val, rhs: Val| { - let output: Val = = >::sub(_self.into_inner(), rhs.into_inner()) + >>::div(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "mul", + "add", |_self: Val, rhs: Ref| { - let output: Val = = >::mul(_self.into_inner(), &rhs) + >>::add(_self.into_inner(), &rhs) .into(); output }, ) .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + "rem", + |_self: Val, rhs: i64| { + let output: Val = >::rem(_self.into_inner(), rhs) .into(); output }, @@ -5800,42 +5786,52 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "mul", - |_self: Val, rhs: i64| { - let output: Val = >::mul(_self.into_inner(), rhs) + "div", + |_self: Val, rhs: Ref| { + let output: Val = >::div(_self.into_inner(), &rhs) .into(); output }, ) .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = >::eq(&_self, &other) + "rem", + |_self: Val, rhs: Ref| { + let output: Val = >::rem(_self.into_inner(), &rhs) .into(); output }, - ); - NamespaceBuilder::<::bevy::math::I64Vec4>::new(world) + ) .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = >::eq(&_self, &other) + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, ) .register( - "div", - |_self: Val, rhs: Ref| { - let output: Val = >::div(_self.into_inner(), &rhs) + "sub", + |_self: Val, rhs: Val| { + let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::I64Vec4>::new(world) + .register( + "sub", + |_self: Val, rhs: i64| { + let output: Val = >::sub(_self.into_inner(), rhs) .into(); output }, @@ -5851,51 +5847,61 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "rem", + "mul", |_self: Val, rhs: Ref| { - let output: Val = = >::rem(_self.into_inner(), &rhs) + >>::mul(_self.into_inner(), &rhs) .into(); output }, ) .register( - "rem", + "sub", + |_self: Val, rhs: Ref| { + let output: Val = >::sub(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "sub", |_self: Val, rhs: Val| { - let output: Val = = >::rem(_self.into_inner(), rhs.into_inner()) + >>::sub(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "add", - |_self: Val, rhs: i64| { - let output: Val = >::add(_self.into_inner(), rhs) + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) .into(); output }, ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + "mul", + |_self: Val, rhs: i64| { + let output: Val = >::mul(_self.into_inner(), rhs) .into(); output }, ) .register( - "sub", - |_self: Val, rhs: Val| { - let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) + "div", + |_self: Val, rhs: Ref| { + let output: Val = >::div(_self.into_inner(), &rhs) .into(); output }, @@ -5911,11 +5917,11 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "div", - |_self: Val, rhs: Val| { - let output: Val = >::div(_self.into_inner(), rhs.into_inner()) + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) .into(); output }, @@ -5930,66 +5936,6 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) - .register( - "sub", - |_self: Val, rhs: i64| { - let output: Val = >::sub(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "mul", - |_self: Val, rhs: i64| { - let output: Val = >::mul(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "add", - |_self: Val, rhs: Ref| { - let output: Val = >::add(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "sub", - |_self: Val, rhs: Ref| { - let output: Val = >::sub(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "mul", - |_self: Val, rhs: Ref| { - let output: Val = >::mul(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( - &_self, - ) - .into(); - output - }, - ) .register( "new", |x: i64, y: i64, z: i64, w: i64| { @@ -6520,60 +6466,49 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + "rem", + |_self: Val, rhs: Ref| { + let output: Val = >::rem(_self.into_inner(), &rhs) .into(); output }, ) .register( - "neg", - |_self: Val| { - let output: Val = ::neg( - _self.into_inner(), - ) - .into(); - output - }, - ); - NamespaceBuilder::<::bevy::math::UVec2>::new(world) - .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = >::eq(&_self, &other) + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "div", - |_self: Val, rhs: Ref| { - let output: Val = >::div(_self.into_inner(), &rhs) + "add", + |_self: Val, rhs: i64| { + let output: Val = >::add(_self.into_inner(), rhs) .into(); output }, ) .register( - "div", - |_self: Val, rhs: u32| { - let output: Val = >::div(_self.into_inner(), rhs) + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( &_self, ) .into(); @@ -6582,40 +6517,41 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { ) .register( "div", - |_self: Val, rhs: Val| { - let output: Val = , rhs: Val| { + let output: Val = >::div(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "sub", - |_self: Val, rhs: Ref| { - let output: Val = >::sub(_self.into_inner(), &rhs) + "add", + |_self: Val, rhs: Ref| { + let output: Val = >::add(_self.into_inner(), &rhs) .into(); output }, ) .register( "rem", - |_self: Val, rhs: Ref| { - let output: Val = >::rem(_self.into_inner(), &rhs) + |_self: Val, rhs: Val| { + let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::UVec2>::new(world) .register( - "rem", - |_self: Val, rhs: Val| { - let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) + "div", + |_self: Val, rhs: Ref| { + let output: Val = >::div(_self.into_inner(), &rhs) .into(); output }, @@ -6632,121 +6568,61 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { ) .register( "add", - |_self: Val, rhs: Ref| { + |_self: Val, rhs: Val| { let output: Val = >::add(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "mul", - |_self: Val, rhs: u32| { - let output: Val = >::mul(_self.into_inner(), rhs) + bevy::math::UVec2, + >>::add(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( "rem", - |_self: Val, rhs: u32| { + |_self: Val, rhs: Val| { let output: Val = >::rem(_self.into_inner(), rhs) + bevy::math::UVec2, + >>::rem(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "add", + "div", |_self: Val, rhs: Val| { - let output: Val = = >::add(_self.into_inner(), rhs.into_inner()) + >>::div(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "mul", - |_self: Val, rhs: Ref| { - let output: Val = >::mul(_self.into_inner(), &rhs) + "new", + |x: u32, y: u32| { + let output: Val = bevy::math::UVec2::new(x, y) .into(); output }, ) .register( - "add", - |_self: Val, rhs: u32| { - let output: Val = >::add(_self.into_inner(), rhs) + "splat", + |v: u32| { + let output: Val = bevy::math::UVec2::splat(v) .into(); output }, ) .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( - &_self, - ) - .into(); - output - }, - ) - .register( - "sub", - |_self: Val, rhs: u32| { - let output: Val = >::sub(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "sub", - |_self: Val, rhs: Val| { - let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "new", - |x: u32, y: u32| { - let output: Val = bevy::math::UVec2::new(x, y) - .into(); - output - }, - ) - .register( - "splat", - |v: u32| { - let output: Val = bevy::math::UVec2::splat(v) - .into(); - output - }, - ) - .register( - "select", - | - mask: Val, - if_true: Val, - if_false: Val| - { - let output: Val = bevy::math::UVec2::select( - mask.into_inner(), - if_true.into_inner(), - if_false.into_inner(), + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::UVec2::select( + mask.into_inner(), + if_true.into_inner(), + if_false.into_inner(), ) .into(); output @@ -7129,33 +7005,102 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { .into(); output }, - ); - NamespaceBuilder::<::bevy::math::UVec3>::new(world) + ) + .register( + "rem", + |_self: Val, rhs: Ref| { + let output: Val = >::rem(_self.into_inner(), &rhs) + .into(); + output + }, + ) .register( "add", - |_self: Val, rhs: Ref| { - let output: Val = >::add(_self.into_inner(), &rhs) + |_self: Val, rhs: u32| { + let output: Val = >::add(_self.into_inner(), rhs) .into(); output }, ) .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( + "sub", + |_self: Val, rhs: u32| { + let output: Val = >::sub(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, ) + .register( + "div", + |_self: Val, rhs: u32| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: u32| { + let output: Val = >::rem(_self.into_inner(), rhs) + .into(); + output + }, + ) .register( "sub", - |_self: Val, rhs: Val| { - let output: Val = , rhs: Ref| { + let output: Val = >::sub(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: Val| { + let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) .into(); output @@ -7163,10 +7108,61 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { ) .register( "add", - |_self: Val, rhs: Val| { + |_self: Val, rhs: Ref| { + let output: Val = >::add(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: u32| { + let output: Val = >::mul(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::UVec3>::new(world) + .register( + "mul", + |_self: Val, rhs: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: Ref| { let output: Val = >::add(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + >>::div(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -7182,31 +7178,61 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = | { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: u32| { + let output: Val = >::rem(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::mul(_self.into_inner(), rhs.into_inner()) + >>::eq(&_self, &other) .into(); output }, ) .register( - "mul", + "rem", |_self: Val, rhs: Ref| { - let output: Val = = >::mul(_self.into_inner(), &rhs) + >>::rem(_self.into_inner(), &rhs) .into(); output }, ) .register( - "mul", + "add", |_self: Val, rhs: u32| { - let output: Val = = >::mul(_self.into_inner(), rhs) + >>::add(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: Ref| { + let output: Val = >::sub(_self.into_inner(), &rhs) .into(); output }, @@ -7663,6 +7689,16 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) + .register( + "mul", + |_self: Val, rhs: u32| { + let output: Val = >::mul(_self.into_inner(), rhs) + .into(); + output + }, + ) .register( "sub", |_self: Val, rhs: u32| { @@ -7674,41 +7710,31 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "rem", + "add", |_self: Val, rhs: Val| { - let output: Val = = >::rem(_self.into_inner(), rhs.into_inner()) + >>::add(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( "rem", - |_self: Val, rhs: Ref| { + |_self: Val, rhs: Val| { let output: Val = >::rem(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = >::eq(&_self, &other) + >>::rem(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "div", + "mul", |_self: Val, rhs: Val| { - let output: Val = = >::div(_self.into_inner(), rhs.into_inner()) + >>::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -7723,32 +7749,12 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) - .register( - "rem", - |_self: Val, rhs: u32| { - let output: Val = >::rem(_self.into_inner(), rhs) - .into(); - output - }, - ) .register( "sub", - |_self: Val, rhs: Ref| { + |_self: Val, rhs: Val| { let output: Val = >::sub(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "add", - |_self: Val, rhs: u32| { - let output: Val = >::add(_self.into_inner(), rhs) + bevy::math::UVec3, + >>::sub(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -7765,81 +7771,41 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { ); NamespaceBuilder::<::bevy::math::UVec4>::new(world) .register( - "sub", - |_self: Val, rhs: Ref| { - let output: Val = >::sub(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "sub", - |_self: Val, rhs: Val| { - let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "div", + "mul", |_self: Val, rhs: u32| { - let output: Val = = >::div(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + >>::mul(_self.into_inner(), rhs) .into(); output }, ) .register( "add", - |_self: Val, rhs: Ref| { - let output: Val = >::add(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "mul", |_self: Val, rhs: Val| { - let output: Val = = >::mul(_self.into_inner(), rhs.into_inner()) + >>::add(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "rem", - |_self: Val, rhs: Val| { - let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) + "div", + |_self: Val, rhs: Ref| { + let output: Val = >::div(_self.into_inner(), &rhs) .into(); output }, ) .register( - "mul", + "sub", |_self: Val, rhs: Ref| { - let output: Val = = >::mul(_self.into_inner(), &rhs) + >>::sub(_self.into_inner(), &rhs) .into(); output }, @@ -8281,61 +8247,51 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, - ) - .register( - "sub", - |_self: Val, rhs: u32| { - let output: Val = >::sub(_self.into_inner(), rhs) + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, ) .register( - "div", + "rem", |_self: Val, rhs: Val| { - let output: Val = = >::div(_self.into_inner(), rhs.into_inner()) + >>::rem(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( "mul", - |_self: Val, rhs: u32| { + |_self: Val, rhs: Val| { let output: Val = >::mul(_self.into_inner(), rhs) + bevy::math::UVec4, + >>::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "rem", - |_self: Val, rhs: Ref| { - let output: Val = >::rem(_self.into_inner(), &rhs) + "add", + |_self: Val, rhs: u32| { + let output: Val = >::add(_self.into_inner(), rhs) .into(); output }, ) .register( - "div", - |_self: Val, rhs: Ref| { - let output: Val = >::div(_self.into_inner(), &rhs) + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) .into(); output }, @@ -8351,102 +8307,102 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "rem", + "div", |_self: Val, rhs: u32| { - let output: Val = = >::rem(_self.into_inner(), rhs) + >>::div(_self.into_inner(), rhs) .into(); output }, ) .register( - "add", - |_self: Val, rhs: Val| { - let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + "rem", + |_self: Val, rhs: u32| { + let output: Val = >::rem(_self.into_inner(), rhs) .into(); output }, ) .register( - "add", + "sub", |_self: Val, rhs: u32| { - let output: Val = = >::add(_self.into_inner(), rhs) + >>::sub(_self.into_inner(), rhs) .into(); output }, - ); - NamespaceBuilder::<::bevy::math::U64Vec2>::new(world) + ) .register( - "mul", - |_self: Val, rhs: u64| { - let output: Val = >::mul(_self.into_inner(), rhs) + "sub", + |_self: Val, rhs: Val| { + let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "rem", - |_self: Val, rhs: Val| { - let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) + "mul", + |_self: Val, rhs: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) .into(); output }, ) .register( - "add", - |_self: Val, rhs: Val| { - let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + "div", + |_self: Val, rhs: Val| { + let output: Val = >::div(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "sub", - |_self: Val, rhs: Ref| { - let output: Val = >::sub(_self.into_inner(), &rhs) + "rem", + |_self: Val, rhs: Ref| { + let output: Val = >::rem(_self.into_inner(), &rhs) .into(); output }, ) .register( - "mul", - |_self: Val, rhs: Ref| { - let output: Val = >::mul(_self.into_inner(), &rhs) + "add", + |_self: Val, rhs: Ref| { + let output: Val = >::add(_self.into_inner(), &rhs) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::U64Vec2>::new(world) .register( "div", - |_self: Val, rhs: u64| { + |_self: Val, rhs: Val| { let output: Val = >::div(_self.into_inner(), rhs) + bevy::math::U64Vec2, + >>::div(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + "add", + |_self: Val, rhs: u64| { + let output: Val = >::add(_self.into_inner(), rhs) .into(); output }, @@ -8461,32 +8417,42 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) + .register( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .into(); + output + }, + ) .register( "rem", - |_self: Val, rhs: Ref| { + |_self: Val, rhs: Val| { let output: Val = >::rem(_self.into_inner(), &rhs) + bevy::math::U64Vec2, + >>::rem(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( "add", - |_self: Val, rhs: u64| { + |_self: Val, rhs: Ref| { let output: Val = >::add(_self.into_inner(), rhs) + &bevy::math::U64Vec2, + >>::add(_self.into_inner(), &rhs) .into(); output }, ) .register( - "div", - |_self: Val, rhs: Ref| { - let output: Val = >::div(_self.into_inner(), &rhs) + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -8910,31 +8876,71 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "add", + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "mul", |_self: Val, rhs: Ref| { - let output: Val = = >::add(_self.into_inner(), &rhs) + >>::mul(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: Ref| { + let output: Val = >::rem(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: u64| { + let output: Val = >::mul(_self.into_inner(), rhs) .into(); output }, ) .register( "div", - |_self: Val, rhs: Val| { + |_self: Val, rhs: Ref| { let output: Val = >::div(_self.into_inner(), rhs.into_inner()) + &bevy::math::U64Vec2, + >>::div(_self.into_inner(), &rhs) .into(); output }, ) .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = , rhs: Ref| { + let output: Val = >::sub(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: Val| { + let output: Val = >::eq(&_self, &other) + >>::sub(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -8950,36 +8956,66 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "mul", + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) + .register( + "add", |_self: Val, rhs: Val| { - let output: Val = = >::mul(_self.into_inner(), rhs.into_inner()) + >>::add(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( - &_self, - ) + "div", + |_self: Val, rhs: u64| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::U64Vec3>::new(world) + .register( + "mul", + |_self: Val, rhs: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: u64| { + let output: Val = >::add(_self.into_inner(), rhs) .into(); output }, ) .register( "sub", - |_self: Val, rhs: Val| { - let output: Val = , rhs: Val| { + let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) .into(); output }, - ); - NamespaceBuilder::<::bevy::math::U64Vec3>::new(world) + ) .register( "mul", |_self: Val, rhs: u64| { @@ -8990,6 +9026,56 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) + .register( + "rem", + |_self: Val, rhs: u64| { + let output: Val = >::rem(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: Ref| { + let output: Val = >::rem(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: Ref| { + let output: Val = >::div(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: Ref| { + let output: Val = >::add(_self.into_inner(), &rhs) + .into(); + output + }, + ) .register( "sub", |_self: Val, rhs: u64| { @@ -9000,6 +9086,36 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) + .register( + "div", + |_self: Val, rhs: u64| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: Val| { + let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) .register( "new", |x: u64, y: u64, z: u64| { @@ -9465,11 +9581,21 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "add", - |_self: Val, rhs: Ref| { - let output: Val = >::add(_self.into_inner(), &rhs) + "div", + |_self: Val, rhs: Val| { + let output: Val = >::div(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) .into(); output }, @@ -9485,21 +9611,11 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "rem", + "sub", |_self: Val, rhs: Ref| { - let output: Val = = >::rem(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "rem", - |_self: Val, rhs: u64| { - let output: Val = >::rem(_self.into_inner(), rhs) + >>::sub(_self.into_inner(), &rhs) .into(); output }, @@ -9513,184 +9629,34 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { .into(); output }, - ) - .register( - "div", - |_self: Val, rhs: Ref| { - let output: Val = >::div(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "div", - |_self: Val, rhs: Val| { - let output: Val = >::div(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "div", - |_self: Val, rhs: u64| { - let output: Val = >::div(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) - .register( - "rem", - |_self: Val, rhs: Val| { - let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "sub", - |_self: Val, rhs: Val| { - let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "add", - |_self: Val, rhs: u64| { - let output: Val = >::add(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, - ) - .register( - "mul", - |_self: Val, rhs: Ref| { - let output: Val = >::mul(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "add", - |_self: Val, rhs: Val| { - let output: Val = >::add(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "sub", - |_self: Val, rhs: Ref| { - let output: Val = >::sub(_self.into_inner(), &rhs) - .into(); - output - }, ); NamespaceBuilder::<::bevy::math::U64Vec4>::new(world) .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( - &_self, - ) - .into(); - output - }, - ) - .register( - "sub", + "mul", |_self: Val, rhs: Val| { - let output: Val = = >::sub(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "rem", - |_self: Val, rhs: Ref| { - let output: Val = >::rem(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "div", - |_self: Val, rhs: u64| { - let output: Val = >::div(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "div", - |_self: Val, rhs: Ref| { - let output: Val = >::div(_self.into_inner(), &rhs) + >>::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "mul", + "add", |_self: Val, rhs: Val| { - let output: Val = = >::mul(_self.into_inner(), rhs.into_inner()) + >>::add(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( "add", - |_self: Val, rhs: Val| { + |_self: Val, rhs: u64| { let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + u64, + >>::add(_self.into_inner(), rhs) .into(); output }, @@ -9706,71 +9672,61 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "sub", + "add", |_self: Val, rhs: Ref| { - let output: Val = = >::sub(_self.into_inner(), &rhs) + >>::add(_self.into_inner(), &rhs) .into(); output }, ) .register( - "mul", + "sub", |_self: Val, rhs: u64| { - let output: Val = = >::mul(_self.into_inner(), rhs) + >>::sub(_self.into_inner(), rhs) .into(); output }, ) .register( - "add", - |_self: Val, rhs: u64| { - let output: Val = >::add(_self.into_inner(), rhs) + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) .into(); output }, ) .register( - "add", + "sub", |_self: Val, rhs: Ref| { - let output: Val = = >::add(_self.into_inner(), &rhs) + >>::sub(_self.into_inner(), &rhs) .into(); output }, ) .register( - "mul", - |_self: Val, rhs: Ref| { - let output: Val = >::mul(_self.into_inner(), &rhs) + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) .into(); output }, ) .register( "div", - |_self: Val, rhs: Val| { + |_self: Val, rhs: Ref| { let output: Val = >::div(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + &bevy::math::U64Vec4, + >>::div(_self.into_inner(), &rhs) .into(); output }, @@ -10220,36 +10176,106 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "rem", - |_self: Val, rhs: u64| { - let output: Val = >::rem(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = , rhs: Val| { + let output: Val = >::eq(&_self, &other) + >>::sub(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "sub", + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: Val| { + let output: Val = >::div(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "rem", |_self: Val, rhs: u64| { - let output: Val = = >::sub(_self.into_inner(), rhs) + >>::rem(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: u64| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: u64| { + let output: Val = >::mul(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: Ref| { + let output: Val = >::rem(_self.into_inner(), &rhs) .into(); output }, ); NamespaceBuilder::<::bevy::math::Vec2>::new(world) + .register( + "mul", + |_self: Val, rhs: f32| { + let output: Val = >::mul(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: Val| { + let output: Val = >::div(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) .register( "div", |_self: Val, rhs: Ref| { @@ -10261,31 +10287,41 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "add", + "sub", |_self: Val, rhs: Val| { - let output: Val = = >::add(_self.into_inner(), rhs.into_inner()) + >>::sub(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "mul", + "sub", |_self: Val, rhs: Ref| { - let output: Val = = >::mul(_self.into_inner(), &rhs) + >>::sub(_self.into_inner(), &rhs) .into(); output }, ) .register( - "sub", + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "mul", |_self: Val, rhs: Ref| { - let output: Val = = >::sub(_self.into_inner(), &rhs) + >>::mul(_self.into_inner(), &rhs) .into(); output }, @@ -10300,6 +10336,46 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) + .register( + "rem", + |_self: Val, rhs: Ref| { + let output: Val = >::rem(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: Ref| { + let output: Val = >::add(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: f32| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: f32| { + let output: Val = >::sub(_self.into_inner(), rhs) + .into(); + output + }, + ) .register( "neg", |_self: Val| { @@ -10311,21 +10387,21 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "div", + "add", |_self: Val, rhs: f32| { - let output: Val = = >::div(_self.into_inner(), rhs) + >>::add(_self.into_inner(), rhs) .into(); output }, ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + "rem", + |_self: Val, rhs: f32| { + let output: Val = >::rem(_self.into_inner(), rhs) .into(); output }, @@ -11155,16 +11231,6 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) - .register( - "sub", - |_self: Val, rhs: Val| { - let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) .register( "mul", |_self: Val, rhs: Val| { @@ -11177,209 +11243,79 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { ) .register( "rem", - |_self: Val, rhs: f32| { + |_self: Val, rhs: Val| { let output: Val = >::rem(_self.into_inner(), rhs) + bevy::math::Vec2, + >>::rem(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( "add", - |_self: Val, rhs: Ref| { + |_self: Val, rhs: Val| { let output: Val = >::add(_self.into_inner(), &rhs) + bevy::math::Vec2, + >>::add(_self.into_inner(), rhs.into_inner()) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::Vec3A>::new(world) .register( - "div", - |_self: Val, rhs: Val| { - let output: Val = >::div(_self.into_inner(), rhs.into_inner()) + "mul", + |_self: Val, rhs: f32| { + let output: Val = >::mul(_self.into_inner(), rhs) .into(); output }, ) .register( - "add", - |_self: Val, rhs: f32| { - let output: Val = >::add(_self.into_inner(), rhs) + "new", + |x: f32, y: f32, z: f32| { + let output: Val = bevy::math::Vec3A::new(x, y, z) .into(); output }, ) .register( - "mul", - |_self: Val, rhs: f32| { - let output: Val = >::mul(_self.into_inner(), rhs) + "splat", + |v: f32| { + let output: Val = bevy::math::Vec3A::splat(v) .into(); output }, ) .register( - "rem", - |_self: Val, rhs: Val| { - let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::Vec3A::select( + mask.into_inner(), + if_true.into_inner(), + if_false.into_inner(), + ) .into(); output }, ) .register( - "sub", - |_self: Val, rhs: f32| { - let output: Val = >::sub(_self.into_inner(), rhs) + "from_array", + |a: [f32; 3]| { + let output: Val = bevy::math::Vec3A::from_array(a) .into(); output }, ) .register( - "rem", - |_self: Val, rhs: Ref| { - let output: Val = >::rem(_self.into_inner(), &rhs) - .into(); - output - }, - ); - NamespaceBuilder::<::bevy::math::Vec3A>::new(world) - .register( - "add", - |_self: Val, rhs: Val| { - let output: Val = >::add(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "eq", - |_self: Ref, rhs: Ref| { - let output: bool = >::eq(&_self, &rhs) - .into(); - output - }, - ) - .register( - "sub", - |_self: Val, rhs: f32| { - let output: Val = >::sub(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) - .register( - "rem", - |_self: Val, rhs: f32| { - let output: Val = >::rem(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "sub", - |_self: Val, rhs: Val| { - let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "div", - |_self: Val, rhs: Val| { - let output: Val = >::div(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "neg", - |_self: Val| { - let output: Val = ::neg( - _self.into_inner(), - ) - .into(); - output - }, - ) - .register( - "new", - |x: f32, y: f32, z: f32| { - let output: Val = bevy::math::Vec3A::new(x, y, z) - .into(); - output - }, - ) - .register( - "splat", - |v: f32| { - let output: Val = bevy::math::Vec3A::splat(v) - .into(); - output - }, - ) - .register( - "select", - | - mask: Val, - if_true: Val, - if_false: Val| - { - let output: Val = bevy::math::Vec3A::select( - mask.into_inner(), - if_true.into_inner(), - if_false.into_inner(), - ) - .into(); - output - }, - ) - .register( - "from_array", - |a: [f32; 3]| { - let output: Val = bevy::math::Vec3A::from_array(a) - .into(); - output - }, - ) - .register( - "to_array", - |_self: Ref| { - let output: [f32; 3] = bevy::math::Vec3A::to_array(&_self).into(); + "to_array", + |_self: Ref| { + let output: [f32; 3] = bevy::math::Vec3A::to_array(&_self).into(); output }, ) @@ -12151,41 +12087,31 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "sub", - |_self: Val, rhs: Ref| { - let output: Val = >::sub(_self.into_inner(), &rhs) + "div", + |_self: Val, rhs: Val| { + let output: Val = >::div(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "mul", + "div", |_self: Val, rhs: f32| { - let output: Val = = >::mul(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "add", - |_self: Val, rhs: Ref| { - let output: Val = >::add(_self.into_inner(), &rhs) + >>::div(_self.into_inner(), rhs) .into(); output }, ) .register( - "add", + "rem", |_self: Val, rhs: f32| { - let output: Val = = >::add(_self.into_inner(), rhs) + >>::rem(_self.into_inner(), rhs) .into(); output }, @@ -12201,122 +12127,162 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "div", - |_self: Val, rhs: f32| { - let output: Val = >::div(_self.into_inner(), rhs) + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) .into(); output }, ) .register( - "rem", - |_self: Val, rhs: Val| { - let output: Val = , rhs: Ref| { + let output: bool = >::rem(_self.into_inner(), rhs.into_inner()) + >>::eq(&_self, &rhs) .into(); output }, ) .register( - "rem", - |_self: Val, rhs: Ref| { - let output: Val = >::rem(_self.into_inner(), &rhs) + "sub", + |_self: Val, rhs: f32| { + let output: Val = >::sub(_self.into_inner(), rhs) .into(); output }, ) .register( - "mul", + "add", |_self: Val, rhs: Ref| { - let output: Val = = >::mul(_self.into_inner(), &rhs) + >>::add(_self.into_inner(), &rhs) .into(); output }, ) .register( - "div", + "rem", |_self: Val, rhs: Ref| { - let output: Val = = >::div(_self.into_inner(), &rhs) + >>::rem(_self.into_inner(), &rhs) .into(); output }, - ); - NamespaceBuilder::<::bevy::math::Vec4>::new(world) + ) .register( - "rem", - |_self: Val, rhs: Ref| { - let output: Val = >::rem(_self.into_inner(), &rhs) + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, ) .register( - "mul", - |_self: Val, rhs: Ref| { - let output: Val = >::mul(_self.into_inner(), &rhs) + "add", + |_self: Val, rhs: f32| { + let output: Val = >::add(_self.into_inner(), rhs) .into(); output }, ) .register( - "eq", - |_self: Ref, rhs: Ref| { - let output: bool = >::eq(&_self, &rhs) + "rem", + |_self: Val, rhs: Val| { + let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "div", - |_self: Val, rhs: Val| { - let output: Val = >::div(_self.into_inner(), rhs.into_inner()) + "sub", + |_self: Val, rhs: Val| { + let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "div", - |_self: Val, rhs: Ref| { - let output: Val = >::div(_self.into_inner(), &rhs) + "add", + |_self: Val, rhs: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "neg", - |_self: Val| { - let output: Val = ::neg( - _self.into_inner(), - ) + "mul", + |_self: Val, rhs: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) .into(); output }, ) .register( - "add", + "div", + |_self: Val, rhs: Ref| { + let output: Val = >::div(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: Ref| { + let output: Val = >::sub(_self.into_inner(), &rhs) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::Vec4>::new(world) + .register( + "rem", + |_self: Val, rhs: f32| { + let output: Val = >::rem(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "sub", |_self: Val, rhs: Val| { - let output: Val = = >::add(_self.into_inner(), rhs.into_inner()) + >>::sub(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: Ref| { + let output: Val = >::div(_self.into_inner(), &rhs) .into(); output }, @@ -12332,11 +12298,41 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "add", + "mul", |_self: Val, rhs: f32| { - let output: Val = = >::add(_self.into_inner(), rhs) + >>::mul(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: Ref| { + let output: Val = >::rem(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "eq", + |_self: Ref, rhs: Ref| { + let output: bool = >::eq(&_self, &rhs) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -12351,6 +12347,76 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: Ref| { + let output: Val = >::sub(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: Val| { + let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: Val| { + let output: Val = >::div(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) .register( "new", |x: f32, y: f32, z: f32, w: f32| { @@ -13110,86 +13176,36 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "sub", - |_self: Val, rhs: Val| { - let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "sub", - |_self: Val, rhs: Ref| { - let output: Val = >::sub(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + "div", + |_self: Val, rhs: f32| { + let output: Val = >::div(_self.into_inner(), rhs) .into(); output }, ) .register( - "rem", + "add", |_self: Val, rhs: f32| { - let output: Val = = >::rem(_self.into_inner(), rhs) + >>::add(_self.into_inner(), rhs) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::BVec2>::new(world) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, ) - .register( - "div", - |_self: Val, rhs: f32| { - let output: Val = >::div(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "rem", - |_self: Val, rhs: Val| { - let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "mul", - |_self: Val, rhs: f32| { - let output: Val = >::mul(_self.into_inner(), rhs) - .into(); - output - }, - ); - NamespaceBuilder::<::bevy::math::BVec2>::new(world) .register( "assert_receiver_is_total_eq", |_self: Ref| { @@ -13270,18 +13286,18 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::BVec3>::new(world) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, - ); - NamespaceBuilder::<::bevy::math::BVec3>::new(world) + ) .register( "new", |x: bool, y: bool, z: bool| { @@ -13354,26 +13370,36 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "clone", + "assert_receiver_is_total_eq", |_self: Ref| { - let output: Val = ::clone( + let output: () = ::assert_receiver_is_total_eq( &_self, ) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::BVec4>::new(world) .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( + "clone", + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, - ); - NamespaceBuilder::<::bevy::math::BVec4>::new(world) + ) + .register( + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) .register( "new", |x: bool, y: bool, z: bool, w: bool| { @@ -13441,42 +13467,92 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "clone", + "assert_receiver_is_total_eq", |_self: Ref| { - let output: Val = ::clone( + let output: () = ::assert_receiver_is_total_eq( &_self, ) .into(); output }, + ); + NamespaceBuilder::<::bevy::math::DVec2>::new(world) + .register( + "rem", + |_self: Val, rhs: f64| { + let output: Val = >::rem(_self.into_inner(), rhs) + .into(); + output + }, ) .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = >::eq(&_self, &other) + "div", + |_self: Val, rhs: Val| { + let output: Val = >::div(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( + "add", + |_self: Val, rhs: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, - ); - NamespaceBuilder::<::bevy::math::DVec2>::new(world) + ) .register( - "neg", - |_self: Val| { - let output: Val = ::neg( - _self.into_inner(), - ) + "rem", + |_self: Val, rhs: Ref| { + let output: Val = >::rem(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: f64| { + let output: Val = >::add(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: Ref| { + let output: Val = >::sub(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: Val| { + let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -13492,21 +13568,21 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "sub", - |_self: Val, rhs: f64| { - let output: Val = >::sub(_self.into_inner(), rhs) + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) .into(); output }, ) .register( - "div", - |_self: Val, rhs: f64| { - let output: Val = >::div(_self.into_inner(), rhs) + "add", + |_self: Val, rhs: Ref| { + let output: Val = >::add(_self.into_inner(), &rhs) .into(); output }, @@ -13522,21 +13598,11 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "rem", + "mul", |_self: Val, rhs: Ref| { - let output: Val = = >::rem(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "div", - |_self: Val, rhs: Val| { - let output: Val = >::div(_self.into_inner(), rhs.into_inner()) + >>::mul(_self.into_inner(), &rhs) .into(); output }, @@ -14370,36 +14436,6 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) - .register( - "mul", - |_self: Val, rhs: Ref| { - let output: Val = >::mul(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "sub", - |_self: Val, rhs: Val| { - let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, - ) .register( "rem", |_self: Val, rhs: Val| { @@ -14411,41 +14447,21 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "add", + "div", |_self: Val, rhs: f64| { - let output: Val = = >::add(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + >>::div(_self.into_inner(), rhs) .into(); output }, ) .register( - "rem", + "sub", |_self: Val, rhs: f64| { - let output: Val = = >::rem(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "add", - |_self: Val, rhs: Val| { - let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + >>::sub(_self.into_inner(), rhs) .into(); output }, @@ -14461,36 +14477,16 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "sub", - |_self: Val, rhs: Ref| { - let output: Val = >::sub(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "add", - |_self: Val, rhs: Ref| { - let output: Val = >::add(_self.into_inner(), &rhs) + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) .into(); output }, ); NamespaceBuilder::<::bevy::math::DVec3>::new(world) - .register( - "div", - |_self: Val, rhs: Ref| { - let output: Val = >::div(_self.into_inner(), &rhs) - .into(); - output - }, - ) .register( "neg", |_self: Val| { @@ -14503,30 +14499,10 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { ) .register( "div", - |_self: Val, rhs: f64| { - let output: Val = >::div(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "sub", |_self: Val, rhs: Ref| { - let output: Val = = >::sub(_self.into_inner(), &rhs) + >>::div(_self.into_inner(), &rhs) .into(); output }, @@ -15347,50 +15323,30 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { ) .register( "sub", - |_self: Val, rhs: f64| { + |_self: Val, rhs: Ref| { let output: Val = >::sub(_self.into_inner(), rhs) + &bevy::math::DVec3, + >>::sub(_self.into_inner(), &rhs) .into(); output }, ) .register( "rem", - |_self: Val, rhs: f64| { + |_self: Val, rhs: Ref| { let output: Val = >::rem(_self.into_inner(), rhs) + &bevy::math::DVec3, + >>::rem(_self.into_inner(), &rhs) .into(); output }, ) .register( - "div", + "add", |_self: Val, rhs: Val| { - let output: Val = >::div(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = = >::eq(&_self, &other) - .into(); - output - }, - ) - .register( - "rem", - |_self: Val, rhs: Ref| { - let output: Val = >::rem(_self.into_inner(), &rhs) + >>::add(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -15415,26 +15371,6 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) - .register( - "add", - |_self: Val, rhs: Ref| { - let output: Val = >::add(_self.into_inner(), &rhs) - .into(); - output - }, - ) - .register( - "mul", - |_self: Val, rhs: Ref| { - let output: Val = >::mul(_self.into_inner(), &rhs) - .into(); - output - }, - ) .register( "mul", |_self: Val, rhs: f64| { @@ -15446,21 +15382,21 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "rem", + "mul", |_self: Val, rhs: Val| { - let output: Val = = >::rem(_self.into_inner(), rhs.into_inner()) + >>::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "add", - |_self: Val, rhs: Val| { - let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + "rem", + |_self: Val, rhs: f64| { + let output: Val = >::rem(_self.into_inner(), rhs) .into(); output }, @@ -15474,104 +15410,104 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { .into(); output }, - ); - NamespaceBuilder::<::bevy::math::DVec4>::new(world) + ) .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = >::eq(&_self, &other) + "div", + |_self: Val, rhs: f64| { + let output: Val = >::div(_self.into_inner(), rhs) .into(); output }, ) .register( - "mul", - |_self: Val, rhs: Ref| { - let output: Val = >::mul(_self.into_inner(), &rhs) + "sub", + |_self: Val, rhs: f64| { + let output: Val = >::sub(_self.into_inner(), rhs) .into(); output }, ) .register( - "add", - |_self: Val, rhs: Val| { - let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + "div", + |_self: Val, rhs: Val| { + let output: Val = >::div(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "sub", - |_self: Val, rhs: f64| { - let output: Val = >::sub(_self.into_inner(), rhs) + "mul", + |_self: Val, rhs: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) .into(); output }, ) .register( - "div", - |_self: Val, rhs: f64| { - let output: Val = >::div(_self.into_inner(), rhs) + "add", + |_self: Val, rhs: Ref| { + let output: Val = >::add(_self.into_inner(), &rhs) .into(); output }, ) .register( - "div", - |_self: Val, rhs: Val| { - let output: Val = >::div(_self.into_inner(), rhs.into_inner()) + "rem", + |_self: Val, rhs: Val| { + let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "rem", - |_self: Val, rhs: Ref| { - let output: Val = >::rem(_self.into_inner(), &rhs) + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::DVec4>::new(world) .register( - "mul", - |_self: Val, rhs: f64| { - let output: Val = >::mul(_self.into_inner(), rhs) + "rem", + |_self: Val, rhs: Val| { + let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "rem", - |_self: Val, rhs: f64| { - let output: Val = >::rem(_self.into_inner(), rhs) + "sub", + |_self: Val, rhs: Ref| { + let output: Val = >::sub(_self.into_inner(), &rhs) .into(); output }, ) .register( - "add", + "rem", |_self: Val, rhs: Ref| { - let output: Val = = >::add(_self.into_inner(), &rhs) + >>::rem(_self.into_inner(), &rhs) .into(); output }, @@ -15586,16 +15522,6 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) .register( "div", |_self: Val, rhs: Ref| { @@ -15607,41 +15533,41 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "rem", + "div", |_self: Val, rhs: Val| { - let output: Val = = >::rem(_self.into_inner(), rhs.into_inner()) + >>::div(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "sub", - |_self: Val, rhs: Ref| { - let output: Val = >::sub(_self.into_inner(), &rhs) + "add", + |_self: Val, rhs: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, ) .register( - "neg", - |_self: Val| { - let output: Val = ::neg( - _self.into_inner(), - ) + "add", + |_self: Val, rhs: Ref| { + let output: Val = >::add(_self.into_inner(), &rhs) .into(); output }, @@ -16422,45 +16348,95 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { .into(); output }, - ); - NamespaceBuilder::<::bevy::math::Mat2>::new(world) + ) .register( "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + |_self: Val, rhs: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) .into(); output }, ) .register( - "div", - |_self: Val, rhs: f32| { - let output: Val = >::div(_self.into_inner(), rhs) + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) .into(); output }, ) .register( - "sub", - |_self: Val, rhs: Val| { - let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) + "div", + |_self: Val, rhs: f64| { + let output: Val = >::div(_self.into_inner(), rhs) .into(); output }, ) .register( - "from_cols", - |x_axis: Val, y_axis: Val| { - let output: Val = bevy::math::Mat2::from_cols( - x_axis.into_inner(), - y_axis.into_inner(), - ) + "sub", + |_self: Val, rhs: f64| { + let output: Val = >::sub(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: f64| { + let output: Val = >::mul(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: f64| { + let output: Val = >::rem(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::Mat2>::new(world) + .register( + "from_cols", + |x_axis: Val, y_axis: Val| { + let output: Val = bevy::math::Mat2::from_cols( + x_axis.into_inner(), + y_axis.into_inner(), + ) .into(); output }, @@ -16720,21 +16696,21 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "eq", - |_self: Ref, rhs: Ref| { - let output: bool = >::eq(&_self, &rhs) + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, ) .register( - "add", - |_self: Val, rhs: Val| { - let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -16750,66 +16726,66 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "mul", + "div", |_self: Val, rhs: f32| { - let output: Val = = >::mul(_self.into_inner(), rhs) + >>::div(_self.into_inner(), rhs) .into(); output }, ) .register( - "mul", + "sub", |_self: Val, rhs: Val| { - let output: Val = = >::mul(_self.into_inner(), rhs.into_inner()) + >>::sub(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + "mul", + |_self: Val, rhs: f32| { + let output: Val = >::mul(_self.into_inner(), rhs) .into(); output }, - ); - NamespaceBuilder::<::bevy::math::Mat3>::new(world) + ) .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + "add", + |_self: Val, rhs: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "add", - |_self: Val, rhs: Val| { - let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + "eq", + |_self: Ref, rhs: Ref| { + let output: bool = >::eq(&_self, &rhs) .into(); output }, ) .register( "mul", - |_self: Val, rhs: Val| { - let output: Val = , rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::Mat3>::new(world) .register( "from_cols", | @@ -17202,11 +17178,31 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "eq", - |_self: Ref, rhs: Ref| { - let output: bool = , rhs: f32| { + let output: Val = >::mul(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: Val| { + let output: Val = >::eq(&_self, &rhs) + >>::add(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, @@ -17221,41 +17217,51 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) + .register( + "eq", + |_self: Ref, rhs: Ref| { + let output: bool = >::eq(&_self, &rhs) + .into(); + output + }, + ) .register( "mul", - |_self: Val, rhs: Val| { - let output: Val = , rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + "div", + |_self: Val, rhs: f32| { + let output: Val = >::div(_self.into_inner(), rhs) .into(); output }, ) .register( - "sub", + "mul", |_self: Val, rhs: Val| { - let output: Val = = >::sub(_self.into_inner(), rhs.into_inner()) + >>::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( "mul", - |_self: Val, rhs: Val| { - let output: Val = , rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output @@ -17263,31 +17269,51 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { ) .register( "mul", - |_self: Val, rhs: f32| { - let output: Val = >::mul(_self.into_inner(), rhs) + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "div", - |_self: Val, rhs: f32| { - let output: Val = >::div(_self.into_inner(), rhs) + "sub", + |_self: Val, rhs: Val| { + let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) .into(); output }, ); NamespaceBuilder::<::bevy::math::Mat3A>::new(world) .register( - "div", - |_self: Val, rhs: f32| { - let output: Val = >::div(_self.into_inner(), rhs) + "sub", + |_self: Val, rhs: Val| { + let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -17302,6 +17328,46 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) + .register( + "mul", + |_self: Val, rhs: f32| { + let output: Val = >::mul(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: f32| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) .register( "mul", |_self: Val, rhs: Val| { @@ -17313,21 +17379,21 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "sub", + "mul", |_self: Val, rhs: Val| { - let output: Val = = >::sub(_self.into_inner(), rhs.into_inner()) + >>::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -17689,183 +17755,43 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { ) .into(); output - }, - ) - .register( - "abs_diff_eq", - | - _self: Ref, - rhs: Val, - max_abs_diff: f32| - { - let output: bool = bevy::math::Mat3A::abs_diff_eq( - &_self, - rhs.into_inner(), - max_abs_diff, - ) - .into(); - output - }, - ) - .register( - "abs", - |_self: Ref| { - let output: Val = bevy::math::Mat3A::abs(&_self) - .into(); - output - }, - ) - .register( - "as_dmat3", - |_self: Ref| { - let output: Val = bevy::math::Mat3A::as_dmat3( - &_self, - ) - .into(); - output - }, - ) - .register( - "mul", - |_self: Val, rhs: f32| { - let output: Val = >::mul(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "add", - |_self: Val, rhs: Val| { - let output: Val = >::add(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "neg", - |_self: Val| { - let output: Val = ::neg( - _self.into_inner(), - ) - .into(); - output - }, - ) - .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ); - NamespaceBuilder::<::bevy::math::Mat4>::new(world) - .register( - "eq", - |_self: Ref, rhs: Ref| { - let output: bool = >::eq(&_self, &rhs) - .into(); - output - }, - ) - .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "sub", - |_self: Val, rhs: Val| { - let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "div", - |_self: Val, rhs: f32| { - let output: Val = >::div(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "neg", - |_self: Val| { - let output: Val = ::neg( - _self.into_inner(), + }, + ) + .register( + "abs_diff_eq", + | + _self: Ref, + rhs: Val, + max_abs_diff: f32| + { + let output: bool = bevy::math::Mat3A::abs_diff_eq( + &_self, + rhs.into_inner(), + max_abs_diff, ) .into(); output }, ) .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + "abs", + |_self: Ref| { + let output: Val = bevy::math::Mat3A::abs(&_self) .into(); output }, ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( + "as_dmat3", + |_self: Ref| { + let output: Val = bevy::math::Mat3A::as_dmat3( &_self, ) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::Mat4>::new(world) .register( "from_cols", | @@ -18478,102 +18404,112 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "add", + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "mul", |_self: Val, rhs: Val| { - let output: Val = = >::add(_self.into_inner(), rhs.into_inner()) + >>::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( "mul", - |_self: Val, rhs: f32| { + |_self: Val, rhs: Val| { let output: Val = >::mul(_self.into_inner(), rhs) + bevy::math::Affine3A, + >>::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, - ); - NamespaceBuilder::<::bevy::math::DMat2>::new(world) + ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + "eq", + |_self: Ref, rhs: Ref| { + let output: bool = >::eq(&_self, &rhs) .into(); output }, ) .register( - "mul", - |_self: Val, rhs: f64| { - let output: Val = >::mul(_self.into_inner(), rhs) + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) .into(); output }, ) .register( - "div", - |_self: Val, rhs: f64| { - let output: Val = >::div(_self.into_inner(), rhs) + "sub", + |_self: Val, rhs: Val| { + let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + "div", + |_self: Val, rhs: f32| { + let output: Val = >::div(_self.into_inner(), rhs) .into(); output }, ) .register( "add", - |_self: Val, rhs: Val| { - let output: Val = , rhs: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "sub", - |_self: Val, rhs: Val| { - let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + |_self: Val, rhs: f32| { + let output: Val = >::mul(_self.into_inner(), rhs) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::DMat2>::new(world) .register( - "eq", - |_self: Ref, rhs: Ref| { - let output: bool = >::eq(&_self, &rhs) + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, @@ -18823,6 +18759,66 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) + .register( + "div", + |_self: Val, rhs: f64| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: Val| { + let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: f64| { + let output: Val = >::mul(_self.into_inner(), rhs) + .into(); + output + }, + ) .register( "neg", |_self: Val| { @@ -18832,24 +18828,34 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { .into(); output }, + ) + .register( + "eq", + |_self: Ref, rhs: Ref| { + let output: bool = >::eq(&_self, &rhs) + .into(); + output + }, ); NamespaceBuilder::<::bevy::math::DMat3>::new(world) .register( "mul", - |_self: Val, rhs: f64| { + |_self: Val, rhs: Val| { let output: Val = >::mul(_self.into_inner(), rhs) + bevy::math::DMat3, + >>::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + "eq", + |_self: Ref, rhs: Ref| { + let output: bool = >::eq(&_self, &rhs) .into(); output }, @@ -18864,16 +18870,6 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) - .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) .register( "sub", |_self: Val, rhs: Val| { @@ -19249,130 +19245,90 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "abs", - |_self: Ref| { - let output: Val = bevy::math::DMat3::abs(&_self) - .into(); - output - }, - ) - .register( - "as_mat3", - |_self: Ref| { - let output: Val = bevy::math::DMat3::as_mat3( - &_self, - ) - .into(); - output - }, - ) - .register( - "div", - |_self: Val, rhs: f64| { - let output: Val = >::div(_self.into_inner(), rhs) - .into(); - output - }, - ) - .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + "abs", + |_self: Ref| { + let output: Val = bevy::math::DMat3::abs(&_self) .into(); output }, ) .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + "as_mat3", + |_self: Ref| { + let output: Val = bevy::math::DMat3::as_mat3( + &_self, + ) .into(); output }, ) .register( - "eq", - |_self: Ref, rhs: Ref| { - let output: bool = >::eq(&_self, &rhs) + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "neg", - |_self: Val| { - let output: Val = ::neg( - _self.into_inner(), - ) + "mul", + |_self: Val, rhs: f64| { + let output: Val = >::mul(_self.into_inner(), rhs) .into(); output }, - ); - NamespaceBuilder::<::bevy::math::DMat4>::new(world) + ) .register( - "sub", - |_self: Val, rhs: Val| { - let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) + "div", + |_self: Val, rhs: f64| { + let output: Val = >::div(_self.into_inner(), rhs) .into(); output }, ) .register( "mul", - |_self: Val, rhs: Val| { - let output: Val = , rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) .into(); output }, ) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); output }, - ) - .register( - "eq", - |_self: Ref, rhs: Ref| { - let output: bool = >::eq(&_self, &rhs) - .into(); - output - }, - ) + ); + NamespaceBuilder::<::bevy::math::DMat4>::new(world) .register( "mul", - |_self: Val, rhs: f64| { + |_self: Val, rhs: Val| { let output: Val = >::mul(_self.into_inner(), rhs) + bevy::math::DMat4, + >>::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -19958,11 +19914,41 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "div", + "add", + |_self: Val, rhs: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "mul", |_self: Val, rhs: f64| { - let output: Val = = >::div(_self.into_inner(), rhs) + >>::mul(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: Val| { + let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -19978,16 +19964,66 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "add", - |_self: Val, rhs: Val| { - let output: Val = , rhs: Ref| { + let output: bool = >::add(_self.into_inner(), rhs.into_inner()) + >>::eq(&_self, &rhs) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: f64| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, ); NamespaceBuilder::<::bevy::math::Affine2>::new(world) + .register( + "eq", + |_self: Ref, rhs: Ref| { + let output: bool = >::eq(&_self, &rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) .register( "from_cols", | @@ -20183,11 +20219,11 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, @@ -20201,38 +20237,28 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::math::Affine3A>::new(world) .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, ) .register( - "eq", - |_self: Ref, rhs: Ref| { - let output: bool = >::eq(&_self, &rhs) + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ); - NamespaceBuilder::<::bevy::math::Affine3A>::new(world) .register( "from_cols", | @@ -20546,16 +20572,6 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) - .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) .register( "eq", |_self: Ref, rhs: Ref| { @@ -20564,24 +20580,14 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { >>::eq(&_self, &rhs) .into(); output - }, - ) - .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + }, + ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -20597,16 +20603,6 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) - .register( - "eq", - |_self: Ref, rhs: Ref| { - let output: bool = >::eq(&_self, &rhs) - .into(); - output - }, - ) .register( "clone", |_self: Ref| { @@ -20617,6 +20613,16 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) .register( "from_cols", | @@ -20802,26 +20808,16 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + "eq", + |_self: Ref, rhs: Ref| { + let output: bool = >::eq(&_self, &rhs) .into(); output }, ); NamespaceBuilder::<::bevy::math::DAffine3>::new(world) - .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) .register( "clone", |_self: Ref| { @@ -20842,6 +20838,16 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) .register( "from_cols", | @@ -21135,9 +21141,9 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { ) .register( "mul", - |_self: Val, rhs: Val| { - let output: Val = , rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output @@ -21146,50 +21152,20 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { NamespaceBuilder::<::bevy::math::DQuat>::new(world) .register( "mul", - |_self: Val, rhs: f64| { - let output: Val = >::mul(_self.into_inner(), rhs) + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, ) .register( - "add", + "mul", |_self: Val, rhs: Val| { - let output: Val = >::add(_self.into_inner(), rhs.into_inner()) - .into(); - output - }, - ) - .register( - "eq", - |_self: Ref, rhs: Ref| { - let output: bool = = >::eq(&_self, &rhs) - .into(); - output - }, - ) - .register( - "neg", - |_self: Val| { - let output: Val = ::neg( - _self.into_inner(), - ) - .into(); - output - }, - ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + >>::mul(_self.into_inner(), rhs.into_inner()) .into(); output }, @@ -21204,6 +21180,16 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) + .register( + "add", + |_self: Val, rhs: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) .register( "from_xyzw", |x: f64, y: f64, z: f64, w: f64| { @@ -21602,6 +21588,16 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) + .register( + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) + .into(); + output + }, + ) .register( "sub", |_self: Val, rhs: Val| { @@ -21614,20 +21610,30 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { ) .register( "mul", - |_self: Val, rhs: Val| { - let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + |_self: Val, rhs: f64| { + let output: Val = >::mul(_self.into_inner(), rhs) .into(); output }, ) .register( - "mul", - |_self: Val, rhs: Val| { - let output: Val = , rhs: Ref| { + let output: bool = >::mul(_self.into_inner(), rhs.into_inner()) + >>::eq(&_self, &rhs) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, @@ -21664,6 +21670,26 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ); NamespaceBuilder::<::bevy::math::BVec3A>::new(world) + .register( + "eq", + |_self: Ref, rhs: Ref| { + let output: bool = >::eq(&_self, &rhs) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "new", |x: bool, y: bool, z: bool| { @@ -21732,28 +21758,18 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { .into(); output }, - ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) + ); + NamespaceBuilder::<::bevy::math::BVec4A>::new(world) .register( "eq", - |_self: Ref, rhs: Ref| { - let output: bool = , rhs: Ref| { + let output: bool = >::eq(&_self, &rhs) .into(); output }, - ); - NamespaceBuilder::<::bevy::math::BVec4A>::new(world) + ) .register( "clone", |_self: Ref| { @@ -21833,18 +21849,18 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { .into(); output }, - ) + ); + NamespaceBuilder::<::smol_str::SmolStr>::new(world) .register( - "eq", - |_self: Ref, rhs: Ref| { - let output: bool = >::eq(&_self, &rhs) + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, - ); - NamespaceBuilder::<::smol_str::SmolStr>::new(world) + ) .register( "to_string", |_self: Ref| { @@ -21886,18 +21902,18 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { .into(); output }, - ) + ); + NamespaceBuilder::<::uuid::Uuid>::new(world) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) .into(); output }, - ); - NamespaceBuilder::<::uuid::Uuid>::new(world) + ) .register( "nil", || { @@ -21951,16 +21967,6 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { output }, ) - .register( - "assert_receiver_is_total_eq", - |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( - &_self, - ) - .into(); - output - }, - ) .register( "get_version_num", |_self: Ref| { @@ -22035,19 +22041,19 @@ impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { }, ) .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = >::eq(&_self, &other) - .into(); + "new_v4", + || { + let output: Val = uuid::Uuid::new_v4().into(); output }, ) .register( - "new_v4", - || { - let output: Val = uuid::Uuid::new_v4().into(); + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .into(); output }, ) 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 b3234e16ec..a74d5cac02 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 @@ -6,7 +6,13 @@ use super::bevy_ecs::*; use super::bevy_reflect::*; use bevy_mod_scripting_core::{ AddContextInitializer, StoreDocumentation, - bindings::{ReflectReference, function::from::{Ref, Mut, Val}}, + bindings::{ + ReflectReference, + function::{ + from::{Ref, Mut, Val}, + namespace::NamespaceBuilder, + }, + }, }; use crate::*; pub struct BevyTimeScriptingPlugin; @@ -46,6 +52,19 @@ impl ::bevy::app::Plugin for BevyTimeScriptingPlugin { output }, ) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) .register( "from_seconds", |duration: f32, mode: Val| { @@ -191,21 +210,18 @@ impl ::bevy::app::Plugin for BevyTimeScriptingPlugin { .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::time::prelude::TimerMode>::new(world) .register( - "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = >::eq(&_self, &other) + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) .into(); output }, - ); - NamespaceBuilder::<::bevy::time::prelude::TimerMode>::new(world) + ) .register( "eq", | @@ -228,16 +244,6 @@ impl ::bevy::app::Plugin for BevyTimeScriptingPlugin { .into(); output }, - ) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, ); NamespaceBuilder::<::bevy::time::prelude::Virtual>::new(world) .register( @@ -252,9 +258,9 @@ impl ::bevy::app::Plugin for BevyTimeScriptingPlugin { ); NamespaceBuilder::<::bevy::time::Stopwatch>::new(world) .register( - "assert_receiver_is_total_eq", + "clone", |_self: Ref| { - let output: () = ::assert_receiver_is_total_eq( + let output: Val = ::clone( &_self, ) .into(); @@ -313,21 +319,21 @@ impl ::bevy::app::Plugin for BevyTimeScriptingPlugin { }, ) .register( - "eq", - |_self: Ref, other: Ref| { - let output: bool = >::eq(&_self, &other) + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) .into(); output }, ) .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) .into(); output }, 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 5fc7357eeb..cab4d331d6 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 @@ -9,7 +9,13 @@ use super::bevy_math::*; use super::bevy_hierarchy::*; use bevy_mod_scripting_core::{ AddContextInitializer, StoreDocumentation, - bindings::{ReflectReference, function::from::{Ref, Mut, Val}}, + bindings::{ + ReflectReference, + function::{ + from::{Ref, Mut, Val}, + namespace::NamespaceBuilder, + }, + }, }; use crate::*; pub struct BevyTransformScriptingPlugin; @@ -17,29 +23,6 @@ impl ::bevy::app::Plugin for BevyTransformScriptingPlugin { fn build(&self, app: &mut ::bevy::prelude::App) { let mut world = app.world_mut(); NamespaceBuilder::<::bevy::transform::components::GlobalTransform>::new(world) - .register( - "clone", - |_self: Ref| { - let output: Val = ::clone( - &_self, - ) - .into(); - output - }, - ) - .register( - "eq", - | - _self: Ref, - other: Ref| - { - let output: bool = >::eq(&_self, &other) - .into(); - output - }, - ) .register( "from_xyz", |x: f32, y: f32, z: f32| { @@ -91,14 +74,14 @@ impl ::bevy::app::Plugin for BevyTransformScriptingPlugin { }, ) .register( - "mul", + "eq", | - _self: Val, - global_transform: Val| + _self: Ref, + other: Ref| { - let output: Val = >::mul(_self.into_inner(), global_transform.into_inner()) + >>::eq(&_self, &other) .into(); output }, @@ -115,12 +98,11 @@ impl ::bevy::app::Plugin for BevyTransformScriptingPlugin { .into(); output }, - ); - NamespaceBuilder::<::bevy::transform::components::Transform>::new(world) + ) .register( "clone", - |_self: Ref| { - let output: Val = ::clone( + |_self: Ref| { + let output: Val = ::clone( &_self, ) .into(); @@ -128,27 +110,28 @@ impl ::bevy::app::Plugin for BevyTransformScriptingPlugin { }, ) .register( - "eq", + "mul", | - _self: Ref, - other: Ref| + _self: Val, + global_transform: Val| { - let output: bool = >::eq(&_self, &other) + let output: Val = >::mul(_self.into_inner(), global_transform.into_inner()) .into(); output }, - ) + ); + NamespaceBuilder::<::bevy::transform::components::Transform>::new(world) .register( - "mul", + "eq", | - _self: Val, - global_transform: Val| + _self: Ref, + other: Ref| { - let output: Val = >::mul(_self.into_inner(), global_transform.into_inner()) + let output: bool = >::eq(&_self, &other) .into(); output }, @@ -255,6 +238,16 @@ impl ::bevy::app::Plugin for BevyTransformScriptingPlugin { output }, ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) .register( "mul", | @@ -267,6 +260,19 @@ impl ::bevy::app::Plugin for BevyTransformScriptingPlugin { .into(); output }, + ) + .register( + "mul", + | + _self: Val, + global_transform: Val| + { + let output: Val = >::mul(_self.into_inner(), global_transform.into_inner()) + .into(); + output + }, ); } } From f7ce25b4560b0864ab863d6f9709988b0955254f Mon Sep 17 00:00:00 2001 From: makspll Date: Sat, 11 Jan 2025 23:46:55 +0000 Subject: [PATCH 11/21] refactor function interface, reduce amount of string cloning, happy cows --- .../src/bindings/function/from.rs | 19 +- .../src/bindings/function/into.rs | 6 + .../src/bindings/function/mod.rs | 62 --- .../src/bindings/function/namespace.rs | 113 ++--- .../src/bindings/function/script_function.rs | 190 ++++++--- .../src/bindings/pretty_print.rs | 11 +- .../src/bindings/script_value.rs | 20 +- .../src/bindings/world.rs | 63 +-- crates/bevy_mod_scripting_core/src/error.rs | 25 +- .../src/test_functions.rs | 6 +- .../src/bindings/reference.rs | 385 +++++++++++------- .../src/bindings/script_value.rs | 45 +- .../src/bindings/reference.rs | 27 +- .../src/bindings/script_value.rs | 69 ++-- examples/game_of_life.rs | 10 +- 15 files changed, 595 insertions(+), 456 deletions(-) diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/from.rs b/crates/bevy_mod_scripting_core/src/bindings/function/from.rs index 9cd2c77bb9..e97a37990a 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/from.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/from.rs @@ -11,7 +11,7 @@ use std::{ path::PathBuf, }; -use super::script_function::DynamicScriptFunctionMut; +use super::script_function::{DynamicScriptFunction, DynamicScriptFunctionMut}; /// Describes the procedure for constructing a value of type `T` from a [`ScriptValue`]. /// @@ -393,6 +393,23 @@ where impl FromScript for DynamicScriptFunctionMut { type This<'w> = Self; + fn from_script(value: ScriptValue, _: WorldGuard<'_>) -> Result, InteropError> + where + Self: Sized, + { + match value { + ScriptValue::FunctionMut(f) => Ok(f), + _ => Err(InteropError::value_mismatch( + std::any::TypeId::of::(), + value, + )), + } + } +} + +impl FromScript for DynamicScriptFunction { + type This<'w> = Self; + fn from_script(value: ScriptValue, _: WorldGuard<'_>) -> Result, InteropError> where Self: Sized, diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/into.rs b/crates/bevy_mod_scripting_core/src/bindings/function/into.rs index d5ab5145b2..9dc44b4ab5 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/into.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/into.rs @@ -33,6 +33,12 @@ impl IntoScript for () { self_type_dependency_only!(()); impl IntoScript for DynamicScriptFunctionMut { + fn into_script(self, _world: WorldGuard) -> Result { + Ok(ScriptValue::FunctionMut(self)) + } +} + +impl IntoScript for DynamicScriptFunction { fn into_script(self, _world: WorldGuard) -> Result { Ok(ScriptValue::Function(self)) } diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/mod.rs b/crates/bevy_mod_scripting_core/src/bindings/function/mod.rs index dd2529cc05..b5d1a3251d 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/mod.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/mod.rs @@ -4,65 +4,3 @@ pub mod into; pub mod into_ref; pub mod namespace; pub mod script_function; - -use script_function::{CallerContext, DynamicScriptFunction, DynamicScriptFunctionMut}; - -use crate::error::InteropError; - -use super::{script_value::ScriptValue, WorldCallbackAccess, WorldGuard}; - -/// Can be implemented for callables which require dynamic access to the world to be called. -/// -/// The claim and release functions must be used to scope the access to the world such that function output . -pub trait CallScriptFunction { - fn call_script_function>( - &mut self, - args: I, - world: WorldGuard, - context: CallerContext, - ) -> Result; -} - -impl CallScriptFunction for DynamicScriptFunction { - fn call_script_function>( - &mut self, - args: I, - world: WorldGuard, - context: CallerContext, - ) -> Result { - let args = args.into_iter().collect::>(); - let world_callback_access = WorldCallbackAccess::from_guard(world.clone()); - // should we be inlining call errors into the return value? - let return_val = self.call(context, world_callback_access, args); - match return_val { - ScriptValue::Error(e) => Err(InteropError::function_interop_error( - self.name(), - context.self_type, - e, - )), - v => Ok(v), - } - } -} - -impl CallScriptFunction for DynamicScriptFunctionMut { - fn call_script_function>( - &mut self, - args: I, - world: WorldGuard, - context: CallerContext, - ) -> Result { - let args = args.into_iter().collect::>(); - let world_callback_access = WorldCallbackAccess::from_guard(world.clone()); - // should we be inlining call errors into the return value? - let return_val = self.call(context, world_callback_access, args); - match return_val { - ScriptValue::Error(e) => Err(InteropError::function_interop_error( - self.name(), - context.self_type, - e, - )), - v => Ok(v), - } - } -} diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/namespace.rs b/crates/bevy_mod_scripting_core/src/bindings/function/namespace.rs index 8def2c700a..8378458b21 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/namespace.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/namespace.rs @@ -1,6 +1,5 @@ use crate::bindings::function::script_function::{ AppScriptFunctionRegistry, DynamicScriptFunction, GetFunctionTypeDependencies, ScriptFunction, - ScriptFunctionRegistry, }; use bevy::{ prelude::{AppTypeRegistry, World}, @@ -53,10 +52,14 @@ pub trait GetNamespacedFunction { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] pub enum Namespace { - /// The function is registered in the global namespace, i.e. with no namespace + /// The function is registered in the global namespace, i.e. with no namespace. + /// In practice functions in this namespace should be callable directly by their name, i.e. `my_function()` + #[default] Global, - /// The function is registered in the namespace corresponding to the given type + /// The function is registered in the namespace corresponding to the given type. + /// In practice functions in this namespace should be callable by their qualified name, i.e. `MyType.my_function()` OnType(TypeId), } @@ -79,63 +82,61 @@ impl Namespace { } /// Returns the fully qualified name of a function in this namespace - pub fn function_name(self, name: Cow<'static, str>) -> Cow<'static, str> { + pub fn function_name>>(self, name: I) -> Cow<'static, str> { match self { - Namespace::Global => name, - Namespace::OnType(type_id) => Cow::Owned(format!("{:?}::{}", type_id, name)), + Namespace::Global => name.into(), + Namespace::OnType(type_id) => Cow::Owned(format!("{:?}::{}", type_id, name.into())), } } } -impl RegisterNamespacedFunction for ScriptFunctionRegistry { - fn register_namespaced_function(&mut self, name: N, function: F) - where - N: Into>, - S: IntoNamespace, - F: ScriptFunction<'static, M>, - { - let cow: Cow<'static, str> = name.into(); - let function_name = S::into_namespace().function_name(cow); - self.register(function_name, function); - } -} - -impl GetNamespacedFunction for ScriptFunctionRegistry { - fn iter_overloads_namespaced( - &self, - name: N, - namespace: Namespace, - ) -> impl Iterator - where - N: Into>, - { - let cow: Cow<'static, str> = name.into(); - let function_name = namespace.function_name(cow); - self.iter_overloads(function_name) - } - - fn get_namespaced_function( - &self, - name: N, - namespace: Namespace, - ) -> Option<&DynamicScriptFunction> - where - N: Into>, - { - let cow: Cow<'static, str> = name.into(); - let function_name = namespace.function_name(cow); - self.get_first(&function_name) - } - - fn has_namespaced_function(&self, name: N, namespace: Namespace) -> bool - where - N: Into>, - { - let cow: Cow<'static, str> = name.into(); - let function_name = namespace.function_name(cow); - self.contains(&function_name) - } -} +// impl RegisterNamespacedFunction for ScriptFunctionRegistry { +// fn register_namespaced_function(&mut self, name: N, function: F) +// where +// N: Into>, +// S: IntoNamespace, +// F: ScriptFunction<'static, M>, +// { +// self.register(S::into_namespace(), name, function); +// } +// } + +// impl GetNamespacedFunction for ScriptFunctionRegistry { +// fn iter_overloads_namespaced( +// &self, +// name: N, +// namespace: Namespace, +// ) -> impl Iterator +// where +// N: Into>, +// { +// let cow: Cow<'static, str> = name.into(); +// let function_name = namespace.function_name(cow); +// self.iter_overloads(function_name) +// } + +// fn get_namespaced_function( +// &self, +// name: N, +// namespace: Namespace, +// ) -> Option<&DynamicScriptFunction> +// where +// N: Into>, +// { +// let cow: Cow<'static, str> = name.into(); +// let function_name = namespace.function_name(cow); +// self.get_first(&function_name) +// } + +// fn has_namespaced_function(&self, name: N, namespace: Namespace) -> bool +// where +// N: Into>, +// { +// let cow: Cow<'static, str> = name.into(); +// let function_name = namespace.function_name(cow); +// self.contains(&function_name) +// } +// } pub struct NamespaceBuilder<'a, N> { namespace: PhantomData, @@ -179,7 +180,7 @@ impl<'a, S: IntoNamespace> NamespaceBuilder<'a, S> { .world .get_resource_or_init::(); let mut registry = registry.write(); - registry.register_namespaced_function::(name, function); + registry.register(S::into_namespace(), name, function); } { let type_registry = self.world.get_resource_or_init::(); diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs b/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs index 17217b2047..e7697cdac7 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs @@ -1,8 +1,8 @@ -use super::{from::FromScript, into::IntoScript}; +use super::{from::FromScript, into::IntoScript, namespace::Namespace}; use crate::{ bindings::{ function::from::{Mut, Ref, Val}, - ReflectReference, + ReflectReference, WorldGuard, }, error::InteropError, ScriptValue, WorldCallbackAccess, @@ -15,11 +15,11 @@ use bevy::{ }, }; use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard}; +use std::borrow::Cow; use std::collections::HashMap; use std::hash::Hash; use std::ops::{Deref, DerefMut}; use std::sync::Arc; -use std::{any::TypeId, borrow::Cow}; #[diagnostic::on_unimplemented( message = "Only functions with all arguments impplementing FromScript and return values supporting IntoScript are supported. Registering functions also requires they implement GetInnerTypeDependencies", @@ -120,13 +120,12 @@ pub trait GetFunctionTypeDependencies { #[reflect(opaque)] pub struct CallerContext { pub convert_to_0_indexed: bool, - pub self_type: Option, } #[derive(Clone, Debug, PartialEq, Default)] pub struct FunctionInfo { pub name: Cow<'static, str>, - pub on_type: Option, + pub namespace: Namespace, } impl FunctionInfo { @@ -136,8 +135,8 @@ impl FunctionInfo { } /// If the function is namespaced to a specific type, this will return the type id of that type - pub fn on_type(&self) -> Option { - self.on_type + pub fn namespace(&self) -> Namespace { + self.namespace } } @@ -183,13 +182,27 @@ impl PartialEq for DynamicScriptFunctionMut { } impl DynamicScriptFunction { - pub fn call( + /// Call the function with the given arguments and caller context. + /// + /// In the case of errors wraps the error in a [`InteropError::function_interop_error`] to provide more context. + pub fn call>( &self, + args: I, + world: WorldGuard, context: CallerContext, - world: WorldCallbackAccess, - args: Vec, - ) -> ScriptValue { - (self.func)(context, world, args) + ) -> Result { + let args = args.into_iter().collect::>(); + let world_callback_access = WorldCallbackAccess::from_guard(world.clone()); + // should we be inlining call errors into the return value? + let return_val = (self.func)(context, world_callback_access, args); + match return_val { + ScriptValue::Error(e) => Err(InteropError::function_interop_error( + self.name(), + self.info.namespace(), + e, + )), + v => Ok(v), + } } pub fn name(&self) -> &Cow<'static, str> { @@ -206,10 +219,10 @@ impl DynamicScriptFunction { } } - pub fn with_on_type(self, on_type: Option) -> Self { + pub fn with_namespace(self, namespace: Namespace) -> Self { Self { info: FunctionInfo { - on_type, + namespace, ..self.info }, func: self.func, @@ -218,16 +231,29 @@ impl DynamicScriptFunction { } impl DynamicScriptFunctionMut { - pub fn call( + /// Call the function with the given arguments and caller context. + /// + /// In the case of errors wraps the error in a [`InteropError::function_interop_error`] to provide more context. + pub fn call>( &self, + args: I, + world: WorldGuard, context: CallerContext, - world: WorldCallbackAccess, - args: Vec, - ) -> ScriptValue { + ) -> Result { + let args = args.into_iter().collect::>(); + let world_callback_access = WorldCallbackAccess::from_guard(world.clone()); + // should we be inlining call errors into the return value? let mut write = self.func.write(); - write(context, world, args) + let return_val = (write)(context, world_callback_access, args); + match return_val { + ScriptValue::Error(e) => Err(InteropError::function_interop_error( + self.name(), + self.info.namespace(), + e, + )), + v => Ok(v), + } } - pub fn name(&self) -> &Cow<'static, str> { &self.info.name } @@ -242,10 +268,10 @@ impl DynamicScriptFunctionMut { } } - pub fn with_on_type(self, on_type: Option) -> Self { + pub fn with_namespace(self, namespace: Namespace) -> Self { Self { info: FunctionInfo { - on_type, + namespace, ..self.info }, func: self.func, @@ -332,38 +358,55 @@ impl ScriptFunctionRegistryArc { } } +#[derive(Debug, PartialEq, Eq, Hash)] +struct FunctionKey { + name: Cow<'static, str>, + namespace: Namespace, +} + #[derive(Debug, Default)] pub struct ScriptFunctionRegistry { - functions: HashMap, DynamicScriptFunction>, + functions: HashMap, } impl ScriptFunctionRegistry { /// Register a script function with the given name. If the name already exists, /// the new function will be registered as an overload of the function. - pub fn register(&mut self, name: impl Into>, func: F) - where + pub fn register( + &mut self, + namespace: Namespace, + name: impl Into>, + func: F, + ) where F: ScriptFunction<'static, M>, { - self.register_overload(name, func); + self.register_overload(namespace, name, func); } - fn register_overload(&mut self, name: impl Into>, func: F) - where + fn register_overload( + &mut self, + namespace: Namespace, + name: impl Into>, + func: F, + ) where F: ScriptFunction<'static, M>, { // always start with non-suffixed registration - let name = name.into().clone(); - - if !self.contains(&name) { - let func = func.into_dynamic_script_function().with_name(name.clone()); - self.functions.insert(name, func); + // TODO: we do alot of string work, can we make this all more efficient? + let name: Cow<'static, str> = name.into(); + if !self.contains(namespace, name.clone()) { + let func = func + .into_dynamic_script_function() + .with_name(name.clone()) + .with_namespace(namespace); + self.functions.insert(FunctionKey { name, namespace }, func); return; } for i in 1..16 { let overload = format!("{name}-{i}"); - if !self.contains(&overload) { - self.register(overload, func); + if !self.contains(namespace, overload.clone()) { + self.register(namespace, overload, func); return; } } @@ -373,30 +416,54 @@ impl ScriptFunctionRegistry { ); } - pub fn contains(&self, name: impl AsRef) -> bool { - self.functions.contains_key(name.as_ref()) + pub fn contains(&self, namespace: Namespace, name: impl Into>) -> bool { + self.functions.contains_key(&FunctionKey { + name: name.into(), + namespace, + }) } - pub fn get_first(&self, name: impl AsRef) -> Option<&DynamicScriptFunction> { - self.functions.get(name.as_ref()) + /// Get the first overload for the function with the given name and namespace + pub fn get_function( + &self, + namespace: Namespace, + name: impl Into>, + ) -> Result<&DynamicScriptFunction, Cow<'static, str>> { + let name = name.into(); + let key = FunctionKey { name, namespace }; + if let Some(func) = self.functions.get(&key) { + Ok(func) + } else { + Err(key.name) + } } + /// Iterate over all overloads for the function with the given name and namespace + /// If the iterator variant is returned it is guaranteed to contain at least one element pub fn iter_overloads( &self, + namespace: Namespace, name: impl Into>, - ) -> impl Iterator { - let name = name.into(); - (0..16) + ) -> Result, Cow<'static, str>> { + let name: Cow<'static, str> = name.into(); + let seed = match self.get_function(namespace, name.clone()) { + Ok(func) => std::iter::once(func), + Err(name) => return Err(name), + }; + + let overloads = (1..16) .map(move |i| { if i == 0 { - self.functions.get(&name) + self.get_function(namespace, name.clone()) } else { let name: Cow<'static, str> = format!("{}-{i}", name).into(); - self.functions.get(&name) + self.get_function(namespace, name) } }) - .take_while(|o| o.is_some()) - .map(|o| o.unwrap()) + .take_while(|o| o.is_ok()) + .map(|o| o.unwrap()); + + Ok(seed.chain(overloads)) } } @@ -529,20 +596,39 @@ mod test { fn test_register_script_function() { let mut registry = ScriptFunctionRegistry::default(); let fn_ = |a: usize, b: usize| a + b; - registry.register("test", fn_); - registry.get_first("test").expect("Failed to get function"); + let namespace = Namespace::Global; + registry.register(namespace, "test", fn_); + let function = registry + .get_function(namespace, "test") + .expect("Failed to get function"); + + assert_eq!(function.info.name(), "test"); + assert_eq!(function.info.namespace(), namespace); } #[test] fn test_overloaded_script_function() { let mut registry = ScriptFunctionRegistry::default(); let fn_ = |a: usize, b: usize| a + b; - registry.register("test", fn_); + let namespace = Namespace::Global; + registry.register(namespace, "test", fn_); let fn_2 = |a: usize, b: i32| a + (b as usize); - registry.register("test", fn_2); + registry.register(namespace, "test", fn_2); + + let first_function = registry + .get_function(namespace, "test") + .expect("Failed to get function"); + + assert_eq!(first_function.info.name(), "test"); + assert_eq!(first_function.info.namespace(), namespace); - registry.get_first("test").expect("Failed to get function"); + let all_functions = registry + .iter_overloads(namespace, "test") + .expect("Failed to get overloads") + .collect::>(); - assert_eq!(registry.iter_overloads("test").collect::>().len(), 2); + assert_eq!(all_functions.len(), 2); + assert_eq!(all_functions[0].info.name(), "test"); + assert_eq!(all_functions[1].info.name(), "test-1"); } } diff --git a/crates/bevy_mod_scripting_core/src/bindings/pretty_print.rs b/crates/bevy_mod_scripting_core/src/bindings/pretty_print.rs index a9ebb8143b..c7faba4d64 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/pretty_print.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/pretty_print.rs @@ -313,6 +313,11 @@ impl ReflectReferencePrinter { /// For types which can't be pretty printed without world access. /// Implementors should try to print the best value they can, and never panick. pub trait DisplayWithWorld: std::fmt::Debug { + /// # Warning + /// Display this type without world access. It is not recommended to use this method for anything other than debugging or necessary trait impl corners. + /// For many types this will just print type id's with no further information. + /// + /// Prefer using [`DisplayWithWorld::display_with_world`] or [`DisplayWithWorld::display_value_with_world`] instead. fn display_without_world(&self) -> String; /// Display the `shallowest` representation of the type using world access. @@ -399,6 +404,7 @@ impl DisplayWithWorld for ScriptValue { fn display_value_with_world(&self, world: WorldGuard) -> String { match self { ScriptValue::Reference(r) => r.display_value_with_world(world), + ScriptValue::FunctionMut(f) => format!("FunctionMut({})", f.name()), ScriptValue::Function(f) => format!("Function({})", f.name()), ScriptValue::Unit => "()".to_owned(), ScriptValue::Bool(b) => b.to_string(), @@ -428,9 +434,12 @@ impl DisplayWithWorld for ScriptValue { string } ScriptValue::Reference(reflect_reference) => reflect_reference.display_without_world(), - ScriptValue::Function(dynamic_script_function_mut) => { + ScriptValue::FunctionMut(dynamic_script_function_mut) => { format!("Function({})", dynamic_script_function_mut.name()) } + ScriptValue::Function(dynamic_script_function) => { + format!("Function({})", dynamic_script_function.name()) + } ScriptValue::Error(interop_error) => interop_error.display_without_world(), } } diff --git a/crates/bevy_mod_scripting_core/src/bindings/script_value.rs b/crates/bevy_mod_scripting_core/src/bindings/script_value.rs index cbf8ea3655..9cbf5b7167 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/script_value.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/script_value.rs @@ -4,7 +4,10 @@ use bevy::reflect::{OffsetAccess, ParsedPath, Reflect}; use crate::error::InteropError; -use super::{function::script_function::DynamicScriptFunctionMut, ReflectReference}; +use super::{ + function::script_function::{DynamicScriptFunction, DynamicScriptFunctionMut}, + ReflectReference, +}; /// An abstraction of values that can be passed to and from scripts. /// This allows us to re-use logic between scripting languages. @@ -25,13 +28,23 @@ pub enum ScriptValue { List(Vec), /// Represents a reference to a value. Reference(ReflectReference), - /// A dynamic script function - Function(DynamicScriptFunctionMut), + /// A dynamic script function possibly storing state. Preffer using the [`ScriptValue::Function`] variant instead if possible. + FunctionMut(DynamicScriptFunctionMut), + /// A stateless dynamic script function + Function(DynamicScriptFunction), /// Represents any error, will be thrown when returned to a script Error(InteropError), } impl ScriptValue { + /// Returns the contained string if this is a string variant otherwise returns the original value. + pub fn as_string(self) -> Result, Self> { + match self { + ScriptValue::String(s) => Ok(s), + other => Err(other), + } + } + pub fn type_name(&self) -> String { match self { ScriptValue::Unit => "Unit".to_owned(), @@ -41,6 +54,7 @@ impl ScriptValue { ScriptValue::String(_) => "String".to_owned(), ScriptValue::List(_) => "List".to_owned(), ScriptValue::Reference(_) => "Reference".to_owned(), + ScriptValue::FunctionMut(_) => "FunctionMut".to_owned(), ScriptValue::Function(_) => "Function".to_owned(), ScriptValue::Error(_) => "Error".to_owned(), } diff --git a/crates/bevy_mod_scripting_core/src/bindings/world.rs b/crates/bevy_mod_scripting_core/src/bindings/world.rs index 99b40a6f24..516a3f22ea 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/world.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/world.rs @@ -7,6 +7,7 @@ use super::{ access_map::{AccessCount, AccessMap, ReflectAccessId}, + function::script_function::AppScriptFunctionRegistry, AppReflectAllocator, ReflectBase, ReflectBaseType, ReflectReference, ScriptTypeRegistration, }; use crate::{error::InteropError, with_access_read, with_access_write, with_global_access}; @@ -234,6 +235,7 @@ pub(crate) struct WorldAccessGuardInner<'w> { /// Cached for convenience, since we need it for most operations, means we don't need to lock the type registry every time type_registry: TypeRegistryArc, allocator: AppReflectAllocator, + function_registry: AppScriptFunctionRegistry, } impl<'w> WorldAccessGuard<'w> { @@ -250,11 +252,17 @@ impl<'w> WorldAccessGuard<'w> { .expect("Reflect allocator not present, cannot create world access guard") .clone(); + let function_registry = world + .get_resource::() + .expect("Function registry not present, cannot create world access guard") + .clone(); + Self(Arc::new(WorldAccessGuardInner { cell: world.as_unsafe_world_cell(), accesses: Default::default(), allocator, type_registry, + function_registry, })) } @@ -339,63 +347,20 @@ impl<'w> WorldAccessGuard<'w> { self.0.accesses.release_global_access() } + /// Returns the type registry for the world pub fn type_registry(&self) -> TypeRegistryArc { self.0.type_registry.clone() } + /// Returns the script allocator for the world pub fn allocator(&self) -> AppReflectAllocator { self.0.allocator.clone() } - // #[track_caller] - // /// Call a function on a type which can be proxied, first by unproxying the input with world access, - // /// then calling the function and finally proxying the output with the allocator. - // pub fn proxy_call<'i, O: Proxy, T: Unproxy, F: Fn(T::Output<'_>) -> O::Input<'i>>( - // &self, - // proxied_input: T, - // f: F, - // ) -> ScriptResult { - // self.try_proxy_call(proxied_input, |o| Ok::<_, ScriptError>(f(o))) - // } - - // pub fn try_proxy_call< - // 'i, - // O: Proxy, - // E: Into>, - // T: Unproxy, - // F: Fn(T::Output<'_>) -> Result, E>, - // >( - // &self, - // mut proxied_input: T, - // f: F, - // ) -> ScriptResult { - // let type_registry = self.type_registry(); - // let type_registry = type_registry.read(); - - // let app_allocator = self.allocator(); - - // let output = (|| { - // let unproxied_input = { - // let allocator = app_allocator.read(); - // proxied_input.collect_accesses(self)?; - // unsafe { proxied_input.unproxy_with_world(self, &type_registry, &allocator) }? - // }; - - // let out = f(unproxied_input).map_err(|e| { - // let e: Box = e.into(); - // ScriptError::new_generic_error(e) - // })?; - - // let mut allocator = app_allocator.write(); - // let proxied_output = O::proxy_with_allocator(out, &mut allocator)?; - // Ok(proxied_output) - // })(); - - // // make sure to release all accesses - // proxied_input.release_accesses(self); - - // output - // } + /// Returns the function registry for the world + pub fn script_function_registry(&self) -> AppScriptFunctionRegistry { + self.0.function_registry.clone() + } /// Safely accesses the resource by claiming and releasing access to it. /// diff --git a/crates/bevy_mod_scripting_core/src/error.rs b/crates/bevy_mod_scripting_core/src/error.rs index e8902de562..d332d92853 100644 --- a/crates/bevy_mod_scripting_core/src/error.rs +++ b/crates/bevy_mod_scripting_core/src/error.rs @@ -1,6 +1,6 @@ use crate::bindings::{ - access_map::DisplayCodeLocation, pretty_print::DisplayWithWorld, script_value::ScriptValue, - ReflectBaseType, ReflectReference, + access_map::DisplayCodeLocation, function::namespace::Namespace, + pretty_print::DisplayWithWorld, script_value::ScriptValue, ReflectBaseType, ReflectReference, }; use bevy::{ ecs::component::ComponentId, @@ -382,11 +382,7 @@ impl InteropError { } /// Thrown when an error happens in a function call. The inner error provides details on the error. - pub fn function_interop_error( - function_name: &str, - on: Option, - error: InteropError, - ) -> Self { + pub fn function_interop_error(function_name: &str, on: Namespace, error: InteropError) -> Self { Self(Arc::new(InteropErrorInner::FunctionInteropError { function_name: function_name.to_string(), on, @@ -530,7 +526,7 @@ pub enum InteropErrorInner { }, FunctionInteropError { function_name: String, - on: Option, + on: Namespace, error: InteropError, }, FunctionArgConversionError { @@ -667,7 +663,10 @@ impl DisplayWithWorld for InteropErrorInner { "Missing world. The world was not initialized in the script context.".to_owned() }, InteropErrorInner::FunctionInteropError { function_name, on, error } => { - let opt_on = on.map(|t| format!("on type: {}", t.display_with_world(world.clone()))).unwrap_or_default(); + let opt_on = match on { + Namespace::Global => "".to_owned(), + Namespace::OnType(type_id) => format!("on type: {}", type_id.display_with_world(world.clone())), + }; let display_name = if function_name.starts_with("TypeId") { function_name.split("::").last().unwrap() } else { @@ -703,7 +702,7 @@ impl DisplayWithWorld for InteropErrorInner { } } - // todo macro this + // todo macro this, or use format strings to reduce duplication fn display_without_world(&self) -> String { match self { InteropErrorInner::MissingFunctionError { on, function_name } => { @@ -822,8 +821,10 @@ impl DisplayWithWorld for InteropErrorInner { "Missing world. The world was not initialized in the script context.".to_owned() }, InteropErrorInner::FunctionInteropError { function_name, on, error } => { - let opt_on = on.map(|t| format!("on type: {}", t.display_without_world())).unwrap_or_default(); - let display_name = if function_name.starts_with("TypeId") { + let opt_on = match on { + Namespace::Global => "".to_owned(), + Namespace::OnType(type_id) => format!("on type: {}", type_id.display_without_world()), + }; let display_name = if function_name.starts_with("TypeId") { function_name.split("::").last().unwrap() } else { function_name.as_str() diff --git a/crates/bevy_mod_scripting_functions/src/test_functions.rs b/crates/bevy_mod_scripting_functions/src/test_functions.rs index b1a11786c1..70229c78dd 100644 --- a/crates/bevy_mod_scripting_functions/src/test_functions.rs +++ b/crates/bevy_mod_scripting_functions/src/test_functions.rs @@ -10,7 +10,6 @@ use bevy_mod_scripting_core::{ function::{ namespace::NamespaceBuilder, script_function::{CallerContext, DynamicScriptFunctionMut}, - CallScriptFunction, }, pretty_print::DisplayWithWorld, ReflectReference, ScriptTypeRegistration, WorldCallbackAccess, @@ -52,11 +51,10 @@ pub fn register_test_functions(world: &mut App) { ) .register( "_assert_throws", - |s: WorldCallbackAccess, mut f: DynamicScriptFunctionMut, reg: String| { + |s: WorldCallbackAccess, f: DynamicScriptFunctionMut, reg: String| { let world = s.try_read().unwrap(); - let result = - f.call_script_function(vec![], world.clone(), CallerContext::default()); + let result = f.call(vec![], world.clone(), CallerContext::default()); let err = match result { Ok(_) => { return Err(InteropError::external_error( diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs index d34b431fbf..e41ca5f95c 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs @@ -1,11 +1,7 @@ -use super::script_value::LuaScriptValue; -use crate::bindings::script_value::lua_caller_context; +use super::script_value::{LuaScriptValue, LUA_CALLER_CONTEXT}; use bevy_mod_scripting_core::{ bindings::{ - function::{ - script_function::{AppScriptFunctionRegistry, DynamicScriptFunction}, - CallScriptFunction, - }, + function::{namespace::Namespace, script_function::DynamicScriptFunction}, pretty_print::DisplayWithWorld, script_value::ScriptValue, ReflectReference, ThreadWorldContainer, WorldContainer, WorldGuard, @@ -13,9 +9,8 @@ use bevy_mod_scripting_core::{ error::InteropError, reflection_extensions::TypeIdExtensions, }; -use bevy_mod_scripting_functions::{namespaced_register::Namespace, GetNamespacedFunction}; -use mlua::{Function, IntoLua, Lua, MetaMethod, UserData, UserDataMethods, Variadic}; -use std::any::TypeId; +use mlua::{MetaMethod, UserData, UserDataMethods}; +use std::{any::TypeId, borrow::Cow}; /// Lua UserData wrapper for [`bevy_mod_scripting_core::bindings::ReflectReference`]. /// Acts as a lua reflection interface. Any value which is registered in the type registry can be interacted with using this type. @@ -40,250 +35,329 @@ impl From for LuaReflectReference { } } -/// Looks up a function in the registry on the given type id -fn lookup_function(lua: &Lua, key: &str, type_id: TypeId) -> Option> { - let function = lookup_dynamic_function(lua, key, type_id); - - function.map(|mut function| { - lua.create_function_mut(move |_lua, args: Variadic| { - let world = ThreadWorldContainer.get_world(); - let out = function.call_script_function( - args.into_iter().map(Into::into), - world, - lua_caller_context(Some(type_id)), - )?; - - Ok(LuaScriptValue::from(out)) - }) - }) -} - -fn lookup_function_typed( - lua: &Lua, - key: &str, -) -> Option> { - let type_id = TypeId::of::(); - lookup_function(lua, key, type_id) -} - -fn lookup_dynamic_function( - _lua: &Lua, - key: &str, - type_id: TypeId, -) -> Option { - let function_registry = ThreadWorldContainer - .get_world() - .with_resource(|registry: &AppScriptFunctionRegistry| registry.clone()); - let registry = function_registry.read(); - - registry - .get_namespaced_function(key.to_string(), Namespace::OnType(type_id)) - .cloned() -} - -fn lookup_dynamic_function_typed( - lua: &Lua, - key: &str, -) -> Option { - let type_id = TypeId::of::(); - lookup_dynamic_function(lua, key, type_id) -} - -fn iter_dynamic_function_overloads( - _lua: &Lua, - key: &str, - type_id: TypeId, -) -> impl Iterator { - let registry = ThreadWorldContainer - .get_world() - .with_resource(|registry: &AppScriptFunctionRegistry| registry.clone()); +// Looks up a function in the registry on the given type id +// fn lookup_function(lua: &Lua, key: &str, type_id: TypeId) -> Option> { +// let function = lookup_dynamic_function(lua, key, type_id); + +// function.map(|mut function| { +// lua.create_function_mut(move |_lua, args: Variadic| { +// let world = ThreadWorldContainer.get_world(); +// let out = function.call_script_function( +// args.into_iter().map(Into::into), +// world, +// LUA_CALLER_CONTEXT, +// )?; + +// Ok(LuaScriptValue::from(out)) +// }) +// }) +// } + +// fn lookup_function_typed( +// lua: &Lua, +// key: &str, +// ) -> Option> { +// let type_id = TypeId::of::(); +// lookup_function(lua, key, type_id) +// } + +// fn lookup_dynamic_function( +// _lua: &Lua, +// key: &str, +// type_id: TypeId, +// ) -> Option { +// let function_registry = ThreadWorldContainer +// .get_world() +// .with_resource(|registry: &AppScriptFunctionRegistry| registry.clone()); +// let registry = function_registry.read(); + +// registry +// .get_function(Namespace::OnType(type_id), key.to_string()) +// .cloned() +// } + +// fn lookup_dynamic_function_typed( +// lua: &Lua, +// key: &str, +// ) -> Option { +// let type_id = TypeId::of::(); +// lookup_dynamic_function(lua, key, type_id) +// } + +// fn iter_dynamic_function_overloads( +// _lua: &Lua, +// key: &str, +// type_id: TypeId, +// ) -> impl Iterator { +// let registry = ThreadWorldContainer +// .get_world() +// .with_resource(|registry: &AppScriptFunctionRegistry| registry.clone()); +// let registry = registry.read(); + +// registry +// .iter_overloads(Namespace::OnType(type_id), key.to_string()) +// .cloned() +// .collect::>() +// .into_iter() +// } + +// fn try_call_overloads( +// lua: &Lua, +// key: &str, +// type_id: TypeId, +// args: Vec, +// world: WorldGuard, +// ) -> Result { +// let overloads = iter_dynamic_function_overloads(lua, key, type_id); +// let mut last_error = None; +// for mut overload in overloads { +// match overload.call_script_function( +// args.clone(), +// world.clone(), +// lua_caller_context(Some(type_id)), +// ) { +// Ok(out) => return Ok(out.into()), +// Err(e) => last_error = Some(e), +// } +// } + +// Err(last_error.unwrap_or_else(|| InteropError::missing_function(type_id, key.to_string()))) +// } + +/// Look up a function on the given type ids +fn lookup_function( + guard: WorldGuard, + type_ids: impl IntoIterator, + name: impl Into>, +) -> Result> { + let registry = guard.script_function_registry(); let registry = registry.read(); - registry - .iter_overloads_namespaced(key.to_string(), Namespace::OnType(type_id)) - .cloned() - .collect::>() - .into_iter() + let mut name = name.into(); + for type_id in type_ids { + name = match registry.get_function(Namespace::OnType(type_id), name) { + Ok(func) => return Ok(func.clone()), + Err(name) => name, + }; + } + + Err(name) } fn try_call_overloads( - lua: &Lua, - key: &str, + guard: WorldGuard, type_id: TypeId, + name: impl Into>, args: Vec, - world: WorldGuard, ) -> Result { - let overloads = iter_dynamic_function_overloads(lua, key, type_id); + let registry = guard.script_function_registry(); + let registry = registry.read(); + + let name = name.into(); + let overload_iter = match registry.iter_overloads(Namespace::OnType(type_id), name) { + Ok(iter) => iter, + Err(name) => return Err(InteropError::missing_function(type_id, name.to_string())), + }; + let mut last_error = None; - for mut overload in overloads { - match overload.call_script_function( - args.clone(), - world.clone(), - lua_caller_context(Some(type_id)), - ) { + for overload in overload_iter { + match overload.call(args.clone(), guard.clone(), LUA_CALLER_CONTEXT) { Ok(out) => return Ok(out.into()), Err(e) => last_error = Some(e), } } - Err(last_error.unwrap_or_else(|| InteropError::missing_function(type_id, key.to_string()))) + Err(last_error.expect("invariant, iterator should always return at least one item, and if the call fails it should return an error")) } impl UserData for LuaReflectReference { fn add_methods>(m: &mut T) { m.add_meta_function( MetaMethod::Index, - |lua, (self_, key): (LuaReflectReference, LuaScriptValue)| { + |_, (self_, key): (LuaReflectReference, LuaScriptValue)| { let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let key: ScriptValue = key.into(); - - if let ScriptValue::String(ref key) = key { - if let Some(func) = lookup_function(lua, key, type_id) { - return func?.into_lua(lua); - } - // try look up the function under the reflect reference namespace as well - if let Some(func) = lookup_function_typed::(lua, key) { - return func?.into_lua(lua); + let key = match key.as_string() { + Ok(string) => { + match lookup_function( + world.clone(), + [type_id, TypeId::of::()], + string, + ) { + Ok(func) => return Ok(LuaScriptValue(ScriptValue::Function(func))), + + Err(e) => ScriptValue::String(e), + } } + Err(key) => key, }; - // lookup get index function - let mut index_func = lookup_dynamic_function_typed::(lua, "get") - .expect("No 'get' function registered for a ReflectReference"); - + let func = + lookup_function(world.clone(), [TypeId::of::()], "get") + .expect("No 'get' function registered for a ReflectReference"); // call the function with the key - let out = index_func.call_script_function( + let out = func.call( vec![ScriptValue::Reference(self_), key], - world.clone(), - lua_caller_context(Some(std::any::TypeId::of::())), + world, + LUA_CALLER_CONTEXT, )?; - LuaScriptValue::from(out).into_lua(lua) + Ok(LuaScriptValue(out)) + // // call the function with the key + // let out = index_func.call_script_function( + // vec![ScriptValue::Reference(self_), key], + // world.clone(), + // lua_caller_context(Some(std::any::TypeId::of::())), + // )?; + // LuaScriptValue::from(out).into_lua(lua) }, ); m.add_meta_function( MetaMethod::NewIndex, - |lua, (self_, key, value): (LuaReflectReference, LuaScriptValue, LuaScriptValue)| { + |_, (self_, key, value): (LuaReflectReference, LuaScriptValue, LuaScriptValue)| { let self_: ReflectReference = self_.into(); let key: ScriptValue = key.into(); let value: ScriptValue = value.into(); - lookup_dynamic_function_typed::(lua, "set") - .expect("No 'set' function registered for a ReflectReference") - .call_script_function( - vec![ScriptValue::Reference(self_), key, value], - ThreadWorldContainer.get_world(), - lua_caller_context(Some(std::any::TypeId::of::())), - )?; + // lookup_dynamic_function_typed::(lua, "set") + // .expect("No 'set' function registered for a ReflectReference") + // .call_script_function( + // vec![ScriptValue::Reference(self_), key, value], + // ThreadWorldContainer.get_world(), + // lua_caller_context(Some(std::any::TypeId::of::())), + // )?; + // Ok(()) + + let func = lookup_function( + ThreadWorldContainer.get_world(), + [TypeId::of::()], + "set", + ) + .expect("No 'set' function registered for a ReflectReference"); + + let out = func.call( + vec![ScriptValue::Reference(self_), key, value], + ThreadWorldContainer.get_world(), + LUA_CALLER_CONTEXT, + )?; - Ok(()) + Ok(LuaScriptValue(out)) }, ); m.add_meta_function( MetaMethod::Sub, - |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { + |_, (self_, other): (LuaReflectReference, LuaScriptValue)| { let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - Ok(try_call_overloads(lua, "sub", target_type_id, args, world)?) + // Ok(try_call_overloads(lua, "sub", target_type_id, args, world)?) + Ok(try_call_overloads(world, target_type_id, "sub", args)?) }, ); m.add_meta_function( MetaMethod::Add, - |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { + |_, (self_, other): (LuaReflectReference, LuaScriptValue)| { let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - Ok(try_call_overloads(lua, "add", target_type_id, args, world)?) + // Ok(try_call_overloads(lua, "add", target_type_id, args, world)?) + Ok(try_call_overloads(world, target_type_id, "add", args)?) }, ); m.add_meta_function( MetaMethod::Mul, - |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { + |_, (self_, other): (LuaReflectReference, LuaScriptValue)| { let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - Ok(try_call_overloads(lua, "mul", target_type_id, args, world)?) + // Ok(try_call_overloads(lua, "mul", target_type_id, args, world)?) + Ok(try_call_overloads(world, target_type_id, "mul", args)?) }, ); m.add_meta_function( MetaMethod::Div, - |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { + |_, (self_, other): (LuaReflectReference, LuaScriptValue)| { let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - Ok(try_call_overloads(lua, "div", target_type_id, args, world)?) + // Ok(try_call_overloads(lua, "div", target_type_id, args, world)?) + Ok(try_call_overloads(world, target_type_id, "div", args)?) }, ); m.add_meta_function( MetaMethod::Mod, - |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { + |_, (self_, other): (LuaReflectReference, LuaScriptValue)| { let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - Ok(try_call_overloads(lua, "rem", target_type_id, args, world)?) + // Ok(try_call_overloads(lua, "rem", target_type_id, args, world)?) + Ok(try_call_overloads(world, target_type_id, "rem", args)?) }, ); - m.add_meta_function(MetaMethod::Unm, |lua, self_: LuaReflectReference| { + m.add_meta_function(MetaMethod::Unm, |_, self_: LuaReflectReference| { let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_)]; - Ok(try_call_overloads(lua, "neg", target_type_id, args, world)?) + // Ok(try_call_overloads(lua, "neg", target_type_id, args, world)?) + Ok(try_call_overloads(world, target_type_id, "neg", args)?) }); m.add_meta_function( MetaMethod::Pow, - |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { + |_, (self_, other): (LuaReflectReference, LuaScriptValue)| { let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - Ok(try_call_overloads(lua, "pow", target_type_id, args, world)?) + // Ok(try_call_overloads(lua, "pow", target_type_id, args, world)?) + Ok(try_call_overloads(world, target_type_id, "pow", args)?) }, ); m.add_meta_function( MetaMethod::Eq, - |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { + |_, (self_, other): (LuaReflectReference, LuaScriptValue)| { let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - Ok(try_call_overloads(lua, "eq", target_type_id, args, world)?) + // Ok(try_call_overloads(lua, "eq", target_type_id, args, world)?) + Ok(try_call_overloads(world, target_type_id, "eq", args)?) }, ); m.add_meta_function( MetaMethod::Lt, - |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { + |_, (self_, other): (LuaReflectReference, LuaScriptValue)| { let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - Ok(try_call_overloads(lua, "lt", target_type_id, args, world)?) + // Ok(try_call_overloads(lua, "lt", target_type_id, args, world)?) + Ok(try_call_overloads(world, target_type_id, "lt", args)?) }, ); @@ -303,33 +377,42 @@ impl UserData for LuaReflectReference { feature = "lua52", feature = "luajit52", ))] - m.add_meta_function(MetaMethod::Pairs, |l, s: LuaReflectReference| { - let mut iter_func = lookup_dynamic_function_typed::(l, "iter") - .expect("No iter function registered"); + m.add_meta_function(MetaMethod::Pairs, |_, s: LuaReflectReference| { + // let mut iter_func = lookup_dynamic_function_typed::(l, "iter") + // .expect("No iter function registered"); + let iter_func = lookup_function( + ThreadWorldContainer.get_world(), + [TypeId::of::()], + "iter", + ) + .expect("No iter function registered"); let world = ThreadWorldContainer.get_world(); - Ok(LuaScriptValue::from(iter_func.call_script_function( + Ok(LuaScriptValue::from(iter_func.call( vec![ScriptValue::Reference(s.into())], world, - lua_caller_context(Some(std::any::TypeId::of::())), + LUA_CALLER_CONTEXT, )?)) }); - m.add_meta_function(MetaMethod::ToString, |lua, self_: LuaReflectReference| { + m.add_meta_function(MetaMethod::ToString, |_, ()| { let world = ThreadWorldContainer.get_world(); - let self_: ReflectReference = self_.into(); - let mut display_func = - lookup_dynamic_function_typed::(lua, "display_ref") - .expect("No 'display' function registered for a ReflectReference"); + let func = lookup_function(world, [TypeId::of::()], "display") + .expect("No 'display' function registered for a ReflectReference"); - let out = display_func.call_script_function( - vec![ScriptValue::Reference(self_)], - world, - lua_caller_context(Some(std::any::TypeId::of::())), - )?; + Ok(LuaScriptValue(ScriptValue::Function(func))) + // let mut display_func = + // lookup_dynamic_function_typed::(lua, "display_ref") + // .expect("No 'display' function registered for a ReflectReference"); + + // let out = display_func.call_script_function( + // vec![ScriptValue::Reference(self_)], + // world, + // lua_caller_context(Some(std::any::TypeId::of::())), + // )?; - Ok(LuaScriptValue::from(out)) + // Ok(LuaScriptValue::from(out)) }); } } @@ -345,16 +428,26 @@ impl UserData for LuaStaticReflectReference { fn add_methods>(m: &mut T) { m.add_meta_function( MetaMethod::Index, - |lua, (self_, key): (LuaStaticReflectReference, LuaScriptValue)| { + |_, (self_, key): (LuaStaticReflectReference, LuaScriptValue)| { let type_id = self_.0; let key: ScriptValue = key.into(); - if let ScriptValue::String(ref key) = key { - if let Some(func) = lookup_function(lua, key, type_id) { - return func?.into_lua(lua); + // if let ScriptValue::String(ref key) = key { + // if let Some(func) = lookup_function(lua, key, type_id) { + // return func?.into_lua(lua); + // } + // }; + let key = match key.as_string() { + Ok(name) => { + match lookup_function(ThreadWorldContainer.get_world(), [type_id], name) { + Ok(func) => return Ok(LuaScriptValue(ScriptValue::Function(func))), + Err(key) => ScriptValue::String(key), + } } + Err(key) => key, }; + let world = ThreadWorldContainer.get_world(); Err( InteropError::missing_function(type_id, key.display_with_world(world.clone())) diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs index 257a08ef93..f97bd6df1d 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs @@ -1,19 +1,13 @@ -use std::{ - any::TypeId, - ops::{Deref, DerefMut}, -}; - +use super::reference::LuaReflectReference; use bevy_mod_scripting_core::bindings::{ - function::{script_function::CallerContext, CallScriptFunction}, - script_value::ScriptValue, - ThreadWorldContainer, WorldContainer, + function::script_function::CallerContext, script_value::ScriptValue, ThreadWorldContainer, + WorldContainer, }; use mlua::{FromLua, IntoLua, Value, Variadic}; - -use super::reference::LuaReflectReference; +use std::ops::{Deref, DerefMut}; #[derive(Debug, Clone)] -pub struct LuaScriptValue(ScriptValue); +pub struct LuaScriptValue(pub ScriptValue); impl Deref for LuaScriptValue { type Target = ScriptValue; @@ -83,12 +77,9 @@ impl FromLua for LuaScriptValue { } } -pub fn lua_caller_context(self_type: Option) -> CallerContext { - CallerContext { - convert_to_0_indexed: true, - self_type, - } -} +pub const LUA_CALLER_CONTEXT: CallerContext = CallerContext { + convert_to_0_indexed: true, +}; impl IntoLua for LuaScriptValue { fn into_lua(self, lua: &mlua::Lua) -> mlua::Result { @@ -100,13 +91,25 @@ impl IntoLua for LuaScriptValue { ScriptValue::String(s) => Value::String(lua.create_string(s.as_ref())?), ScriptValue::Reference(r) => LuaReflectReference::from(r).into_lua(lua)?, ScriptValue::Error(script_error) => return Err(mlua::Error::external(script_error)), - ScriptValue::Function(mut function) => lua - .create_function_mut(move |_lua, args: Variadic| { + ScriptValue::Function(function) => lua + .create_function(move |_lua, args: Variadic| { + let world = ThreadWorldContainer.get_world(); + let out = function.call( + args.into_iter().map(Into::into), + world, + LUA_CALLER_CONTEXT, + )?; + + Ok(LuaScriptValue::from(out)) + })? + .into_lua(lua)?, + ScriptValue::FunctionMut(function) => lua + .create_function(move |_lua, args: Variadic| { let world = ThreadWorldContainer.get_world(); - let out = function.call_script_function( + let out = function.call( args.into_iter().map(Into::into), world, - lua_caller_context(None), + LUA_CALLER_CONTEXT, )?; Ok(LuaScriptValue::from(out)) diff --git a/crates/languages/bevy_mod_scripting_rhai/src/bindings/reference.rs b/crates/languages/bevy_mod_scripting_rhai/src/bindings/reference.rs index 2ce21a6e6f..ca0ab78b79 100644 --- a/crates/languages/bevy_mod_scripting_rhai/src/bindings/reference.rs +++ b/crates/languages/bevy_mod_scripting_rhai/src/bindings/reference.rs @@ -1,10 +1,8 @@ use super::script_value::FromDynamic; use bevy_mod_scripting_core::bindings::{ - function::script_function::{AppScriptFunctionRegistry, DynamicScriptFunction}, - script_value::ScriptValue, - ReflectReference, ThreadWorldContainer, WorldContainer, WorldGuard, + function::script_function::DynamicScriptFunction, script_value::ScriptValue, ReflectReference, + ThreadWorldContainer, WorldContainer, WorldGuard, }; -use bevy_mod_scripting_functions::{GetNamespacedFunction, Namespace}; use rhai::{CustomType, Dynamic, EvalAltResult}; use std::{ any::TypeId, @@ -46,17 +44,19 @@ impl DerefMut for RhaiReflectReference { } } +#[allow(dead_code)] fn lookup_dynamic_function( - world: WorldGuard, - name: &str, - on: TypeId, + _world: WorldGuard, + _name: &str, + _on: TypeId, ) -> Option { - let registry = world.with_resource(|registry: &AppScriptFunctionRegistry| registry.clone()); - let registry = registry.read(); + // let registry = world.with_resource(|registry: &AppScriptFunctionRegistry| registry.clone()); + // let registry = registry.read(); - registry - .get_namespaced_function(name.to_string(), Namespace::OnType(on)) - .cloned() + // registry + // .get_namespaced_function(name.to_string(), Namespace::OnType(on)) + // .cloned() + todo!() } impl CustomType for RhaiReflectReference { @@ -66,8 +66,9 @@ impl CustomType for RhaiReflectReference { .with_indexer_get(|_obj: &mut Self, _index: Dynamic| { let _world = ThreadWorldContainer.get_world(); let key: ScriptValue = ScriptValue::from_dynamic(_index)?; - if let ScriptValue::String(key) = key { + if let ScriptValue::String(_key) = key { // lookup function + todo!() } Ok::<_, Box>(()) }); diff --git a/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs b/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs index 26df6bfd05..bbf2a5922c 100644 --- a/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs +++ b/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs @@ -1,4 +1,4 @@ -use std::{any::TypeId, str::FromStr, sync::Arc}; +use std::{str::FromStr, sync::Arc}; use bevy_mod_scripting_core::{ bindings::{ @@ -6,7 +6,6 @@ use bevy_mod_scripting_core::{ CallerContext, DynamicScriptFunction, DynamicScriptFunctionMut, }, script_value::ScriptValue, - ThreadWorldContainer, WorldCallbackAccess, WorldContainer, }, error::InteropError, }; @@ -15,14 +14,14 @@ use rhai::{ Dynamic, EvalAltResult, }; -fn rhai_caller_context(self_type: Option) -> CallerContext { - CallerContext { - convert_to_0_indexed: false, - self_type, - } -} +pub const RHAI_CALLER_CONTEXT: CallerContext = CallerContext { + convert_to_0_indexed: false, +}; +#[allow(dead_code)] struct FuncWrapper(DynamicScriptFunction); + +#[allow(dead_code)] struct FuncMutWrapper(DynamicScriptFunctionMut); impl PluginFunc for FuncWrapper { @@ -31,18 +30,19 @@ impl PluginFunc for FuncWrapper { _context: Option, _args: &mut [&mut Dynamic], ) -> rhai::plugin::RhaiResult { - let convert_args = _args - .iter_mut() - .map(|arg| ScriptValue::from_dynamic(arg.clone())) - .collect::, _>>()?; - - let out = self.0.call( - rhai_caller_context(self.0.info.on_type()), - WorldCallbackAccess::from_guard(ThreadWorldContainer.get_world()), - convert_args, - ); - - out.into_dynamic() + // let convert_args = _args + // .iter_mut() + // .map(|arg| ScriptValue::from_dynamic(arg.clone())) + // .collect::, _>>()?; + + // let out = self.0.call( + // rhai_caller_context(self.0.info.namespace()), + // WorldCallbackAccess::from_guard(ThreadWorldContainer.get_world()), + // convert_args, + // ); + + // out.into_dynamic() + todo!() } fn is_method_call(&self) -> bool { @@ -61,18 +61,19 @@ impl PluginFunc for FuncMutWrapper { _context: Option, _args: &mut [&mut Dynamic], ) -> rhai::plugin::RhaiResult { - let convert_args = _args - .iter_mut() - .map(|arg| ScriptValue::from_dynamic(arg.clone())) - .collect::, _>>()?; - - let out = self.0.call( - rhai_caller_context(self.0.info.on_type()), - WorldCallbackAccess::from_guard(ThreadWorldContainer.get_world()), - convert_args, - ); - - out.into_dynamic() + // let convert_args = _args + // .iter_mut() + // .map(|arg| ScriptValue::from_dynamic(arg.clone())) + // .collect::, _>>()?; + + // let out = self.0.call( + // rhai_caller_context(self.0.info.namespace()), + // WorldCallbackAccess::from_guard(ThreadWorldContainer.get_world()), + // convert_args, + // ); + + // out.into_dynamic() + todo!() } fn is_method_call(&self) -> bool { @@ -84,6 +85,7 @@ impl PluginFunc for FuncMutWrapper { } } +#[allow(dead_code)] pub(crate) fn to_rhai_fn(func: DynamicScriptFunction) -> RhaiFunc { RhaiFunc::Plugin { func: Arc::new(FuncWrapper(func)), @@ -120,8 +122,9 @@ impl IntoDynamic for ScriptValue { })?, ScriptValue::List(_vec) => todo!(), ScriptValue::Reference(_reflect_reference) => todo!(), - ScriptValue::Function(func) => Dynamic::from(to_rhai_fn_mut(func)), + ScriptValue::FunctionMut(func) => Dynamic::from(to_rhai_fn_mut(func)), ScriptValue::Error(_interop_error) => todo!(), + ScriptValue::Function(_dynamic_script_function) => todo!(), }) } } diff --git a/examples/game_of_life.rs b/examples/game_of_life.rs index 583525491b..41334d8d23 100644 --- a/examples/game_of_life.rs +++ b/examples/game_of_life.rs @@ -12,10 +12,14 @@ use bevy::{ window::{PrimaryWindow, WindowResized}, }; use bevy_console::{make_layer, AddConsoleCommand, ConsoleCommand, ConsoleOpen, ConsolePlugin}; -use bevy_mod_scripting::{NamespaceBuilder, ScriptFunctionsPlugin}; +use bevy_mod_scripting::ScriptFunctionsPlugin; use bevy_mod_scripting_core::{ - asset::ScriptAsset, bindings::script_value::ScriptValue, callback_labels, - event::ScriptCallbackEvent, script::ScriptComponent, systems::event_handler, + asset::ScriptAsset, + bindings::{function::namespace::NamespaceBuilder, script_value::ScriptValue}, + callback_labels, + event::ScriptCallbackEvent, + script::ScriptComponent, + systems::event_handler, }; use bevy_mod_scripting_lua::LuaScriptingPlugin; use bevy_mod_scripting_rhai::RhaiScriptingPlugin; From 7343b314e2cffae791aa53a446b7379362ab75b0 Mon Sep 17 00:00:00 2001 From: makspll Date: Sat, 11 Jan 2025 23:55:34 +0000 Subject: [PATCH 12/21] remove extra import, fix lua to_string --- assets/scripts/game_of_life.lua | 1 + .../bevy_mod_scripting_functions/src/lib.rs | 3 +-- .../src/bindings/reference.rs | 19 ++++++++++++++----- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/assets/scripts/game_of_life.lua b/assets/scripts/game_of_life.lua index 6941569943..b0e3a72b40 100644 --- a/assets/scripts/game_of_life.lua +++ b/assets/scripts/game_of_life.lua @@ -28,6 +28,7 @@ end function on_click(x,y) -- get the settings world.info("Lua: Clicked at x: " .. x .. " y: " .. y) + print(entity) local life_state = fetch_life_state() local cells = life_state.cells diff --git a/crates/bevy_mod_scripting_functions/src/lib.rs b/crates/bevy_mod_scripting_functions/src/lib.rs index 387f4314ed..db513ec87f 100644 --- a/crates/bevy_mod_scripting_functions/src/lib.rs +++ b/crates/bevy_mod_scripting_functions/src/lib.rs @@ -1,5 +1,4 @@ use ::bevy::prelude::*; -use test_functions::register_test_functions; #[cfg(feature = "bevy_bindings")] pub mod bevy_bindings; pub mod core; @@ -16,7 +15,7 @@ impl Plugin for ScriptFunctionsPlugin { register_bevy_bindings(app); register_core_functions(app); #[cfg(feature = "test_functions")] - register_test_functions(app); + test_functions::register_test_functions(app); // TODO: if bevy ever does this itself we should remove this app.world_mut().register_component::(); diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs index e41ca5f95c..c9763435a7 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs @@ -395,13 +395,22 @@ impl UserData for LuaReflectReference { )?)) }); - m.add_meta_function(MetaMethod::ToString, |_, ()| { + m.add_meta_function(MetaMethod::ToString, |_, self_: LuaReflectReference| { let world = ThreadWorldContainer.get_world(); + let reflect_reference: ReflectReference = self_.into(); - let func = lookup_function(world, [TypeId::of::()], "display") - .expect("No 'display' function registered for a ReflectReference"); - - Ok(LuaScriptValue(ScriptValue::Function(func))) + let func = lookup_function( + world.clone(), + [TypeId::of::()], + "display_ref", + ) + .expect("No 'display' function registered for a ReflectReference"); + let out = func.call( + vec![ScriptValue::Reference(reflect_reference)], + world, + LUA_CALLER_CONTEXT, + )?; + Ok(LuaScriptValue(out)) // let mut display_func = // lookup_dynamic_function_typed::(lua, "display_ref") // .expect("No 'display' function registered for a ReflectReference"); From de4d2da7fee1b397eb77b5748780a229a5088208 Mon Sep 17 00:00:00 2001 From: makspll Date: Sun, 12 Jan 2025 10:53:14 +0000 Subject: [PATCH 13/21] clean up comments --- .../src/bindings/reference.rs | 125 ------------------ 1 file changed, 125 deletions(-) diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs index c9763435a7..4f15a06ecb 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs @@ -35,95 +35,6 @@ impl From for LuaReflectReference { } } -// Looks up a function in the registry on the given type id -// fn lookup_function(lua: &Lua, key: &str, type_id: TypeId) -> Option> { -// let function = lookup_dynamic_function(lua, key, type_id); - -// function.map(|mut function| { -// lua.create_function_mut(move |_lua, args: Variadic| { -// let world = ThreadWorldContainer.get_world(); -// let out = function.call_script_function( -// args.into_iter().map(Into::into), -// world, -// LUA_CALLER_CONTEXT, -// )?; - -// Ok(LuaScriptValue::from(out)) -// }) -// }) -// } - -// fn lookup_function_typed( -// lua: &Lua, -// key: &str, -// ) -> Option> { -// let type_id = TypeId::of::(); -// lookup_function(lua, key, type_id) -// } - -// fn lookup_dynamic_function( -// _lua: &Lua, -// key: &str, -// type_id: TypeId, -// ) -> Option { -// let function_registry = ThreadWorldContainer -// .get_world() -// .with_resource(|registry: &AppScriptFunctionRegistry| registry.clone()); -// let registry = function_registry.read(); - -// registry -// .get_function(Namespace::OnType(type_id), key.to_string()) -// .cloned() -// } - -// fn lookup_dynamic_function_typed( -// lua: &Lua, -// key: &str, -// ) -> Option { -// let type_id = TypeId::of::(); -// lookup_dynamic_function(lua, key, type_id) -// } - -// fn iter_dynamic_function_overloads( -// _lua: &Lua, -// key: &str, -// type_id: TypeId, -// ) -> impl Iterator { -// let registry = ThreadWorldContainer -// .get_world() -// .with_resource(|registry: &AppScriptFunctionRegistry| registry.clone()); -// let registry = registry.read(); - -// registry -// .iter_overloads(Namespace::OnType(type_id), key.to_string()) -// .cloned() -// .collect::>() -// .into_iter() -// } - -// fn try_call_overloads( -// lua: &Lua, -// key: &str, -// type_id: TypeId, -// args: Vec, -// world: WorldGuard, -// ) -> Result { -// let overloads = iter_dynamic_function_overloads(lua, key, type_id); -// let mut last_error = None; -// for mut overload in overloads { -// match overload.call_script_function( -// args.clone(), -// world.clone(), -// lua_caller_context(Some(type_id)), -// ) { -// Ok(out) => return Ok(out.into()), -// Err(e) => last_error = Some(e), -// } -// } - -// Err(last_error.unwrap_or_else(|| InteropError::missing_function(type_id, key.to_string()))) -// } - /// Look up a function on the given type ids fn lookup_function( guard: WorldGuard, @@ -205,13 +116,6 @@ impl UserData for LuaReflectReference { LUA_CALLER_CONTEXT, )?; Ok(LuaScriptValue(out)) - // // call the function with the key - // let out = index_func.call_script_function( - // vec![ScriptValue::Reference(self_), key], - // world.clone(), - // lua_caller_context(Some(std::any::TypeId::of::())), - // )?; - // LuaScriptValue::from(out).into_lua(lua) }, ); @@ -222,15 +126,6 @@ impl UserData for LuaReflectReference { let key: ScriptValue = key.into(); let value: ScriptValue = value.into(); - // lookup_dynamic_function_typed::(lua, "set") - // .expect("No 'set' function registered for a ReflectReference") - // .call_script_function( - // vec![ScriptValue::Reference(self_), key, value], - // ThreadWorldContainer.get_world(), - // lua_caller_context(Some(std::any::TypeId::of::())), - // )?; - // Ok(()) - let func = lookup_function( ThreadWorldContainer.get_world(), [TypeId::of::()], @@ -256,7 +151,6 @@ impl UserData for LuaReflectReference { let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - // Ok(try_call_overloads(lua, "sub", target_type_id, args, world)?) Ok(try_call_overloads(world, target_type_id, "sub", args)?) }, ); @@ -269,7 +163,6 @@ impl UserData for LuaReflectReference { let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - // Ok(try_call_overloads(lua, "add", target_type_id, args, world)?) Ok(try_call_overloads(world, target_type_id, "add", args)?) }, ); @@ -282,7 +175,6 @@ impl UserData for LuaReflectReference { let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - // Ok(try_call_overloads(lua, "mul", target_type_id, args, world)?) Ok(try_call_overloads(world, target_type_id, "mul", args)?) }, ); @@ -295,7 +187,6 @@ impl UserData for LuaReflectReference { let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - // Ok(try_call_overloads(lua, "div", target_type_id, args, world)?) Ok(try_call_overloads(world, target_type_id, "div", args)?) }, ); @@ -308,7 +199,6 @@ impl UserData for LuaReflectReference { let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - // Ok(try_call_overloads(lua, "rem", target_type_id, args, world)?) Ok(try_call_overloads(world, target_type_id, "rem", args)?) }, ); @@ -318,7 +208,6 @@ impl UserData for LuaReflectReference { let self_: ReflectReference = self_.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_)]; - // Ok(try_call_overloads(lua, "neg", target_type_id, args, world)?) Ok(try_call_overloads(world, target_type_id, "neg", args)?) }); @@ -330,7 +219,6 @@ impl UserData for LuaReflectReference { let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - // Ok(try_call_overloads(lua, "pow", target_type_id, args, world)?) Ok(try_call_overloads(world, target_type_id, "pow", args)?) }, ); @@ -343,7 +231,6 @@ impl UserData for LuaReflectReference { let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - // Ok(try_call_overloads(lua, "eq", target_type_id, args, world)?) Ok(try_call_overloads(world, target_type_id, "eq", args)?) }, ); @@ -356,7 +243,6 @@ impl UserData for LuaReflectReference { let other: ScriptValue = other.into(); let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - // Ok(try_call_overloads(lua, "lt", target_type_id, args, world)?) Ok(try_call_overloads(world, target_type_id, "lt", args)?) }, ); @@ -411,17 +297,6 @@ impl UserData for LuaReflectReference { LUA_CALLER_CONTEXT, )?; Ok(LuaScriptValue(out)) - // let mut display_func = - // lookup_dynamic_function_typed::(lua, "display_ref") - // .expect("No 'display' function registered for a ReflectReference"); - - // let out = display_func.call_script_function( - // vec![ScriptValue::Reference(self_)], - // world, - // lua_caller_context(Some(std::any::TypeId::of::())), - // )?; - - // Ok(LuaScriptValue::from(out)) }); } } From d39135c2af54d73300da2ae7087caf6d24db1f63 Mon Sep 17 00:00:00 2001 From: makspll Date: Sun, 12 Jan 2025 14:46:09 +0000 Subject: [PATCH 14/21] remove rhai and rune support for now --- Cargo.toml | 25 +-- crates/bevy_mod_scripting_core/Cargo.toml | 4 +- .../src/bindings/function/script_function.rs | 7 +- .../src/bindings/world.rs | 178 +++++++---------- crates/bevy_mod_scripting_core/src/error.rs | 80 ++++++-- .../src/bindings/reference.rs | 189 ++++++++---------- .../src/bindings/reference.rs | 90 ++++++--- .../src/bindings/script_value.rs | 129 ++++++------ .../bevy_mod_scripting_rhai/src/lib.rs | 44 +++- .../missing_type_returns_nothing.rhai | 6 +- .../registered_type_returns_correct_type.rhai | 2 +- examples/game_of_life.rs | 8 +- release-plz.toml | 16 +- src/lib.rs | 16 +- 14 files changed, 433 insertions(+), 361 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 78b2da0de2..aabd435120 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ name = "bevy_mod_scripting" path = "src/lib.rs" [package.metadata."docs.rs"] -features = ["lua54", "rhai", "rune"] +features = ["lua54"] [features] default = ["core_functions", "bevy_bindings", "unsafe_lua_modules"] @@ -44,17 +44,17 @@ mlua_macros = ["bevy_mod_scripting_lua/mlua_macros"] mlua_async = ["bevy_mod_scripting_lua/mlua_async"] ## rhai -rhai = ["bevy_mod_scripting_rhai"] +# rhai = ["bevy_mod_scripting_rhai"] ## rune -rune = ["bevy_mod_scripting_rune"] +# rune = ["bevy_mod_scripting_rune"] [dependencies] bevy = { workspace = true } bevy_mod_scripting_core = { workspace = true } bevy_mod_scripting_lua = { path = "crates/languages/bevy_mod_scripting_lua", version = "0.9.0-alpha.2", optional = true } -bevy_mod_scripting_rhai = { path = "crates/languages/bevy_mod_scripting_rhai", version = "0.9.0-alpha.2", optional = true } -bevy_mod_scripting_rune = { path = "crates/languages/bevy_mod_scripting_rune", version = "0.9.0-alpha.2", optional = true } +# bevy_mod_scripting_rhai = { path = "crates/languages/bevy_mod_scripting_rhai", version = "0.9.0-alpha.2", optional = true } +# bevy_mod_scripting_rune = { path = "crates/languages/bevy_mod_scripting_rune", version = "0.9.0-alpha.2", optional = true } bevy_mod_scripting_functions = { workspace = true } [workspace.dependencies] @@ -62,7 +62,7 @@ bevy = { version = "0.15.0", default-features = false } bevy_mod_scripting_core = { path = "crates/bevy_mod_scripting_core", version = "0.9.0-alpha.2" } bevy_mod_scripting_functions = { path = "crates/bevy_mod_scripting_functions", version = "0.9.0-alpha.2", default-features = false } mlua = { version = "0.10" } -rhai = { version = "1.20.1" } +# rhai = { version = "1.20.1" } # test utilities script_integration_test_harness = { path = "crates/script_integration_test_harness" } @@ -73,15 +73,15 @@ bevy = { workspace = true, default-features = true } clap = { version = "4.1", features = ["derive"] } rand = "0.8.5" bevy_console = "0.13" -rhai-rand = "0.1" +# rhai-rand = "0.1" ansi-parser = "0.9" [workspace] members = [ "crates/bevy_mod_scripting_core", "crates/languages/bevy_mod_scripting_lua", - "crates/languages/bevy_mod_scripting_rhai", - "crates/languages/bevy_mod_scripting_rune", + # "crates/languages/bevy_mod_scripting_rhai", + # "crates/languages/bevy_mod_scripting_rune", "crates/test_utils", "crates/bevy_mod_scripting_functions", "crates/xtask", @@ -112,9 +112,4 @@ debug = true [[example]] name = "game_of_life" path = "examples/game_of_life.rs" -required-features = [ - "lua54", - "rhai", - "bevy/file_watcher", - "bevy/multi_threaded", -] +required-features = ["lua54", "bevy/file_watcher", "bevy/multi_threaded"] diff --git a/crates/bevy_mod_scripting_core/Cargo.toml b/crates/bevy_mod_scripting_core/Cargo.toml index 3eb6054938..5deee5ed7b 100644 --- a/crates/bevy_mod_scripting_core/Cargo.toml +++ b/crates/bevy_mod_scripting_core/Cargo.toml @@ -21,11 +21,11 @@ doc_always = [] # if enabled enables some common mlua trait implementations mlua_impls = ["mlua"] -rhai_impls = ["rhai"] +# rhai_impls = ["rhai"] [dependencies] mlua = { optional = true, workspace = true } -rhai = { optional = true, workspace = true } +# rhai = { optional = true, workspace = true } bevy = { workspace = true, default-features = false, features = [ "bevy_asset", diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs b/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs index e7697cdac7..842bd2cef9 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs @@ -359,7 +359,7 @@ impl ScriptFunctionRegistryArc { } #[derive(Debug, PartialEq, Eq, Hash)] -struct FunctionKey { +pub struct FunctionKey { name: Cow<'static, str>, namespace: Namespace, } @@ -465,6 +465,11 @@ impl ScriptFunctionRegistry { Ok(seed.chain(overloads)) } + + /// Iterates over all functions including overloads + pub fn iter_all(&self) -> impl Iterator { + self.functions.iter() + } } macro_rules! count { diff --git a/crates/bevy_mod_scripting_core/src/bindings/world.rs b/crates/bevy_mod_scripting_core/src/bindings/world.rs index 516a3f22ea..8bc84ca52e 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/world.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/world.rs @@ -7,7 +7,11 @@ use super::{ access_map::{AccessCount, AccessMap, ReflectAccessId}, - function::script_function::AppScriptFunctionRegistry, + function::{ + namespace::Namespace, + script_function::{AppScriptFunctionRegistry, CallerContext, DynamicScriptFunction}, + }, + script_value::ScriptValue, AppReflectAllocator, ReflectBase, ReflectBaseType, ReflectReference, ScriptTypeRegistration, }; use crate::{error::InteropError, with_access_read, with_access_write, with_global_access}; @@ -25,6 +29,7 @@ use bevy::{ }; use std::{ any::TypeId, + borrow::Cow, cell::RefCell, fmt::Debug, sync::{Arc, Weak}, @@ -218,6 +223,36 @@ impl WorldCallbackAccess { world.exit(); Ok(()) } + + /// Tries to call a fitting overload of the function with the given name and in the type id's namespace based on the arguments provided. + /// Currently does this by repeatedly trying each overload until one succeeds or all fail. + pub fn try_call_overloads( + &self, + type_id: TypeId, + name: impl Into>, + args: Vec, + context: CallerContext, + ) -> Result { + let world = self.try_read()?; + let registry = world.script_function_registry(); + let registry = registry.read(); + + let name = name.into(); + let overload_iter = match registry.iter_overloads(Namespace::OnType(type_id), name) { + Ok(iter) => iter, + Err(name) => return Err(InteropError::missing_function(type_id, name.to_string())), + }; + + let mut last_error = None; + for overload in overload_iter { + match overload.call(args.clone(), world.clone(), context) { + Ok(out) => return Ok(out), + Err(e) => last_error = Some(e), + } + } + + Err(last_error.expect("invariant, iterator should always return at least one item, and if the call fails it should return an error")) + } } pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(5); @@ -459,109 +494,27 @@ impl<'w> WorldAccessGuard<'w> { ) } - // #[track_caller] - // /// Get access to the given component, this is the only way to access a component/resource safely (in the context of the world access guard) - // pub fn get_component_with_access( - // &self, - // access: &WorldAccess, - // entity: Entity, - // ) -> ScriptResult> { - // let component_id = match self.0.cell.components().component_id::() { - // Some(id) => id, - // None => return Ok(None), - // }; - - // if access.can_read(ReflectAccessId { - // kind: ReflectAccessKind::ComponentOrResource, - // id: component_id.index(), - // }) { - // // Safety: we have the correct access id - // unsafe { Ok(self.0.cell.get_entity(entity).and_then(|e| e.get::())) } - // } else { - // Err(ScriptError::new_reflection_error( - // "Cannot read component, received invalid access".to_string(), - // )) - // } - // } - - // #[track_caller] - // /// Get access to the given component, this is the only way to access a component/resource safely (in the context of the world access guard) - // pub fn get_component_with_access_mut( - // &self, - // access: &mut WorldAccess, - // entity: Entity, - // ) -> ScriptResult>> { - // let component_id = match self.0.cell.components().component_id::() { - // Some(id) => id, - // None => return Ok(None), - // }; - - // if access.can_write(ReflectAccessId { - // kind: ReflectAccessKind::ComponentOrResource, - // id: component_id.index(), - // }) { - // // Safety: we have the correct access id - // unsafe { - // Ok(self - // .0 - // .cell - // .get_entity(entity) - // .and_then(|e| e.get_mut::())) - // } - // } else { - // Err(ScriptError::new_reflection_error( - // "Cannot write component, received invalid access".to_string(), - // )) - // } - // } - - // #[track_caller] - // /// Get access to the given resource - // pub fn get_resource_with_access( - // &self, - // access: &WorldAccess, - // ) -> ScriptResult> { - // let resource_id = match self.0.cell.components().resource_id::() { - // Some(id) => id, - // None => return Ok(None), - // }; - - // if access.can_read(ReflectAccessId { - // kind: ReflectAccessKind::ComponentOrResource, - // id: resource_id.index(), - // }) { - // // Safety: we have the correct access id - // unsafe { Ok(self.0.cell.get_resource::()) } - // } else { - // Err(ScriptError::new_reflection_error( - // "Cannot read resource, received invalid access".to_string(), - // )) - // } - // } - - // #[track_caller] - // /// Get access to the given resource, this is the only way to access a component/resource safely (in the context of the world access guard) - // pub fn get_resource_with_access_mut( - // &self, - // access: &mut WorldAccess, - // ) -> ScriptResult>> { - // let resource_id = match self.0.cell.components().resource_id::() { - // Some(id) => id, - // None => return Ok(None), - // }; - - // if access.can_write(ReflectAccessId { - // kind: ReflectAccessKind::ComponentOrResource, - // id: resource_id.index(), - // }) { - // // Safety: we have the correct access id - // unsafe { Ok(self.0.cell.get_resource_mut::()) } - // } else { - // Err(ScriptError::new_reflection_error( - // "Cannot write resource, received invalid access".to_string(), - // )) - // } - // } + /// Try to lookup a function with the given name on the given type id's namespaces. + /// + /// Returns the function if found, otherwise returns the name of the function that was not found. + pub fn lookup_function( + &self, + type_ids: impl IntoIterator, + name: impl Into>, + ) -> Result> { + let registry = self.script_function_registry(); + let registry = registry.read(); + + let mut name = name.into(); + for type_id in type_ids { + name = match registry.get_function(Namespace::OnType(type_id), name) { + Ok(func) => return Ok(func.clone()), + Err(name) => name, + }; + } + + Err(name) + } /// checks if a given entity exists and is valid pub fn is_valid_entity(&self, entity: Entity) -> bool { @@ -926,8 +879,15 @@ pub trait WorldContainer { self.try_get_world().expect("World not set, or expired") } + fn get_callback_world(&self) -> WorldCallbackAccess { + self.try_get_callback_world() + .expect("World not set, or expired") + } + /// Tries to get the world fn try_get_world(&self) -> Result>, Self::Error>; + + fn try_get_callback_world(&self) -> Result; } /// A world container that stores the world in a thread local @@ -955,6 +915,16 @@ impl WorldContainer for ThreadWorldContainer { .ok_or_else(InteropError::missing_world) })? } + + fn try_get_callback_world(&self) -> Result { + WORLD_CALLBACK_ACCESS.with(|w| { + w.borrow() + .as_ref() + .cloned() + // .map(|w| w.try_read()) + .ok_or_else(InteropError::missing_world) + }) + } } // #[cfg(test)] diff --git a/crates/bevy_mod_scripting_core/src/error.rs b/crates/bevy_mod_scripting_core/src/error.rs index d332d92853..36776aa393 100644 --- a/crates/bevy_mod_scripting_core/src/error.rs +++ b/crates/bevy_mod_scripting_core/src/error.rs @@ -33,17 +33,17 @@ impl Deref for ScriptError { } /// The innards are separated to reduce the size of this error -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ScriptErrorInner { pub script: Option, pub context: String, - pub reason: ErrorKind, + pub reason: Arc, } -#[derive(Debug, Clone)] +#[derive(Debug)] pub enum ErrorKind { - Display(Arc), - WithWorld(Arc), + Display(Box), + WithWorld(Box), } impl DisplayWithWorld for ErrorKind { @@ -97,10 +97,30 @@ impl ScriptError { } } + // #[cfg(feature = "rhai_impls")] + // pub fn from_rhai_error(error: rhai::EvalAltResult) -> Self { + // match error { + // rhai::EvalAltResult::ErrorSystem(message, error) => { + // if let Some(inner) = error.downcast_ref::() { + // Self::new(inner.clone()) + // } else if let Some(inner) = error.downcast_ref::() { + // inner.clone() + // } else { + // Self::new_external_boxed(error).with_context(message) + // } + // } + // _ => Self::new_external(error), + // } + // } + pub fn new_external(reason: impl std::error::Error + Send + Sync + 'static) -> Self { + Self::new_external_boxed(Box::new(reason)) + } + + pub fn new_external_boxed(reason: Box) -> Self { Self(Arc::new(ScriptErrorInner { script: None, - reason: ErrorKind::Display(Arc::new(reason)), + reason: Arc::new(ErrorKind::Display(reason)), context: Default::default(), })) } @@ -108,7 +128,7 @@ impl ScriptError { pub fn new(reason: impl DisplayWithWorld + Send + Sync + 'static) -> Self { Self(Arc::new(ScriptErrorInner { script: None, - reason: ErrorKind::WithWorld(Arc::new(reason)), + reason: Arc::new(ErrorKind::WithWorld(Box::new(reason))), context: Default::default(), })) } @@ -187,19 +207,39 @@ impl From for ScriptError { } } -#[cfg(feature = "rhai_impls")] -impl From for ScriptError { - fn from(value: rhai::ParseError) -> Self { - ScriptError::new_external(value) - } -} - -#[cfg(feature = "rhai_impls")] -impl From> for ScriptError { - fn from(value: Box) -> Self { - ScriptError::new_external(value) - } -} +// #[cfg(feature = "rhai_impls")] +// impl From for ScriptError { +// fn from(value: rhai::ParseError) -> Self { +// ScriptError::new_external(value) +// } +// } + +// #[cfg(feature = "rhai_impls")] +// impl From> for ScriptError { +// fn from(value: Box) -> Self { +// ScriptError::from_rhai_error(*value) +// } +// } + +// #[cfg(feature = "rhai_impls")] +// impl From for Box { +// fn from(value: ScriptError) -> Self { +// Box::new(rhai::EvalAltResult::ErrorSystem( +// "ScriptError".to_owned(), +// Box::new(value), +// )) +// } +// } + +// #[cfg(feature = "rhai_impls")] +// impl From for Box { +// fn from(value: InteropError) -> Self { +// Box::new(rhai::EvalAltResult::ErrorSystem( +// "InteropError".to_owned(), +// Box::new(value), +// )) +// } +// } #[derive(Debug, Clone, PartialEq, Reflect)] pub struct InteropError(#[reflect(ignore)] Arc); diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs index 4f15a06ecb..33f7640c7c 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs @@ -1,16 +1,14 @@ use super::script_value::{LuaScriptValue, LUA_CALLER_CONTEXT}; use bevy_mod_scripting_core::{ bindings::{ - function::{namespace::Namespace, script_function::DynamicScriptFunction}, - pretty_print::DisplayWithWorld, - script_value::ScriptValue, - ReflectReference, ThreadWorldContainer, WorldContainer, WorldGuard, + pretty_print::DisplayWithWorld, script_value::ScriptValue, ReflectReference, + ThreadWorldContainer, WorldContainer, }, error::InteropError, reflection_extensions::TypeIdExtensions, }; use mlua::{MetaMethod, UserData, UserDataMethods}; -use std::{any::TypeId, borrow::Cow}; +use std::any::TypeId; /// Lua UserData wrapper for [`bevy_mod_scripting_core::bindings::ReflectReference`]. /// Acts as a lua reflection interface. Any value which is registered in the type registry can be interacted with using this type. @@ -35,52 +33,6 @@ impl From for LuaReflectReference { } } -/// Look up a function on the given type ids -fn lookup_function( - guard: WorldGuard, - type_ids: impl IntoIterator, - name: impl Into>, -) -> Result> { - let registry = guard.script_function_registry(); - let registry = registry.read(); - - let mut name = name.into(); - for type_id in type_ids { - name = match registry.get_function(Namespace::OnType(type_id), name) { - Ok(func) => return Ok(func.clone()), - Err(name) => name, - }; - } - - Err(name) -} - -fn try_call_overloads( - guard: WorldGuard, - type_id: TypeId, - name: impl Into>, - args: Vec, -) -> Result { - let registry = guard.script_function_registry(); - let registry = registry.read(); - - let name = name.into(); - let overload_iter = match registry.iter_overloads(Namespace::OnType(type_id), name) { - Ok(iter) => iter, - Err(name) => return Err(InteropError::missing_function(type_id, name.to_string())), - }; - - let mut last_error = None; - for overload in overload_iter { - match overload.call(args.clone(), guard.clone(), LUA_CALLER_CONTEXT) { - Ok(out) => return Ok(out.into()), - Err(e) => last_error = Some(e), - } - } - - Err(last_error.expect("invariant, iterator should always return at least one item, and if the call fails it should return an error")) -} - impl UserData for LuaReflectReference { fn add_methods>(m: &mut T) { m.add_meta_function( @@ -93,11 +45,9 @@ impl UserData for LuaReflectReference { let key: ScriptValue = key.into(); let key = match key.as_string() { Ok(string) => { - match lookup_function( - world.clone(), - [type_id, TypeId::of::()], - string, - ) { + match world + .lookup_function([type_id, TypeId::of::()], string) + { Ok(func) => return Ok(LuaScriptValue(ScriptValue::Function(func))), Err(e) => ScriptValue::String(e), @@ -106,9 +56,9 @@ impl UserData for LuaReflectReference { Err(key) => key, }; - let func = - lookup_function(world.clone(), [TypeId::of::()], "get") - .expect("No 'get' function registered for a ReflectReference"); + let func = world + .lookup_function([TypeId::of::()], "get") + .expect("No 'get' function registered for a ReflectReference"); // call the function with the key let out = func.call( vec![ScriptValue::Reference(self_), key], @@ -122,16 +72,14 @@ impl UserData for LuaReflectReference { m.add_meta_function( MetaMethod::NewIndex, |_, (self_, key, value): (LuaReflectReference, LuaScriptValue, LuaScriptValue)| { + let world = ThreadWorldContainer.get_world(); let self_: ReflectReference = self_.into(); let key: ScriptValue = key.into(); let value: ScriptValue = value.into(); - let func = lookup_function( - ThreadWorldContainer.get_world(), - [TypeId::of::()], - "set", - ) - .expect("No 'set' function registered for a ReflectReference"); + let func = world + .lookup_function([TypeId::of::()], "set") + .expect("No 'set' function registered for a ReflectReference"); let out = func.call( vec![ScriptValue::Reference(self_), key, value], @@ -146,104 +94,130 @@ impl UserData for LuaReflectReference { m.add_meta_function( MetaMethod::Sub, |_, (self_, other): (LuaReflectReference, LuaScriptValue)| { - let world = ThreadWorldContainer.get_world(); + let world = ThreadWorldContainer.get_callback_world(); + let guard = world.try_read().expect("World is not set or expired"); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); - let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); + let target_type_id = self_.tail_type_id(guard)?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - Ok(try_call_overloads(world, target_type_id, "sub", args)?) + let out = + world.try_call_overloads(target_type_id, "sub", args, LUA_CALLER_CONTEXT)?; + Ok(LuaScriptValue(out)) }, ); m.add_meta_function( MetaMethod::Add, |_, (self_, other): (LuaReflectReference, LuaScriptValue)| { - let world = ThreadWorldContainer.get_world(); + let world = ThreadWorldContainer.get_callback_world(); + let guard = world.try_read().expect("World is not set or expired"); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); - let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); + let target_type_id = self_.tail_type_id(guard)?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - Ok(try_call_overloads(world, target_type_id, "add", args)?) + let out = + world.try_call_overloads(target_type_id, "add", args, LUA_CALLER_CONTEXT)?; + Ok(LuaScriptValue(out)) }, ); m.add_meta_function( MetaMethod::Mul, |_, (self_, other): (LuaReflectReference, LuaScriptValue)| { - let world = ThreadWorldContainer.get_world(); + let world = ThreadWorldContainer.get_callback_world(); + let guard = world.try_read().expect("World is not set or expired"); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); - let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); + let target_type_id = self_.tail_type_id(guard)?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - Ok(try_call_overloads(world, target_type_id, "mul", args)?) + let out = + world.try_call_overloads(target_type_id, "mul", args, LUA_CALLER_CONTEXT)?; + Ok(LuaScriptValue(out)) }, ); m.add_meta_function( MetaMethod::Div, |_, (self_, other): (LuaReflectReference, LuaScriptValue)| { - let world = ThreadWorldContainer.get_world(); + let world = ThreadWorldContainer.get_callback_world(); + let guard = world.try_read().expect("World is not set or expired"); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); - let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); + let target_type_id = self_.tail_type_id(guard)?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - Ok(try_call_overloads(world, target_type_id, "div", args)?) + let out = + world.try_call_overloads(target_type_id, "div", args, LUA_CALLER_CONTEXT)?; + Ok(LuaScriptValue(out)) }, ); m.add_meta_function( MetaMethod::Mod, |_, (self_, other): (LuaReflectReference, LuaScriptValue)| { - let world = ThreadWorldContainer.get_world(); + let world = ThreadWorldContainer.get_callback_world(); + let guard = world.try_read().expect("World is not set or expired"); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); - let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); + let target_type_id = self_.tail_type_id(guard)?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - Ok(try_call_overloads(world, target_type_id, "rem", args)?) + let out = + world.try_call_overloads(target_type_id, "rem", args, LUA_CALLER_CONTEXT)?; + Ok(LuaScriptValue(out)) }, ); m.add_meta_function(MetaMethod::Unm, |_, self_: LuaReflectReference| { - let world = ThreadWorldContainer.get_world(); + let world = ThreadWorldContainer.get_callback_world(); + let guard = world.try_read().expect("World is not set or expired"); let self_: ReflectReference = self_.into(); - let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); + let target_type_id = self_.tail_type_id(guard)?.or_fake_id(); let args = vec![ScriptValue::Reference(self_)]; - Ok(try_call_overloads(world, target_type_id, "neg", args)?) + let out = world.try_call_overloads(target_type_id, "neg", args, LUA_CALLER_CONTEXT)?; + Ok(LuaScriptValue(out)) }); m.add_meta_function( MetaMethod::Pow, |_, (self_, other): (LuaReflectReference, LuaScriptValue)| { - let world = ThreadWorldContainer.get_world(); + let world = ThreadWorldContainer.get_callback_world(); + let guard = world.try_read().expect("World is not set or expired"); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); - let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); + let target_type_id = self_.tail_type_id(guard)?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - Ok(try_call_overloads(world, target_type_id, "pow", args)?) + let out = + world.try_call_overloads(target_type_id, "pow", args, LUA_CALLER_CONTEXT)?; + Ok(LuaScriptValue(out)) }, ); m.add_meta_function( MetaMethod::Eq, |_, (self_, other): (LuaReflectReference, LuaScriptValue)| { - let world = ThreadWorldContainer.get_world(); + let world = ThreadWorldContainer.get_callback_world(); + let guard = world.try_read().expect("World is not set or expired"); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); - let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); + let target_type_id = self_.tail_type_id(guard)?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - Ok(try_call_overloads(world, target_type_id, "eq", args)?) + let out = + world.try_call_overloads(target_type_id, "eq", args, LUA_CALLER_CONTEXT)?; + Ok(LuaScriptValue(out)) }, ); m.add_meta_function( MetaMethod::Lt, |_, (self_, other): (LuaReflectReference, LuaScriptValue)| { - let world = ThreadWorldContainer.get_world(); + let world = ThreadWorldContainer.get_callback_world(); + let guard = world.try_read().expect("World is not set or expired"); let self_: ReflectReference = self_.into(); let other: ScriptValue = other.into(); - let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id(); + let target_type_id = self_.tail_type_id(guard)?.or_fake_id(); let args = vec![ScriptValue::Reference(self_), other]; - Ok(try_call_overloads(world, target_type_id, "lt", args)?) + let out = + world.try_call_overloads(target_type_id, "lt", args, LUA_CALLER_CONTEXT)?; + Ok(LuaScriptValue(out)) }, ); @@ -266,14 +240,12 @@ impl UserData for LuaReflectReference { m.add_meta_function(MetaMethod::Pairs, |_, s: LuaReflectReference| { // let mut iter_func = lookup_dynamic_function_typed::(l, "iter") // .expect("No iter function registered"); - let iter_func = lookup_function( - ThreadWorldContainer.get_world(), - [TypeId::of::()], - "iter", - ) - .expect("No iter function registered"); let world = ThreadWorldContainer.get_world(); + let iter_func = world + .lookup_function([TypeId::of::()], "iter") + .expect("No iter function registered"); + Ok(LuaScriptValue::from(iter_func.call( vec![ScriptValue::Reference(s.into())], world, @@ -285,12 +257,10 @@ impl UserData for LuaReflectReference { let world = ThreadWorldContainer.get_world(); let reflect_reference: ReflectReference = self_.into(); - let func = lookup_function( - world.clone(), - [TypeId::of::()], - "display_ref", - ) - .expect("No 'display' function registered for a ReflectReference"); + let func = world + .lookup_function([TypeId::of::()], "display_ref") + .expect("No 'display' function registered for a ReflectReference"); + let out = func.call( vec![ScriptValue::Reference(reflect_reference)], world, @@ -313,6 +283,7 @@ impl UserData for LuaStaticReflectReference { m.add_meta_function( MetaMethod::Index, |_, (self_, key): (LuaStaticReflectReference, LuaScriptValue)| { + let world = ThreadWorldContainer.get_world(); let type_id = self_.0; let key: ScriptValue = key.into(); @@ -323,12 +294,10 @@ impl UserData for LuaStaticReflectReference { // } // }; let key = match key.as_string() { - Ok(name) => { - match lookup_function(ThreadWorldContainer.get_world(), [type_id], name) { - Ok(func) => return Ok(LuaScriptValue(ScriptValue::Function(func))), - Err(key) => ScriptValue::String(key), - } - } + Ok(name) => match world.lookup_function([type_id], name) { + Ok(func) => return Ok(LuaScriptValue(ScriptValue::Function(func))), + Err(key) => ScriptValue::String(key), + }, Err(key) => key, }; diff --git a/crates/languages/bevy_mod_scripting_rhai/src/bindings/reference.rs b/crates/languages/bevy_mod_scripting_rhai/src/bindings/reference.rs index ca0ab78b79..8677a6f4f1 100644 --- a/crates/languages/bevy_mod_scripting_rhai/src/bindings/reference.rs +++ b/crates/languages/bevy_mod_scripting_rhai/src/bindings/reference.rs @@ -1,7 +1,11 @@ -use super::script_value::FromDynamic; -use bevy_mod_scripting_core::bindings::{ - function::script_function::DynamicScriptFunction, script_value::ScriptValue, ReflectReference, - ThreadWorldContainer, WorldContainer, WorldGuard, +use super::script_value::{FromDynamic, RHAI_CALLER_CONTEXT}; +use bevy_mod_scripting_core::{ + bindings::{ + pretty_print::DisplayWithWorld, script_value::ScriptValue, ReflectReference, + ThreadWorldContainer, WorldContainer, + }, + error::InteropError, + reflection_extensions::TypeIdExtensions, }; use rhai::{CustomType, Dynamic, EvalAltResult}; use std::{ @@ -44,33 +48,67 @@ impl DerefMut for RhaiReflectReference { } } -#[allow(dead_code)] -fn lookup_dynamic_function( - _world: WorldGuard, - _name: &str, - _on: TypeId, -) -> Option { - // let registry = world.with_resource(|registry: &AppScriptFunctionRegistry| registry.clone()); - // let registry = registry.read(); - - // registry - // .get_namespaced_function(name.to_string(), Namespace::OnType(on)) - // .cloned() - todo!() -} - impl CustomType for RhaiReflectReference { fn build(mut builder: rhai::TypeBuilder) { builder .with_name(std::any::type_name::()) - .with_indexer_get(|_obj: &mut Self, _index: Dynamic| { - let _world = ThreadWorldContainer.get_world(); + .with_indexer_get(|self_: &mut Self, _index: Dynamic| { + let world = ThreadWorldContainer.get_world(); + let self_ = &self_.0; + let type_id = self_.tail_type_id(world.clone())?.or_fake_id(); + let key: ScriptValue = ScriptValue::from_dynamic(_index)?; - if let ScriptValue::String(_key) = key { - // lookup function - todo!() - } - Ok::<_, Box>(()) + let key = match key.as_string() { + Ok(string) => { + match world + .lookup_function([type_id, TypeId::of::()], string) + { + Ok(func) => return Ok(Dynamic::from(func)), + Err(string) => ScriptValue::String(string), + } + } + Err(key) => key, + }; + + let func = world + .lookup_function([type_id, TypeId::of::()], "get") + .expect("No 'get' function registered for ReflectReference"); + + let out = func.call( + vec![ScriptValue::Reference(self_.clone()), key], + world, + RHAI_CALLER_CONTEXT, + )?; + + Ok::<_, Box>(Dynamic::from(out)) + }); + } +} + +#[derive(Clone, Debug, Copy, PartialEq)] +pub struct RhaiStaticReflectReference(pub TypeId); + +impl CustomType for RhaiStaticReflectReference { + fn build(mut builder: rhai::TypeBuilder) { + builder + .with_name(std::any::type_name::()) + .with_indexer_get(|self_: &mut Self, index: Dynamic| { + let world = ThreadWorldContainer.get_world(); + let type_id = self_.0; + let key: ScriptValue = ScriptValue::from_dynamic(index)?; + + let key = match key.as_string() { + Ok(name) => match world.lookup_function([type_id], name) { + Ok(func) => return Ok(Dynamic::from(func)), + Err(key) => ScriptValue::String(key), + }, + Err(key) => key, + }; + + Err::<_, Box>( + InteropError::missing_function(type_id, key.display_with_world(world.clone())) + .into(), + ) }); } } diff --git a/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs b/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs index bbf2a5922c..d33e4b320d 100644 --- a/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs +++ b/crates/languages/bevy_mod_scripting_rhai/src/bindings/script_value.rs @@ -11,7 +11,7 @@ use bevy_mod_scripting_core::{ }; use rhai::{ plugin::{PluginFunc, RhaiFunc}, - Dynamic, EvalAltResult, + Dynamic, EvalAltResult, FnPtr, RhaiNativeFunc, }; pub const RHAI_CALLER_CONTEXT: CallerContext = CallerContext { @@ -24,72 +24,89 @@ struct FuncWrapper(DynamicScriptFunction); #[allow(dead_code)] struct FuncMutWrapper(DynamicScriptFunctionMut); -impl PluginFunc for FuncWrapper { - fn call( - &self, - _context: Option, - _args: &mut [&mut Dynamic], - ) -> rhai::plugin::RhaiResult { - // let convert_args = _args - // .iter_mut() - // .map(|arg| ScriptValue::from_dynamic(arg.clone())) - // .collect::, _>>()?; - - // let out = self.0.call( - // rhai_caller_context(self.0.info.namespace()), - // WorldCallbackAccess::from_guard(ThreadWorldContainer.get_world()), - // convert_args, - // ); - - // out.into_dynamic() +impl RhaiNativeFunc for FuncWrapper { + fn into_rhai_function(self, is_pure: bool, is_volatile: bool) -> RhaiFunc { todo!() } - fn is_method_call(&self) -> bool { - // TODO: is this correct? do we care if it's a method call? - false - } - - fn has_context(&self) -> bool { - false - } -} - -impl PluginFunc for FuncMutWrapper { - fn call( - &self, - _context: Option, - _args: &mut [&mut Dynamic], - ) -> rhai::plugin::RhaiResult { - // let convert_args = _args - // .iter_mut() - // .map(|arg| ScriptValue::from_dynamic(arg.clone())) - // .collect::, _>>()?; - - // let out = self.0.call( - // rhai_caller_context(self.0.info.namespace()), - // WorldCallbackAccess::from_guard(ThreadWorldContainer.get_world()), - // convert_args, - // ); - - // out.into_dynamic() + fn param_types() -> [std::any::TypeId; N] { todo!() } - - fn is_method_call(&self) -> bool { - false - } - - fn has_context(&self) -> bool { - false - } } +// impl PluginFunc for FuncWrapper { +// fn call( +// &self, +// _context: Option, +// _args: &mut [&mut Dynamic], +// ) -> rhai::plugin::RhaiResult { +// // let convert_args = _args +// // .iter_mut() +// // .map(|arg| ScriptValue::from_dynamic(arg.clone())) +// // .collect::, _>>()?; + +// // let out = self.0.call( +// // rhai_caller_context(self.0.info.namespace()), +// // WorldCallbackAccess::from_guard(ThreadWorldContainer.get_world()), +// // convert_args, +// // ); + +// // out.into_dynamic() +// todo!() +// } + +// fn is_method_call(&self) -> bool { +// // TODO: is this correct? do we care if it's a method call? +// false +// } + +// fn has_context(&self) -> bool { +// false +// } +// } + +// impl PluginFunc for FuncMutWrapper { +// fn call( +// &self, +// _context: Option, +// _args: &mut [&mut Dynamic], +// ) -> rhai::plugin::RhaiResult { +// // let convert_args = _args +// // .iter_mut() +// // .map(|arg| ScriptValue::from_dynamic(arg.clone())) +// // .collect::, _>>()?; + +// // let out = self.0.call( +// // rhai_caller_context(self.0.info.namespace()), +// // WorldCallbackAccess::from_guard(ThreadWorldContainer.get_world()), +// // convert_args, +// // ); + +// // out.into_dynamic() +// todo!() +// } + +// fn is_method_call(&self) -> bool { +// false +// } + +// fn has_context(&self) -> bool { +// false +// } +// } + #[allow(dead_code)] pub(crate) fn to_rhai_fn(func: DynamicScriptFunction) -> RhaiFunc { RhaiFunc::Plugin { func: Arc::new(FuncWrapper(func)), } + .into() + // FnPtr { + // name: todo!(), + // curry: todo!(), + // environ: todo!(), + // fn_def: todo!(), + // } } pub(crate) fn to_rhai_fn_mut(func: DynamicScriptFunctionMut) -> RhaiFunc { @@ -123,8 +140,8 @@ impl IntoDynamic for ScriptValue { ScriptValue::List(_vec) => todo!(), ScriptValue::Reference(_reflect_reference) => todo!(), ScriptValue::FunctionMut(func) => Dynamic::from(to_rhai_fn_mut(func)), + ScriptValue::Function(func) => Dynamic::from(to_rhai_fn(func)), ScriptValue::Error(_interop_error) => todo!(), - ScriptValue::Function(_dynamic_script_function) => todo!(), }) } } diff --git a/crates/languages/bevy_mod_scripting_rhai/src/lib.rs b/crates/languages/bevy_mod_scripting_rhai/src/lib.rs index e7acadef85..dfc5aa77ab 100644 --- a/crates/languages/bevy_mod_scripting_rhai/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_rhai/src/lib.rs @@ -10,9 +10,12 @@ use bevy_mod_scripting_core::{ context::{ContextBuilder, ContextInitializer, ContextPreHandlingInitializer}, error::ScriptError, event::CallbackLabel, + reflection_extensions::PartialReflectExt, + runtime::RuntimeSettings, script::ScriptId, IntoScriptPluginParams, ScriptingPlugin, }; +use bindings::reference::{RhaiReflectReference, RhaiStaticReflectReference}; use rhai::{CallFnOptions, Engine, FnPtr, Scope, AST}; pub use rhai; @@ -44,7 +47,12 @@ impl Default for RhaiScriptingPlugin { fn default() -> Self { RhaiScriptingPlugin { scripting_plugin: ScriptingPlugin { - runtime_settings: None, + runtime_settings: Some(RuntimeSettings { + initializers: vec![|runtime: &mut Engine| { + runtime.build_type::(); + runtime.build_type::(); + }], + }), callback_handler: Some(rhai_callback_handler), context_assigner: None, context_builder: Some(ContextBuilder { @@ -54,10 +62,20 @@ impl Default for RhaiScriptingPlugin { language_mapper: Some(AssetPathToLanguageMapper { map: rhai_language_mapper, }), - context_initializers: Default::default(), - context_pre_handling_initializers: vec![|_script, _entity, context| { + context_initializers: vec![|_script_id: _, context: &mut RhaiScriptContext| { + context.scope.set_or_push( + "world", + RhaiStaticReflectReference(std::any::TypeId::of::()), + ); + Ok(()) + }], + context_pre_handling_initializers: vec![|script, entity, context| { let world = ThreadWorldContainer.get_world(); - context.scope.push("world", world); + context.scope.set_or_push( + "entity", + RhaiReflectReference(::allocate(Box::new(entity), world)), + ); + context.scope.set_or_push("script_id", script.to_owned()); Ok(()) }], }, @@ -76,6 +94,24 @@ impl Plugin for RhaiScriptingPlugin { fn build(&self, app: &mut bevy::prelude::App) { self.scripting_plugin.build(app); } + + fn cleanup(&self, _app: &mut bevy::prelude::App) { + // let mut runtime = app + // .world_mut() + // .get_non_send_resource_mut::>() + // .expect("Rhai runtime not found"); + // let engine = &mut runtime.runtime; + // let function_registry = app + // .world_mut() + // .get_resource_or_init::(); + + // let function_registry = function_registry.read(); + + // for (k, func) in function_registry.iter_all() { + // let rhai_func = to_rhai_fn(func.clone()); + // // engine.register_fn("func", rhai_func); + // } + } } pub fn rhai_context_load( diff --git a/crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/missing_type_returns_nothing.rhai b/crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/missing_type_returns_nothing.rhai index ea44877a9e..22003426e8 100644 --- a/crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/missing_type_returns_nothing.rhai +++ b/crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/missing_type_returns_nothing.rhai @@ -1,2 +1,4 @@ -assert(false); -assert(world.get_type_by_name("UnregisteredType") == (), "Unregistered type was found"); +let my_fn = world["get_type_by_name"]; +print(my_fn); +let type = my_fn("UnregisteredType"); +assert(type == (), "Unregistered type was found"); diff --git a/crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/registered_type_returns_correct_type.rhai b/crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/registered_type_returns_correct_type.rhai index 3ee1a0a08f..4634858d09 100644 --- a/crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/registered_type_returns_correct_type.rhai +++ b/crates/languages/bevy_mod_scripting_rhai/tests/data/get_type_by_name/registered_type_returns_correct_type.rhai @@ -1,4 +1,4 @@ -local type = world.get_type_by_name('TestComponent') +let type = world.get_type_by_name("TestComponent"); local expected = { type_name = 'test_utils::test_data::TestComponent', diff --git a/examples/game_of_life.rs b/examples/game_of_life.rs index 41334d8d23..a7fa3617cb 100644 --- a/examples/game_of_life.rs +++ b/examples/game_of_life.rs @@ -22,7 +22,7 @@ use bevy_mod_scripting_core::{ systems::event_handler, }; use bevy_mod_scripting_lua::LuaScriptingPlugin; -use bevy_mod_scripting_rhai::RhaiScriptingPlugin; +// use bevy_mod_scripting_rhai::RhaiScriptingPlugin; use clap::Parser; // CONSOLE SETUP @@ -98,7 +98,7 @@ fn game_of_life_app(app: &mut App) -> &mut App { .add_plugins(( // for scripting LuaScriptingPlugin::default(), - RhaiScriptingPlugin::default(), + // RhaiScriptingPlugin::default(), ScriptFunctionsPlugin, )) .register_type::() @@ -114,9 +114,9 @@ fn game_of_life_app(app: &mut App) -> &mut App { send_on_update.after(update_rendered_state), ( event_handler::, - event_handler::, + // event_handler::, event_handler::, - event_handler::, + // event_handler::, ) .after(send_on_update), ), diff --git a/release-plz.toml b/release-plz.toml index d78291e7cd..a13e3450b6 100644 --- a/release-plz.toml +++ b/release-plz.toml @@ -25,8 +25,8 @@ git_release_body = """ changelog_include = [ "bevy_mod_scripting_lua", "bevy_mod_scripting_core", - "bevy_mod_scripting_rhai", - "bevy_mod_scripting_rune", + # "bevy_mod_scripting_rhai", + # "bevy_mod_scripting_rune", "bevy_mod_scripting_functions", ] @@ -39,13 +39,13 @@ version_group = "main" name = "bevy_mod_scripting_core" version_group = "main" -[[package]] -name = "bevy_mod_scripting_rhai" -version_group = "main" +# [[package]] +# name = "bevy_mod_scripting_rhai" +# version_group = "main" -[[package]] -name = "bevy_mod_scripting_rune" -version_group = "main" +# [[package]] +# name = "bevy_mod_scripting_rune" +# version_group = "main" [[package]] name = "bevy_mod_scripting_functions" diff --git a/src/lib.rs b/src/lib.rs index 6a00b7edd9..2d764464de 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,14 +9,14 @@ pub mod lua { pub use bevy_mod_scripting_lua::*; } -#[cfg(feature = "rhai")] -pub mod rhai { - pub use bevy_mod_scripting_rhai::*; -} +// #[cfg(feature = "rhai")] +// pub mod rhai { +// pub use bevy_mod_scripting_rhai::*; +// } -#[cfg(feature = "rune")] -pub mod rune { - pub use bevy_mod_scripting_rune::*; -} +// #[cfg(feature = "rune")] +// pub mod rune { +// pub use bevy_mod_scripting_rune::*; +// } pub use bevy_mod_scripting_functions::*; From c7167254575ab36e69e499335b3e9c190d385669 Mon Sep 17 00:00:00 2001 From: makspll Date: Sun, 12 Jan 2025 14:50:46 +0000 Subject: [PATCH 15/21] correct for changed features in xtasks --- .github/workflows/bevy_mod_scripting.yml | 1 - crates/xtask/src/main.rs | 31 ++++++++++-------------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/.github/workflows/bevy_mod_scripting.yml b/.github/workflows/bevy_mod_scripting.yml index 2e9f2e9ef0..8ccd293e40 100644 --- a/.github/workflows/bevy_mod_scripting.yml +++ b/.github/workflows/bevy_mod_scripting.yml @@ -32,7 +32,6 @@ jobs: {label: Windows, os: windows-latest }, {label: MacOS, os: macOS-latest }, {label: Ubuntu, os: ubuntu-latest }, - {label: Ubuntu Aarch64, os: ubuntu-latest } ] steps: - name: Checkout diff --git a/crates/xtask/src/main.rs b/crates/xtask/src/main.rs index a30d7c851a..93985c424d 100644 --- a/crates/xtask/src/main.rs +++ b/crates/xtask/src/main.rs @@ -3,7 +3,7 @@ use clap::Parser; use itertools::Itertools; use log::*; use std::{collections::HashMap, ffi::OsStr, path::Path, process::Command, str::FromStr}; -use strum::VariantNames; +use strum::{IntoEnumIterator, VariantNames}; #[derive( Clone, @@ -33,19 +33,18 @@ enum Feature { MluaSerialize, MluaMacros, MluaAsync, - // Rhai - Rhai, + // Rhai, // Rune - Rune, + // Rune, } -#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, strum::EnumIter)] enum FeatureGroup { LuaExclusive, - RhaiExclusive, - RuneExclusive, + // RhaiExclusive, + // RuneExclusive, ForExternalCrate, BMSFeature, } @@ -54,8 +53,8 @@ impl FeatureGroup { fn default_feature(self) -> Feature { match self { FeatureGroup::LuaExclusive => Feature::Lua54, - FeatureGroup::RhaiExclusive => Feature::Rhai, - FeatureGroup::RuneExclusive => Feature::Rune, + // FeatureGroup::RhaiExclusive => Feature::Rhai, + // FeatureGroup::RuneExclusive => Feature::Rune, _ => panic!("No default feature for non-exclusive group"), } } @@ -63,7 +62,7 @@ impl FeatureGroup { fn is_exclusive(self) -> bool { matches!( self, - FeatureGroup::LuaExclusive | FeatureGroup::RhaiExclusive | FeatureGroup::RuneExclusive + FeatureGroup::LuaExclusive // | FeatureGroup::RhaiExclusive | FeatureGroup::RuneExclusive ) } } @@ -82,8 +81,8 @@ impl IntoFeatureGroup for Feature { | Feature::Luajit | Feature::Luajit52 | Feature::Luau => FeatureGroup::LuaExclusive, - Feature::Rhai => FeatureGroup::RhaiExclusive, - Feature::Rune => FeatureGroup::RuneExclusive, + // Feature::Rhai => FeatureGroup::RhaiExclusive, + // Feature::Rune => FeatureGroup::RuneExclusive, Feature::MluaAsync | Feature::MluaMacros | Feature::MluaSerialize @@ -695,12 +694,8 @@ impl Xtasks { ); // choose language features - for category in [ - FeatureGroup::LuaExclusive, - FeatureGroup::RhaiExclusive, - FeatureGroup::RuneExclusive, - ] { - feature_set.0.push(category.default_feature()); + for exclusive_category in FeatureGroup::iter().filter(|g| g.is_exclusive()) { + feature_set.0.push(exclusive_category.default_feature()); } // include all non-bms features From 7d2adc03cde6d2f9dfa73cd5966db0edf9e68c87 Mon Sep 17 00:00:00 2001 From: makspll Date: Sun, 12 Jan 2025 15:04:19 +0000 Subject: [PATCH 16/21] Add note in readme about removal of features --- readme.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 8ad2ac888b..83a6284773 100644 --- a/readme.md +++ b/readme.md @@ -20,7 +20,7 @@ Although Bevy doesn't directly support scripting, efforts are underway to incorp - All script bindings managed in one place (`ScriptDynamicFunctionRegistry`) - Customizable event driven communication between bevy and scripts (`on_update`, `on_init` etc..) - Automatically generated bevy bindings -- ~Documentation generation~ temporarilly on hold +- ~Documentation generation~ temporarilly on hold[^1] ## Support @@ -35,9 +35,13 @@ The languages currently supported are as follows: |Luajit| |Luajit52| |Luau| -|Rhai| -|Rune| +|~~Rhai~~ temporarilly on hold[^1]| +|~~Rune~~ temporarilly on hold[^1]| ## Documentation For examples, installation and usage instructions see our shiny new [book](https://makspll.github.io/bevy_mod_scripting) + +## Footnotes + +[^1]: Due to the recent re-write of the crate, documentation generation as well as rhai and rune support are temporarilly on hold. They will likely be re-implemented in the future. `Rhai` in particualar is difficult to re-implement due to a lack of support for first-class-functions. \ No newline at end of file From fe7fde03fe71a3b037d86135c4b3be58c6cef5bc Mon Sep 17 00:00:00 2001 From: makspll Date: Sun, 12 Jan 2025 15:20:22 +0000 Subject: [PATCH 17/21] start adding documentation for new languages --- CONTRIBUTING.MD | 3 +- .../AddingLanguages/evaluating-feasibility.md | 8 +++++ .../AddingLanguages/introduction.md | 3 ++ docs/src/Development/introduction.md | 7 ++++ docs/src/Development/setup.md | 32 +++++++++++++++++++ docs/src/SUMMARY.md | 7 ++++ 6 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 docs/src/Development/AddingLanguages/evaluating-feasibility.md create mode 100644 docs/src/Development/AddingLanguages/introduction.md create mode 100644 docs/src/Development/introduction.md create mode 100644 docs/src/Development/setup.md diff --git a/CONTRIBUTING.MD b/CONTRIBUTING.MD index a6bc9b9c01..1eb69e284e 100644 --- a/CONTRIBUTING.MD +++ b/CONTRIBUTING.MD @@ -135,8 +135,7 @@ Enhancement suggestions are tracked as [GitHub issues](https://github.com/makspl ### Your First Code Contribution -This project uses xtask to manage the build and test process. You can run `cargo xtask` to see the available commands. Run `xtask init` to setup your local development environment. - +Before contributing see the [book](https://makspll.github.io/bevy_mod_scripting) for helpful guides on how to get started with the project. ### Improving The Documentation diff --git a/docs/src/Development/AddingLanguages/evaluating-feasibility.md b/docs/src/Development/AddingLanguages/evaluating-feasibility.md new file mode 100644 index 0000000000..2037574d75 --- /dev/null +++ b/docs/src/Development/AddingLanguages/evaluating-feasibility.md @@ -0,0 +1,8 @@ +# Evaluating Feasibility + +In order for a language to work well with BMS it's necessary it supports the following features: +- [ ] Interoperability with Rust. If you can't call it from Rust easilly and there is no existing crate that can do it for you, it's a no-go. +- [ ] First class functions. Or at least the ability to call an arbitrary function with an arbitrary number of arguments from a script. Without this feature, you would need to separately generate code for the bevy bindings. This is painful and goes against the grain of the project. + +## First Classs Functions + diff --git a/docs/src/Development/AddingLanguages/introduction.md b/docs/src/Development/AddingLanguages/introduction.md new file mode 100644 index 0000000000..0b25745afd --- /dev/null +++ b/docs/src/Development/AddingLanguages/introduction.md @@ -0,0 +1,3 @@ +# Adding New Languages to BMS + +If you are interested in adding a new language to BMS, please read this section first. Adding a new language is a non-trivial task depending on the language you want to add. It also requires a lot of effort and time to maintain a new language, so unless the language you want to add is widely used and has a large community, it might not be worth the effort. \ No newline at end of file diff --git a/docs/src/Development/introduction.md b/docs/src/Development/introduction.md new file mode 100644 index 0000000000..be6eca38c4 --- /dev/null +++ b/docs/src/Development/introduction.md @@ -0,0 +1,7 @@ +# Developing BMS + +This section is for developers who want to contribute to the BMS project. It covers various topics necessary for understanding the project and contributing to it. + +## Contributing + +Please see the [code of conduct](https://github.com/makspll/bevy_mod_scripting/blob/main/CODE_OF_CONDUCT.md) as well as the [contributing guidelines](https://github.com/makspll/bevy_mod_scripting/blob/main/CONTRIBUTING.md) first. \ No newline at end of file diff --git a/docs/src/Development/setup.md b/docs/src/Development/setup.md new file mode 100644 index 0000000000..fffe7856b2 --- /dev/null +++ b/docs/src/Development/setup.md @@ -0,0 +1,32 @@ +# Setup + +this crate contains a work in progress `xtask` setup which in theory should allow you to setup everything you need for local development by running: + +```sh +cargo xtask init +``` + +However at the moment it does not generate IDE specific files for you, so you will need to do that manually. + +## VScode + +For vscode you will want to enter the following into your `settings.json` + +```json +{ + "rust-analyzer.rustc.source": "discover", + "rust-analyzer.linkedProjects": [ + // "./crates/bevy_api_gen/Cargo.toml", uncommenting this is currently not fully supported with xtask + vscode, rust analyzer bugs out a lot sadly + "Cargo.toml", + ], + "rust-analyzer.check.invocationStrategy": "once", + "rust-analyzer.check.overrideCommand": [ + "/absolute-path-to-this-project/bevy_mod_scripting/check.sh" + ], + "rust-analyzer.cargo.buildScripts.overrideCommand": [ + "/absolute-path-to-this-project/bevy_mod_scripting/check.sh" + ], +} +``` + +If you are on windows you might need to create an equivalent `check.exe` to run `cargo xtask check --ide-mode` in the root directory of this workspace. diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 6e3b71226c..3c327ceeb0 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -18,3 +18,10 @@ - [ScriptQueryBuilder](./ScriptingReference/script-query-builder.md) - [ScriptQueryResult](./ScriptingReference/script-query-result.md) - [Core Callbacks](./ScriptingReference/core-callbacks.md) + +# Developing BMS + +- [Introduction](./Development/introduction.md) + - [Setup](./Development/setup.md) +- [New Languages](./Development/AddingLanguages/introduction.md) + - [Evaluating Feasibility](./Development/AddingLanguages/evaluating-feasibility.md) \ No newline at end of file From d3a3a9e020a9b9f901cea34ba602a53828169e4c Mon Sep 17 00:00:00 2001 From: makspll Date: Sun, 12 Jan 2025 15:20:53 +0000 Subject: [PATCH 18/21] format --- .../bevy_mod_scripting_lua/tests/lua_tests.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/crates/languages/bevy_mod_scripting_lua/tests/lua_tests.rs b/crates/languages/bevy_mod_scripting_lua/tests/lua_tests.rs index 95c12a946f..672a5f576d 100644 --- a/crates/languages/bevy_mod_scripting_lua/tests/lua_tests.rs +++ b/crates/languages/bevy_mod_scripting_lua/tests/lua_tests.rs @@ -1,4 +1,8 @@ -use bevy_mod_scripting_core::{bindings::{pretty_print::DisplayWithWorld, ThreadWorldContainer, WorldContainer}, error::ScriptError, AddContextInitializer}; +use bevy_mod_scripting_core::{ + bindings::{pretty_print::DisplayWithWorld, ThreadWorldContainer, WorldContainer}, + error::ScriptError, + AddContextInitializer, +}; use bevy_mod_scripting_lua::LuaScriptingPlugin; use libtest_mimic::{Arguments, Failed, Trial}; use mlua::{Function, Lua, MultiValue}; @@ -36,11 +40,11 @@ impl Test { "Expected function to throw error, but it did not.", )) } - Err(e) => + Err(e) => ScriptError::from_mlua_error(e).display_with_world(world) , }; - + let regex = regex::Regex::new(®).unwrap(); if regex.is_match(&err) { Ok(()) From 94cb1c19f8d9f9e802ca089a1a31626d531a7885 Mon Sep 17 00:00:00 2001 From: makspll Date: Mon, 13 Jan 2025 13:06:07 +0000 Subject: [PATCH 19/21] fix failing test utils test --- crates/test_utils/Cargo.toml | 2 +- crates/test_utils/src/test_data.rs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/test_utils/Cargo.toml b/crates/test_utils/Cargo.toml index 9c3b96d895..7adc1968dd 100644 --- a/crates/test_utils/Cargo.toml +++ b/crates/test_utils/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" publish = false [dependencies] -bevy = { workspace = true } +bevy = { workspace = true, features = ["bevy_asset"] } [lib] path = "src/lib.rs" diff --git a/crates/test_utils/src/test_data.rs b/crates/test_utils/src/test_data.rs index c869c48b87..d12305d1ed 100644 --- a/crates/test_utils/src/test_data.rs +++ b/crates/test_utils/src/test_data.rs @@ -1,5 +1,6 @@ use std::alloc::Layout; +use bevy::asset::AssetPlugin; use bevy::ecs::{component::*, world::World}; use bevy::prelude::*; use bevy::reflect::*; @@ -225,6 +226,9 @@ impl_test_component_ids!( ); fn init_world(world: &mut World, init: F) { + let type_registry = world.get_resource_or_init::().clone(); + let mut type_registry_guard = type_registry.0.write(); + while world.components().len() < TEST_COMPONENT_ID_START { unsafe { world.register_component_with_descriptor(ComponentDescriptor::new_with_layout( @@ -236,8 +240,6 @@ fn init_world(world: &mut World, init: }; } - let type_registry = world.get_resource_or_init::().clone(); - let mut type_registry_guard = type_registry.0.write(); init_all_components(world, &mut type_registry_guard); init(world, &mut type_registry_guard); } From bd152c0c14f399e968198260a43cf6c32037860d Mon Sep 17 00:00:00 2001 From: makspll Date: Mon, 13 Jan 2025 15:22:46 +0000 Subject: [PATCH 20/21] generate matrix from xtask --- crates/xtask/Cargo.toml | 2 + crates/xtask/readme.md | 6 +- crates/xtask/src/main.rs | 410 +++++++++++++++++++++++++++++++-------- 3 files changed, 332 insertions(+), 86 deletions(-) diff --git a/crates/xtask/Cargo.toml b/crates/xtask/Cargo.toml index 07c4edff59..3e8b62803d 100644 --- a/crates/xtask/Cargo.toml +++ b/crates/xtask/Cargo.toml @@ -17,3 +17,5 @@ pretty_env_logger = "0.5" log = "0.4" itertools = "0.14" cargo_metadata = "*" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" diff --git a/crates/xtask/readme.md b/crates/xtask/readme.md index e95f8ae159..4b50c80830 100644 --- a/crates/xtask/readme.md +++ b/crates/xtask/readme.md @@ -1,3 +1,7 @@ # X-Tasks -This crate provides a set of tasks to be used in CI/CD pipelines as well as for local development. \ No newline at end of file +This crate provides a set of tasks to be used in CI/CD pipelines as well as for local development. + +## Developing + +When developing it's reccomended to open this in a separate window if using Vscode, as otherwise since this crate is used to compile itself effectively, you will not get IDE feedback. \ No newline at end of file diff --git a/crates/xtask/src/main.rs b/crates/xtask/src/main.rs index 93985c424d..b41406404e 100644 --- a/crates/xtask/src/main.rs +++ b/crates/xtask/src/main.rs @@ -2,7 +2,15 @@ use anyhow::*; use clap::Parser; use itertools::Itertools; use log::*; -use std::{collections::HashMap, ffi::OsStr, path::Path, process::Command, str::FromStr}; +use serde::Serialize; +use std::{ + collections::{HashMap, HashSet}, + ffi::{OsStr, OsString}, + io::Write, + path::Path, + process::Command, + str::FromStr, +}; use strum::{IntoEnumIterator, VariantNames}; #[derive( @@ -11,6 +19,9 @@ use strum::{IntoEnumIterator, VariantNames}; Debug, PartialEq, Eq, + Hash, + PartialOrd, + Ord, strum::EnumString, strum::EnumIter, strum::Display, @@ -87,15 +98,20 @@ impl IntoFeatureGroup for Feature { | Feature::MluaMacros | Feature::MluaSerialize | Feature::UnsafeLuaModules => FeatureGroup::ForExternalCrate, - _ => FeatureGroup::BMSFeature, + Feature::BevyBindings | Feature::CoreFunctions => FeatureGroup::BMSFeature, + // don't use wildcard here, we want to be explicit } } } -#[derive(Debug, Clone)] -struct Features(Vec); +#[derive(Debug, Clone, PartialEq, Eq)] +struct Features(HashSet); impl Features { + fn new>(features: I) -> Self { + Self(features.into_iter().collect()) + } + /// Returns all features except the exclusive ones which are not the default fn all_features() -> Self { // remove exclusive features which are not the default @@ -111,6 +127,16 @@ impl Features { ) } + fn non_exclusive_features() -> Self { + Self( + ::VARIANTS + .iter() + .filter(|f| !f.to_feature_group().is_exclusive()) + .cloned() + .collect(), + ) + } + fn to_cargo_args(&self) -> Vec { if self.0.is_empty() { vec![] @@ -135,7 +161,10 @@ impl Features { impl std::fmt::Display for Features { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - for (i, feature) in self.0.iter().enumerate() { + if &Self::all_features() == self { + return write!(f, "all"); + } + for (i, feature) in self.0.iter().sorted().enumerate() { if i > 0 { write!(f, ",")?; } @@ -148,7 +177,7 @@ impl std::fmt::Display for Features { impl From for Features { fn from(s: String) -> Self { if s.is_empty() { - return Self(vec![]); + return Self::new(vec![]); } let features = s @@ -165,16 +194,115 @@ impl From for Features { } } -#[derive(Debug, Parser)] +#[derive(Debug, Clone, Parser)] struct App { - #[clap(long, short, global = true, value_parser=clap::value_parser!(Features), value_name=Features::to_placeholder(), default_value="lua54",required = false)] - features: Features, + #[clap(flatten)] + global_args: GlobalArgs, #[clap(subcommand)] subcmd: Xtasks, } -#[derive(Debug, Clone, Default, strum::EnumString, strum::VariantNames)] +impl App { + fn into_command(self) -> Command { + let mut cmd = Command::new("cargo"); + cmd.arg("xtask"); + match self.subcmd { + Xtasks::Macros { macro_name } => { + cmd.arg("macros").arg(macro_name.as_ref()); + } + Xtasks::Init => { + cmd.arg("init"); + } + Xtasks::Build => { + cmd.arg("build"); + } + Xtasks::Check { ide_mode, kind } => { + cmd.arg("check"); + if ide_mode { + cmd.arg("--ide-mode"); + } + cmd.arg("--kind").arg(kind.as_ref()); + } + Xtasks::Docs { open, no_rust_docs } => { + cmd.arg("docs"); + if open { + cmd.arg("--open"); + } + if no_rust_docs { + cmd.arg("--no-rust-docs"); + } + } + Xtasks::Test { + name, + package, + no_coverage, + } => { + cmd.arg("test"); + if let Some(name) = name { + cmd.arg("--name").arg(name); + } + if let Some(package) = package { + cmd.arg("--package").arg(package); + } + if no_coverage { + cmd.arg("--no-coverage"); + } + } + Xtasks::CiCheck => { + cmd.arg("ci-check"); + } + Xtasks::CiMatrix => { + cmd.arg("ci-matrix"); + } + } + + cmd + } + + pub(crate) fn into_command_string(self) -> OsString { + let cmd = self.into_command(); + let program = cmd.get_program(); + let args = cmd.get_args(); + let len = args.len(); + let mut os_string = OsString::new(); + os_string.push(program); + os_string.push(" "); + for (i, arg) in args.enumerate() { + os_string.push(arg); + if i < len - 1 { + os_string.push(" "); + } + } + + os_string + } + + pub(crate) fn into_ci_row(self, os: String) -> CiMatrixRow { + CiMatrixRow { + command: self.clone().into_command_string().into_string().unwrap(), + name: format!("{} - {}", self.subcmd.as_ref(), self.global_args.features), + os, + } + } +} + +#[derive(Debug, Parser, Clone)] +struct GlobalArgs { + #[clap(long, short, global = true, value_parser=clap::value_parser!(Features), value_name=Features::to_placeholder(), default_value="lua54",required = false)] + features: Features, + + #[clap( + long, + short, + global = true, + value_name = "PROFILE", + help = "The cargo profile to use for commands that support it" + )] + profile: Option, +} + +#[derive(Debug, Clone, Default, strum::EnumString, strum::VariantNames, strum::AsRefStr)] #[strum(serialize_all = "snake_case")] enum CheckKind { #[default] @@ -189,7 +317,7 @@ impl CheckKind { } } -#[derive(Debug, Clone, strum::EnumString, strum::VariantNames)] +#[derive(Debug, Clone, strum::EnumString, strum::AsRefStr, strum::VariantNames)] #[strum(serialize_all = "snake_case")] enum Macro { /// Integration tests for all script plugins @@ -202,7 +330,7 @@ impl Macro { } } -#[derive(Debug, clap::Subcommand)] +#[derive(Clone, Debug, clap::Subcommand, strum::AsRefStr)] #[clap( name = "xtask", bin_name = "cargo xtask", @@ -268,42 +396,86 @@ enum Xtasks { #[clap(long, short)] no_coverage: bool, }, - /// Perform a full check as it would be done in CI + /// Perform a full check as it would be done in CI, except not parallelised CiCheck, + /// Generate a json job matrix, containing, describing maximally parallelised jobs for running in CI/CD. + /// + /// The format of the output is: + /// + /// [ + /// { + /// "command": "the command to run" + /// } + /// ] + /// + CiMatrix, +} + +#[derive(Serialize, Clone)] +struct CiMatrixRow { + /// The command to run + command: String, + /// The display name of the job + name: String, + /// The os to run this on + os: String, } impl Xtasks { - fn run(self, features: Features) -> Result<()> { + fn run(self, app_settings: GlobalArgs) -> Result { match self { - Xtasks::Build => Self::build(features), - Xtasks::Check { ide_mode, kind } => Self::check(features, ide_mode, kind), - Xtasks::Docs { open, no_rust_docs } => Self::docs(open, no_rust_docs), + Xtasks::Build => Self::build(app_settings), + Xtasks::Check { ide_mode, kind } => Self::check(app_settings, ide_mode, kind), + Xtasks::Docs { open, no_rust_docs } => Self::docs(app_settings, open, no_rust_docs), Xtasks::Test { name, package, no_coverage, - } => Self::test(features, name, package, no_coverage), - Xtasks::CiCheck => Self::cicd(), - Xtasks::Init => Self::init(), + } => Self::test(app_settings, name, package, no_coverage), + Xtasks::CiCheck => Self::cicd(app_settings), + Xtasks::Init => Self::init(app_settings), Xtasks::Macros { macro_name } => match macro_name { - Macro::ScriptTests => Self::test( - Features::all_features(), - Some("script_test".to_owned()), - None, - true, - ), + Macro::ScriptTests => { + let mut settings = app_settings.clone(); + settings.features = Features::all_features(); + Self::test(settings, Some("script_test".to_owned()), None, true) + } }, - } - } + Xtasks::CiMatrix => { + let output = Self::ci_matrix(app_settings)?; + let mut matrix = output + .into_iter() + .map(|a| a.into_ci_row("ubuntu-latest".to_owned())) + .collect::>(); - // TODO: have a global args struct instead of this - fn set_cargo_profile(profile: &str) { - std::env::set_var("BMS_CARGO_PROFILE", profile); - } + // clone for macos and windows for certain steps + let mut multi_os_steps = matrix.clone(); + + // we don't need to verify all feature flags on all platforms, this is mostly a "does it compile" check + // for finding out missing compile time logic or bad imports + multi_os_steps + .retain(|e| !e.command.contains("build") && !e.command.contains("docs")); + + let mut macos_matrix = multi_os_steps.clone(); + let mut windows_matrix = multi_os_steps.clone(); + + for row in macos_matrix.iter_mut() { + row.os = "macos-latest".to_owned(); + } + + for row in windows_matrix.iter_mut() { + row.os = "windows-latest".to_owned(); + } + + matrix.extend(macos_matrix); + matrix.extend(windows_matrix); + + let json = serde_json::to_string_pretty(&matrix)?; + return Ok(json); + } + }?; - fn get_cargo_profile() -> Option { - let val = std::env::var("BMS_CARGO_PROFILE").ok(); - val.filter(|v| !v.is_empty()) + Ok("".into()) } fn cargo_metadata() -> Result { @@ -369,9 +541,9 @@ impl Xtasks { } fn run_workspace_command>>( + app_settings: &GlobalArgs, command: &str, context: &str, - features: Features, add_args: I, dir: Option<&Path>, ) -> Result<()> { @@ -380,13 +552,13 @@ impl Xtasks { let mut args = vec![]; args.push(command.to_owned()); args.push("--workspace".to_owned()); - let profile = Self::get_cargo_profile(); - if let Some(profile) = profile { + + if let Some(profile) = app_settings.profile.as_ref() { args.push("--profile".to_owned()); - args.push(profile); + args.push(profile.clone()); } - args.extend(features.to_cargo_args()); + args.extend(app_settings.features.to_cargo_args()); args.extend(add_args.into_iter().map(|s| { s.as_ref() .to_str() @@ -411,26 +583,27 @@ impl Xtasks { match output.status.code() { Some(0) => Ok(()), _ => bail!( - "{} failed with exit code: {}. Features: {features}", + "{} failed with exit code: {}. Features: {}", context, - output.status.code().unwrap_or(-1) + output.status.code().unwrap_or(-1), + app_settings.features ), } } - fn build(features: Features) -> Result<()> { + fn build(app_settings: GlobalArgs) -> Result<()> { // build workspace using the given features Self::run_workspace_command( + &app_settings, "build", "Failed to build workspace", - features, vec!["--all-targets"], None, )?; Ok(()) } - fn check_main_workspace(features: Features, ide_mode: bool) -> Result<()> { + fn check_main_workspace(app_settings: GlobalArgs, ide_mode: bool) -> Result<()> { // start with cargo clippy let mut clippy_args = vec![]; if ide_mode { @@ -439,9 +612,9 @@ impl Xtasks { clippy_args.extend(vec!["--all-targets", "--", "-D", "warnings"]); Self::run_workspace_command( + &app_settings, "clippy", "Failed to run clippy", - features, clippy_args, None, )?; @@ -461,7 +634,7 @@ impl Xtasks { Ok(()) } - fn check_codegen_crate(_ide_mode: bool) -> Result<()> { + fn check_codegen_crate(_app_settings: GlobalArgs, _ide_mode: bool) -> Result<()> { // set the working directory to the codegen crate // let crates_path = Self::relative_workspace_dir(PathBuf::from("crates"))?; // let codegen_crate_path = crates_path.join("bevy_api_gen"); @@ -484,23 +657,23 @@ impl Xtasks { Ok(()) } - fn check(features: Features, ide_mode: bool, kind: CheckKind) -> Result<()> { + fn check(app_settings: GlobalArgs, ide_mode: bool, kind: CheckKind) -> Result<()> { match kind { CheckKind::All => { - Self::check_main_workspace(features.clone(), ide_mode)?; - Self::check_codegen_crate(ide_mode)?; + Self::check_main_workspace(app_settings.clone(), ide_mode)?; + Self::check_codegen_crate(app_settings, ide_mode)?; } CheckKind::Main => { - Self::check_main_workspace(features, ide_mode)?; + Self::check_main_workspace(app_settings, ide_mode)?; } CheckKind::Codegen => { - Self::check_codegen_crate(ide_mode)?; + Self::check_codegen_crate(app_settings, ide_mode)?; } } Ok(()) } - fn docs(open: bool, no_rust_docs: bool) -> Result<()> { + fn docs(mut app_settings: GlobalArgs, open: bool, no_rust_docs: bool) -> Result<()> { // find [package.metadata."docs.rs"] key in Cargo.toml if !no_rust_docs { info!("Building rust docs"); @@ -534,7 +707,8 @@ impl Xtasks { .map(|s| Feature::from_str(s).expect("invalid feature")) .collect::>(); - let features = Features(string_list); + let features = Features::new(string_list); + app_settings.features = features; let mut args = Vec::default(); args.push("--all"); @@ -542,9 +716,9 @@ impl Xtasks { args.push("--open"); } Self::run_workspace_command( + &app_settings, "doc", "Failed to build crates.io docs", - features.clone(), args, None, )?; @@ -565,7 +739,7 @@ impl Xtasks { } fn test( - features: Features, + app_settings: GlobalArgs, package: Option, name: Option, no_coverage: bool, @@ -599,9 +773,9 @@ impl Xtasks { } Self::run_workspace_command( + &app_settings, "test", "Failed to run tests", - features, vec!["--exclude", "xtask"], None, )?; @@ -657,18 +831,18 @@ impl Xtasks { Ok(()) } - fn cicd() -> Result<()> { - // set profile - Self::set_cargo_profile("ephemeral-build"); + fn ci_matrix(app_settings: GlobalArgs) -> Result> { + // split up the tests we want to run into different jobs + // everything that can be parallelised should be + // each row in the output will correspond to a separate job in the matrix. - // setup the CI environment - Self::init()?; + let mut output = vec![]; - // run everything with the ephemereal profile - // first check everything compiles with every combination of features apart from mutually exclusive ones - let all_features = Features(::VARIANTS.into()); + // first of all we run a powerset of check commands with various features enabled. all of which can be run in parallel + let available_features = + Features::new(::VARIANTS.iter().cloned()); - let grouped = all_features.split_by_group(); + let grouped = available_features.split_by_group(); let features_to_combine = grouped .get(&FeatureGroup::BMSFeature) @@ -679,23 +853,19 @@ impl Xtasks { .iter() .cloned() .powerset() + .map(Features::new) .collect::>(); // start with longest to compile all first powersets.reverse(); info!("Powerset: {:?}", powersets); - let length = powersets.len(); - for (i, mut feature_set) in powersets.into_iter().map(Features).enumerate() { - info!( - "Running check {}/{length} with features: {}", - i + 1, - feature_set - ); + let profile = app_settings.profile.or(Some("ephemeral-build".to_owned())); + for feature_set in powersets.iter_mut() { // choose language features for exclusive_category in FeatureGroup::iter().filter(|g| g.is_exclusive()) { - feature_set.0.push(exclusive_category.default_feature()); + feature_set.0.insert(exclusive_category.default_feature()); } // include all non-bms features @@ -703,25 +873,89 @@ impl Xtasks { feature_set.0.extend(f.iter().cloned()); } - Self::build(feature_set)?; + output.push(App { + global_args: GlobalArgs { + features: feature_set.clone(), + profile: profile.clone(), + }, + subcmd: Xtasks::Build, + }) + } + + // also run a all features + each exclusive feature by itself + for feature in available_features + .0 + .iter() + .filter(|f| f.to_feature_group().is_exclusive()) + { + // run with all features + let mut features = Features::non_exclusive_features(); + features.0.insert(*feature); + + // don't include if we already ran this combination + if powersets.iter().any(|f| f == &features) { + continue; + } + + output.push(App { + global_args: GlobalArgs { + features, + profile: profile.clone(), + }, + subcmd: Xtasks::Build, + }); } - // run lints - let all_features = Features::all_features(); - Self::check(all_features.clone(), false, CheckKind::Main)?; + let global_args = GlobalArgs { + features: Features::all_features(), + profile: profile.clone(), + }; - // run docs - Self::docs(false, false)?; + // next run a full lint check with all features + output.push(App { + global_args: global_args.clone(), + subcmd: Xtasks::Check { + ide_mode: false, + kind: CheckKind::All, + }, + }); - info!("All checks passed, running tests"); + // then run docs + output.push(App { + global_args: global_args.clone(), - // run tests - Self::test(all_features, None, None, false)?; + subcmd: Xtasks::Docs { + open: false, + no_rust_docs: false, + }, + }); + + // and finally run tests with coverage + output.push(App { + global_args: global_args.clone(), + subcmd: Xtasks::Test { + name: None, + package: None, + no_coverage: false, + }, + }); + + Ok(output) + } + + fn cicd(app_settings: GlobalArgs) -> Result<()> { + // get the ci matrix + let matrix = Self::ci_matrix(app_settings.clone())?; + let length = matrix.len(); + for (i, app) in matrix.into_iter().enumerate() { + info!("Running CI job {}/{}. {:?}", i + 1, length, app.subcmd); + app.subcmd.run(app_settings.clone())?; + } Ok(()) } - fn init() -> Result<()> { + fn init(_app_settings: GlobalArgs) -> Result<()> { // install cargo mdbook Self::run_system_command( "cargo", @@ -762,7 +996,13 @@ fn try_main() -> Result<()> { .filter_level(LevelFilter::Info) .init(); let args = App::try_parse()?; - args.subcmd.run(args.features) + let out = args.subcmd.run(args.global_args)?; + // push any output to stdout + if !out.is_empty() { + std::io::stdout().write_all(out.as_bytes())?; + println!(); + } + Ok(()) } fn main() { From 93484a090578fc711a194ddfb24ad56bb169daae Mon Sep 17 00:00:00 2001 From: makspll Date: Mon, 13 Jan 2025 15:53:59 +0000 Subject: [PATCH 21/21] chore: make ci use new matrix from xtask --- .github/workflows/bevy_mod_scripting.yml | 29 +++++++++++++----------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/.github/workflows/bevy_mod_scripting.yml b/.github/workflows/bevy_mod_scripting.yml index 8ccd293e40..6b502d51b1 100644 --- a/.github/workflows/bevy_mod_scripting.yml +++ b/.github/workflows/bevy_mod_scripting.yml @@ -21,21 +21,28 @@ concurrency: cancel-in-progress: true jobs: + generate-job-matrix: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.generate-matrix.outputs.matrix }} + steps: + - name: Generate matrix + id: generate-matrix + run: | + echo "matrix=$(cargo xtask ci-matrix)" >> $GITHUB_OUTPUT + check: permissions: pull-requests: write - name: Check - ${{ matrix.run_args.label }} + name: Check - ${{ matrix.run_args.name }} runs-on: ${{ matrix.run_args.os }} + needs: generate-job-matrix strategy: matrix: - run_args: [ - {label: Windows, os: windows-latest }, - {label: MacOS, os: macOS-latest }, - {label: Ubuntu, os: ubuntu-latest }, - ] + run_args: ${{fromJson(needs.generate-job-matrix.outputs.matrix)}} steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install alsa and udev if: runner.os == 'linux' run: | @@ -49,9 +56,5 @@ jobs: uses: Swatinem/rust-cache@v2.7.3 - uses: actions-rs/cargo@v1 with: - command: xtask - args: ci-check - - uses: romeovs/lcov-reporter-action@v0.2.16 - continue-on-error: true - with: - lcov-file: ./target/coverage/lcov.info \ No newline at end of file + command: ${{ matrix.run_args.command }} + args: ci-check \ No newline at end of file