From bbfda42f38f1d6d3c7231378a37b3fe30596ae62 Mon Sep 17 00:00:00 2001 From: makspll Date: Sun, 5 Jan 2025 22:05:23 +0000 Subject: [PATCH] feat: complete plugin re-write --- .cargo/config.toml | 3 + .github/workflows/bevy_api_gen.yml | 22 +- .github/workflows/bevy_mod_scripting.yml | 114 +- .github/workflows/doc_gen.yml | 60 - .github/workflows/generate_bindings.yml | 93 + .github/workflows/macro_tests.yml | 33 - .github/workflows/mdbook.yml | 6 +- .rustfmt.toml | 5 + .vscode/launch.json | 2 +- .vscode/settings.json | 9 +- .vscode/tasks.json | 9 +- CODE_OF_CONDUCT.md | 69 + CONTRIBUTING.MD | 158 + Cargo.toml | 148 +- architecture.md | 199 - assets/scripts/bevy_api.lua | 159 + assets/scripts/coroutines.lua | 3 +- assets/scripts/dynamic_queries.lua | 30 +- assets/scripts/event_recipients.lua | 6 +- assets/scripts/game_of_life.lua | 121 +- check.exe | Bin 0 -> 26112 bytes check.ps1 | 9 + check.sh | 2 +- crates/bevy_api_gen/Cargo.bootstrap.toml | 4 +- crates/bevy_api_gen/Cargo.toml | 6 +- crates/bevy_api_gen/rust-toolchain.toml | 2 +- crates/bevy_api_gen/src/args.rs | 8 +- crates/bevy_api_gen/src/bin/main.rs | 2 +- crates/bevy_api_gen/src/callback.rs | 63 +- crates/bevy_api_gen/src/context.rs | 15 +- crates/bevy_api_gen/src/import_path.rs | 2 +- crates/bevy_api_gen/src/lib.rs | 1 + crates/bevy_api_gen/src/meta.rs | 22 + .../bevy_api_gen/src/modifying_file_loader.rs | 10 +- .../bevy_api_gen/src/passes/cache_traits.rs | 29 +- crates/bevy_api_gen/src/passes/codegen.rs | 1 + .../src/passes/find_methods_and_fields.rs | 54 +- .../src/passes/find_reflect_types.rs | 3 +- .../src/passes/find_trait_impls.rs | 8 +- .../src/passes/populate_template_data.rs | 343 +- crates/bevy_api_gen/src/plugin.rs | 11 +- crates/bevy_api_gen/src/template.rs | 34 +- crates/bevy_api_gen/templates/crate.tera | 4 - crates/bevy_api_gen/templates/field.tera | 6 +- crates/bevy_api_gen/templates/footer.tera | 102 +- crates/bevy_api_gen/templates/function.tera | 57 +- crates/bevy_api_gen/templates/header.tera | 17 +- crates/bevy_api_gen/templates/item.tera | 22 +- crates/bevy_api_gen/templates/macros.tera | 54 +- crates/bevy_api_gen/templates/mod.tera | 60 +- crates/bevy_event_priority/CHANGELOG.md | 26 - crates/bevy_event_priority/Cargo.toml | 20 - crates/bevy_event_priority/src/lib.rs | 412 - crates/bevy_mod_scripting_common/CHANGELOG.md | 21 - crates/bevy_mod_scripting_common/Cargo.toml | 33 - crates/bevy_mod_scripting_common/readme.md | 3 - crates/bevy_mod_scripting_common/src/input.rs | 678 - crates/bevy_mod_scripting_common/src/lib.rs | 2 - crates/bevy_mod_scripting_common/src/utils.rs | 59 - crates/bevy_mod_scripting_core/Cargo.toml | 25 +- crates/bevy_mod_scripting_core/src/asset.rs | 108 +- .../src/bindings/access_map.rs | 473 + .../src/bindings/allocator.rs | 248 + .../src/bindings/function/from.rs | 389 + .../src/bindings/function/from_ref.rs | 107 + .../src/bindings/function/into.rs | 168 + .../src/bindings/function/into_ref.rs | 110 + .../src/bindings/function/mod.rs | 74 + .../src/bindings/function/script_function.rs | 502 + .../src/bindings/mod.rs | 12 + .../src/bindings/pretty_print.rs | 478 + .../src/bindings/query.rs | 201 + .../src/bindings/reference.rs | 549 + .../src/bindings/script_value.rs | 170 + .../src/bindings/world.rs | 1846 ++ .../bevy_mod_scripting_core/src/commands.rs | 210 + crates/bevy_mod_scripting_core/src/context.rs | 160 + crates/bevy_mod_scripting_core/src/docs.rs | 22 +- crates/bevy_mod_scripting_core/src/error.rs | 887 +- crates/bevy_mod_scripting_core/src/event.rs | 274 +- crates/bevy_mod_scripting_core/src/handler.rs | 33 + crates/bevy_mod_scripting_core/src/hosts.rs | 453 - crates/bevy_mod_scripting_core/src/lib.rs | 376 +- .../src/reflection_extensions.rs | 657 + crates/bevy_mod_scripting_core/src/runtime.rs | 37 + crates/bevy_mod_scripting_core/src/script.rs | 40 + crates/bevy_mod_scripting_core/src/systems.rs | 627 +- crates/bevy_mod_scripting_core/src/world.rs | 5 +- .../bevy_mod_scripting_functions/Cargo.toml | 35 + .../readme.md | 2 +- .../src/bevy_bindings/bevy_core.rs | 41 + .../src/bevy_bindings/bevy_ecs.rs | 382 + .../src/bevy_bindings/bevy_hierarchy.rs | 93 + .../src/bevy_bindings/bevy_input.rs | 1399 + .../src/bevy_bindings/bevy_math.rs | 3449 +++ .../src/bevy_bindings/bevy_reflect.rs | 22065 +++++++++++++++ .../src/bevy_bindings/bevy_time.rs | 336 + .../src/bevy_bindings/bevy_transform.rs | 272 + .../src/bevy_bindings/mod.rs | 25 + .../bevy_mod_scripting_functions/src/core.rs | 430 + .../bevy_mod_scripting_functions/src/lib.rs | 18 + .../src/namespaced_register.rs | 192 + crates/bevy_script_api/CHANGELOG.md | 31 - crates/bevy_script_api/Cargo.toml | 41 - crates/bevy_script_api/readme.md | 3 - crates/bevy_script_api/src/common/bevy/mod.rs | 443 - crates/bevy_script_api/src/common/mod.rs | 2 - crates/bevy_script_api/src/common/std.rs | 141 - crates/bevy_script_api/src/core_providers.rs | 115 - crates/bevy_script_api/src/error.rs | 37 - crates/bevy_script_api/src/lib.rs | 45 - crates/bevy_script_api/src/lua/bevy/mod.rs | 386 - crates/bevy_script_api/src/lua/mod.rs | 306 - crates/bevy_script_api/src/lua/std.rs | 492 - crates/bevy_script_api/src/lua/util.rs | 427 - .../src/providers/bevy_core.rs | 95 - .../bevy_script_api/src/providers/bevy_ecs.rs | 560 - .../src/providers/bevy_hierarchy.rs | 161 - .../src/providers/bevy_input.rs | 1887 -- .../src/providers/bevy_math.rs | 5539 ---- .../src/providers/bevy_reflect.rs | 22578 ---------------- .../src/providers/bevy_time.rs | 736 - .../src/providers/bevy_transform.rs | 819 - crates/bevy_script_api/src/providers/mod.rs | 80 - crates/bevy_script_api/src/rhai/bevy/mod.rs | 359 - crates/bevy_script_api/src/rhai/mod.rs | 194 - crates/bevy_script_api/src/rhai/std.rs | 454 - crates/bevy_script_api/src/script_ref.rs | 185 - crates/bevy_script_api/src/sub_reflect.rs | 390 - crates/bevy_script_api/src/wrappers.rs | 107 - .../bevy_mod_scripting_lua/Cargo.toml | 48 +- .../bevy_mod_scripting_lua/src/assets.rs | 157 - .../src/bindings/mod.rs | 3 + .../src/bindings/reference.rs | 368 + .../src/bindings/script_value.rs | 124 + .../src/bindings/world.rs | 45 + .../bevy_mod_scripting_lua/src/docs.rs | 227 - .../bevy_mod_scripting_lua/src/lib.rs | 367 +- .../bevy_mod_scripting_lua/src/util.rs | 155 - .../data/access/aliasing_global_access.lua | 11 + .../tests/data/access/aliasing_write.lua | 11 + .../tests/data/access/multiple_read_refs.lua | 3 + .../tests/data/add/vec3.lua | 11 + ...t_no_default_or_from_world_data_errors.lua | 7 + ...efault_and_component_data_adds_default.lua | 9 + ..._with_default_no_component_data_errors.lua | 6 + ..._world_and_component_data_adds_default.lua | 9 + ...th_from_world_no_component_data_errors.lua | 6 + .../api_available_on_callback.lua | 5 + .../api_available_on_script_load.lua | 3 + .../tests/data/clear/vec.lua | 6 + .../tests/data/despawn/despawns_only_root.lua | 7 + .../data/despawn/invalid_entity_errors.lua | 3 + .../despawns_only_child.lua | 7 + .../invalid_entity_errors.lua | 3 + .../despawns_recursively.lua | 7 + .../invalid_entity_errors.lua | 3 + .../tests/data/div/vec3.lua | 10 + .../tests/data/eq/vec3.lua | 7 + .../has_children_returns_them.lua | 9 + .../get_children/invalid_entity_errors.lua | 4 + .../no_children_returns_empty_table.lua | 4 + .../component_no_component_data.lua | 6 + .../component_with_component_data.lua | 6 + ...y_entity_component_with_component_data.lua | 5 + .../data/get_parent/has_parent_returns_it.lua | 9 + .../data/get_parent/invalid_entity_errors.lua | 4 + .../data/get_parent/no_parent_returns_nil.lua | 4 + .../missing_resource_returns_nil.lua | 2 + .../no_resource_data_returns_resource.lua | 5 + .../with_resource_data_returns_resource.lua | 5 + .../missing_type_returns_nothing.lua | 1 + .../registered_type_returns_correct_type.lua | 15 + .../empty_entity_mock_component_is_false.lua | 4 + .../data/has_component/no_component_data.lua | 3 + .../has_component/with_component_data.lua | 3 + .../existing_no_resource_data.lua | 2 + .../existing_with_resource_data.lua | 2 + ...issing_resource_mock_resource_is_false.lua | 2 + .../tests/data/insert/vec.lua | 6 + .../adding_empty_list_does_nothing.lua | 5 + .../adds_children_at_correct_index.lua | 8 + .../adds_children_to_existing_enttity.lua | 6 + .../insert_children/invalid_entity_errors.lua | 10 + .../tests/data/iter/vec.lua | 13 + .../tests/data/len/vec.lua | 4 + .../tests/data/mod/vec3.lua | 10 + .../tests/data/mul/vec3.lua | 10 + .../tests/data/pop/vec.lua | 6 + .../tests/data/push/vec.lua | 6 + .../adding_empty_list_does_nothing.lua | 5 + .../adds_children_to_existing_enttity.lua | 7 + .../push_children/invalid_entity_errors.lua | 10 + .../query/empty_query_returns_nothing.lua | 5 + .../query_returns_all_entities_matching.lua | 31 + .../tests/data/remove/vec.lua | 6 + .../empty_entity_does_nothing.lua | 5 + .../no_component_data_errors.lua | 7 + .../with_component_data_removes_component.lua | 5 + ...source_with_resource_data_does_nothing.lua | 4 + .../no_resource_data_errors.lua | 6 + .../with_resource_data_removes_resource.lua | 4 + .../tests/data/sub/vec3.lua | 13 + .../tests/data/unm/vec3.lua | 5 + .../bevy_mod_scripting_lua/tests/lua_tests.rs | 275 + .../CHANGELOG.md | 16 - .../bevy_mod_scripting_lua_derive/Cargo.toml | 38 - .../bevy_mod_scripting_lua_derive/readme.md | 3 - .../bevy_mod_scripting_lua_derive/src/arg.rs | 119 - .../src/function.rs | 602 - .../bevy_mod_scripting_lua_derive/src/lib.rs | 543 - .../src/signature.rs | 143 - .../src/visitor.rs | 386 - .../bevy_mod_scripting_rhai/Cargo.toml | 7 +- .../bevy_mod_scripting_rhai/src/assets.rs | 42 - .../bevy_mod_scripting_rhai/src/docs.rs | 17 - .../bevy_mod_scripting_rhai/src/lib.rs | 318 +- .../CHANGELOG.md | 14 - .../bevy_mod_scripting_rhai_derive/Cargo.toml | 29 - .../bevy_mod_scripting_rhai_derive/readme.md | 3 - .../bevy_mod_scripting_rhai_derive/src/lib.rs | 13 - .../bevy_mod_scripting_rune/Cargo.toml | 2 +- .../bevy_mod_scripting_rune/src/lib.rs | 535 +- crates/macro_tests/Cargo.toml | 26 - .../fail/references/non-proxy-reference.rs | 21 - .../references/non-proxy-reference.stderr | 18 - .../references/output-with-proxy-reference.rs | 15 - .../output-with-proxy-reference.stderr | 63 - .../fail/simple/invalid-argument-count.rs | 17 - .../fail/simple/invalid-argument-count.stderr | 12 - .../fail/simple/invalid-argument-type.rs | 17 - .../fail/simple/invalid-argument-type.stderr | 15 - .../fail/simple/invalid-function-type.rs | 15 - .../fail/simple/invalid-function-type.stderr | 7 - .../simple/invalid-output-type-custom-body.rs | 14 - .../invalid-output-type-custom-body.stderr | 10 - .../tests/fail/simple/invalid-output-type.rs | 17 - .../fail/simple/invalid-output-type.stderr | 10 - .../fail/simple/method-without-receiver.rs | 22 - .../simple/method-without-receiver.stderr | 7 - crates/macro_tests/tests/macro_tests.rs | 11 - .../success/containers/option-argument.rs | 16 - .../tests/success/containers/option-output.rs | 36 - .../tests/success/containers/vec-argument.rs | 21 - .../tests/success/containers/vec-output.rs | 29 - .../proxy-non-receiver-reference.rs | 22 - .../tests/success/simple/function.rs | 33 - .../tests/success/simple/metafunction.rs | 25 - .../simple/metamethod-owned-receiver.rs | 25 - .../tests/success/simple/metamethod.rs | 24 - .../success/simple/method-owned-receiver.rs | 35 - .../tests/success/simple/method.rs | 34 - .../tests/success/simple/mutable-function.rs | 37 - .../success/simple/mutable-metafunction.rs | 24 - .../mutating-metamethod-owned-receiver.rs | 26 - .../success/simple/mutating-metamethod.rs | 25 - .../simple/mutating-method-owned-receiver.rs | 35 - .../tests/success/simple/mutating-method.rs | 30 - crates/test_utils/Cargo.toml | 11 + crates/test_utils/src/lib.rs | 1 + crates/test_utils/src/test_data.rs | 264 + crates/xtask/Cargo.toml | 19 + crates/xtask/readme.md | 3 + crates/xtask/src/main.rs | 626 + crates/xtask/templates/settings.json.tera | 31 + docs/book.toml | 7 +- docs/multi-code-block.js | 3 + docs/src/SUMMARY.md | 19 +- docs/src/ScriptingReference/core-api.md | 5 + docs/src/ScriptingReference/core-callbacks.md | 28 + docs/src/ScriptingReference/introduction.md | 5 + .../ScriptingReference/reflect-reference.md | 222 + .../script-query-builder.md | 83 + .../ScriptingReference/script-query-result.md | 41 + .../script-type-registration.md | 79 + docs/src/ScriptingReference/world.md | 302 + .../Summary/controlling-script-bindings.md | 81 + docs/src/Summary/installation.md | 56 + docs/src/Summary/managing-scripts.md | 52 + docs/src/Summary/running-scripts.md | 50 + docs/src/chapter_1.md | 6 - examples/lua/bevy_api.rs | 207 - examples/lua/complex_game_loop.rs | 193 - examples/lua/console_integration.rs | 180 - examples/lua/coroutines.rs | 40 - examples/lua/documentation_gen.rs | 99 - examples/lua/dynamic_queries.rs | 64 - examples/lua/event_recipients.rs | 134 - examples/lua/game_of_life.rs | 220 +- examples/rhai/bevy_api.rs | 180 - examples/rhai/console_integration.rs | 174 - examples/rhai/dynamic_queries.rs | 63 - examples/rune/event_recipients.rs | 119 - examples/rune/minimal.rs | 57 - examples/wrappers.rs | 120 - log.out | 841 + makefile | 16 +- readme.md | 294 +- release-plz.toml | 24 +- src/documentation/main.rs | 32 - src/lib.rs | 31 +- 301 files changed, 43256 insertions(+), 45692 deletions(-) delete mode 100644 .github/workflows/doc_gen.yml create mode 100644 .github/workflows/generate_bindings.yml delete mode 100644 .github/workflows/macro_tests.yml create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.MD delete mode 100644 architecture.md create mode 100644 assets/scripts/bevy_api.lua create mode 100644 check.exe create mode 100644 check.ps1 delete mode 100644 crates/bevy_event_priority/CHANGELOG.md delete mode 100644 crates/bevy_event_priority/Cargo.toml delete mode 100644 crates/bevy_event_priority/src/lib.rs delete mode 100644 crates/bevy_mod_scripting_common/CHANGELOG.md delete mode 100644 crates/bevy_mod_scripting_common/Cargo.toml delete mode 100644 crates/bevy_mod_scripting_common/readme.md delete mode 100644 crates/bevy_mod_scripting_common/src/input.rs delete mode 100644 crates/bevy_mod_scripting_common/src/lib.rs delete mode 100644 crates/bevy_mod_scripting_common/src/utils.rs create mode 100644 crates/bevy_mod_scripting_core/src/bindings/access_map.rs create mode 100644 crates/bevy_mod_scripting_core/src/bindings/allocator.rs create mode 100644 crates/bevy_mod_scripting_core/src/bindings/function/from.rs create mode 100644 crates/bevy_mod_scripting_core/src/bindings/function/from_ref.rs create mode 100644 crates/bevy_mod_scripting_core/src/bindings/function/into.rs create mode 100644 crates/bevy_mod_scripting_core/src/bindings/function/into_ref.rs create mode 100644 crates/bevy_mod_scripting_core/src/bindings/function/mod.rs create mode 100644 crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs create mode 100644 crates/bevy_mod_scripting_core/src/bindings/mod.rs create mode 100644 crates/bevy_mod_scripting_core/src/bindings/pretty_print.rs create mode 100644 crates/bevy_mod_scripting_core/src/bindings/query.rs create mode 100644 crates/bevy_mod_scripting_core/src/bindings/reference.rs create mode 100644 crates/bevy_mod_scripting_core/src/bindings/script_value.rs create mode 100644 crates/bevy_mod_scripting_core/src/bindings/world.rs create mode 100644 crates/bevy_mod_scripting_core/src/commands.rs create mode 100644 crates/bevy_mod_scripting_core/src/context.rs create mode 100644 crates/bevy_mod_scripting_core/src/handler.rs delete mode 100644 crates/bevy_mod_scripting_core/src/hosts.rs create mode 100644 crates/bevy_mod_scripting_core/src/reflection_extensions.rs create mode 100644 crates/bevy_mod_scripting_core/src/runtime.rs create mode 100644 crates/bevy_mod_scripting_core/src/script.rs create mode 100644 crates/bevy_mod_scripting_functions/Cargo.toml rename crates/{bevy_event_priority => bevy_mod_scripting_functions}/readme.md (75%) create mode 100644 crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_core.rs create mode 100644 crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_ecs.rs create mode 100644 crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_hierarchy.rs create mode 100644 crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_input.rs create mode 100644 crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_math.rs create mode 100644 crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_reflect.rs create mode 100644 crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_time.rs create mode 100644 crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_transform.rs create mode 100644 crates/bevy_mod_scripting_functions/src/bevy_bindings/mod.rs create mode 100644 crates/bevy_mod_scripting_functions/src/core.rs create mode 100644 crates/bevy_mod_scripting_functions/src/lib.rs create mode 100644 crates/bevy_mod_scripting_functions/src/namespaced_register.rs delete mode 100644 crates/bevy_script_api/CHANGELOG.md delete mode 100644 crates/bevy_script_api/Cargo.toml delete mode 100644 crates/bevy_script_api/readme.md delete mode 100644 crates/bevy_script_api/src/common/bevy/mod.rs delete mode 100644 crates/bevy_script_api/src/common/mod.rs delete mode 100644 crates/bevy_script_api/src/common/std.rs delete mode 100644 crates/bevy_script_api/src/core_providers.rs delete mode 100644 crates/bevy_script_api/src/error.rs delete mode 100644 crates/bevy_script_api/src/lib.rs delete mode 100644 crates/bevy_script_api/src/lua/bevy/mod.rs delete mode 100644 crates/bevy_script_api/src/lua/mod.rs delete mode 100644 crates/bevy_script_api/src/lua/std.rs delete mode 100644 crates/bevy_script_api/src/lua/util.rs delete mode 100644 crates/bevy_script_api/src/providers/bevy_core.rs delete mode 100644 crates/bevy_script_api/src/providers/bevy_ecs.rs delete mode 100644 crates/bevy_script_api/src/providers/bevy_hierarchy.rs delete mode 100644 crates/bevy_script_api/src/providers/bevy_input.rs delete mode 100644 crates/bevy_script_api/src/providers/bevy_math.rs delete mode 100644 crates/bevy_script_api/src/providers/bevy_reflect.rs delete mode 100644 crates/bevy_script_api/src/providers/bevy_time.rs delete mode 100644 crates/bevy_script_api/src/providers/bevy_transform.rs delete mode 100644 crates/bevy_script_api/src/providers/mod.rs delete mode 100644 crates/bevy_script_api/src/rhai/bevy/mod.rs delete mode 100644 crates/bevy_script_api/src/rhai/mod.rs delete mode 100644 crates/bevy_script_api/src/rhai/std.rs delete mode 100644 crates/bevy_script_api/src/script_ref.rs delete mode 100644 crates/bevy_script_api/src/sub_reflect.rs delete mode 100644 crates/bevy_script_api/src/wrappers.rs delete mode 100644 crates/languages/bevy_mod_scripting_lua/src/assets.rs create mode 100644 crates/languages/bevy_mod_scripting_lua/src/bindings/mod.rs create mode 100644 crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs create mode 100644 crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs create mode 100644 crates/languages/bevy_mod_scripting_lua/src/bindings/world.rs delete mode 100644 crates/languages/bevy_mod_scripting_lua/src/docs.rs delete mode 100644 crates/languages/bevy_mod_scripting_lua/src/util.rs create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/access/aliasing_global_access.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/access/aliasing_write.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/access/multiple_read_refs.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/add/vec3.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_no_default_or_from_world_data_errors.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_with_default_and_component_data_adds_default.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_with_default_no_component_data_errors.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_with_from_world_and_component_data_adds_default.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_with_from_world_no_component_data_errors.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/api_availability/api_available_on_callback.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/api_availability/api_available_on_script_load.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/clear/vec.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/despawn/despawns_only_root.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/despawn/invalid_entity_errors.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/despawn_descendants/despawns_only_child.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/despawn_descendants/invalid_entity_errors.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/despawn_recursive/despawns_recursively.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/despawn_recursive/invalid_entity_errors.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/div/vec3.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/eq/vec3.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/get_children/has_children_returns_them.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/get_children/invalid_entity_errors.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/get_children/no_children_returns_empty_table.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/get_component/component_no_component_data.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/get_component/component_with_component_data.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/get_component/empty_entity_component_with_component_data.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/get_parent/has_parent_returns_it.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/get_parent/invalid_entity_errors.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/get_parent/no_parent_returns_nil.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/get_resource/missing_resource_returns_nil.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/get_resource/no_resource_data_returns_resource.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/get_resource/with_resource_data_returns_resource.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/get_type_by_name/missing_type_returns_nothing.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/get_type_by_name/registered_type_returns_correct_type.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/has_component/empty_entity_mock_component_is_false.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/has_component/no_component_data.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/has_component/with_component_data.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/has_resource/existing_no_resource_data.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/has_resource/existing_with_resource_data.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/has_resource/missing_resource_mock_resource_is_false.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/insert/vec.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/insert_children/adding_empty_list_does_nothing.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/insert_children/adds_children_at_correct_index.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/insert_children/adds_children_to_existing_enttity.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/insert_children/invalid_entity_errors.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/iter/vec.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/len/vec.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/mod/vec3.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/mul/vec3.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/pop/vec.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/push/vec.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/push_children/adding_empty_list_does_nothing.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/push_children/adds_children_to_existing_enttity.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/push_children/invalid_entity_errors.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/query/empty_query_returns_nothing.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/query/query_returns_all_entities_matching.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/remove/vec.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/remove_component/empty_entity_does_nothing.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/remove_component/no_component_data_errors.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/remove_component/with_component_data_removes_component.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/remove_resource/missing_resource_with_resource_data_does_nothing.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/remove_resource/no_resource_data_errors.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/remove_resource/with_resource_data_removes_resource.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/sub/vec3.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/data/unm/vec3.lua create mode 100644 crates/languages/bevy_mod_scripting_lua/tests/lua_tests.rs delete mode 100644 crates/languages/bevy_mod_scripting_lua_derive/CHANGELOG.md delete mode 100644 crates/languages/bevy_mod_scripting_lua_derive/Cargo.toml delete mode 100644 crates/languages/bevy_mod_scripting_lua_derive/readme.md delete mode 100644 crates/languages/bevy_mod_scripting_lua_derive/src/arg.rs delete mode 100644 crates/languages/bevy_mod_scripting_lua_derive/src/function.rs delete mode 100644 crates/languages/bevy_mod_scripting_lua_derive/src/lib.rs delete mode 100644 crates/languages/bevy_mod_scripting_lua_derive/src/signature.rs delete mode 100644 crates/languages/bevy_mod_scripting_lua_derive/src/visitor.rs delete mode 100644 crates/languages/bevy_mod_scripting_rhai/src/assets.rs delete mode 100644 crates/languages/bevy_mod_scripting_rhai/src/docs.rs delete mode 100644 crates/languages/bevy_mod_scripting_rhai_derive/CHANGELOG.md delete mode 100644 crates/languages/bevy_mod_scripting_rhai_derive/Cargo.toml delete mode 100644 crates/languages/bevy_mod_scripting_rhai_derive/readme.md delete mode 100644 crates/languages/bevy_mod_scripting_rhai_derive/src/lib.rs delete mode 100644 crates/macro_tests/Cargo.toml delete mode 100644 crates/macro_tests/tests/fail/references/non-proxy-reference.rs delete mode 100644 crates/macro_tests/tests/fail/references/non-proxy-reference.stderr delete mode 100644 crates/macro_tests/tests/fail/references/output-with-proxy-reference.rs delete mode 100644 crates/macro_tests/tests/fail/references/output-with-proxy-reference.stderr delete mode 100644 crates/macro_tests/tests/fail/simple/invalid-argument-count.rs delete mode 100644 crates/macro_tests/tests/fail/simple/invalid-argument-count.stderr delete mode 100644 crates/macro_tests/tests/fail/simple/invalid-argument-type.rs delete mode 100644 crates/macro_tests/tests/fail/simple/invalid-argument-type.stderr delete mode 100644 crates/macro_tests/tests/fail/simple/invalid-function-type.rs delete mode 100644 crates/macro_tests/tests/fail/simple/invalid-function-type.stderr delete mode 100644 crates/macro_tests/tests/fail/simple/invalid-output-type-custom-body.rs delete mode 100644 crates/macro_tests/tests/fail/simple/invalid-output-type-custom-body.stderr delete mode 100644 crates/macro_tests/tests/fail/simple/invalid-output-type.rs delete mode 100644 crates/macro_tests/tests/fail/simple/invalid-output-type.stderr delete mode 100644 crates/macro_tests/tests/fail/simple/method-without-receiver.rs delete mode 100644 crates/macro_tests/tests/fail/simple/method-without-receiver.stderr delete mode 100644 crates/macro_tests/tests/macro_tests.rs delete mode 100644 crates/macro_tests/tests/success/containers/option-argument.rs delete mode 100644 crates/macro_tests/tests/success/containers/option-output.rs delete mode 100644 crates/macro_tests/tests/success/containers/vec-argument.rs delete mode 100644 crates/macro_tests/tests/success/containers/vec-output.rs delete mode 100644 crates/macro_tests/tests/success/references/proxy-non-receiver-reference.rs delete mode 100644 crates/macro_tests/tests/success/simple/function.rs delete mode 100644 crates/macro_tests/tests/success/simple/metafunction.rs delete mode 100644 crates/macro_tests/tests/success/simple/metamethod-owned-receiver.rs delete mode 100644 crates/macro_tests/tests/success/simple/metamethod.rs delete mode 100644 crates/macro_tests/tests/success/simple/method-owned-receiver.rs delete mode 100644 crates/macro_tests/tests/success/simple/method.rs delete mode 100644 crates/macro_tests/tests/success/simple/mutable-function.rs delete mode 100644 crates/macro_tests/tests/success/simple/mutable-metafunction.rs delete mode 100644 crates/macro_tests/tests/success/simple/mutating-metamethod-owned-receiver.rs delete mode 100644 crates/macro_tests/tests/success/simple/mutating-metamethod.rs delete mode 100644 crates/macro_tests/tests/success/simple/mutating-method-owned-receiver.rs delete mode 100644 crates/macro_tests/tests/success/simple/mutating-method.rs create mode 100644 crates/test_utils/Cargo.toml create mode 100644 crates/test_utils/src/lib.rs create mode 100644 crates/test_utils/src/test_data.rs create mode 100644 crates/xtask/Cargo.toml create mode 100644 crates/xtask/readme.md create mode 100644 crates/xtask/src/main.rs create mode 100644 crates/xtask/templates/settings.json.tera create mode 100644 docs/multi-code-block.js create mode 100644 docs/src/ScriptingReference/core-api.md create mode 100644 docs/src/ScriptingReference/core-callbacks.md create mode 100644 docs/src/ScriptingReference/introduction.md create mode 100644 docs/src/ScriptingReference/reflect-reference.md create mode 100644 docs/src/ScriptingReference/script-query-builder.md create mode 100644 docs/src/ScriptingReference/script-query-result.md create mode 100644 docs/src/ScriptingReference/script-type-registration.md create mode 100644 docs/src/ScriptingReference/world.md create mode 100644 docs/src/Summary/controlling-script-bindings.md create mode 100644 docs/src/Summary/installation.md create mode 100644 docs/src/Summary/managing-scripts.md create mode 100644 docs/src/Summary/running-scripts.md delete mode 100644 docs/src/chapter_1.md delete mode 100644 examples/lua/bevy_api.rs delete mode 100644 examples/lua/complex_game_loop.rs delete mode 100644 examples/lua/console_integration.rs delete mode 100644 examples/lua/coroutines.rs delete mode 100644 examples/lua/documentation_gen.rs delete mode 100644 examples/lua/dynamic_queries.rs delete mode 100644 examples/lua/event_recipients.rs delete mode 100644 examples/rhai/bevy_api.rs delete mode 100644 examples/rhai/console_integration.rs delete mode 100644 examples/rhai/dynamic_queries.rs delete mode 100644 examples/rune/event_recipients.rs delete mode 100644 examples/rune/minimal.rs delete mode 100644 examples/wrappers.rs create mode 100644 log.out delete mode 100644 src/documentation/main.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index b423dd3e..9051a9f9 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,2 +1,5 @@ [env] TARGET_DIR = { value = "target", relative = true } + +[alias] +xtask = "run --package xtask --" diff --git a/.github/workflows/bevy_api_gen.yml b/.github/workflows/bevy_api_gen.yml index 2a916bce..8c5ea41f 100644 --- a/.github/workflows/bevy_api_gen.yml +++ b/.github/workflows/bevy_api_gen.yml @@ -5,10 +5,15 @@ on: paths: - "crates/bevy_api_gen/**" - ".github/workflows/bevy_api_gen.yml" + - ".github/workflows/generate_bindings.yml" + name: Check and Lint - bevy_api_gen +env: + RUST_TOOLCHAIN: nightly-2024-12-15 + jobs: check: name: Check - bevy_api_gen @@ -25,7 +30,7 @@ jobs: - uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: nightly-2024-11-05 + toolchain: ${{ env.RUST_TOOLCHAIN }} override: true - name: Rust Cache uses: Swatinem/rust-cache@v2.7.3 @@ -52,7 +57,7 @@ jobs: with: profile: minimal components: rustfmt - toolchain: nightly-2024-11-05 + toolchain: ${{ env.RUST_TOOLCHAIN }} override: true - name: Rust Cache uses: Swatinem/rust-cache@v2.7.3 @@ -75,7 +80,7 @@ jobs: rm -rf crates - uses: actions-rs/toolchain@v1 with: - toolchain: nightly-2024-11-05 + toolchain: ${{ env.RUST_TOOLCHAIN }} components: clippy override: true - name: Rust Cache @@ -98,7 +103,7 @@ jobs: rm -rf crates - uses: actions-rs/toolchain@v1 with: - toolchain: nightly-2024-11-05 + toolchain: ${{ env.RUST_TOOLCHAIN }} override: true - name: Rust Cache uses: Swatinem/rust-cache@v2.7.3 @@ -120,7 +125,7 @@ jobs: rm -rf crates - uses: actions-rs/toolchain@v1 with: - toolchain: nightly-2024-11-05 + toolchain: ${{ env.RUST_TOOLCHAIN }} override: true - name: Rust Cache uses: Swatinem/rust-cache@v2.7.3 @@ -131,3 +136,10 @@ jobs: with: command: doc args: --profile=ephemeral-build + bindings: + permissions: + contents: write + pull-requests: write + name: Generate Bindings - bevy_api_gen + uses: ./.github/workflows/generate_bindings.yml + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/bevy_mod_scripting.yml b/.github/workflows/bevy_mod_scripting.yml index 92497dee..2e9f2e9e 100644 --- a/.github/workflows/bevy_mod_scripting.yml +++ b/.github/workflows/bevy_mod_scripting.yml @@ -21,93 +21,27 @@ concurrency: cancel-in-progress: true jobs: - check: + check: + permissions: + pull-requests: write name: Check - ${{ matrix.run_args.label }} runs-on: ${{ matrix.run_args.os }} strategy: matrix: run_args: [ - {label: Windows - All Features, os: windows-latest, features: "lua54,rhai,teal,lua_script_api,rhai_script_api,rune", cross: x86_64-pc-windows-msvc }, - {label: MacOS - All Features, os: macOS-latest, features: "lua54,rhai,teal,lua_script_api,rhai_script_api,rune", cross: x86_64-apple-darwin }, - {label: Ubuntu - All Features, os: ubuntu-latest, features: "lua54,lua_script_api,rhai,teal,rhai_script_api,rune", cross: x86_64-unknown-linux-gnu }, - {label: Ubuntu Aarch64 - All Features, os: ubuntu-latest, features: "lua54,rhai,teal,lua_script_api,rhai_script_api,rune", cross: aarch64-unknown-linux-gnu }, - {label: Ubuntu - Lua51, os: ubuntu-latest, features: "lua51,lua_script_api", cross: x86_64-unknown-linux-gnu }, - {label: Ubuntu - Lua52, os: ubuntu-latest, features: "lua52,lua_script_api", cross: x86_64-unknown-linux-gnu }, - {label: Ubuntu - Lua53, os: ubuntu-latest, features: "lua53,lua_script_api", cross: x86_64-unknown-linux-gnu }, - {label: Ubuntu - Luajit, os: ubuntu-latest, features: "luajit,lua_script_api", cross: x86_64-unknown-linux-gnu }, - {label: Ubuntu - Luajit52, os: ubuntu-latest, features: "luajit52,lua_script_api", cross: x86_64-unknown-linux-gnu }, - {label: Ubuntu - Luau, os: ubuntu-latest, features: "luau,lua_script_api", cross: x86_64-unknown-linux-gnu } - + {label: Windows, os: windows-latest }, + {label: MacOS, os: macOS-latest }, + {label: Ubuntu, os: ubuntu-latest }, + {label: Ubuntu Aarch64, os: ubuntu-latest } ] steps: - - if: runner.os == 'linux' - name: Install alsa and udev - run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - - name: Rust Cache - uses: Swatinem/rust-cache@v2.7.3 - - if: runner.os != 'windows' - name: Clear space - run: rm -rf /usr/share/dotnet; rm -rf /opt/ghc; rm -rf "/usr/local/share/boost"; rm -rf "$AGENT_TOOLSDIRECTORY" - - uses: houseabsolute/actions-rust-cross@v0 - with: - command: check - target: ${{ matrix.run_args.cross }} - args: --workspace --features=${{ matrix.run_args.features }} --profile=ephemeral-build - - fmt: - name: Rustfmt - runs-on: ubuntu-latest - steps: - - name: Install alsa and udev - run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - components: rustfmt - toolchain: stable - override: true - - name: Rust Cache - uses: Swatinem/rust-cache@v2.7.3 - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check - - clippy: - name: Clippy - runs-on: ubuntu-latest - steps: - - name: Install alsa and udev - run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: clippy - override: true - - name: Rust Cache - uses: Swatinem/rust-cache@v2.7.3 - - uses: actions-rs/cargo@v1 - with: - command: clippy - args: --features=lua54,rhai,teal,lua_script_api,rhai_script_api,rune --profile=ephemeral-build -- -D warnings - tests: - name: Tests - runs-on: ubuntu-latest - steps: - - name: Clear space - run: sudo rm -rf /usr/share/dotnet; sudo rm -rf /opt/ghc; sudo rm -rf "/usr/local/share/boost"; sudo rm -rf "$AGENT_TOOLSDIRECTORY" - name: Checkout uses: actions/checkout@v3 - name: Install alsa and udev - run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev + if: runner.os == 'linux' + run: | + sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev + sudo rm -rf /usr/share/dotnet; sudo rm -rf /opt/ghc; sudo rm -rf "/usr/local/share/boost"; sudo rm -rf "$AGENT_TOOLSDIRECTORY" - uses: actions-rs/toolchain@v1 with: toolchain: stable @@ -116,25 +50,9 @@ jobs: uses: Swatinem/rust-cache@v2.7.3 - uses: actions-rs/cargo@v1 with: - command: test - args: --workspace --features=lua54,rhai,teal,lua_script_api,rhai_script_api,rune --profile=ephemeral-build - docs: - name: Docs - runs-on: ubuntu-latest - steps: - - name: Install alsa and udev - run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - override: true - - name: Rust Cache - uses: Swatinem/rust-cache@v2.7.3 - - name: Find docs.rs features - run: echo "DOCS_FEATURES=$(cargo metadata --no-deps | python -c "import sys,json; [print(','.join(x['metadata']['docs.rs']['features'])) for x in json.load(sys.stdin)['packages'] if x['name'] == 'bevy_mod_scripting']")" >> $GITHUB_OUTPUT - id: features - - uses: actions-rs/cargo@v1 + command: xtask + args: ci-check + - uses: romeovs/lcov-reporter-action@v0.2.16 + continue-on-error: true with: - command: doc - args: --workspace --features=${{ steps.features.outputs.DOCS_FEATURES }} --profile=ephemeral-build + lcov-file: ./target/coverage/lcov.info \ No newline at end of file diff --git a/.github/workflows/doc_gen.yml b/.github/workflows/doc_gen.yml deleted file mode 100644 index 0d8a75a7..00000000 --- a/.github/workflows/doc_gen.yml +++ /dev/null @@ -1,60 +0,0 @@ -on: - release: - types: [published] - workflow_dispatch: - inputs: - manual_tag: - description: 'release tag' - required: true - default: 'undefined' - type: string - -name: Documentation Generation - -jobs: - lua: - name: Lua Documentation - runs-on: ubuntu-latest - steps: - - name: Install alsa and udev - run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - - uses: Swatinem/rust-cache@v2.2.0 - - run: cargo install --git https://github.com/lenscas/tealr_doc_gen - - run: mkdir -p ./assets/scripts/doc/ - - run: cp tealr_doc_gen_config.json ./assets/scripts/doc/tealr_doc_gen_config.json - - run: sed -i "s//bevy_mod_scripting_lua\/${{github.event.release.tag_name || inputs.manual_tag}}\//" ./assets/scripts/doc/tealr_doc_gen_config.json - - uses: actions-rs/cargo@v1 - with: - command: run - args: --features=lua54,lua_script_api lua - - run: cat ./assets/scripts/doc/tealr_doc_gen_config.json - - name: Push to pages - uses: cpina/github-action-push-to-another-repository@main - env: - SSH_DEPLOY_KEY: ${{ secrets.LUA_DOCUMENTATION_SSH_KEY }} - with: - source-directory: './assets/scripts/doc/CoreBevyAPI/bevy_mod_scripting_lua/${{ github.event.release.tag_name || inputs.manual_tag }}' - destination-github-username: 'makspll' - destination-repository-name: 'bevy_mod_scripting_lua' - user-email: makspl17@gmail.com - target-branch: main - target-directory: ${{ github.event.release.tag_name || inputs.manual_tag }} - - name: Pushes to pages as latest - if: ${{ github.event.release.tag_name }} == '' - uses: cpina/github-action-push-to-another-repository@main - env: - SSH_DEPLOY_KEY: ${{ secrets.LUA_DOCUMENTATION_SSH_KEY }} - with: - source-directory: './assets/scripts/doc/CoreBevyAPI/bevy_mod_scripting_lua/${{ github.event.release.tag_name || inputs.manual_tag }}' - destination-github-username: 'makspll' - destination-repository-name: 'bevy_mod_scripting_lua' - user-email: makspl17@gmail.com - target-branch: main - target-directory: latest - diff --git a/.github/workflows/generate_bindings.yml b/.github/workflows/generate_bindings.yml new file mode 100644 index 00000000..95faf836 --- /dev/null +++ b/.github/workflows/generate_bindings.yml @@ -0,0 +1,93 @@ +name: Generate Bindings (Bevy, Glam) + +on: + workflow_call: + # inputs: + # config-path: + # required: true + # type: string + # secrets: + # token: + # required: true + workflow_dispatch: + +env: + RUST_TOOLCHAIN: nightly-2024-12-15 + BEVY_API_GEN_PATH: ${{ github.workspace }}/crates/bevy_api_gen + BEVY_PATH: ${{ github.workspace }}/target/codegen/bevy + OUTPUT_PATH: ${{ github.workspace }}/crates/bevy_mod_scripting_functions/src/bevy_bindings/ + BEVY_FEATURES: bevy_asset,bevy_animation,bevy_core_pipeline,bevy_ui,bevy_pbr,bevy_render,bevy_text,bevy_sprite,file_watcher,multi_threaded + BRANCH_NAME: __update-bevy-bindings-${{ github.head_ref || github.ref_name }} + GH_TOKEN: ${{ github.token }} + +jobs: + generate_bindings: + permissions: + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Bot GitHub Credentials + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + - name: Install Rust Toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ env.RUST_TOOLCHAIN }} + components: rust-src, rustc-dev, llvm-tools-preview + override: true + - name: Install bevy_api_gen Binaries + run: cargo install --path ${{ env.BEVY_API_GEN_PATH }} + - name: read bevy workspace version + uses: SebRollen/toml-action@v1.2.0 + id: read_toml + with: + file: 'Cargo.toml' + field: 'workspace.dependencies.bevy.version' + - name: Prepare Directories + run: | + mkdir -p ${{ env.OUTPUT_PATH }} + mkdir -p ${{ env.BEVY_PATH }} + - name: Clone Bevy + run: | + git clone https://github.com/bevyengine/bevy --branch v${{ steps.read_toml.outputs.value }} --depth 1 ${{ env.BEVY_PATH }} + cd ${{ env.BEVY_PATH }} && git fetch --tags && git checkout v${{ steps.read_toml.outputs.value }} + ls -la ${{ env.BEVY_PATH }} + - name: Generate Bevy Bindings + run: | + cd ${{ env.BEVY_PATH }} && cargo bevy-api-gen generate --output ${{ env.OUTPUT_PATH }} --template-args '{ "self_is_bms_lua": true}' --features ${{ env.BEVY_FEATURES }} -vv + - name: Collect Bevy Bindings + run: | + ls -la ${{ env.BEVY_PATH }} + cd ${{ env.BEVY_PATH }} && cargo bevy-api-gen collect --output ${{ env.OUTPUT_PATH }} --template-args '{ "self_is_bms_lua": true}' + - name: Prune Output + run: | + find ${{ env.OUTPUT_PATH }} -type f ! -name "*.rs" -delete + - name: Check for changes + id: check_changes + run: | + if [[ -n $(git status --porcelain) ]]; then + echo "changes=true" >> "$GITHUB_OUTPUT"; + fi + - name: Commit Changes + if: steps.check_changes.outputs.changes + run: | + git checkout -b ${{ env.BRANCH_NAME }} || git checkout ${{ env.BRANCH_NAME }} + git add -A + git commit -m "chore(codegen): update bevy bindings" + git push -u origin ${{ env.BRANCH_NAME }} --force + - uses: jwalton/gh-find-current-pr@master + if: steps.check_changes.outputs.changes + id: findPR + with: + state: all + - name: Create Or Update PR + if: steps.check_changes.outputs.changes && success() && steps.findPR.outputs.number + run: | + gh pr list --base feature/bevy-system-refactor --search "chore(codegen): update bevy bindings" --json number > prs.json + if [ $(jq '. | length' prs.json) -eq 0 ]; then + gh pr create --title "chore(codegen): update bevy bindings" --body "This PR updates the bevy bindings for #${{ steps.findPR.outputs.number }}" --base ${{ github.ref }} --head ${{ env.BRANCH_NAME }} || true + fi \ No newline at end of file diff --git a/.github/workflows/macro_tests.yml b/.github/workflows/macro_tests.yml deleted file mode 100644 index a4e17c54..00000000 --- a/.github/workflows/macro_tests.yml +++ /dev/null @@ -1,33 +0,0 @@ -on: - pull_request: - paths: - - "crates/macro_tests/**" - push: - branches: - - main - paths: - - "crates/macro_tests/**" - - -name: Run macro tests - -jobs: - tests: - name: Macro Tests - runs-on: ubuntu-latest - steps: - - name: Clear space - run: sudo rm -rf /usr/share/dotnet; sudo rm -rf /opt/ghc; sudo rm -rf "/usr/local/share/boost"; sudo rm -rf "$AGENT_TOOLSDIRECTORY" - - uses: actions/checkout@v3 - - name: Install alsa and udev - run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - override: true - - name: Rust Cache - uses: Swatinem/rust-cache@v2.7.3 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - - run: cd crates/macro_tests && cargo test --profile=ephemeral-build diff --git a/.github/workflows/mdbook.yml b/.github/workflows/mdbook.yml index 80984049..2a9dac95 100644 --- a/.github/workflows/mdbook.yml +++ b/.github/workflows/mdbook.yml @@ -13,6 +13,8 @@ jobs: build: name: Build Book - mdbook runs-on: ubuntu-latest + permissions: + contents: write steps: - name: Checkout repository @@ -22,8 +24,10 @@ jobs: with: toolchain: stable override: true + - name: Rust Cache uses: Swatinem/rust-cache@v2.7.3 + - name: Install mdBook run: cargo install mdbook @@ -31,7 +35,7 @@ jobs: run: cd docs && mdbook build - name: Deploy to GitHub Pages - if: github.ref == 'refs/heads/main' + if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/staging' uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.rustfmt.toml b/.rustfmt.toml index 6e65172c..9a5f6e52 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -1,3 +1,8 @@ # max_width = 60 # use_small_heuristics = "Max" # format_generated_files = false + +reorder_imports = true +# currently unsupported but want them in when stable +imports_granularity = "Crate" +group_imports = "StdExternalCrate" diff --git a/.vscode/launch.json b/.vscode/launch.json index a6483eca..67b227bd 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -25,7 +25,7 @@ "build", "--example=game_of_life_lua", "--package=bevy_mod_scripting", - "--features=lua54,teal,lua_script_api", + "--features=lua54,teal", ], "filter": { "name": "game_of_life_lua", diff --git a/.vscode/settings.json b/.vscode/settings.json index 3c966b29..ae2266a1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,7 +11,6 @@ "rust-analyzer.rustc.source": "discover", "rust-analyzer.linkedProjects": [ "./crates/bevy_api_gen/Cargo.toml", - // "./crates/macro_tests/Cargo.toml", "Cargo.toml", ], "rust-analyzer.check.invocationStrategy": "per_workspace", @@ -23,5 +22,11 @@ "/home/makspll/git/bevy_mod_scripting/check.sh" ], "rust-analyzer.showUnlinkedFileNotification": false, + "rust-analyzer.runnables.extraTestBinaryArgs": [ + "--show-output", + ], + "rust-analyzer.runnables.extraArgs": [ + "--profile=release-with-debug", + ], // "rust-analyzer.semanticHighlighting.operator.enable": false -} +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 14262c18..ddfbb877 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -12,6 +12,12 @@ "type": "promptString", "description": "The crate location of this unit test", "default": "bevy_mod_scripting" + }, + { + "id": "features", + "type": "promptString", + "description": "The features to enable for this unit test", + "default": "" } ], "tasks": [ @@ -22,7 +28,8 @@ "args": [ "build_test_in_package", "PACKAGE=${input:package}", - "TEST_NAME=${input:test_name}" + "TEST_NAME=${input:test_name}", + "TEST_FEATURES=${input:features}" ] } ] diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..8abdfe31 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,69 @@ +# Code of Conduct - bevy_mod_scripting + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to make participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behaviour that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologising to those affected by our mistakes, +and learning from the experience +* Focusing on what is best not just for us as individuals, but for the +overall community + +Examples of unacceptable behaviour include: + +* The use of sexualised language or imagery, and sexual attention or advances +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email +address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a +professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying and enforcing our standards of +acceptable behaviour and will take appropriate and fair corrective action in +response to any instances of unacceptable behaviour. + +Project maintainers have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, or to ban +temporarily or permanently any contributor for other behaviours that they deem +inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behaviour may be +reported to the community leaders responsible for enforcement at <>. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://contributor-covenant.org/), version +[1.4](https://www.contributor-covenant.org/version/1/4/code-of-conduct/code_of_conduct.md) and +[2.0](https://www.contributor-covenant.org/version/2/0/code_of_conduct/code_of_conduct.md), +and was generated by [contributing.md](https://contributing.md/generator). \ No newline at end of file diff --git a/CONTRIBUTING.MD b/CONTRIBUTING.MD new file mode 100644 index 00000000..a6bc9b9c --- /dev/null +++ b/CONTRIBUTING.MD @@ -0,0 +1,158 @@ + +# Contributing to bevy_mod_scripting + +First off, thanks for taking the time to contribute! ❤️ + +All types of contributions are encouraged and valued. See the [Table of Contents](#table-of-contents) for different ways to help and details about how this project handles them. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 🎉 + +> And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about: +> - Star the project +> - Tweet about it +> - Refer this project in your project's readme +> - Mention the project at local meetups and tell your friends/colleagues + + +## Table of Contents + +- [Code of Conduct](#code-of-conduct) +- [I Have a Question](#i-have-a-question) +- [I Want To Contribute](#i-want-to-contribute) +- [Reporting Bugs](#reporting-bugs) +- [Suggesting Enhancements](#suggesting-enhancements) +- [Your First Code Contribution](#your-first-code-contribution) +- [Improving The Documentation](#improving-the-documentation) +- [Styleguides](#styleguides) +- [Commit Messages](#commit-messages) +- [Join The Project Team](#join-the-project-team) + + +## Code of Conduct + +This project and everyone participating in it is governed by the +[bevy_mod_scripting Code of Conduct](https://github.com/makspll/bevy_mod_scripting/blob//CODE_OF_CONDUCT.md). +By participating, you are expected to uphold this code. Please report unacceptable behavior +to <>. + + +## I Have a Question + +> If you want to ask a question, we assume that you have read the available [Documentation](https://makspll.github.io/bevy_mod_scripting/). + +Before you ask a question, it is best to search for existing [Issues](https://github.com/makspll/bevy_mod_scripting/issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first. + +If you then still feel the need to ask a question and need clarification, we recommend the following: + +- Open an [Issue](https://github.com/makspll/bevy_mod_scripting/issues/new). +- Provide as much context as you can about what you're running into. +- Provide project and platform versions (nodejs, npm, etc), depending on what seems relevant. + +We will then take care of the issue as soon as possible. + + + +## I Want To Contribute + +> ### Legal Notice +> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project licence. + +### Reporting Bugs + + +#### Before Submitting a Bug Report + +A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible. + +- Make sure that you are using the latest version. +- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](https://makspll.github.io/bevy_mod_scripting/). If you are looking for support, you might want to check [this section](#i-have-a-question)). +- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/makspll/bevy_mod_scripting/issues?q=label%3Abug). +- Also make sure to search the internet (including Stack Overflow) to see if users outside of the GitHub community have discussed the issue. +- Collect information about the bug: +- Stack trace (Traceback) +- OS, Platform and Version (Windows, Linux, macOS, x86, ARM) +- Version of the interpreter, compiler, SDK, runtime environment, package manager, depending on what seems relevant. +- Possibly your input and the output +- Can you reliably reproduce the issue? And can you also reproduce it with older versions? + + +#### How Do I Submit a Good Bug Report? + +> You must never report security related issues, vulnerabilities or bugs including sensitive information to the issue tracker, or elsewhere in public. Instead sensitive bugs must be sent by email to <>. + + +We use GitHub issues to track bugs and errors. If you run into an issue with the project: + +- Open an [Issue](https://github.com/makspll/bevy_mod_scripting/issues/new). (Since we can't be sure at this point whether it is a bug or not, we ask you not to talk about a bug yet and not to label the issue.) +- Explain the behavior you would expect and the actual behavior. +- Please provide as much context as possible and describe the *reproduction steps* that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case. +- Provide the information you collected in the previous section. + +Once it's filed: + +- The project team will label the issue accordingly. +- A team member will try to reproduce the issue with your provided steps. If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for those steps and mark the issue as `needs-repro`. Bugs with the `needs-repro` tag will not be addressed until they are reproduced. +- If the team is able to reproduce the issue, it will be marked `needs-fix`, as well as possibly other tags (such as `critical`), and the issue will be left to be [implemented by someone](#your-first-code-contribution). + + + + +### Suggesting Enhancements + +This section guides you through submitting an enhancement suggestion for bevy_mod_scripting, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions. + + +#### Before Submitting an Enhancement + +- Make sure that you are using the latest version. +- Read the [documentation](https://makspll.github.io/bevy_mod_scripting/) carefully and find out if the functionality is already covered, maybe by an individual configuration. +- Perform a [search](https://github.com/makspll/bevy_mod_scripting/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. +- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library. + + +#### How Do I Submit a Good Enhancement Suggestion? + +Enhancement suggestions are tracked as [GitHub issues](https://github.com/makspll/bevy_mod_scripting/issues). + +- Use a **clear and descriptive title** for the issue to identify the suggestion. +- Provide a **step-by-step description of the suggested enhancement** in as many details as possible. +- **Describe the current behavior** and **explain which behavior you expected to see instead** and why. At this point you can also tell which alternatives do not work for you. +- You may want to **include screenshots or screen recordings** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [LICEcap](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and the built-in [screen recorder in GNOME](https://help.gnome.org/users/gnome-help/stable/screen-shot-record.html.en) or [SimpleScreenRecorder](https://github.com/MaartenBaert/ssr) on Linux. +- **Explain why this enhancement would be useful** to most bevy_mod_scripting users. You may also want to point out the other projects that solved it better and which could serve as inspiration. + + + +### 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. + + + +### Improving The Documentation + +Most of the documentation can be found in the `docs` folder. The documentation is written in markdown and built using mdbook. You can run `cargo xtask doc` to build the documentation. You can also run `cargo xtask doc --open` to build and open the documentation in your browser. + +## Styleguides +### Commit Messages + +Follow conventional commit messages for PR titles, and keep your commit messages as descriptive as possible. Don't stress about it though! + +For example if you are adding a new feature, name your PR title as `feat: add new feature` and your commit message as `adding new feature` or ideally `feat: add new feature`. + +## Join The Project Team + +We are open to new members and would be happy to welcome you to our team. If you are interested in becoming a long-term contributor, please send an email to `makspl17@gmail.com`. + +## Attribution +This guide is based on the [contributing.md](https://contributing.md/generator)! \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 0fe92852..0d5cd8b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bevy_mod_scripting" -version = "0.8.0" +version = "0.9.0-alpha.1" authors = ["Maksymilian Mozolewski "] edition = "2021" license = "MIT OR Apache-2.0" @@ -12,28 +12,15 @@ categories = ["game-development"] readme = "readme.md" include = ["readme.md", "/src", "/examples", "/assets", "LICENSE"] -[[bin]] -name = "bevy_mod_scripting_doc_gen" -path = "src/documentation/main.rs" - [lib] name = "bevy_mod_scripting" path = "src/lib.rs" [package.metadata."docs.rs"] -features = [ - "lua", - "lua54", - "rhai", - "lua_script_api", - "rhai_script_api", - "teal", - "rune", -] +features = ["lua54", "rhai", "rune"] [features] -## core -doc_always = ["bevy_mod_scripting_core/doc_always"] +default = ["core_functions", "bevy_bindings", "unsafe_lua_modules"] ## lua lua = ["bevy_mod_scripting_lua"] @@ -46,17 +33,18 @@ luajit = ["bevy_mod_scripting_lua/luajit", "lua"] luajit52 = ["bevy_mod_scripting_lua/luajit52", "lua"] luau = ["bevy_mod_scripting_lua/luau", "lua"] +# bindings +core_functions = ["bevy_mod_scripting_functions/core_functions"] +bevy_bindings = ["bevy_mod_scripting_functions/bevy_bindings"] + # optional -lua_script_api = ["bevy_script_api/lua"] unsafe_lua_modules = ["bevy_mod_scripting_lua/unsafe_lua_modules"] -teal = ["bevy_mod_scripting_lua/teal"] mlua_serialize = ["bevy_mod_scripting_lua/mlua_serialize"] mlua_macros = ["bevy_mod_scripting_lua/mlua_macros"] mlua_async = ["bevy_mod_scripting_lua/mlua_async"] ## rhai rhai = ["bevy_mod_scripting_rhai"] -rhai_script_api = ["bevy_script_api/rhai"] ## rune rune = ["bevy_mod_scripting_rune"] @@ -64,16 +52,18 @@ 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.8.0", optional = true } -bevy_mod_scripting_rhai = { path = "crates/languages/bevy_mod_scripting_rhai", version = "0.8.0", optional = true } -bevy_mod_scripting_rune = { path = "crates/languages/bevy_mod_scripting_rune", version = "0.8.0", optional = true } -bevy_script_api = { path = "crates/bevy_script_api", version = "0.8.0", optional = true } - +bevy_mod_scripting_lua = { path = "crates/languages/bevy_mod_scripting_lua", version = "0.9.0-alpha.1", optional = true } +bevy_mod_scripting_rhai = { path = "crates/languages/bevy_mod_scripting_rhai", version = "0.9.0-alpha.1", optional = true } +bevy_mod_scripting_rune = { path = "crates/languages/bevy_mod_scripting_rune", version = "0.9.0-alpha.1", optional = true } +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.8.0" } -bevy_mod_scripting_common = { path = "crates/bevy_mod_scripting_common", version = "0.8.0" } +bevy_mod_scripting_core = { path = "crates/bevy_mod_scripting_core", version = "0.9.0-alpha.1" } +bevy_mod_scripting_functions = { path = "crates/bevy_mod_scripting_functions", version = "0.9.0-alpha.1" } +test_utils = { path = "crates/test_utils" } +mlua = { version = "0.10" } +rhai = { version = "1.20.1" } [dev-dependencies] bevy = { workspace = true, default-features = true } @@ -81,18 +71,17 @@ clap = { version = "4.1", features = ["derive"] } rand = "0.8.5" bevy_console = "0.13" rhai-rand = "0.1" +ansi-parser = "0.9" [workspace] members = [ "crates/bevy_mod_scripting_core", - "crates/bevy_event_priority", - "crates/bevy_script_api", "crates/languages/bevy_mod_scripting_lua", - "crates/languages/bevy_mod_scripting_lua_derive", "crates/languages/bevy_mod_scripting_rhai", - "crates/languages/bevy_mod_scripting_rhai_derive", "crates/languages/bevy_mod_scripting_rune", - "crates/bevy_mod_scripting_common", + "crates/test_utils", + "crates/bevy_mod_scripting_functions", + "crates/xtask", ] resolver = "2" exclude = ["crates/bevy_api_gen", "crates/macro_tests"] @@ -112,97 +101,16 @@ codegen-units = 8 incremental = false debug = false -[[example]] -name = "console_integration_lua" -path = "examples/lua/console_integration.rs" -required-features = [ - "lua54", - "lua_script_api", - "bevy/file_watcher", - "bevy/multi_threaded", -] - -[[example]] -name = "console_integration_rhai" -path = "examples/rhai/console_integration.rs" -required-features = [ - "rhai", - "rhai_script_api", - "bevy/file_watcher", - "bevy/multi_threaded", -] - -[[example]] -name = "complex_game_loop_lua" -path = "examples/lua/complex_game_loop.rs" -required-features = ["lua54"] - -[[example]] -name = "dynamic_queries_lua" -path = "examples/lua/dynamic_queries.rs" -required-features = ["lua54", "lua_script_api"] - -[[example]] -name = "dynamic_queries_rhai" -path = "examples/rhai/dynamic_queries.rs" -required-features = ["rhai", "rhai_script_api"] +[profile.release-with-debug] +inherits = "release" +debug = true [[example]] name = "game_of_life_lua" path = "examples/lua/game_of_life.rs" -required-features = [ - "lua54", - "lua_script_api", - "bevy/file_watcher", - "bevy/multi_threaded", -] - -[[example]] -name = "game_of_life_rhai" -path = "examples/rhai/game_of_life.rs" -required-features = [ - "rhai", - "rhai_script_api", - "bevy/file_watcher", - "bevy/multi_threaded", -] +required-features = ["lua54", "bevy/file_watcher", "bevy/multi_threaded"] -[[example]] -name = "event_recipients_lua" -path = "examples/lua/event_recipients.rs" -required-features = ["lua54"] - -[[example]] -name = "coroutines_lua" -path = "examples/lua/coroutines.rs" -required-features = ["lua54"] - -[[example]] -name = "documentation_gen_lua" -path = "examples/lua/documentation_gen.rs" -required-features = ["lua54", "teal", "lua_script_api"] - -[[example]] -name = "bevy_api_lua" -path = "examples/lua/bevy_api.rs" -required-features = ["lua54", "lua_script_api"] - -[[example]] -name = "bevy_api_rhai" -path = "examples/rhai/bevy_api.rs" -required-features = ["rhai", "rhai_script_api"] - -[[example]] -name = "wrappers" -path = "examples/wrappers.rs" -required-features = ["lua54", "lua_script_api"] - -[[example]] -name = "minimal_rune" -path = "examples/rune/minimal.rs" -required-features = ["rune"] - -[[example]] -name = "event_recipients_rune" -path = "examples/rune/event_recipients.rs" -required-features = ["rune"] +# [[example]] +# required-features = ["rhai", "bevy/file_watcher", "bevy/multi_threaded"] +# name = "game_of_life_rhai" +# path = "examples/rhai/game_of_life.rs" diff --git a/architecture.md b/architecture.md deleted file mode 100644 index 9c940e7d..00000000 --- a/architecture.md +++ /dev/null @@ -1,199 +0,0 @@ -# Architecture - -## Reflection - -`bevy_mod_scripting` first and foremost relies on `Reflection`, a feature of Bevy which allows us to interact with type erased data. This is the foundation of the scripting system, as it allows us to interact with the Bevy ECS without knowing the exact types of the components/resources our scripts will be interacting with at compile time. - -Normally in Bevy, you would define your components and resources as structs, and then use them in your systems. This is very powerful but also very limiting, as it requires you to know the exact types of the components/resources you will be interacting with at compile time. This is where [`Reflection`](https://docs.rs/bevy_reflect/0.13.1/bevy_reflect/) comes in. - -Bevy provides us with a [`TypeRegistry`](https://docs.rs/bevy_reflect/0.13.1/bevy_reflect/struct.TypeRegistry.html), which is essentially just a map from type ids to [`TypeRegistrations`](https://docs.rs/bevy_reflect/0.13.1/bevy_reflect/struct.TypeRegistration.html). A `TypeRegistration` is a container for all sorts of metadata about the type but most importantly it allows us to query [`TypeData`](https://docs.rs/bevy_reflect/0.13.1/bevy_reflect/trait.TypeData.html) of any type which was previously registered via the `TypeRegistry`. - -How is this useful ? Well it allows us to register arbitrary information including function pointers which we can then retrieve given just a `TypeId`. This is exactly what we do with [`ReflectProxyable`](https://docs.rs/bevy_mod_scripting/0.3.0/bevy_mod_scripting/api/lua/struct.ReflectLuaProxyable.html), the interface between Bevy and Lua: - -```rust,ignore -pub fn ref_to_lua<'lua>( - &self, - ref_: ReflectReference, - lua: &'lua Lua -) -> Result, Error> - -pub fn apply_lua<'lua>( - &self, - ref_: &mut ReflectReference, - lua: &'lua Lua, - new_val: Value<'lua> -) -> Result<(), Error> -``` - -A `ReflectProxyable` `TypeData` is registered for every type which we want to have custom Lua bindings for. With this we can represent any Reflectable type in any way we want in Lua. For example we can represent a `Vec3` as a table with `x`, `y`, `z` fields, or we can represent it as a userdata with a metatable which has `__index` and `__newindex` metamethods. The best part about this is we do not need to even own the types we are adding this `TypeData` for! This bypasses the pesky orphan rule and allows us to add custom Lua bindings for any type in Bevy. - -Note: for your own types you can do this by deriving `Reflect` and adding a `reflect(LuaProxyable)` attribute like so: - -```rust,ignore -#[derive(Reflect)] -#[reflect(LuaProxyable)] -pub struct MyType { - pub x: f32, - pub y: f32, - pub z: f32, -} - -impl LuaProxyable for MyType { - // ... -} -``` - -Now when you register your type with the `AppTypeRegistry` it will automatically have a `ReflectLuaProxyable` `TypeData` registered for it! You must not forget to register your type with: - -```rust,ignore -app.register_type::(); -``` - -## Script References - -All accesses to the bevy world are done via `ReflectReference` types which look like this: - -```rust,ignore -pub struct ReflectReference { - /// The reflection path from the root - pub(crate) path: ReflectionPath, - pub(crate) world_ptr: WorldPointer, -} -``` - -I.e. they are essentially just a path to the data in the Bevy world. This allows us to have a reference to a piece of data in the Bevy world which can be passed around and modified in Lua safely. - -The `ReflectionPath` itself consists of a "base" reference and a list of path segments. Most interesting of which is the base: - -```rust,ignore -pub(crate) enum ReflectBase { - /// A bevy component reference - Component { - comp: ReflectComponent, - entity: Entity, - }, - /// A bevy resource reference - Resource { res: ReflectResource }, - - /// A script owned reflect type (for example a vector constructed in lua) - ScriptOwned { val: Weak> }, -} -``` - -Given a valid base and a valid path we should always be able to get a valid reference to a piece of data in the Bevy world. Note we make use of other `TypeData` here, i.e. `ReflectComponent` and `ReflectResource` which store function pointers for the specific types of components/resources we are dealing with that allow us to interact with them. For example `ReflectComponent` let's us call: - -```rust,ignore -pub fn reflect<'a>( - &self, - entity: EntityRef<'a> -) -> Option<&'a (dyn Reflect + 'static)> -``` - -To retrieve a reflect reference to our component on a specific entity! - -You might be wondering how exactly we get a `TypeId` from a script in the first place, and the answer is we use a simple String type name! The journey begins in our custom `World` UserData: - -```rust,ignore - methods.add_method("get_type_by_name", |_, world, type_name: String| { - let w = world.read(); - - let registry: &AppTypeRegistry = w.get_resource().unwrap(); - - let registry = registry.read(); - - Ok(registry - .get_with_short_type_path(&type_name) - .or_else(|| registry.get_with_type_path(&type_name)) - .map(|registration| LuaTypeRegistration::new(Arc::new(registration.clone())))) - }); -``` - -Given a String type name like: `my_crate::MyType` we can then retrieve both `TypeId` and `TypeRegistration` structs, which we can use to retrieve any `TypeData` we need! - - -## Bevy to Lua Bridge - -Now finally our `ReflectReference` type has a custom `IntoLua` implementation which does the following: -- Check the type has a `ReflectLuaProxyable` `TypeData` -- If it does, call `ref_to_lua` on it and generate the Lua representation of the data -- If it does not, default to a "vanilla" representation of the data i.e. a [`ReflectedValue`](https://docs.rs/bevy_mod_scripting/0.3.0/bevy_mod_scripting/api/struct.ReflectedValue.html) which is a simple wrapper around a `ReflectReference`. It uses pure reflection to provide `__index` and `__newindex` metamethods for the data. - -```rust,ignore - fn into_lua(self, ctx: &'lua Lua) -> mlua::Result> { - let world = self.world_ptr.clone(); - let world = world.read(); - - let typedata = &world.resource::(); - let g = typedata.read(); - - let type_id = self.get(|s| s.type_id())?; - if let Some(v) = g.get_type_data::(type_id) { - v.ref_to_lua(self, ctx) - } else { - ReflectedValue { ref_: self }.into_lua(ctx) - } - } -``` - -Note that assigning to bevy via ReflectedValue's will check if the value we're trying to assign has a `ReflectLuaProxyable` type data, and if it does it uses it's `apply_lua` method to apply the new value to the `ReflectReference`, if it does not it expects it to be another `ReflectedValue` and will clone then apply it to itself using pure reflection. - -All primitive data types will have a `ReflectLuaProxyable` type data registered for them via their `FromLua` and `Clone` implementations. - - -## Proxy macros -We provide a set of macros to make it easier to define custom Lua bindings for your types. For example: - -```rust,ignore -#[derive(LuaProxy, Reflect, Resource, Default, Debug, Clone)] -#[reflect(Resource, LuaProxyable)] -#[proxy( - derive(clone), - functions[ - r#" - #[lua(kind="MutatingMethod")] - fn set_my_string(&mut self, another_string: Option); - "#, - r#" - #[lua(kind="MutatingMethod")] - fn set_with_another(&mut self, #[proxy] another: Self); - "#, - r#" - #[lua(kind="Method")] - fn get_my_string(&self) -> String; - "#, - r#" - #[lua(kind="Method",raw)] - fn raw_method(&self, ctx : &Lua) -> Result { - let a = ctx.globals().get::<_,String>("world").unwrap(); - let a = self.inner()?; - Ok("".to_owned()) - } - "#, - r#" - #[lua(kind="MetaMethod", metamethod="ToString")] - fn to_string(&self) -> String { - format!("{:#?}", _self) - } - "# - ]) - ] -pub struct MyProxiedStruct { - my_string: String, -} -``` - -will generate a `LuaMyProxiedStruct` which will act as the Lua representation of `MyProxiedStruct`. It will have the following methods: -- `set_my_string` which will set the `my_string` field of the struct -- `set_with_another` which will set the struct to be equal to another struct -- `get_my_string` which will return the `my_string` field of the struct -- `ToString` metamethod which will return a string representation of the struct - -It will also implement `UserData` for the proxy, meaning it can be passed around in Lua as a first class citizen. And it will implement `LuaProxyable` for `MyProxiedStruct`, meaning you can register your type and have it work in Lua with no extra work! - -## Bevy API Generation - -A good scripting system should be able to interact with the Bevy API as well as the user's own types. We provide a way to generate Lua bindings for the Bevy API using a rustc plugin. We scrape the Bevy codebase and generate proxy macro invocations like the one above for every appropriate `Reflect` implementing type, and package them in `APIProvider` structs which you can use to provide the Bevy API to your Lua scripts. - -This generator is a work in progress but it is designed with the possibility of generating bindings for ANY crate in mind. It is not limited to Bevy, and can be used to generate bindings for any crate which uses `Reflect` types. In theory you should be able to use the CLI to generate your own bindings without writing macros yourself! See the [`bevy_api_gen`](crates/bevy_api_gen/readme.md) crate for more information. - - diff --git a/assets/scripts/bevy_api.lua b/assets/scripts/bevy_api.lua new file mode 100644 index 00000000..7cb343b3 --- /dev/null +++ b/assets/scripts/bevy_api.lua @@ -0,0 +1,159 @@ +function table_to_string(t) + local result = "[" + for k,v in pairs(t) do + result = result .. string.format("%s:%s,",k,v) + end + return result .. "]" +end + + +function on_event() + -- send exit event, to finish after one call + world.exit() + + print(entity) + print(script) + print(world) + + -- print(world.hello(entity, entity)) + -- print(world.test_vec({entity, entity})[1]) + + + local my_component_type = world.get_type_by_name("MyComponent") + print("MyComponent type: ", my_component_type:short_name()) + + local comp = world.get_component(entity, my_component_type) + print("Before script: ", comp:print_value()) + + print("\noption") + -- print(comp:get("option_usize")) + print(comp.option_usize) + comp.option_usize = 69 + print(comp.option_usize) + comp.option_usize = nil + print(comp.option_usize) + print("\nvec") + -- print(table_to_string(comp.vec_of_usize)) + comp.vec_of_usize = {42,69,72} + print(comp.vec_of_usize:print_value()) + comp.vec_of_usize[1] = 612312312 + print(comp.vec_of_usize:print_value()) + -- print(table_to_string(comp.vec_of_usize)) + -- comp.vec_of_usize[1] = 0 + -- print(comp.vec_of_usize[2]) + -- print(table_to_string(comp.vec_of_usize)) + -- comp.vec_of_usize = {} + -- print(table_to_string(comp.vec_of_usize)) + -- comp.vec_of_usize = comp.vec_of_usize2 + -- print(table_to_string(comp.vec_of_usize)) + -- comp.vec_of_usize = comp.vec_of_usize + -- print(table_to_string(comp.vec_of_usize)) + -- comp.vec_of_usize:insert(1, 42) + -- print(table_to_string(comp.vec_of_usize)) + + -- print("\nmap") + -- -- print(comp.map_of_strings["key"]) + -- comp.map_of_strings:insert("key2", "value") + -- -- print(comp.map_of_strings["key2"]) + + + + -- print("============") + + -- -- vec's and matrices have custom __index and __newindex overrides + -- print("comp.vec2 before: ", comp.vec2) + -- comp.vec2[1] = 69 + -- print("comp.vec2 after: ", comp.vec2) + + -- -- Option's get converted to nil or the value inside + -- print("comp.option_vec3 before: ", comp.option_vec3) + -- comp.option_vec3 = Vec3.new(2,1,3) + -- print("comp.option_vec3 after: ", comp.option_vec3) + + -- -- reflection via index is indexed starting at 1, unlike in Rust to match Lua's indexing + -- print("comp.option_vec3[1] before: ", comp.option_vec3[1]) + -- comp.option_vec3[1] = 5 + -- print("comp.option_vec3[1] after: ", comp.option_vec3[1]) + + -- print("============") + + -- -- Vec references get converted to a custom proxy `LuaVec` which is + -- -- also assignable via lua tables + + -- print("comp.vec_of_option_bools before: ", table_to_string(comp.vec_of_option_bools)) + -- comp.vec_of_option_bools = {true,false,true} + -- print("comp.vec_of_option_bools after assignment: ", table_to_string(comp.vec_of_option_bools)) + + -- print("comp.vec_of_option_bools[1] before: ", comp.vec_of_option_bools[1]) + -- comp.vec_of_option_bools[1] = false + -- print("comp.vec_of_option_bools[1] after: ", comp.vec_of_option_bools[1]) + + -- -- there are some additional methods available on LuaVec proxies imitating the Vec api + -- print("comp.vec_of_option_bools before insert: ", table_to_string(comp.vec_of_option_bools)) + -- comp.vec_of_option_bools:insert(1,nil) + -- print("comp.vec_of_option_bools after insert: ", table_to_string(comp.vec_of_option_bools)) + + + + -- print("comp.vec_of_option_bools before push: ", table_to_string(comp.vec_of_option_bools)) + -- comp.vec_of_option_bools:push(false) + -- print("comp.vec_of_option_bools after push: ", table_to_string(comp.vec_of_option_bools)) + + -- print("comp.vec_of_option_bools len after push: ", #comp.vec_of_option_bools) + + -- print("comp.vec_of_option_bools before pop: ", table_to_string(comp.vec_of_option_bools)) + -- print(comp.vec_of_option_bools:pop():print_value()) + -- print("comp.vec_of_option_bools after pop: ", table_to_string(comp.vec_of_option_bools)) + + -- print("the pairs inside comp.vec_of_option_bools: ") + -- for k,v in pairs(comp.vec_of_option_bools) do + -- print(string.format(" - %s:%s",k,v)) + -- end + + + -- comp.vec_of_option_bools:clear() + -- print("comp.vec_of_option_bools after clear: ", table_to_string(comp.vec_of_option_bools)) + -- print("comp.vec_of_option_bools len after clear: ", #comp.vec_of_option_bools) + + -- print("============") + + -- print(Vec3.new(0,1,0) + Vec3.new(1,0,0)) + -- print(Vec3.new(0,1,0):any_orthonormal_vector()) + -- print(comp.mat3[1]) + -- print(Vec3.new(0,1,0):any_orthonormal_vector() + comp.mat3[1]) + -- local complex_vec_op = Vec3.new(0,1,0):any_orthonormal_vector() + comp.mat3[1] + -- print("(0,1,0).any_orthonormal_vector() + mat3.x_axis is: ", complex_vec_op) + + -- local new_mat3 = Mat3.from_cols(Vec3.new(1,0,0),Vec3.new(0,1,0),Vec3.new(0,0,-1)) + -- print("new_mat3 is:", new_mat3) + + -- comp.vec2 = comp.vec2 + comp.vec2 + -- print("A") + -- comp.usize = comp.vec2:min_element() + + -- print("B") + -- comp.f32 = comp.f32 + comp.f32 + comp.vec2:min_element() + -- print("C") + -- comp.vec2 = Vec2.new(2,1) + -- print("D") + -- comp.quat = Quat.from_xyzw(3,2,1,4) + -- print("E") + -- comp.mat3[1] = Vec3.new(69,69,69) + -- print("F") + + + -- world.exit() + -- do return end + -- print("============") + + -- -- this is an example of something impossible to achieve with plain bevy reflection under the hood + -- comp.mat3[1][1] = 42 + + -- -- now let's retrieve these again to see if we actually changed their values permanently + -- comp = world.get_component(entity,my_component_type) + + -- print("After script:") + -- print(comp) + + -- world.exit() +end \ No newline at end of file diff --git a/assets/scripts/coroutines.lua b/assets/scripts/coroutines.lua index 8fec50da..728dd03d 100644 --- a/assets/scripts/coroutines.lua +++ b/assets/scripts/coroutines.lua @@ -1,7 +1,6 @@ local my_routine; function on_update() - if my_routine == nil then my_routine = coroutine.create(function() local starttime = os.time() @@ -18,7 +17,7 @@ function on_update() coroutine.resume(my_routine) else print("Couroutine has finished, no longer running") + world.exit() end end - end diff --git a/assets/scripts/dynamic_queries.lua b/assets/scripts/dynamic_queries.lua index 8128df28..a12c8e4a 100644 --- a/assets/scripts/dynamic_queries.lua +++ b/assets/scripts/dynamic_queries.lua @@ -1,9 +1,23 @@ -function on_event() - local component_a = world:get_type_by_name("ComponentA") - local component_b = world:get_type_by_name("ComponentB") - local component_c = world:get_type_by_name("ComponentC") - - for entity, _ in world:query(component_a):with(component_b):without(component_c):iter() do - print(entity) - end +local component_a = world.get_type_by_name("ComponentA") +local component_b = world.get_type_by_name("ComponentB") +local component_c = world.get_type_by_name("ComponentC") + +print("Querying for entities with component_a and without component_c") +for entity, c in world.query(component_a):without(component_c):iter() do + print("Entity with index: " .. entity:index() .. " component: " .. tostring(c)) +end + +print("Querying for entities with component_b and without component_a") +for entity, c in world.query(component_b):without(component_a):iter() do + print("Entity with index: " .. entity:index() .. " component: " .. tostring(c)) end + +print("Querying for all components at once") +for entity, c1,c2,c3 in world.query(component_a, component_b, component_c):iter() do + print("Entity with index: " .. entity:index()) + print("\tComponentA: " .. tostring(c1)) + print("\tComponentB: " .. tostring(c2)) + print("\tComponentC: " .. tostring(c3)) +end + +world.exit() \ No newline at end of file diff --git a/assets/scripts/event_recipients.lua b/assets/scripts/event_recipients.lua index 2aa50e25..b846a742 100644 --- a/assets/scripts/event_recipients.lua +++ b/assets/scripts/event_recipients.lua @@ -1,4 +1,6 @@ function on_event(id) - print(string.format("on_event, script_id: %d, Handling:", script_id)) - print(string.format("\t-> id: %d", id)) + print(string.format("on_event, script_id: %s, Handling:", script_id)) + print(string.format("\t-> id : %d", id)) + print(string.format("\t-> entity : %s", entity)) + end diff --git a/assets/scripts/game_of_life.lua b/assets/scripts/game_of_life.lua index 408e00de..69415699 100644 --- a/assets/scripts/game_of_life.lua +++ b/assets/scripts/game_of_life.lua @@ -1,45 +1,100 @@ +LifeState = world.get_type_by_name("LifeState") +Settings = world.get_type_by_name("Settings") + +world.info("Lua: The game_of_life.lua script just got loaded") + math.randomseed(os.time()) -function init() - local LifeState = world:get_type_by_name("LifeState") - local life_state = world:get_component(entity,LifeState) - local cells = life_state.cells +function fetch_life_state() + -- find the first entity with life state + local i,v = next(world.query():component(LifeState):build()) + return v:components()[1] +end +function on_script_loaded() + world.info("Lua: Hello! I am initiating the game of life simulation state with randomness!") + world.info("Lua: Click on the screen to set cells alive after running the `gol start` command") + + local life_state = fetch_life_state() + local cells = life_state.cells + -- set some cells alive - for _=1,10000 do + for _=1,1000 do local index = math.random(#cells) cells[index] = 255 end -end +end -function on_update() - local LifeState = world:get_type_by_name("LifeState") - local Settings = world:get_type_by_name("Settings") - - local life_state = world:get_component(entity,LifeState) - -- note currently this is a copy of the cells, as of now the macro does not automatically support Vec proxies by reference +function on_click(x,y) + -- get the settings + world.info("Lua: Clicked at x: " .. x .. " y: " .. y) + local life_state = fetch_life_state() local cells = life_state.cells - -- note that here we do not make use of LuaProxyable and just go off pure reflection - local settings = world:get_resource(Settings) + local settings = world.get_resource(Settings) local dimensions = settings.physical_grid_dimensions + local screen = settings.display_grid_dimensions + + local dimension_x = dimensions._1 + local dimension_y = dimensions._2 + + local screen_x = screen._1 + local screen_y = screen._2 + + local cell_width = screen_x / dimension_x + local cell_height = screen_y / dimension_y + + local cell_x = math.floor(x / cell_width) + local cell_y = math.floor(y / cell_height) + + local index = (cell_y * dimension_x) + cell_x + + -- toggle a bunch of cells around if they exist + local cell_offsets = { + {0,0}, + {1,0}, + {0,1}, + {1,1}, + {-1,0}, + {0,-1}, + {-1,-1}, + {1,-1}, + {-1,1} + } + + for _,offset in pairs(cell_offsets) do + local offset_x = offset[1] + local offset_y = offset[2] + local new_index = index + offset_x + offset_y * dimension_x + if new_index > 0 and new_index <= (dimension_x * dimension_y) then + cells[new_index] = 255 + end + end +end + +function on_update() + local cells = fetch_life_state().cells + world.log_all_allocations() + local settings = world.get_resource(Settings) + local dimensions = settings.physical_grid_dimensions + local dimension_x = dimensions._1 + local dimension_y = dimensions._2 - -- primitives are passed by value to lua, keep a hold of old state but turn 255's into 1's local prev_state = {} - for k,v in pairs(cells) do - prev_state[k] = (not(v == 0)) and 1 or 0 + for v in pairs(cells) do + prev_state[#prev_state+1] = (not(v == 0)) and 1 or 0 end - - for i=1,(dimensions[1] * dimensions[2]) do - local north = prev_state[i - dimensions[1]] or 1 - local south = prev_state[i + dimensions[1]] or 1 - local east = prev_state[i + 1] or 1 - local west = prev_state[i - 1] or 1 - local northeast = prev_state[i - dimensions[1] + 1] or 1 - local southeast = prev_state[i + dimensions[1] + 1] or 1 - local northwest = prev_state[i - dimensions[1] - 1] or 1 - local southwest = prev_state[i + dimensions[1] - 1] or 1 + for i=1,(dimension_x * dimension_y) do + -- wrap around the north and south edges + local north = prev_state[i - dimension_x] or prev_state[i + dimension_x * (dimension_y - 1)] + local south = prev_state[i + dimension_x] or prev_state[i - dimension_x * (dimension_y - 1)] + local east = prev_state[i + 1] or 0 + local west = prev_state[i - 1] or 0 + local northeast = prev_state[i - dimension_x + 1] or 0 + local southeast = prev_state[i + dimension_x + 1] or 0 + local northwest = prev_state[i - dimension_x - 1] or 0 + local southwest = prev_state[i + dimension_x - 1] or 0 local neighbours = north + south + east + west + northeast + southeast + northwest + southwest @@ -52,7 +107,15 @@ function on_update() cells[i] = 0 end end +end - -- propagate the updates - life_state.cells = cells +function on_script_unloaded() + world.info("Lua: I am being unloaded, goodbye!") + + -- set state to 0's + local life_state = fetch_life_state() + local cells = life_state.cells + for i=1,#cells do + cells[i] = 0 + end end \ No newline at end of file diff --git a/check.exe b/check.exe new file mode 100644 index 0000000000000000000000000000000000000000..e69db476314141b890ff041abaa4753a265cb706 GIT binary patch literal 26112 zcmeHvdwd(!mH(a5X!Nixdn8%16DL-j2TJ@%oCF$ZLgLs?Q1h^3J1-t_6l-jY$Qm;v zCo!qP?t{_?6t-QKq%EZ_eef%k!qRtX+26L5ZlS=o?6zH?Wq0Ye-NHf(?62)M?Dw2I zvScT8`F-}E-{UdjMCE+i8^IH^rn9sk_$6ia+6v~00`PBL z3IHDW)wLTKe-c6*ZnGVG2pHQoje?HvA$-d|Ti}p3+ss)IWLs|slXPY9E&FT{Vrv=7 z#oNiR_>gU?@QRj;h1jrB2n9IQ={KQ#ijX(>S&*y}BDiX?CmEvab;%|uX$dx-Xk6=5 z6D5i92qp~xi4RvR$uN;304PVPTnn&jYcfXVIDk_}1QM+$(gFaK7gD)_I17@C=z>-k z)AdMl30iHfY4*jFjUcQ@CIDN11355Q4rT>cp-+)Dy0``X!+)dkl_VlSC)G>A#$_2U z2jd4&S}qAIB*8fk*NU+JOf4#?VgFeIqf=hQBs1o!8lA!bYKFfu9B?ZKVp0}YW(BIk z!85g}u7=43YH@VRN7{-OjZR@wNR-SPoeC6DYHM^VNG${-n(p%l!dent(^o*#Ttm(> z*-4^u#2bs~%}y-hYu;;k4c+i1SAy*068sfB>4EYx6#ds4s|V*%5--BFgN-$p#hhkT znt?@%;fo)L_zd5?hTCs7bTD*7pJ(F5$6tHxHN%TBqrpQowBV9#1(1QWRYnqplO$j) zyAfoGGC9E3Wu%3jhzG78mO+Y-1VF17A&)C`#*9~s>aUpwMqMWm2vC9TQwJros z!$!-E#45sa!Kqf+HeA>!m5oYX1i4kQm=vuHt7R3d!X93!Brl?2nw7Mo*IwrS3AMED z>_&`Wp3km3TFiPgn$+TanZL%kuK3~LR`0@1M!1pD+|fF zO){gn#>67t<_TIeumoVeNYWZXp~_?K)0jppNZHtzQ_0w|08+FJ}S z77VZ9b?sR@?Jjhf_lOo+(^Y}>owiCNEY8$oc~mg$*vW#)O=O=)VwVdhHv{OrtME>; z1t`LWdYbG2K-@_^SbSLzR$bC_J_&3EKzTitI{~B~-pIOuLJx0b-6&%P+eR1cPTTpa zCNH5Y+lj4=QXHf4Ra&U@piZluUg4{2^Y~iT*s8eOpINzA-k{veuP3)yP43|4g$Mmh zqka0Qjg?c_ZZ)+rG=VTwAVYk-QlLUEtwRRCp z;*<9Yn<;0i5Ok7LnQl6yg@Y%X&45$3n{<8omg=9u3)fMS)6;&|iXNH`o$9t6S0Ade?6 zMJY)&BATJaZ@}Oxk%$qA1wL*>tjk<_A_@zl*IW)XYF$A@gkRJ;L?s=YrHyeOkNADo zASkjci&PtX>D9q)-8ym=dYbT_Y+Shy<-+fDMO8 zccd~Jsq#OLahEPkj(~OHzat#{k0Tu`Cq4*bdG{(+iE(dy)+j2s}Znyh+WkA$JbtarqVE4e4tpMJf&k!cVH0d^CZ3y6P*|jFRokQ zc3ea!0*-R|9$ag2r4S(cdjR|KeH!$lJc$KEjdjCg&9W=(>lTUQf|wIjA(D~_@r($=j~ z)swt9@nU10gp}=7#JGViMb5Rif@Elw%_IpoYSt78Zt-=*VSW&u=dt_uGdy;c7`sY2 zcCV+W9?klb93|8yJ2c`;UV}3CA>u>oYh4SprJ739C`BrsMt1~qY+4Ij0wE2Q=RtYK zvjWlUvkyWk&xZ^9VTe0CRU7W6N>w~Ow1UhTpn!`PM+R#|ZF`+dG=g)7hJ>)9`OaxDqc74y|Tx8NUtAk zjjHw(3@%%jgUzeUXd!oV3acT_{&N}<3RfxaZe`c|2Iu zQm;2&&XXp#I^^opc@qliKIiSISLr8zP#^Aj1AS=uf6w~Ga(*H0q3B0vs4rM%XnYLk z9iRo}v7EARI!QHFt@9<{i9&OaOIf^bscu~dO04~dx-7*HTJHkE{wo@Q>q+>l5MGNy z%e^=-aLIZ%Nql!!;#M6woFb~xcGYa#Djg(|Xi@&9h-UCY;Bn>>7!;pie^0=^OP0pt6rcJlim_bzK4wZr&+G`UaE|` z*mjXN#i?$IE9)*`cgQ$+BR0MdD(Bev2K#naJ@k!et90(2Tw52Bg}*D=Pcxd?oF|?{ zzO301b#CW5x7-5X(nn3+fGXCF08{WRl1IkhPdI!8{3a?c8lWm)F54{A-Ym4s}|U; zFqlwope?pA*0|XD0IH(r^53v}l5B`umqV*8dnn=4SJ^Uw_Ow>myP(DSAgWyrlUI=D zwdzT_^5CwzKq4N_tY=v?;w2Vi#aiUi5{t1Si`-mdF;-+z5SCbs68s)h47c@%9Z9D?wO?P*VXwb=FU@Cm-R4YV$>PgIMZHnsqv?;2ko@@csTdRC$ z^f8D!w?au!k6NclGjF$ONP#kelVf75@OXgUrk-4hYMufPEDJU3G-Rz05%@5Hj}W*G zVAXqya>0_^M~QnofnE~X=dnJ9YfGhC)+02@IocIEIzj!2EQm%HMk5W*Fl>x0qLfm{ zt*dK3j;fW$A_qaOPmxKwv4~A`E(E2@SQK+U0g)*v)RK3g6g{J7z;Ql_vh^u|K=RXo zbi|2SpFs(k)t$IRBXQ?S2uA9RI%Clkxy`6c{x5K*$YDmjwc4mVqaP(*pCtuxBc8mA z>esPHq2}%qW_=E2>mDL3K*dF8^bxA~c@QECj0M)cC^+{K=B4FUZ)uQelHMGk`vlfs zg2j8r@`&F0yy3O(rwZ7~gLL1}SSWRl&gxufEVRA|ZY<)DMFO#in{`#Fk;Yggu|ZSd z(?%n4nvM&0Kc;Ft`6Y&u|F^c$7&8`fdiBTI}WG5acTK5i_j zi(6kI18_XKF2fn&TkeS|a+B zUqizyK&F-gMglNlB#g!zvzuQ+3Yq*m^#z9=`%|c7JwOH75dxIfJ41M65a3!1w}+PqNlBgh+1pZTHit8!f9gES`VXaeHWm9OCA&w z49Ajx1HwggWH!PrvxbDN?}5C+tyE_{LRB9n@O=OdZF!ijcSYhQkw|z0Ww>Y8wKu|G zuGYHrY%ZUu>}^Gnme!(Eq~T=^#NUTCM6n(t3*mZ z)|!W2SMnTvD%#lG3h!belEaKUz!;-hp5fA&`Z)Ei2SsD*)QUZK;y9XwOQ%1g^^W5)Uc1X_OK z+GYI^Sh4&h%GTcjEL_**uGDi_e^30`{o|RK%WSDEN?8zi3XAKHa7Acq2yM*`^aYW6 z`z9Ka>%lYXSq-m8&j?>jjr|Q`y$`J9j{#tH8dk3|7Q<%I@m6`pdMD-v)_AcRv$+yi z`hX;k17K2!P4nnT$;7Bvh~MFhq?JD;KZNfWK&#VBdWd-$zTX3V1?b2|#1=&2mG-a6 zGTNMYZQwJM^An&~7q@;$3W4*LSh{5Ogk!HhlFhF+^T!h7$DPrtV4pc=9Wz_^rR{9` zNX|^O?oN-HiN3x41ABW12YPyTc3#qv+MQ_awr$Jq7%F6~e4;;_GxLSqWT%xcWb+dy z9y@pL?d$8_Juujn>Pu`&^pEGVh1TA5VKmXY(@YO1WI4IrEVS;lhSH>EWmT{$m>o_e z=hSUAuSzr>F^^3SrpL2`BWAv7W#VL2FoDld+8(hI&H3!eDB5mayJqeB*7min?dKmRr5qt1AG z2yXbVbwOs>Ocy3>)7jLNn@FF(K4Fihv-DKn#MAj>ldFf}r@`at!qBK`OUl?pu88V`iFQ4#s9{|68^y@-`I5&9U`uYueVWS=Wv%gziS=02>e>ORo{)dR$+wN4dXX zXY(TtNxXFp_=t<8d;7($=ga5tOSkV$b%FO8;5Q*&mTt|_tx^6U#+3b=Kd~rK0rdCF z*HQ2xJj79aYw%r-FS0p~L!#539>ABxDLxU#lvnX1^Ch@qk7hc>Jep!%Btvzn9$gWT z?o}5riN}D|DTWdhO$=88>Y`0~4E47H2F0hD@)T2EV|cwv+z&APHN%$ygQ8uJ>AJXB zzYpbMeLKpIPLl6scsJ;}_$tFkSf<_=@af{+K9Yal_ak3WEcKHmf5Gs<3M#L!tgQ@+ z?F{!ad=JClRy|u46u}U|r3^1-c#z>ShWCWt9}0@c82&aydM>Iaoj(QCMMDkQd}$3) z{v1#j_cO&~5akmF$$y36w;2AM>3=X{dQfzPNoE_v8yG$iCQBY=_!EZDG7LmWGRE-w z$V4P4KEmaD0Ylt6nP&^f< zzWhE;R-IS3ur4SrtfTTahL-_`#HZ`7uM3I08U7{1ZvzI!uj;5@zIrOx*OLt!>Zz@R z_0*TEP}apqnes^e`$H6sGA8A$s}WJL4D*bzFb*rY&49R7MWYA;yO=Sri_x442p=#7 zbEOCMsxU7ag$D{R2hRYuoH3Iz0~pOJ3zD_?C$YBzs}~8}c~ilA7bL303Y@!cN9h!J zLY&8|eGT>#YT-OF2%Rl;H~u{|H!=33&s`KD0%!5oJZJ z@y6l%3%m;fcQ8E6@HoR88GeG{ml;0B@aGKA04n19J_qng-*Ld-`Az~>`3WZd*8*+8Ts)_h})Wx=_Szu2}3{NTYh?y5$-eI*1*efnpP*cFf z5`oV{cphP68UJ__WBz;8Yeih#>0%G6J;1)|Vn1Q*5sBeI{&w&NmP#!Zp7)44amO-= zB|Nu?262Ky7A+(^w~58#hbtKKuk~Dt_*Ku7Shr^oSc8il@bti}x477dX8>5n#g2LI z!kvJlE_R*g^T6ndyb#yb-Qvj$HiXCFwDRLJ%+Y>|nebMYyhU8AJ%^cehl}0J*ds1> z2V=h})45#y#~dt|WUIwH^hRa5c&b@qAJN;Dr1)W*#QssgSZNWr(pHGR|D(P`Su6Un z&r%e;st+g^h|45~$9H#$3q*#o8L`555WJtcytRz|hl{0rhrnCcE_J4SpU3=vvy1fr zyGUH>VuygeS={1cW4^rDC~lv{4k;VOj~JT~$DwnxsK)(TvU3dewu-om-Rc`rIz_#U zeG0s8vBAZ@1ZhvfNN{qIF&KjUJ({tp8Cxr+@k_JWI@@Sg(jRTq1g z|1Oade{`{%{I`MU#mS$1_EG;QfEf}KpY`V<8F8@(7^`)$?=u#6vF8}8cd_65v#7U@ zF|zuvl(&dpiTQT~y2K7~g^OhZDPTukYzn-c;)ILc0^Uw>or~QA-Y)S07yBFVc8QO< z*mL0R7N2u55ljL5x{ECgc47Vhu8XY)uSfj7i|qohSNyY!4TIM!e&b@-g11M!=3=M8 z+as!I%MsW4zW`pJSm0uhgV)FJLJ;p?!Rr_2yF6b-3RtI$Ev@Jh1ESZ(HiI`n3h{ZU z>avP!#a@X3yRzatN(q~+FvY%E-gOmOV24=C&jVC%zZiBgs<&TQE=KhZh~q9s^$v*X z^GVUo;%gO;DF?;qMu|OD@uYI8cspZqhF>nGxn2=#;Ck1IUqo-vE*D)c_FG_w#E6Sk z)c(14SX^ILFD$Q+lUiEbRK^<;x4OKWQEv!_DB_P5YC;v2NKrlF2%sh`K(Ckr zB(8E!?kznck9Ydvt$`yc>tU2n!Xic43 zDWWwAbq^>>HKjDykmjv`dz7O!`#_njA9xm?|&e5U4znuh!^xZh^^CrMuX z9P~Yca+*DY@~VKK3@W9(T=RZ)QVAG$Lq1|q@0tv(`bv_^7jSu_L4DZ)*dY#r(jhWT z&oliRhVM6i1P!N*r_=yi&x;v&`&sp7_J2K7Rx%6-%B1inBw9M9Ja4?9uH=2Rfw{{> zAgp>?L_8ezyjv^{-zDx;4utDHcPdwgn*i1 zD)QAK(#;N zm0G<@c}BfT`Nem|Rnc*+owZGh$>@ak1j^Ie5|!rHO2E80sD7^YTCqpHul74i8k8?; zDfN4`U)L^FU#>N=yNl@GYgegfYM<5=wK8@W{7gC30MqLQjZ}wP7rPc-O~(FJYlnvK zD3j`j*bCYWYnxQFv6r=Xs}IKhpxvxK6Z3d)R$q!CYf)c~1-&1WEh_PNjW?yPipK%F zlE`!q1C?upy84FEyM=0$3|w1Y9p(0o)*d54cgh2Dn9Nh^|XS72r;m?8W)J zO{^1xdK{hjua2ve>TT+M>i5+jsJ~Ee_e8YKTCa9MyFxpuJ)~*6inTs~buWmMbp=jhl{oWM z;cO$shdo~ayvu_}P~uA-Jk${ndA` z5fA49ZpU0z5ETU9g1Z|kGJb+PL@Ove8SchCN)>rJ!5+~LdM}`gon#%#eSj+E$|w&2 zs>pxegz`Ry2l%ebeuf8Oks>Z-csVRmao2_56|hLb&w)0hJc!*z5r+Zkt=>+Qj{xe` zKQ?r=TK%p12es1kW6!gmUwFQ+{gbxZ+vV+2JR(x9;I|51fggy7Es9S}D|8Kr)3^$p z*iI{mNbFvYrV4EugEZ&!Jnm6>$|%T(7}LsVLE(ogit5rQC=8|%g$n(*eiA4e(Tc*b>`tD|}#b+!Xx- zU6-WunOwPQ(mUHuv0kT@v+Q2mIx)%2j`8tSzF^wJ)GA4XAo?erf;rZ(5*>;KL6hv=7U8rM@X_vH*IYXA6%N}txh<)kYgfzbA$d%?$L3HOQ z#@xztYf6RG$HAVx1HF3(1~2K@-LyMs^!uUi%?6KNRb9y&T=TN8OS0iOxy9JK!I)ut3?jf}Ef3GK8j zJCn_)3#P-8ofEc$5wM&ryOX5nk*IM=n$=f^Zp%$Lqp3VP>-K`gw^_D1-`4pwDc))3 za`4+wA)OyVw7>-}9S@x_($dBq=48jQbT&tiuGr{Z=@Y%9lTLOho!g(yXRPD19S5h3 zf{GlMG%zUlj8h*S9w(qe4#m6%`_E~DR655^^GMY1vZl$AWoU^zkS(AWCAP%dh6)(d z`C}|iCsao! zD4Gu7II+_lE{FkZT=dcNJF(R&V4~8f&aMn8hl8ch%w%m0yO|LwM^2VGBz_QCMma{a zb8t{>OYQ6)95~q9J-B!Gj@>=`cb8GRQvEy1P+GLg(B2e&EnBMI*S)J}pqnRgYIoTj zrdi$H*VofmoYXe2h-}aN5N6{1G25TE^LS=AU)Ckhm+mr;Oq?al#QBo@O#6uCnDh0z z`fJ?x71EbN_A=e$-Rx%f}Pns_9(fn^qWHySf#NVP{EW>Txpf*O*;-A6=!(4pc);{ z91&jIbpV21lgPMv<>fwiEObu z+wlZAoy%S=cgIdViAJY*5wz^=2p0a_xoCS+<<#vH*^C&QOl5en?X|PVuw8Ve3u!Sp zB)5Csf?zDRZSpKuBQnF)QBImw%*0gQ!9qV|x|%7$U^-F*^wpvLoYWP|-INOKHnIC> z@FNL1&X zjM*CVRn69z&!8G^T+d&dsLt!K%4*G5SXOI3i)s~T)VUgaJzjae`8uh&V!io1s#g|a zBwB_Nmm;qd3ncIVvq+iHEX^rJs#&Z=39;ClALYy%Q9NYwa@u_ibFah3Ya(vob|E>= z<_FJ~6r*!<(cHMqFp7&u-vn0LF|&==C~Lgmw2xtdc94nN&S*N<;dB(YdzdlC`FMu& zeeB>RR_1tF-cm$3?-aRlT7LU5T`|>D`BI(SIIn*$CpRurvr=N18}G#HKP5bK9NPw7 zOXBI?!z&wfsSlT{%wz{(Y{A^|?HvV*evczzA;bP@ z4wTWjnmfUZCm*WkX5myUs*>qBQMgh^CPT@hkfzd^jAu3T=|wxIAWs6N{_ZR%yB%2U|I1|DVB?uoG@rp;){YUa@4j2g$4PZ?kraB2qHUzk0)&NoTo z<<7)WC5%+f0iN+fGl?sbr^_A8`jz)@Euw)h?uGBhOgOK&7;J+gUbr|k+-XN;_l5=35w;Df z{agyGOF6Sn@6Pc}99F}lJ7BriVwjP?VYfMIx`z)IV&kcV4G!riJIBJE9Nci)3UAP1 zE0@L!NC*ad*79QLQBTV%V&6Gt9mV6ed|};MfxG~Bl1T9})21T{b_#hLNQ&*k$_b^I zA;KERT`u#g38dF><_IF<5;HfxOTK?f-0pH-m)rsPwo-9_EuD&-^16NeY4fRh-tzcYOVXRZE;BXA1bfG%as6FtK?f$tq3ht&ht zPV6x@^{$Z4=AGiaO5uK*R3ImSd_B0MAdoI&8{tuL7v@xt7=UHGJKJ1`6Wd~s2KXgc zYFn0A!i^)BvfDh)2Z|17_V9>g1%a3^P;i!YZ=gd~DaG{0i-!gW$q~8qWM?kzI2#Zh zd5l1xiP-1FM~vaO`*b+L5Sf`$F0_%drHhXY4z9%=Pq(;Eq&l3*{19qmb1u=>V+$2$ zwRPld5^ja|FWY$WhQUGny{L2!zaZ)*2ltQCZ7dAjXmOM1q+?F*9M-Ivr(vjMMZ2&C z*Vv!V7Th`1Zx-YV&-$>F!}?C74wM!MKKAq%usrqllLt!Sh3U=1goKHb1d0`o4LN|b z0Y&s;{IZNg`)Cf+J|pCkfq;Z1Ri}x}Z z5d(I1tT^MkvgwgLZfIwR9KmO@5lrx%>52T%=xn0LYx@b@&p?JeQe41EJ&Y$FoSz-W zu8w)Y>7>hXhlb`m?tbHLAI)oui@gKeHn`RMkiXN)0vWeRmjMfBZNB|4Gp7z@5Tu1F zZ?m&lQ*x8Md0>(vwa0CsVs}Wa4Qc;GE^T+87$?WO_h?7V6PWCHtzK-$ZEu+Z^-l~T zyLKd{6z<#(OSw0-ahtp#x~vJhVLV_@VoSi!0nzsC-XM^P(47&kDc9(&7M^3I@xn$X zQ(T{@jG@9wCxaJ zLsYg<1~=7#w<&5mbGR4CK}Fdz@0O6wlvYmpaA(}%HweY%e*A4OM-*^87{jlDJMpG+ z4*zhN0WAwG4{jTt%9$vcSckIUwBb2imTL(Q)F`6%B%bn4;py2)(T?jCc;1)5n+zb-Gtl{JZDSbon{OCgct=4D<;~&yAfX2<0T2P zeLwhQ&&aIw81xnJw+#}IC!5o-i8Rt-hjbG+0Za41CQxQ=71CCzIRU!D`m*fyEK2HGyZAMZJpKI?y`!QC1Xouc*oTI6+7qWfmImHAHmxu%t{kQ}c zQUod93HVx6w8G{zN}w36kT`)7jXXt^;<-qO>8De0VFCeQL0N*8QNU$EodjOsARrgb zt(<`TIJhz_OZ6!*ac1Y57GRpgj;<6|Sq_a-fX&re)I~ueTc*HHa2F==cr=JI{hM#g zMHuppv)YTpcQL3+fMoNqLGiXCfRsop2Tg&ULSYIHXk-Tsx(r=MC~({`hgD7}RkF?z z;3JS8Vvh{rCpvAAcQDCBgk_aR(L)3NcZ8&Q`0W4K!KDglO&HaUkDNaFvg?1FUe()vy2AyH(w zfJOt}2@?PUOu9`=K>$Vhlj=twYp1UK3tMH8z2`i3(`|!=zFzfh^VBL?BIFHmOugAWI&mx{87>s_3sD ztqE0W2#>MzC)8EF=rjgM&;WVSnBR|H`!(Qx9sZfVQ}q{z83j2sFsjB_>Bk?n#I@4z zr_u3HSB&Yqm-s5?#Dx(p*7Ex)PK>A*#!uhN@Cz6+tc6n z`qX+FeMJrV+!58~fCdtxHaz_Veq96xuHkMtJVM(~c=}0W`p0k)3L$g`7rbOd!yQNv zZ4tg+onQn*KmDvR{akqZmxRMh&%^r-iyF8>LjztxYG?qXD&cJiNjWfS)Ea2`BO;>U z*I6ng@E>orsG$&GDAcgQSL>P^?v`AJ&o=l&4dEGB@jyc;yeoVVW!HKS8_4%DqrPhr$Pa zJ`Z4c7u>B-Z#+Jq8a{{-#vp_bVj@z=c!dbh1Q=FPD4JflbW;O~Z1PcL;G^l`nR;>s zdbNngEIhLWb72F~m%H?pAZ#SUN{Zr!x7!sY?A6be6V6B6|N`LnAyd=*Y6(*}8W9Eur!m}u}DC9S0(%^>{dAOM@^oM80q&-)mAB2TxuEJ<2H1ZIn zz(v>P<((XUGdJiI88ubRdN<8Yl4y{U4GY((UigEJSu8DH3>66A~R zXU5E(Fa~3Fsc%_$J@`quLv{sg9lOl$M+`0sg=eyC-$V$-8Gm@@omKErcq0d$^am=i zUuYOMUCvi%wIB&oW?Sw; ziif9fXf0coPEtDweAm$CH7mOhvUq>4%$7As9ZO$jhQxZzLi~TMhG0xq_dhSOr z>RL#SCtyJV<2tuDrG8MKC=RLbcn1~#==6UCtx@v)U)4iZ@o!)I=Elt@#&QYV8>ibc zo0{6&)-)wd_ukN^Cfpcm-O!Y9@O(9s&RKbLQ`4mBG;O}PD!37MYx${T0t)i@;|UXX z{vrprCC1WD>sS_VK|0oOp>@a_yD069wH<43O5i>V- String { "bevy_reflect::DynamicTuple", "bevy_reflect::DynamicTupleStruct", "bevy_reflect::DynamicEnum", + "bevy_reflect::DynamicSet", "bevy_reflect::OsString", // TODO: once macros allow Vecs for primitives as args remove this from ignored types ] .join(",") @@ -189,7 +190,12 @@ pub enum Command { /// The name of the API, this will be passed to the `collect.rs` template, which by default will be used as the APIProvider name and the /// title of the documentation. - #[arg(short, long, value_name = "NAME", default_value = "LuaBevyAPIProvider")] + #[arg( + short, + long, + value_name = "NAME", + default_value = "LuaBevyScriptingPlugin" + )] api_name: String, }, } diff --git a/crates/bevy_api_gen/src/bin/main.rs b/crates/bevy_api_gen/src/bin/main.rs index 658afed6..137f00ee 100644 --- a/crates/bevy_api_gen/src/bin/main.rs +++ b/crates/bevy_api_gen/src/bin/main.rs @@ -68,7 +68,7 @@ fn main() { let plugin_subdir = format!("plugin-{}", env!("RUSTC_CHANNEL")); let plugin_target_dir = metadata.target_directory.join(plugin_subdir); - info!("Computing wokrspace metadata"); + info!("Computing workspace metadata"); // inform the deps about the workspace crates, this is going to be useful when working with meta files as we will be able to // know when to panic if a crate is not found diff --git a/crates/bevy_api_gen/src/callback.rs b/crates/bevy_api_gen/src/callback.rs index a762ed76..d2e7483b 100644 --- a/crates/bevy_api_gen/src/callback.rs +++ b/crates/bevy_api_gen/src/callback.rs @@ -1,5 +1,4 @@ use log::{info, trace}; -use rustc_errors::FatalError; use rustc_hir::def_id::LOCAL_CRATE; use tera::Context; @@ -16,15 +15,13 @@ impl BevyAnalyzerCallbacks { } impl rustc_driver::Callbacks for BevyAnalyzerCallbacks { - fn after_expansion<'tcx>( + fn after_expansion( &mut self, compiler: &rustc_interface::interface::Compiler, - queries: &'tcx rustc_interface::Queries<'tcx>, + tcx: rustc_middle::ty::TyCtxt<'_>, ) -> rustc_driver::Compilation { trace!("After expansion callback"); - let Ok(mut gcx) = queries.global_ctxt() else { - FatalError.raise() - }; + let sess = &compiler.sess; if sess.dcx().has_errors().is_some() { @@ -59,36 +56,36 @@ impl rustc_driver::Callbacks for BevyAnalyzerCallbacks { _ => false, }; - gcx.enter(|tcx| { - // tera environment for import processor - let tera = crate::configure_tera(tcx.crate_name(LOCAL_CRATE).as_str(), &templates_dir); + // tera environment for import processor + let tera = crate::configure_tera(tcx.crate_name(LOCAL_CRATE).as_str(), &templates_dir); - let mut ctxt = crate::BevyCtxt::new( - tcx, - &meta_dirs, - WorkspaceMeta::from_env(), - include_private, - Some(Box::new(move |import_path| { - let mut ctxt = Context::new(); - ctxt.insert("import", import_path); - tera.render(&TemplateKind::ImportProcessor.to_string(), &ctxt) - .unwrap() - })), - ); + let mut ctxt = crate::BevyCtxt::new( + tcx, + &meta_dirs, + WorkspaceMeta::from_env(), + include_private, + Some(Box::new(move |import_path| { + let mut ctxt = Context::new(); + ctxt.insert("import", import_path); + tera.render(&TemplateKind::ImportProcessor.to_string(), &ctxt) + .unwrap() + })), + ); - trace!("Running all passes"); - for p in ALL_PASSES { - info!( - "{}, in crate: {}", - p.description, - tcx.crate_name(LOCAL_CRATE), - ); - let continue_ = tcx.sess.time(p.name, || (p.cb)(&mut ctxt, &self.args)); - if !continue_ { - break; - } + trace!("Running all passes"); + for p in ALL_PASSES { + info!( + "{}, in crate: {}", + p.description, + tcx.crate_name(LOCAL_CRATE), + ); + let continue_ = tcx.sess.time(p.name, || (p.cb)(&mut ctxt, &self.args)); + if !continue_ { + break; } - }); + trace!("Finished pass, continuing"); + } + rustc_driver::Compilation::Continue } } diff --git a/crates/bevy_api_gen/src/context.rs b/crates/bevy_api_gen/src/context.rs index 498a958c..1e282a74 100644 --- a/crates/bevy_api_gen/src/context.rs +++ b/crates/bevy_api_gen/src/context.rs @@ -83,7 +83,8 @@ impl ReflectType<'_> { pub(crate) const DEF_PATHS_FROM_LUA: [&str; 2] = ["value::FromLuaMulti", "mlua::FromLuaMulti"]; pub(crate) const DEF_PATHS_INTO_LUA: [&str; 2] = ["value::IntoLuaMulti", "mlua::IntoLuaMulti"]; -pub(crate) const DEF_PATHS_REFLECT: [&str; 2] = ["bevy_reflect::Reflect", "reflect::Reflect"]; +pub(crate) const DEF_PATHS_REFLECT: [&str; 2] = + ["bevy_reflect::PartialReflect", "reflect::PartialReflect"]; pub(crate) const DEF_PATHS_GET_TYPE_REGISTRATION: [&str; 2] = [ "bevy_reflect::GetTypeRegistration", "reflect::GetTypeRegistration", @@ -132,11 +133,11 @@ impl CachedTraits { self.bevy_reflect_reflect.is_some() && self.bevy_reflect_get_type_registration.is_some() } - pub(crate) fn has_all_std_source_traits(&self) -> bool { - STD_SOURCE_TRAITS - .iter() - .all(|t| self.std_source_traits.contains_key(*t)) - } + // pub(crate) fn has_all_std_source_traits(&self) -> bool { + // STD_SOURCE_TRAITS + // .iter() + // .all(|t| self.std_source_traits.contains_key(*t)) + // } // pub(crate) fn missing_std_source_traits(&self) -> Vec { // STD_SOURCE_TRAITS @@ -152,7 +153,7 @@ pub(crate) struct FunctionContext { pub(crate) def_id: DefId, pub(crate) has_self: bool, pub(crate) is_unsafe: bool, - pub(crate) trait_did: Option, + pub(crate) trait_and_impl_did: Option<(DefId, DefId)>, /// strategies for input and output (last element is the output) pub(crate) reflection_strategies: Vec, } diff --git a/crates/bevy_api_gen/src/import_path.rs b/crates/bevy_api_gen/src/import_path.rs index 2f26fd12..c8f55226 100644 --- a/crates/bevy_api_gen/src/import_path.rs +++ b/crates/bevy_api_gen/src/import_path.rs @@ -27,7 +27,7 @@ impl std::fmt::Debug for ImportPathElement { /// Because we do not need ALL the items in the crate, we start searching from the item itself and traverse up the tree. /// Caches results for already found items. pub(crate) struct ImportPathFinder<'tcx> { - tcx: TyCtxt<'tcx>, + pub(crate) tcx: TyCtxt<'tcx>, pub(crate) cache: IndexMap>>, pub(crate) include_private_paths: bool, pub(crate) import_path_processor: Option String>>, diff --git a/crates/bevy_api_gen/src/lib.rs b/crates/bevy_api_gen/src/lib.rs index 23d29403..cc8c1c28 100644 --- a/crates/bevy_api_gen/src/lib.rs +++ b/crates/bevy_api_gen/src/lib.rs @@ -2,6 +2,7 @@ #![deny(rustc::internal)] extern crate rustc_ast; +extern crate rustc_const_eval; extern crate rustc_driver; extern crate rustc_errors; extern crate rustc_hir; diff --git a/crates/bevy_api_gen/src/meta.rs b/crates/bevy_api_gen/src/meta.rs index a9861da3..d517d0dd 100644 --- a/crates/bevy_api_gen/src/meta.rs +++ b/crates/bevy_api_gen/src/meta.rs @@ -66,6 +66,28 @@ impl MetaLoader { self.meta_for_retry(crate_name, 3) } + /// Searches the given meta sources in order for the provided DefPathHash, once a meta file containing this hash is found + /// the search stops and returns true, if no meta file is found containing the hash, false is returned + /// + /// if a curr_source argument is provided, the search will skip this source as it is assumed that the current crate is still being compiled and not meta file for it exists yet + pub fn one_of_meta_files_contains( + &self, + meta_sources: &[&str], + curr_source: Option<&str>, + target_def_path_hash: DefPathHash, + ) -> bool { + let meta = match meta_sources + .iter() + .filter(|s| curr_source.is_none() || curr_source.is_some_and(|cs| cs == **s)) + .find_map(|s| self.meta_for(s)) + { + Some(meta) => meta, + None => return false, // TODO: is it possible we get false negatives here ? perhaps due to parallel compilation ? or possibly because of dependency order + }; + + meta.contains_def_path_hash(target_def_path_hash) + } + fn meta_for_retry(&self, crate_name: &str, _try_attempts: usize) -> Option { let meta = self .meta_dirs diff --git a/crates/bevy_api_gen/src/modifying_file_loader.rs b/crates/bevy_api_gen/src/modifying_file_loader.rs index 7fab22dd..5458080d 100644 --- a/crates/bevy_api_gen/src/modifying_file_loader.rs +++ b/crates/bevy_api_gen/src/modifying_file_loader.rs @@ -1,11 +1,12 @@ use std::{ io, - sync::atomic::{AtomicBool, Ordering}, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, }; use log::trace; -use rustc_middle::ty::data_structures::Lrc; -// use rustc_data_structures::sync::{AtomicBool, Lrc}; use rustc_span::source_map::{FileLoader, RealFileLoader}; /// Injects extern statements into the first loaded file (crate root) @@ -41,7 +42,6 @@ impl FileLoader for ModifyingFileLoader { } } } - f }) } else { @@ -49,7 +49,7 @@ impl FileLoader for ModifyingFileLoader { } } - fn read_binary_file(&self, path: &std::path::Path) -> io::Result> { + fn read_binary_file(&self, path: &std::path::Path) -> io::Result> { RealFileLoader.read_binary_file(path) } } diff --git a/crates/bevy_api_gen/src/passes/cache_traits.rs b/crates/bevy_api_gen/src/passes/cache_traits.rs index 12e2972b..c0c36b05 100644 --- a/crates/bevy_api_gen/src/passes/cache_traits.rs +++ b/crates/bevy_api_gen/src/passes/cache_traits.rs @@ -57,22 +57,21 @@ pub(crate) fn cache_traits(ctxt: &mut BevyCtxt<'_>, _args: &Args) -> bool { log::trace!("has_std: {}", has_std); - if has_std && !ctxt.cached_traits.has_all_std_source_traits() { - log::debug!( - "all traits: {}", - tcx.all_traits() - .map(|t| tcx.def_path_str(t).to_string()) - .collect::>() - .join(", ") - ); + // if has_std && !ctxt.cached_traits.has_all_std_source_traits() { + // log::debug!( + // "all traits: {}", + // tcx.all_traits() + // .map(|t| tcx.def_path_str(t).to_string()) + // .collect::>() + // .join(", ") + // ); - // TODO: figure out why some crates are missing std::fmt::Display etc - // panic!( - // "Could not find traits: [{}] in crate: {}, did bootstrapping go wrong?", - // ctxt.cached_traits.missing_std_source_traits().join(", "), - // tcx.crate_name(LOCAL_CRATE) - // ) - } + // panic!( + // "Could not find traits: [{}] in crate: {}, did bootstrapping go wrong?", + // ctxt.cached_traits.missing_std_source_traits().join(", "), + // tcx.crate_name(LOCAL_CRATE) + // ) + // } true } diff --git a/crates/bevy_api_gen/src/passes/codegen.rs b/crates/bevy_api_gen/src/passes/codegen.rs index 6a2a1a68..cd2e9ccd 100644 --- a/crates/bevy_api_gen/src/passes/codegen.rs +++ b/crates/bevy_api_gen/src/passes/codegen.rs @@ -37,6 +37,7 @@ pub(crate) fn codegen(ctxt: &mut BevyCtxt<'_>, args: &Args) -> bool { .expect("Failed to render crate artifact"); file.flush().unwrap(); + log::trace!("Written files"); true } diff --git a/crates/bevy_api_gen/src/passes/find_methods_and_fields.rs b/crates/bevy_api_gen/src/passes/find_methods_and_fields.rs index 8034681a..583ad0ae 100644 --- a/crates/bevy_api_gen/src/passes/find_methods_and_fields.rs +++ b/crates/bevy_api_gen/src/passes/find_methods_and_fields.rs @@ -6,9 +6,7 @@ use rustc_hir::{ Safety, }; use rustc_infer::infer::TyCtxtInferExt; -use rustc_middle::ty::{ - AdtKind, AssocKind, FieldDef, FnSig, ParamEnv, Ty, TyCtxt, TyKind, TypingMode, -}; +use rustc_middle::ty::{AdtKind, AssocKind, FieldDef, FnSig, Ty, TyCtxt, TyKind, TypingEnv}; use rustc_span::Symbol; use rustc_trait_selection::infer::InferCtxtExt; @@ -36,8 +34,8 @@ pub(crate) fn find_methods_and_fields(ctxt: &mut BevyCtxt<'_>, _args: &Args) -> info!("ignoring enum variant: {}::{} due to 'reflect(ignore)' attribute", ctxt.tcx.item_name(def_id), variant.name); todo!(); } - - process_fields(ctxt.tcx, &ctxt.meta_loader, &ctxt.reflect_types, &ctxt.cached_traits, variant.fields.iter(), ctxt.tcx.param_env(variant.def_id)) + let param_env = TypingEnv::non_body_analysis(ctxt.tcx, variant.def_id); + process_fields(ctxt.tcx, &ctxt.meta_loader, &ctxt.reflect_types, &ctxt.cached_traits, variant.fields.iter(), param_env) }).collect::>(); strats.iter().for_each(|(f_did, strat)| match strat { @@ -52,7 +50,8 @@ pub(crate) fn find_methods_and_fields(ctxt: &mut BevyCtxt<'_>, _args: &Args) -> }, AdtKind::Struct => { - let fields = process_fields(ctxt.tcx, &ctxt.meta_loader, &ctxt.reflect_types,&ctxt.cached_traits, adt_def.all_fields(), ctxt.tcx.param_env(def_id)); + let param_env = TypingEnv::non_body_analysis(ctxt.tcx, def_id); + let fields = process_fields(ctxt.tcx, &ctxt.meta_loader, &ctxt.reflect_types,&ctxt.cached_traits, adt_def.all_fields(), param_env); fields.iter().for_each(|(f_did, strat)| match strat { ReflectionStrategy::Reflection => report_field_not_supported(ctxt.tcx, *f_did, def_id, None, "type is neither a proxy nor a type expressible as lua primitive"), ReflectionStrategy::Filtered => report_field_not_supported(ctxt.tcx, *f_did, def_id, None, "field has a 'reflect(ignore)' attribute"), @@ -118,7 +117,8 @@ pub(crate) fn find_methods_and_fields(ctxt: &mut BevyCtxt<'_>, _args: &Args) -> ctxt.tcx.item_name(def_id) ); - let param_env = ctxt.tcx.param_env(fn_did); + // let param_env = ctxt.tcx.param_env(fn_did); + let param_env = TypingEnv::non_body_analysis(ctxt.tcx, def_id); let sig: FnSig = ctxt.tcx.normalize_erasing_late_bound_regions( param_env, ctxt.tcx.fn_sig(fn_did).instantiate_identity(), @@ -206,7 +206,7 @@ pub(crate) fn find_methods_and_fields(ctxt: &mut BevyCtxt<'_>, _args: &Args) -> is_unsafe, def_id: fn_did, has_self, - trait_did, + trait_and_impl_did: trait_did.map(|td| (td, *impl_did)), reflection_strategies, }) }) @@ -238,10 +238,9 @@ fn report_field_not_supported( variant_did: Option, reason: &'static str, ) { - let normalised_ty = tcx.normalize_erasing_regions( - tcx.param_env(type_did), - tcx.type_of(f_did).instantiate_identity(), - ); + let param_env = TypingEnv::non_body_analysis(tcx, type_did); + let normalised_ty = + tcx.normalize_erasing_regions(param_env, tcx.type_of(f_did).instantiate_identity()); info!( "Ignoring field: `{}:{}` on type: `{}` in variant: `{}` as it is not supported: `{}`", tcx.item_name(f_did), @@ -259,7 +258,7 @@ fn process_fields<'tcx, 'f, I: Iterator>( reflect_types: &IndexMap>, cached_traits: &CachedTraits, fields: I, - param_env: ParamEnv<'tcx>, + param_env: TypingEnv<'tcx>, ) -> Vec<(DefId, ReflectionStrategy)> { fields .map(move |f| { @@ -332,6 +331,7 @@ fn type_is_adt_and_reflectable<'tcx>( ty.ty_adt_def().is_some_and(|adt_def| { let did = adt_def.did(); + // even though our meta might already be written at this point, we use this as a quick out if reflect_types.contains_key(&did) { // local types are easy to check return true; @@ -344,24 +344,18 @@ fn type_is_adt_and_reflectable<'tcx>( // so search for these metas! let crate_name = tcx.crate_name(did.krate).to_ident_string(); - let meta_sources = if tcx.crate_name(LOCAL_CRATE).as_str() == "bevy_reflect" { - // otherwise meta loader might expect the meta to exist - vec![crate_name] - } else { - vec![crate_name, "bevy_reflect".to_string()] - }; - - let meta = match meta_sources.iter().find_map(|s| meta_loader.meta_for(s)) { - Some(meta) => meta, - None => return false, // TODO: is it possible we get false negatives here ? perhaps due to parallel compilation ? or possibly because of dependency order - }; + let contains_hash = meta_loader.one_of_meta_files_contains( + &[&crate_name, "bevy_reflect"], + Some(&tcx.crate_name(LOCAL_CRATE).to_ident_string()), + tcx.def_path_hash(did), + ); - let contains_hash = meta.contains_def_path_hash(tcx.def_path_hash(did)); log::trace!( "Meta for type: `{}`, contained in meta `{}`", tcx.item_name(did), contains_hash ); + contains_hash }) } @@ -369,7 +363,7 @@ fn type_is_adt_and_reflectable<'tcx>( /// Checks if the type can be used directly as a lua function argument, by checking if it implements the FromLua trait fn type_is_supported_as_non_proxy_arg<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + param_env: TypingEnv<'tcx>, cached_traits: &CachedTraits, ty: Ty<'tcx>, ) -> bool { @@ -385,7 +379,7 @@ fn type_is_supported_as_non_proxy_arg<'tcx>( /// Checks if the type can be used directly as a lua function output fn type_is_supported_as_non_proxy_return_val<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + param_env: TypingEnv<'tcx>, cached_traits: &CachedTraits, ty: Ty<'tcx>, ) -> bool { @@ -406,12 +400,12 @@ fn type_is_supported_as_non_proxy_return_val<'tcx>( pub(crate) fn impls_trait<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + param_env: TypingEnv<'tcx>, ty: Ty<'tcx>, trait_did: DefId, ) -> bool { tcx.infer_ctxt() - .build(TypingMode::non_body_analysis()) - .type_implements_trait(trait_did, [ty], param_env) + .build(param_env.typing_mode) + .type_implements_trait(trait_did, [ty], param_env.param_env) .must_apply_modulo_regions() } diff --git a/crates/bevy_api_gen/src/passes/find_reflect_types.rs b/crates/bevy_api_gen/src/passes/find_reflect_types.rs index f808922c..22096759 100644 --- a/crates/bevy_api_gen/src/passes/find_reflect_types.rs +++ b/crates/bevy_api_gen/src/passes/find_reflect_types.rs @@ -45,8 +45,7 @@ pub(crate) fn find_reflect_types(ctxt: &mut BevyCtxt<'_>, args: &Args) -> bool { generics.count() == 0 && self_ty.def().is_some_and(|did| { let short_form = format!("{}::{}",ctxt.tcx.crate_name(LOCAL_CRATE),ctxt.tcx.item_name(did)); - if ignored_types.contains(&short_form) || ignored_types.contains(&tcx.def_path_str(did)) { - info!("Ignoring type: {:?}", tcx.def_path_str(did)); + if ignored_types.contains(&short_form) || ignored_types.contains(&tcx.def_path_str(did)) { info!("Ignoring type: {:?}", tcx.def_path_str(did)); return false; }; let adt_generics = tcx.generics_of(did); diff --git a/crates/bevy_api_gen/src/passes/find_trait_impls.rs b/crates/bevy_api_gen/src/passes/find_trait_impls.rs index 95418690..7a6cb832 100644 --- a/crates/bevy_api_gen/src/passes/find_trait_impls.rs +++ b/crates/bevy_api_gen/src/passes/find_trait_impls.rs @@ -6,7 +6,7 @@ use rustc_infer::{ infer::{InferCtxt, TyCtxtInferExt}, traits::{Obligation, ObligationCause}, }; -use rustc_middle::ty::{Ty, TypingMode}; +use rustc_middle::ty::{Ty, TypingEnv, TypingMode}; use rustc_span::DUMMY_SP; use rustc_trait_selection::traits::ObligationCtxt; @@ -134,8 +134,12 @@ fn impl_matches<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>, impl_def_id: DefId) let impl_may_apply = |impl_def_id| { let ocx = ObligationCtxt::new(infcx); - let param_env = tcx.param_env_reveal_all_normalized(impl_def_id); + // let param_env = infcx.resolve_regions(impl_def_id); + // let param_env = tcx.param_env_reveal_all_normalized(impl_def_id); + let typing_env = TypingEnv::non_body_analysis(tcx, impl_def_id); + let param_env = typing_env.with_post_analysis_normalized(tcx).param_env; let impl_args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id); + let impl_trait_ref = tcx .impl_trait_ref(impl_def_id) .expect("Expected defid to be an impl for a trait") diff --git a/crates/bevy_api_gen/src/passes/populate_template_data.rs b/crates/bevy_api_gen/src/passes/populate_template_data.rs index e5aff8e6..498066e5 100644 --- a/crates/bevy_api_gen/src/passes/populate_template_data.rs +++ b/crates/bevy_api_gen/src/passes/populate_template_data.rs @@ -1,14 +1,16 @@ -use std::fmt::Write; +use std::{borrow::Cow, convert::identity}; -use log::trace; +use log::{trace, warn}; use rustc_ast::Attribute; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; -use rustc_middle::ty::{FieldDef, ParamTy, Ty, TyKind, TypeFoldable}; +use rustc_middle::ty::{ + AdtDef, FieldDef, GenericArg, GenericParamDefKind, TraitRef, Ty, TyKind, TypingEnv, +}; use rustc_span::Symbol; use crate::{ - Arg, Args, BevyCtxt, Field, Function, FunctionContext, ImportPathFinder, Item, Output, - ReflectType, TemplateContext, Variant, + Arg, Args, BevyCtxt, Field, Function, FunctionContext, Item, Output, ReflectType, + TemplateContext, Variant, }; /// Converts the BevyCtxt into simpler data that can be used in templates directly, /// Clears the BevyCtxt by clearing data structures after it uses them. @@ -126,7 +128,7 @@ pub(crate) fn process_fields<'f, I: Iterator>( .map(|field| Field { docstrings: docstrings(ctxt.tcx.get_attrs_unchecked(field.did)), ident: field.name.to_ident_string(), - ty: ty_to_string(ctxt, ctxt.tcx.type_of(field.did).skip_binder()), + ty: ty_to_string(ctxt, ctxt.tcx.type_of(field.did).skip_binder(), false), reflection_strategy: *ty_ctxt .get_field_reflection_strat(field.did) .unwrap_or_else(|| panic!("{ty_ctxt:#?}")), @@ -145,52 +147,27 @@ pub(crate) fn process_functions(ctxt: &BevyCtxt, fns: &[FunctionContext]) -> Vec .zip(fn_sig.inputs()) .enumerate() .map(|(idx, (ident, ty))| { - let (ident, ty) = if fn_ctxt.has_self && idx == 0 { - // self argument, we want to map to something like `&self` instead of `&Component` - // we do that by renaming every adt inside to "self" - // this is a bit hacky but it works, might not work if we decide to support generics in the future - // TODO: fix to work with generics - let ty = ty.fold_with(&mut rustc_middle::ty::fold::BottomUpFolder { - tcx: ctxt.tcx, - ty_op: |ty| { - if ty.is_adt() { - ctxt.tcx.mk_ty_from_kind(TyKind::Param(ParamTy::new( - 0, - Symbol::intern("self"), - ))) - } else { - ty - } - }, - lt_op: |lt| lt, - ct_op: |ct| ct, - }); - (None, ty) - } else { - (ident.to_string().into(), *ty) - }; - // remove projections like `::AssocType` - let ty = ty_to_string( - ctxt, - ctxt.tcx - .normalize_erasing_regions(ctxt.tcx.param_env(fn_ctxt.def_id), ty), + let normalized_ty = ctxt.tcx.normalize_erasing_regions( + TypingEnv::non_body_analysis(ctxt.tcx, fn_ctxt.def_id), + *ty, ); Arg { - ident, - ty, + ident: ident.to_string(), + ty: ty_to_string(ctxt, normalized_ty, false), + proxy_ty: ty_to_string(ctxt, normalized_ty, true), reflection_strategy: fn_ctxt.reflection_strategies[idx], } }) .collect(); - let ty = ty_to_string( - ctxt, - ctxt.tcx - .normalize_erasing_regions(ctxt.tcx.param_env(fn_ctxt.def_id), fn_sig.output()), + let out_ty = ctxt.tcx.normalize_erasing_regions( + TypingEnv::non_body_analysis(ctxt.tcx, fn_ctxt.def_id), + fn_sig.output(), ); let output = Output { - ty, + ty: ty_to_string(ctxt, out_ty, false), + proxy_ty: ty_to_string(ctxt, out_ty, true), reflection_strategy: *fn_ctxt.reflection_strategies.last().unwrap(), }; @@ -203,9 +180,11 @@ pub(crate) fn process_functions(ctxt: &BevyCtxt, fns: &[FunctionContext]) -> Vec output, has_self: fn_ctxt.has_self, docstrings: docstrings(ctxt.tcx.get_attrs_unchecked(fn_ctxt.def_id)), - from_trait_path: fn_ctxt - .trait_did - .map(|trait_did| import_path(ctxt, trait_did)), + from_trait_path: fn_ctxt.trait_and_impl_did.map(|(_, impl_did)| { + let trait_ref = ctxt.tcx.impl_trait_ref(impl_did).unwrap().skip_binder(); + + trait_ref_to_string(ctxt, trait_ref) + }), } }) .collect() @@ -236,51 +215,269 @@ pub(crate) fn import_path(ctxt: &BevyCtxt, def_id: DefId) -> String { } /// Normalizes type import paths in types before printing them -fn ty_to_string<'tcx>(ctxt: &BevyCtxt<'tcx>, ty: Ty<'tcx>) -> String { +fn ty_to_string<'tcx>(ctxt: &BevyCtxt<'tcx>, ty: Ty<'tcx>, proxy_types: bool) -> String { // walk through the type and replace all paths with their standardised import paths - TyPrinter::new().print(&ctxt.path_finder, ty) + TyPrinter::new( + Box::new(|ty| { + ty.ty_adt_def() + .map(|def| { + let def_id = def.did(); + let def_path_hash = ctxt.tcx.def_path_hash(def_id); + let meta_sources = [ + &ctxt.tcx.crate_name(def_id.krate).to_ident_string(), + "bevy_reflect", + ]; + + ctxt.meta_loader.one_of_meta_files_contains( + &meta_sources, + Some(&ctxt.tcx.crate_name(LOCAL_CRATE).to_ident_string()), + def_path_hash, + ) + }) + .is_some_and(identity) + }), + Box::new(|did| Cow::Owned(import_path(ctxt, did))), + proxy_types, + ) + .print(ty) +} + +/// Converts a specific trait instantiation (in the context of an impl) into a string taking into account correctly the +/// import transformations and generics +/// TODO: this doesn't explicitly print out associated types, because I don't think it's necessary yet and annoying to do (idk how to do it) +fn trait_ref_to_string<'tcx>(ctxt: &BevyCtxt<'tcx>, trait_ref: TraitRef<'tcx>) -> String { + let generics_def = ctxt.tcx.generics_of(trait_ref.def_id); + + let generic_args = trait_ref + .args + .iter() + .enumerate() + .skip(if generics_def.has_self { 1 } else { 0 }) + .map(|(idx, a)| (a, generics_def.param_at(idx, ctxt.tcx))) + // filter out non const | type generics and the compiler generated ones + .filter(|(_, arg_def)| match arg_def.kind { + GenericParamDefKind::Lifetime => false, + GenericParamDefKind::Const { synthetic, .. } => !synthetic, + _ => true, + }) + .map(|(arg, arg_def)| { + log::trace!("Printing for trait: `{trait_ref}` arg: `{arg}`, with def: `{arg_def:#?}`"); + + let arg_ty = if let Some(ty) = arg.as_type() { + ty + } else if arg.as_const().is_some() { + arg.as_type().unwrap() + } else { + unreachable!("should be filtered") + }; + + ty_to_string(ctxt, arg_ty, false) + }) + .collect::>(); + + let trait_path = import_path(ctxt, trait_ref.def_id); + + if generic_args.is_empty() { + trait_path + } else { + format!("{trait_path}::<{}>", generic_args.join(", ")) + } } -struct TyPrinter { +#[derive(Clone, Copy)] +pub(crate) enum ProxyType { + Ref, + RefMut, + Val, +} + +impl ProxyType { + pub fn to_ident_str(self) -> &'static str { + match self { + ProxyType::Ref => "Ref", + ProxyType::RefMut => "Mut", + ProxyType::Val => "Val", + } + } +} +/// Pretty prints types fully using the given import path finder or ADT's +struct TyPrinter<'a> { buffer: String, + path_finder: Box Cow<'static, str> + 'a>, + is_proxied_check: Box) -> bool + 'a>, + /// If true will wrap types in appropriate proxies instead of directly pringting the type + proxy_types: bool, } -impl TyPrinter { - pub fn new() -> Self { +impl<'a> TyPrinter<'a> { + pub fn new( + is_proxied_check: Box) -> bool + 'a>, + path_finder: Box Cow<'static, str> + 'a>, + proxy_types: bool, + ) -> Self { TyPrinter { buffer: String::new(), + is_proxied_check, + proxy_types, + path_finder, } } - pub fn print(mut self, path_finder: &ImportPathFinder, ty: Ty<'_>) -> String { - self.build_str(path_finder, ty); + + pub fn print(mut self, ty: Ty<'_>) -> String { + log::trace!("Printing type: {:#?}", ty); + self.print_ty(ty); self.buffer } - fn build_str(&mut self, path_finder: &ImportPathFinder, ty: Ty<'_>) { + fn print_args<'tcx, I: Iterator>>(&mut self, mut args: I) { + let mut next = args.next(); + if next.is_some() { + self.buffer.push('<'); + while let Some(arg) = next { + let ty = if let Some(ty) = arg.as_type() { + ty + } else if arg.as_const().is_some() { + arg.as_type().unwrap() + } else { + next = args.next(); + continue; + }; + self.print_ty(ty); + + next = args.next(); + if next.is_some() { + self.buffer.push_str(", "); + } + } + + self.buffer.push('>'); + } + } + + fn print_adt<'tcx, I: Iterator>>(&mut self, ty: AdtDef<'tcx>, args: I) { + log::trace!("Printing ADT: {:#?}", ty); + let did = ty.did(); + let import_path = (self.path_finder)(did); + self.buffer.push_str(&import_path); + self.print_args(args); + } + + fn print_ty(&mut self, ty: Ty<'_>) { + log::trace!("Printing type: {:#?}", ty); + match ty.kind() { - TyKind::Adt(adt_def, args) => { - let did = adt_def.did(); - let import_path = path_finder - .find_import_paths(did) - .first() - .unwrap() - .to_owned(); - self.buffer.push_str(&import_path); - if args.len() > 0 { - self.buffer.push('<'); - for (idx, a) in args.iter().enumerate() { - match a.as_type() { - Some(ty) => self.build_str(path_finder, ty), - None => _ = self.buffer.write_str(&a.to_string()), - } - if idx != args.len() - 1 { - self.buffer.push_str(", "); - } + TyKind::Bool => self.print_literal("bool"), + TyKind::Char => self.print_literal("char"), + TyKind::Str => self.print_literal("str"), + TyKind::Int(ty) => self.print_literal(ty.name_str()), + TyKind::Uint(ty) => self.print_literal(ty.name_str()), + TyKind::Float(ty) => self.print_literal(ty.name_str()), + TyKind::Adt(adt_ty, args) => { + if self.proxy_types { + self.print_proxied_ty(ty, ProxyType::Val); + } else { + self.print_adt(*adt_ty, args.iter()); + } + } + TyKind::Array(ty, const_) => { + self.buffer.push('['); + self.print_ty(*ty); + self.buffer.push(';'); + // shortcut, we won't encounter ADT's here just use native printer + self.buffer.push_str(&const_.to_string()); + self.buffer.push(']'); + } + TyKind::Slice(ty) => { + self.buffer.push('['); + self.print_ty(*ty); + self.buffer.push(']'); + } + TyKind::RawPtr(ptr, mutability) => { + self.buffer.push('*'); + if mutability.is_mut() { + self.buffer.push_str("mut "); + } + self.print_ty(*ptr); + } + TyKind::Ref(_, ty, mut_) => { + if self.proxy_types { + let proxy_type = if mut_.is_mut() { + ProxyType::RefMut + } else { + ProxyType::Ref + }; + self.print_proxied_ty(*ty, proxy_type); + } else { + self.buffer.push('&'); + if mut_.is_mut() { + self.buffer.push_str("mut "); } - self.buffer.push('>'); + self.print_ty(*ty); } } - _ => self.buffer.push_str(&ty.to_string()), + TyKind::Tuple(tys) => { + self.buffer.push('('); + for (idx, ty) in tys.iter().enumerate() { + self.print_ty(ty); + if idx != tys.len() - 1 { + self.buffer.push(','); + } + } + self.buffer.push(')'); + } + TyKind::Alias(_, ty) => { + self.buffer.push_str(&(self.path_finder)(ty.def_id)); + self.print_args(ty.args.iter()); + } + // self is one I think + TyKind::Param(param) => self.print_literal(param.name.as_str()), + _ => { + warn!( + "Type outside the scope of the TyPrinter being printed: pretty=`{}` kind=`{:?}`", + ty, ty.kind() + ); + self.buffer.push_str(&ty.to_string()) + } + } + } + + /// prints a type but without making further proxies at this level + /// i.e. a &T will be printed as RefProxy instead of RefProxy> since the T will not be printed via print_ty but directly here + /// But only for ADT's, other types are printed as normal + fn print_proxied_ty(&mut self, ty: Ty<'_>, proxy_type: ProxyType) { + match ty.kind() { + TyKind::Adt(adt_ty, args) => { + if (self.is_proxied_check)(ty) { + self.print_literal_surround_content( + proxy_type.to_ident_str(), + '<', + '>', + |self_| { + self_.print_adt(*adt_ty, args.iter()); + }, + ); + } else { + self.print_adt(*adt_ty, args.iter()) + } + } + _ => self.print_ty(ty), } } + + fn print_literal_surround_content( + &mut self, + literal: &str, + start: char, + end: char, + f: F, + ) { + self.buffer.push_str(literal); + self.buffer.push(start); + f(self); + self.buffer.push(end); + } + + fn print_literal(&mut self, literal: &str) { + self.buffer.push_str(literal); + } } diff --git a/crates/bevy_api_gen/src/plugin.rs b/crates/bevy_api_gen/src/plugin.rs index b365458e..cc4bc10c 100644 --- a/crates/bevy_api_gen/src/plugin.rs +++ b/crates/bevy_api_gen/src/plugin.rs @@ -1,9 +1,9 @@ +use std::env; + use clap::Parser; use log::debug; use rustc_plugin::{CrateFilter, RustcPlugin, RustcPluginArgs, Utf8Path}; -use std::env; - use crate::{modifying_file_loader::ModifyingFileLoader, BevyAnalyzerCallbacks, WorkspaceMeta}; pub struct BevyAnalyzer; @@ -47,13 +47,16 @@ impl RustcPlugin for BevyAnalyzer { struct DefaultCallbacks; impl rustc_driver::Callbacks for DefaultCallbacks {} - return rustc_driver::RunCompiler::new(&compiler_args, &mut DefaultCallbacks).run(); + rustc_driver::RunCompiler::new(&compiler_args, &mut DefaultCallbacks).run(); + return Ok(()); } } let mut callbacks = BevyAnalyzerCallbacks::new(plugin_args); let mut compiler = rustc_driver::RunCompiler::new(&compiler_args, &mut callbacks); compiler.set_file_loader(Some(Box::new(ModifyingFileLoader))); - compiler.run() + compiler.run(); + log::trace!("Finished compiling with plugin"); + Ok(()) } fn modify_cargo(&self, cmd: &mut std::process::Command, args: &Self::Args) { diff --git a/crates/bevy_api_gen/src/template.rs b/crates/bevy_api_gen/src/template.rs index e9219d00..2349dcaf 100644 --- a/crates/bevy_api_gen/src/template.rs +++ b/crates/bevy_api_gen/src/template.rs @@ -111,17 +111,21 @@ pub(crate) struct Function { pub(crate) struct Arg { /// the name of the argument as in source code /// None if this is a receiver, in which case ty contains the ident - pub(crate) ident: Option, + pub(crate) ident: String, /// the type of argument /// i.e. `&Vec` pub(crate) ty: String, + /// The proxied type of argument for use in Unproxy and Proxy targetted code + /// i.e. AppropriateRefProxy instead of &MyTy for a reference + pub(crate) proxy_ty: String, pub(crate) reflection_strategy: ReflectionStrategy, } #[derive(Serialize)] pub(crate) struct Output { pub(crate) ty: String, + pub(crate) proxy_ty: String, pub(crate) reflection_strategy: ReflectionStrategy, } @@ -313,6 +317,34 @@ pub(crate) fn configure_tera_env(tera: &mut Tera, crate_name: &str) { let case = expect_str(expect_arg(args, "case")?)?; Ok(Value::String(str.to_case(case_from_str(case)?))) }, + ); + + tera.register_filter( + "to_arg_pattern", + |val: &Value, _args: &HashMap| { + let ty = expect_str(val)?; + if ty == "self" { + return Ok(Value::String("_self".to_owned())); + } + Ok(Value::String(ty.to_owned())) + }, + ); + + tera.register_function( + "function_call_expression", + |args: &HashMap| { + let ident = expect_str(expect_arg(args, "type")?)?; + let function_name = expect_str(expect_arg(args, "function")?)?; + let trait_name: Option<&str> = args.get("trait").and_then(|v| v.as_str()); + + if let Some(trait_name) = trait_name { + Ok(Value::String(format!( + "<{ident} as {trait_name}>::{function_name}" + ))) + } else { + Ok(Value::String(format!("{ident}::{function_name}"))) + } + }, ) } diff --git a/crates/bevy_api_gen/templates/crate.tera b/crates/bevy_api_gen/templates/crate.tera index 58bba6f2..bd2fbc71 100644 --- a/crates/bevy_api_gen/templates/crate.tera +++ b/crates/bevy_api_gen/templates/crate.tera @@ -2,9 +2,5 @@ {% filter prettyplease -%} {% include "header.tera" %} -{% for item in items %} - {% include "item.tera" %} -{% endfor %} - {% include "footer.tera" %} {%- endfilter -%} \ No newline at end of file diff --git a/crates/bevy_api_gen/templates/field.tera b/crates/bevy_api_gen/templates/field.tera index bf9baae5..ea5fb145 100644 --- a/crates/bevy_api_gen/templates/field.tera +++ b/crates/bevy_api_gen/templates/field.tera @@ -1,6 +1,4 @@ -{%- if field.reflection_strategy == "Proxy" -%} - #[lua(output(proxy))] -{%- elif field.reflection_strategy == "Filtered" -%} +{%- if field.reflection_strategy == "Filtered" -%} #[lua(skip)] {%- endif -%} @@ -10,6 +8,6 @@ {% if field.reflection_strategy != "Reflection" -%} {{- field.ty -}} {%- else -%} -ReflectedValue +ReflectReference {%- endif -%} , diff --git a/crates/bevy_api_gen/templates/footer.tera b/crates/bevy_api_gen/templates/footer.tera index b14a4794..5f32e86a 100644 --- a/crates/bevy_api_gen/templates/footer.tera +++ b/crates/bevy_api_gen/templates/footer.tera @@ -1,70 +1,48 @@ -#[derive(Default)] -pub(crate) struct Globals; +{% if args.self_is_bms_lua %} +{% set bms_lua_path="crate" %} +{% else %} +{% set bms_lua_path="bevy_mod_scripting::lua"%} +{% endif %} -impl bevy_mod_scripting_lua::tealr::mlu::ExportInstances for Globals { - fn add_instances<'lua, T: bevy_mod_scripting_lua::tealr::mlu::InstanceCollector<'lua>>( - self, - instances: &mut T, - ) -> bevy_mod_scripting_lua::tealr::mlu::mlua::Result<()> { - {% for item in items %} - {% if item.has_static_methods %} - instances.add_instance("{{ item.ident }}", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::<{{item.ident | prefix_lua}}>::new)?; - {% endif %} - {% endfor %} - Ok(()) - } -} - -pub struct {{ "A P I Provider" | prefix_cratename | convert_case(case="upper_camel")}}; - -impl bevy_mod_scripting_core::hosts::APIProvider for {{ "A P I Provider" | prefix_cratename | convert_case(case="upper_camel") }} { - type APITarget = std::sync::Mutex; - type ScriptContext = std::sync::Mutex; - type DocTarget = bevy_mod_scripting_lua::docs::LuaDocFragment; - - fn attach_api(&mut self, ctx: &mut Self::APITarget) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - let ctx = ctx - .get_mut() - .expect("Unable to acquire lock on Lua context"); - bevy_mod_scripting_lua::tealr::mlu::set_global_env(Globals, ctx) - .map_err(|e| bevy_mod_scripting_core::error::ScriptError::Other(e.to_string())) - } - fn get_doc_fragment(&self) -> Option { - Some(bevy_mod_scripting_lua::docs::LuaDocFragment::new("{{ "A P I" | prefix_cratename | convert_case(case="upper_camel") }}", |tw| { - tw - .document_global_instance::().expect("Something went wrong documenting globals") - {% for item in items %} - .process_type::<{{ item.ident | prefix_lua }}>() - {% if item.has_static_methods %} - .process_type::>() - {% endif %} - {% endfor %} - } - )) - } +pub struct {{ "ScriptingPlugin" | prefix_cratename | convert_case(case="upper_camel")}}; - fn setup_script( - &mut self, - script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - - fn setup_script_runtime( - &mut self, - world_ptr: bevy_mod_scripting_core::world::WorldPointer, - _script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } +impl ::bevy::app::Plugin for {{ "ScriptingPlugin" | prefix_cratename | convert_case(case="upper_camel")}} { + fn build(&self, app: &mut ::bevy::prelude::App) { + let mut world = app.world_mut(); - fn register_with_app(&self, app: &mut bevy::app::App) { {% for item in items %} - app.register_foreign_lua_type::<{{ item.import_path }}>(); + NamespaceBuilder::<::{{ item.import_path }}>::new(world) + {%- for function in item.functions -%} + .register("{{ function.ident }}", | + {%- for arg in function.args -%} + {%- if arg.proxy_ty is matching("Mut.*")-%} + mut {% endif -%} + {{- arg.ident | to_arg_pattern() -}} + : {{- arg.proxy_ty -}}, + {%- endfor -%} + | { + let output: {{ function.output.proxy_ty }} = + {%- if function.from_trait_path -%} + {{- function_call_expression(type=item.import_path, trait=function.from_trait_path, function=function.ident) -}} + {%- else -%} + {{- function_call_expression(type=item.import_path, function=function.ident) -}} + {%- endif -%} + ( + {%- for arg in function.args -%} + {%- if arg.proxy_ty is matching("Ref.*")-%} + &{% endif -%} + {%- if arg.proxy_ty is matching ("Mut.*")-%} + &mut {% endif -%} + {{- arg.ident | to_arg_pattern() -}} + {%- if arg.proxy_ty is matching("Val.*")-%} + .into_inner() + {%- endif -%}, + {%- endfor -%} + ).into(); + output + }) + {%- endfor -%}; {% endfor %} } } \ No newline at end of file diff --git a/crates/bevy_api_gen/templates/function.tera b/crates/bevy_api_gen/templates/function.tera index a525af9b..d6625298 100644 --- a/crates/bevy_api_gen/templates/function.tera +++ b/crates/bevy_api_gen/templates/function.tera @@ -12,55 +12,42 @@ r#" {% endif %} as_trait="{{ function.from_trait_path }}", {%- endif -%} - -{% if function.has_self and not is_op %} -kind="{% if function.args.0.ty is starting_with("&mut") %}Mutating{% endif %}Method", -{% elif is_op %} -kind="MetaFunction", -{% else %} -kind="Function", -{% endif %} - -{%- if function.output.reflection_strategy == "Proxy" -%} -output(proxy), -{%- endif -%} - {% if is_op %} composite="{{ function.ident }}", {% endif %} -{% if function.from_trait_path == "std::ops::Neg" %} -metamethod="Unm", -{% elif function.from_trait_path == "std::ops::Mul" %} -metamethod="Mul", -{% elif function.from_trait_path == "std::ops::Add" %} -metamethod="Add", -{% elif function.from_trait_path == "std::ops::Sub" %} -metamethod="Sub", -{% elif function.from_trait_path == "std::ops::Div" %} -metamethod="Div", -{% elif function.from_trait_path == "std::ops::Rem" %} -metamethod="Mod", -{% elif function.from_trait_path == "std::cmp::PartialEq" %} -metamethod="Eq", +{% if function.from_trait_path %} + {% if function.from_trait_path is starting_with("std::ops::Neg") %} + metamethod="Unm", + {% elif function.from_trait_path is starting_with("std::ops::Mul") %} + metamethod="Mul", + {% elif function.from_trait_path is starting_with("std::ops::Add") %} + metamethod="Add", + {% elif function.from_trait_path is starting_with("std::ops::Sub") %} + metamethod="Sub", + {% elif function.from_trait_path is starting_with("std::ops::Div") %} + metamethod="Div", + {% elif function.from_trait_path is starting_with("std::ops::Rem") %} + metamethod="Mod", + {% elif function.from_trait_path is starting_with("std::cmp::PartialEq") %} + metamethod="Eq", + {% endif %} {% endif %} - )] {% if function.is_unsafe %}unsafe {% endif -%}fn {{ function.ident }} ( {%- filter separated(delimeter=", ", split_at="---", ignore_first=true) -%} {%- for arg in function.args -%} --- - {%- if arg.ident and arg.reflection_strategy == "Proxy" -%} - #[proxy] - {%- endif -%} - {%- if arg.ident -%} - {{- arg.ident }} : {# -#} + {%- if arg.ident != "self" -%} + {{- arg.ident -}} + {%- else -%} + _{{- arg.ident -}} {%- endif -%} - {{- arg.ty -}} + : {{- arg.proxy_ty -}} {%- endfor -%} {%- endfilter -%} -) -> {{ function.output.ty -}}; +) -> {{ function.output.proxy_ty -}}; {%- endfilter %} "# \ No newline at end of file diff --git a/crates/bevy_api_gen/templates/header.tera b/crates/bevy_api_gen/templates/header.tera index e40a725a..cdab05ca 100644 --- a/crates/bevy_api_gen/templates/header.tera +++ b/crates/bevy_api_gen/templates/header.tera @@ -8,8 +8,17 @@ use super::{{crate}}::*; {% endif %} {% endfor %} -{% if args.self_is_bevy_script_api %} -extern crate self as bevy_script_api; -{% endif %} -use bevy_script_api::{lua::RegisterForeignLuaType, ReflectedValue, common::bevy::GetWorld}; \ No newline at end of file +use bevy_mod_scripting_core::{ + AddContextInitializer, + StoreDocumentation, + bindings::{ + ReflectReference, + function::from::{Ref, Mut, Val} + } +}; +{% if args.self_is_bms_lua %} +use crate::*; +{% else %} +use bevy_mod_scripting_lua::*; +{% endif %} \ No newline at end of file diff --git a/crates/bevy_api_gen/templates/item.tera b/crates/bevy_api_gen/templates/item.tera index 3a8a8bfa..969b9324 100644 --- a/crates/bevy_api_gen/templates/item.tera +++ b/crates/bevy_api_gen/templates/item.tera @@ -3,14 +3,20 @@ {# for now #} {% endfor %} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] +{% if args.self_is_bms_lua %} +{% set bms_core_path="bevy_mod_scripting_core" %} +{% set bms_lua_path="crate" %} +{% else %} +{% set bms_core_path="bevy_mod_scripting::core" %} +{% set bms_lua_path="bevy_mod_scripting::lua" %} +{% endif %} + +#[derive(bevy_mod_scripting_derive::LuaProxy)] #[proxy( -derive( - {%- if item.impls_clone -%} - clone, - {%- endif -%} -), remote="{{ item.import_path }}", +bms_core_path="{{bms_core_path}}", +bms_lua_path="{{bms_lua_path}}", + functions[ {%- filter separated(delimeter=",\n\t\t\t", split_at="---", ignore_first=true) -%} {%- for function in item.functions -%} @@ -61,7 +67,7 @@ functions[ r#" {%- set mat_type = item.import_path | split(pat="::") | last -%} {%- set col_type = mat_type | replace(from="Mat", to="Vec")-%} - {{- macros::matrix_index(col_type=col_type,mat_type=mat_type)-}} + {{- macros::matrix_index(col_type=col_type,mat_type=mat_type,bms_core_path=bms_core_path)-}} "# {% endif %} {%- endfilter -%} @@ -76,7 +82,7 @@ functions[ {% set close_item = "}" %} {% endif %} -struct {{ item.ident -}} {{ open_item }} +pub struct {{ item.ident -}} {{ open_item }} {% if not item.is_enum %} {% for field in item.variants[0].fields %} {% if field.reflection_strategy != "Filtered" %} diff --git a/crates/bevy_api_gen/templates/macros.tera b/crates/bevy_api_gen/templates/macros.tera index 4e75fc50..5297a436 100644 --- a/crates/bevy_api_gen/templates/macros.tera +++ b/crates/bevy_api_gen/templates/macros.tera @@ -1,51 +1,45 @@ {% macro vector_index(num_type) %} -#[lua(kind="MetaMethod", raw , metamethod="Index")] -fn index(&self, lua: &Lua, idx: crate::lua::util::LuaIndex) -> Result<{{ num_type }},_> { - Ok(self.inner()?[*idx]) +#[lua(metamethod="Index")] +fn index(self, idx: usize) -> LuaIdentityProxy<{{ num_type }}> { + _self[idx - 1] } {% endmacro vector_index %} {% macro vector_newindex(num_type) %} -#[lua(kind="MutatingMetaMethod", raw, metamethod="NewIndex")] -fn index(&mut self, lua: &Lua, idx: crate::lua::util::LuaIndex, val: {{ num_type }}) -> Result<(),_> { - self.val_mut(|s| Ok(s[*idx] = val))? +#[lua(metamethod="NewIndex")] +fn index(&mut self, idx: usize, val: {{ num_type }}) -> () { + _self[idx - 1] = val } {% endmacro vector_newindex %} -{% macro matrix_index(col_type, mat_type) %} -#[lua(kind = "MetaMethod", raw, metamethod="Index")] -fn index(&self, ctx : &Lua, idx: crate::lua::util::LuaIndex) -> Result<{{ col_type | prefix_lua }},_> { - Ok({{ col_type | prefix_lua }}::new_ref( - self.reflect_ref(ctx.get_world()?).sub_ref(bevy_script_api::ReflectionPathElement::SubReflection{ - label:"col", - get: std::sync::Arc::new(|ref_| Err(bevy_script_api::error::ReflectionError::InsufficientProvenance{ - path: "".to_owned(), - msg: "Cannot get column of matrix with immutable reference".to_owned() - })), - get_mut: std::sync::Arc::new(move |ref_| { - if ref_.is::(){ - Ok(ref_.downcast_mut::() - .unwrap() - .col_mut(*idx)) - } else { - Err(bevy_script_api::error::ReflectionError::CannotDowncast{from: ref_.get_represented_type_info().unwrap().type_path().into(), to:"Mat3".into()}) - } - }) - }) - ) - ) +{% macro matrix_index(col_type, mat_type, bms_core_path) %} +#[lua(metamethod="Index", with_context, no_proxy)] +fn index(_self: Self, idx: usize, lua: &tealr::mlu::mlua::Lua) -> Result { + let mut curr_ref = _self.0; + + let path = match idx { + 1 => "x_axis", + 2 => "y_axis", + 3 => "z_axis", + 4 => "w_axis", + _ => "unknown_axis" + }; + + let parsed_path = ::bevy::reflect::ParsedPath::parse_static(path).expect("invariant"); + curr_ref.index_path(bevy_mod_scripting_core::bindings::ReflectionPathElem::new_reflection(parsed_path)); + crate::bindings::reference::LuaReflectReference(curr_ref).to_lua_proxy(lua) } {% endmacro matrix_index %} {% macro debug_as_to_string() %} -#[lua(kind="MetaMethod", metamethod="ToString")] +#[lua(metamethod="ToString")] fn index(&self) -> String { format!("{:?}", _self) } {% endmacro debug_as_to_string %} {% macro display_as_to_string() %} -#[lua(kind="MetaMethod", metamethod="ToString")] +#[lua(metamethod="ToString")] fn index(&self) -> String { format!("{}", _self) } diff --git a/crates/bevy_api_gen/templates/mod.tera b/crates/bevy_api_gen/templates/mod.tera index 186b98ac..3655a08e 100644 --- a/crates/bevy_api_gen/templates/mod.tera +++ b/crates/bevy_api_gen/templates/mod.tera @@ -7,66 +7,14 @@ pub mod {{ crate.name }}; {% endfor -%} -{% if args.self_is_bevy_script_api %} -extern crate self as bevy_script_api; -{% endif %} - -use bevy_mod_scripting_core::docs::DocFragment; - - pub struct {{ api_name }}; -impl bevy_mod_scripting_core::hosts::APIProvider for {{ api_name }} { - type APITarget = std::sync::Mutex; - type ScriptContext = std::sync::Mutex; - type DocTarget = bevy_mod_scripting_lua::docs::LuaDocFragment; - - fn attach_api(&mut self, ctx: &mut Self::APITarget) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { +impl ::bevy::app::Plugin for {{ api_name }} { + fn build(&self, app: &mut ::bevy::prelude::App) { {% for crate in crates %} - {% set crate_name = crate.name %} - {{ crate_name }}::{{ "A P I Provider" | prefix(val=crate_name) | convert_case(case="upper_camel")}}.attach_api(ctx)?; - {% endfor %} - Ok(()) - } - - fn get_doc_fragment(&self) -> Option { - [ - {% for crate in crates %} - {% set crate_name = crate.name %} - {{ crate_name }}::{{ "A P I Provider" | prefix(val=crate_name) | convert_case(case="upper_camel")}}.get_doc_fragment(), - {% endfor %} - ] - .into_iter() - .filter_map(|a: Option<_>| a) - .fold(None, |a, b| match a { - Some(a) => Some(a.merge(b)), - None => Some(b), - }) - } - - fn setup_script( - &mut self, - script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - - fn setup_script_runtime( - &mut self, - world_ptr: bevy_mod_scripting_core::world::WorldPointer, - _script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - - fn register_with_app(&self, app: &mut bevy::app::App) { - {% for crate in crates %} - {% set crate_name = crate.name %} - {{ crate_name }}::{{ "A P I Provider" | prefix(val=crate_name) | convert_case(case="upper_camel")}}.register_with_app(app); + {% set crate_name = crate.name %} + {{ crate_name }}::{{ "ScriptingPlugin" | prefix(val=crate_name) | convert_case(case="upper_camel")}}.build(app); {% endfor %} } } - {% endfilter %} \ No newline at end of file diff --git a/crates/bevy_event_priority/CHANGELOG.md b/crates/bevy_event_priority/CHANGELOG.md deleted file mode 100644 index bef63721..00000000 --- a/crates/bevy_event_priority/CHANGELOG.md +++ /dev/null @@ -1,26 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -## [0.8.0-alpha.2](https://github.com/makspll/bevy_mod_scripting/compare/bevy_event_priority-v0.8.0-alpha.1...bevy_event_priority-v0.8.0-alpha.2) - 2024-12-03 - -### Other - -- Small fixes ([#155](https://github.com/makspll/bevy_mod_scripting/pull/155)) - -## [0.8.0-alpha.1](https://github.com/makspll/bevy_mod_scripting/compare/bevy_event_priority-v0.8.0-alpha.0...bevy_event_priority-v0.8.0-alpha.1) - 2024-11-10 - -### Other - -- update Cargo.toml dependencies - -## [0.7.0](https://github.com/makspll/bevy_mod_scripting/compare/bevy_event_priority-v0.6.0...bevy_event_priority-v0.7.0) - 2024-11-03 - -### Other - -- update metadata diff --git a/crates/bevy_event_priority/Cargo.toml b/crates/bevy_event_priority/Cargo.toml deleted file mode 100644 index e1d2a8f6..00000000 --- a/crates/bevy_event_priority/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "bevy_event_priority" -version = "0.8.0" -authors = ["Maksymilian Mozolewski "] -edition = "2021" -license = "MIT OR Apache-2.0" -description = "Bevy plugin providing priority based event handling" -repository = "https://github.com/makspll/bevy_mod_scripting" -homepage = "https://github.com/makspll/bevy_mod_scripting" -keywords = ["bevy", "gamedev", "scripting", "lua"] -categories = ["game-development"] -readme = "readme.md" - - -[lib] -name = "bevy_event_priority" -path = "src/lib.rs" - -[dependencies] -bevy = { workspace = true, default-features = false } diff --git a/crates/bevy_event_priority/src/lib.rs b/crates/bevy_event_priority/src/lib.rs deleted file mode 100644 index 9dffb1be..00000000 --- a/crates/bevy_event_priority/src/lib.rs +++ /dev/null @@ -1,412 +0,0 @@ -use bevy::ecs::system::SystemParam; -use bevy::prelude::*; -use std::marker::PhantomData; -use std::sync::atomic::Ordering::Relaxed; -use std::{collections::BinaryHeap, sync::atomic::AtomicU32}; - -pub trait PriorityEvent: Send + Sync + 'static {} -impl PriorityEvent for E {} - -#[derive(Debug)] -struct EventInstance { - prio: u32, - event_id: u32, - event: E, -} - -impl EventInstance { - fn new(event: E, prio: u32) -> Self { - static COUNTER: AtomicU32 = AtomicU32::new(0); - - Self { - prio, - event_id: COUNTER.fetch_add(1, Relaxed), - event, - } - } -} - -impl PartialEq for EventInstance { - fn eq(&self, other: &Self) -> bool { - self.prio == other.prio && self.event_id == other.event_id - } -} -impl Eq for EventInstance {} - -impl Ord for EventInstance { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - match self.prio.cmp(&other.prio) { - std::cmp::Ordering::Equal => self.event_id.cmp(&other.event_id), - v => v, - } - .reverse() - } -} -impl PartialOrd for EventInstance { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Clone for EventInstance { - fn clone(&self) -> Self { - Self { - prio: self.prio, - event_id: self.event_id, - event: self.event.clone(), - } - } -} - -/// An event priority queue. -/// Used when the ordering of events should be influenced by other factors. -/// This implementation does NOT provide double buffering. -/// Writers and readers are expected to remove events as soon as they are read, -/// this implies a one to one mapping between events and event handlers. -#[derive(Debug, Resource)] -pub struct PriorityEvents { - events: BinaryHeap>, -} - -impl Default for PriorityEvents { - fn default() -> Self { - Self { - events: BinaryHeap::new(), - } - } -} - -#[derive(SystemParam)] -pub struct PriorityEventReader<'w, 's, E: PriorityEvent> { - events: ResMut<'w, PriorityEvents>, - #[system_param(ignore)] - marker: PhantomData<&'s usize>, -} - -pub struct PriorityIterator<'w, E: PriorityEvent> { - min: u32, - max: u32, - events: &'w mut PriorityEvents, -} - -impl Iterator for PriorityIterator<'_, E> { - type Item = E; - - fn next(&mut self) -> Option { - while let Some(e) = self.events.events.peek() { - if e.prio > self.min { - return None; - } else if e.prio < self.max { - // discard events which should have already run - self.events.events.pop(); - } else { - break; - }; - } - - self.events.events.pop().map(|e| e.event) - } -} - -impl PriorityEventReader<'_, '_, E> { - /// Iterates over events this reader has not seen yet, while also clearing them. - /// Will not remove any events of priority lower than min (0 is highest, inf is lowest) - /// but will discard events of higher priority - /// i.e. will handle events in the priority range [min,max] (inclusive) - pub fn iter_prio_range(&mut self, max: u32, min: u32) -> impl Iterator + '_ { - PriorityIterator { - min, - max, - events: self.events.as_mut(), - } - } - - /// Determines the number of events available to be read, without consuming any - pub fn len(&self) -> usize { - self.events.events.len() - } - - /// Determines if there are any events to be read, without consuming any. - pub fn is_empty(&self) -> bool { - self.len() == 0 - } -} - -#[derive(SystemParam)] -pub struct PriorityEventWriter<'w, 's, E: PriorityEvent> { - events: ResMut<'w, PriorityEvents>, - - #[system_param(ignore)] - marker: PhantomData<&'s usize>, -} - -impl PriorityEventWriter<'_, '_, E> { - pub fn send(&mut self, event: E, prio: u32) { - self.events.events.push(EventInstance::new(event, prio)); - } - - pub fn send_batch(&mut self, events: impl Iterator, prio: u32) { - self.events - .events - .extend(events.map(|v| EventInstance::new(v, prio))) - } - - pub fn send_default(&mut self, prio: u32) - where - E: Default, - { - self.events - .events - .push(EventInstance::new(E::default(), prio)) - } -} - -/// a convenience for initialising prioritised event types -pub trait AddPriorityEvent { - fn add_priority_event(&mut self) -> &mut Self; -} - -impl AddPriorityEvent for App { - fn add_priority_event(&mut self) -> &mut Self { - self.init_resource::>(); - - self - } -} - -#[cfg(test)] -mod tests { - use bevy::{ecs::system::SystemState, prelude::World}; - - use super::*; - - #[derive(Copy, Clone, PartialEq, Eq, Debug)] - struct TestEvent(usize); - - fn collect_events(events: BinaryHeap>) -> Vec { - events - .into_sorted_vec() - .iter() - .map(|e| e.event) - .rev() - .collect() - } - - #[test] - fn test_events() { - let mut world = World::new(); - let mut state_writer: SystemState> = - SystemState::new(&mut world); - let mut state_reader: SystemState> = - SystemState::new(&mut world); - - world.init_resource::>(); - - // stage 1 - - { - let mut w = state_writer.get_mut(&mut world); - - // system writes three events, out of order - w.send(TestEvent(0), 5); - w.send(TestEvent(1), 1); - w.send(TestEvent(2), 0); - } - - // events are send and ordered in decreasing priority order - assert_eq!( - collect_events(world.resource::>().events.clone()), - vec![TestEvent(2), TestEvent(1), TestEvent(0)] - ); - - // stage 2 - - { - let mut w = state_reader.get_mut(&mut world); - - // system reads only top event - w.iter_prio_range(0, 0).for_each(drop); - } - - // first event is consumed immediately - assert_eq!( - collect_events(world.resource::>().events.clone()), - vec![TestEvent(1), TestEvent(0)] - ); - - // stage 3 - - { - let mut w = state_reader.get_mut(&mut world); - - // system reads all events - w.iter_prio_range(1, 5).for_each(drop); - } - - // first event is consumed immediately - assert_eq!( - collect_events(world.resource::>().events.clone()), - Vec::default() - ); - } - - #[test] - fn test_not_cleared_events() { - let mut world = World::new(); - let mut state_writer: SystemState> = - SystemState::new(&mut world); - let mut state_reader: SystemState> = - SystemState::new(&mut world); - - world.init_resource::>(); - - // two systems run at different frequencies, both serve non-overlapping priorities - - // stage 1 - // system sends events of lower priority than it serves - { - let mut w = state_writer.get_mut(&mut world); - - w.send(TestEvent(0), 1); - } - { - let mut w = state_reader.get_mut(&mut world); - - w.iter_prio_range(0, 0).for_each(drop); - } - - assert_eq!( - collect_events(world.resource::>().events.clone()), - vec![TestEvent(0)] - ); - - // stage 2 - // same system runs writes another of the same event - - { - let mut w = state_writer.get_mut(&mut world); - - w.send(TestEvent(0), 1); - } - { - let mut w = state_reader.get_mut(&mut world); - - w.iter_prio_range(0, 0).for_each(drop); - } - - assert_eq!( - collect_events(world.resource::>().events.clone()), - vec![TestEvent(0), TestEvent(0)] - ); - - // stage 3 - // this time another system runs clearing those events - { - let mut w = state_reader.get_mut(&mut world); - - w.iter_prio_range(1, 1).for_each(drop); - } - assert_eq!( - collect_events(world.resource::>().events.clone()), - Vec::default() - ); - } - - #[test] - fn test_higher_prio_destroyed() { - let mut world = World::new(); - let mut state_writer: SystemState> = - SystemState::new(&mut world); - let mut state_reader: SystemState> = - SystemState::new(&mut world); - - world.init_resource::>(); - - // two systems run at different frequencies, both serve non-overlapping priorities - - // stage 1 - // system sends events of higher priority than another serves - { - let mut w = state_writer.get_mut(&mut world); - - w.send(TestEvent(0), 0); - } - - // stage 2 - // system receives event of higher priority than it serves - { - let mut w = state_reader.get_mut(&mut world); - - // event is not read but discarded - assert_eq!( - w.iter_prio_range(1, 1).collect::>(), - Vec::default() - ); - } - - // the event is cleared - assert_eq!( - collect_events(world.resource::>().events.clone()), - vec![] - ); - } - - #[test] - fn test_prio_range() { - let mut world = World::new(); - let mut state_writer: SystemState> = - SystemState::new(&mut world); - let mut state_reader: SystemState> = - SystemState::new(&mut world); - - world.init_resource::>(); - - // two systems run at different frequencies, both serve non-overlapping priorities - - // stage 1 - // system sends events of various priorities - { - let mut w = state_writer.get_mut(&mut world); - - w.send(TestEvent(0), 0); - w.send(TestEvent(1), 1); - w.send(TestEvent(2), 2); - w.send(TestEvent(3), 3); - w.send(TestEvent(4), 4); - w.send(TestEvent(5), 5); - } - - // stage 2 - // multiple systems in order of priority remove them one by one - { - let mut w = state_reader.get_mut(&mut world); - - assert_eq!( - w.iter_prio_range(0, 1).collect::>(), - vec![TestEvent(0), TestEvent(1)] - ); - - assert_eq!( - w.iter_prio_range(2, 2).collect::>(), - vec![TestEvent(2)] - ); - - assert_eq!( - w.iter_prio_range(3, 3).collect::>(), - vec![TestEvent(3)] - ); - - // 4 is discarded - assert_eq!( - w.iter_prio_range(5, 5).collect::>(), - vec![TestEvent(5)] - ); - } - - // the events are all cleared - assert_eq!( - collect_events(world.resource::>().events.clone()), - vec![] - ); - } -} diff --git a/crates/bevy_mod_scripting_common/CHANGELOG.md b/crates/bevy_mod_scripting_common/CHANGELOG.md deleted file mode 100644 index 6b6f1588..00000000 --- a/crates/bevy_mod_scripting_common/CHANGELOG.md +++ /dev/null @@ -1,21 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -## [0.8.0-alpha.2](https://github.com/makspll/bevy_mod_scripting/compare/bevy_mod_scripting_common-v0.8.0-alpha.1...bevy_mod_scripting_common-v0.8.0-alpha.2) - 2024-12-03 - -### Other - -- Small fixes ([#155](https://github.com/makspll/bevy_mod_scripting/pull/155)) - -## [0.7.0](https://github.com/makspll/bevy_mod_scripting/compare/bevy_mod_scripting_common-v0.6.0...bevy_mod_scripting_common-v0.7.0) - 2024-11-03 - -### Other - -- Migrate to bevy 0.14 ([#127](https://github.com/makspll/bevy_mod_scripting/pull/127)) -- update metadata diff --git a/crates/bevy_mod_scripting_common/Cargo.toml b/crates/bevy_mod_scripting_common/Cargo.toml deleted file mode 100644 index 077e270c..00000000 --- a/crates/bevy_mod_scripting_common/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "bevy_mod_scripting_common" -version = "0.8.0" -authors = ["Maksymilian Mozolewski "] -edition = "2021" -license = "MIT OR Apache-2.0" -description = "Traits and syn structures for language implementors" -repository = "https://github.com/makspll/bevy_mod_scripting" -homepage = "https://github.com/makspll/bevy_mod_scripting" -keywords = ["bevy", "gamedev", "scripting", "lua"] -categories = ["game-development"] -readme = "readme.md" - -[lib] -name = "bevy_mod_scripting_common" -path = "src/lib.rs" - -[dependencies] -darling = "0.20.3" -paste = "1.0.7" -syn = { version = "2.0.38", features = [ - "full", - "fold", - "extra-traits", - "visit-mut", -] } -quote = "1.0.8" -proc-macro2 = "1.0" -convert_case = "0.5.0" -serde = { version = "1.0", features = ["derive"] } -serde_derive = "1.0.137" -indexmap = { version = "1.9.1", features = ["serde"] } -strum = { version = "0.24.1", features = ["derive"] } diff --git a/crates/bevy_mod_scripting_common/readme.md b/crates/bevy_mod_scripting_common/readme.md deleted file mode 100644 index 674bf81c..00000000 --- a/crates/bevy_mod_scripting_common/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -# bevy_mod_scripting_common - -This crate is a part of the ["bevy_mod_scripting" workspace](https://github.com/makspll/bevy_mod_scripting). \ No newline at end of file diff --git a/crates/bevy_mod_scripting_common/src/input.rs b/crates/bevy_mod_scripting_common/src/input.rs deleted file mode 100644 index 2547c918..00000000 --- a/crates/bevy_mod_scripting_common/src/input.rs +++ /dev/null @@ -1,678 +0,0 @@ -#![allow(clippy::manual_unwrap_or_default)] // from darling -use darling::{util::Flag, FromDeriveInput, FromMeta}; -use proc_macro2::Ident; -use quote::format_ident; -use std::{ - collections::HashMap, - ops::{Deref, DerefMut}, - str::FromStr, -}; -use strum::{Display, EnumString}; -use syn::{ - punctuated::Punctuated, - spanned::Spanned, - token::{And, Gt, Lt, Mut, PathSep}, - visit_mut::VisitMut, - AngleBracketedGenericArguments, Attribute, Error, Field, Fields, GenericArgument, PatType, - Path, PathArguments, PathSegment, Receiver, TraitItemFn, Type, TypePath, TypeReference, - TypeTuple, Variant, -}; - -use crate::utils::ident_to_type_path; - -/// Flags which detail required functionality or additional derivation requirements -#[derive(Debug, FromMeta, Default)] -pub struct ProxyFlags { - pub clone: Flag, -} - -/// Enumeration of commonly encountered Rust standard library type identifiers which can be effectively proxied in Lua, -/// These types are `container` types, which wrap other types rather than standalone and literal types. -#[derive(EnumString, Debug, Clone, Copy, Display, PartialEq, Eq)] -pub enum StdTypeIdent { - Option, - Result, - Vec, - Box, - Rc, - Arc, - Cow, - Cell, - RefCell, - Mutex, - RwLock, - Pin, -} - -/// Detailed information about the proxy, here we can access fields/variants etc. -#[derive(Debug)] -pub enum ProxyData { - Struct { fields: Fields }, -} - -/// For types of the form `Option` i.e. an outer identifier with a nested type inside angle brackets. -/// This type helps us destructure these patterns and unwrap/wrap proxies fully without dealing with the complicated full syn::Type enum -#[derive(Debug, Clone)] -pub struct UnitPath { - pub std_type_ident: Option, - pub ident: Ident, - pub colon2_token: Option, - pub lt_token: Lt, - pub gt_token: Gt, - pub inner: Box, -} - -/// For types of the form `Result` i.e. an outer identifier with two nested types inside angle brackets. -#[derive(Debug, Clone)] -pub struct DuoPath { - pub std_type_ident: Option, - pub ident: Ident, - pub colon2_token: Option, - pub lt_token: Lt, - pub gt_token: Gt, - pub left: Box, - pub right: Box, -} - -/// Represents a type prefixed with an outer reference, e.g. `&T` or `&mut T` -#[derive(Debug, Clone)] -pub struct Reference { - pub and_token: And, - pub mutability: Option, - pub inner: Box, -} - -/// Represents the identifier part of a type which doubles as a proxy type, e.g. `T` in `Option` -/// Stores both the proxied and proxy identifier i.e. `T` and `LuaT` -#[derive(Debug, Clone)] -pub struct ProxyType { - pub proxied_path: Path, - pub proxy_ident: Ident, -} - -/// Proxies can also be returned in "container" types, such as: -/// - Option -/// - Result -/// - Vec -/// - Tuple -/// -/// This type helps us destructure these patterns and unwrap/wrap proxies fully without dealing with the full syn::Type enum -#[derive(Debug, Clone)] -pub enum SimpleType { - /// The unit type `()` - Unit, - /// A type of the form `Option` - UnitPath(UnitPath), - /// A type of the form `Result` a list containing two elements is referred to as a - DuoPath(DuoPath), - - /// A type with an outer reference, e.g. `&T` or `&mut T` - Reference(Reference), - /// A type which doubles as a proxy type, e.g. `T` in `Option` - ProxyType(ProxyType), - /// A type which is not a proxy type, e.g. `i32`, required for composite types which can contain both proxy and non-proxy types - /// like tuples: `(i32, T)` - Type(syn::Type), -} - -impl SimpleType { - /// Constructs a new SimpleProxyType from a `syn::FnArg` using contextual resolution for receivers such as `Self` and `self` with the proxied type identifier given. - pub fn new_from_fn_arg( - proxy_prefix: &'static str, - arg: &syn::FnArg, - proxied_type_path: &Path, - proxied_to_proxy_ident_map: &HashMap>, - ) -> Result { - match arg { - syn::FnArg::Receiver(Receiver { - reference, - mutability, - .. - }) => match reference { - Some((and, ..)) => { - let mutability = mutability.as_ref().copied(); - let inner = Box::new(SimpleType::new_from_contextual_type( - proxy_prefix, - &Type::Path(TypePath { - qself: None, - path: proxied_type_path.clone(), - }), - proxied_type_path, - proxied_to_proxy_ident_map, - )?); - Ok(Self::Reference(Reference { - and_token: *and, - mutability, - inner, - })) - } - None => Self::new_from_contextual_type( - proxy_prefix, - &Type::Path(TypePath { - qself: None, - path: proxied_type_path.clone(), - }), - proxied_type_path, - proxied_to_proxy_ident_map, - ), - }, - syn::FnArg::Typed(PatType { ty, .. }) => Self::new_from_contextual_type( - proxy_prefix, - ty.as_ref(), - proxied_type_path, - proxied_to_proxy_ident_map, - ), - } - } - - /// Constructs a new SimpleProxyType from a `syn::Type`, contextual receivers such as `Self` and `self` will cause an error - /// to be returned. - pub fn new_from_fully_specified_type( - proxy_prefix: &'static str, - proxied_type: &Type, - proxied_to_proxy_ident_map: &HashMap>, - ) -> Result { - Self::new_from_type( - proxy_prefix, - proxied_type, - None, - proxied_to_proxy_ident_map, - false, - ) - } - - pub fn new_from_fully_specified_type_proxy_all( - proxy_prefix: &'static str, - proxied_type: &Type, - ) -> Result { - Self::new_from_type(proxy_prefix, proxied_type, None, &Default::default(), true) - } - - /// Constructs a new SimpleProxyType from a `syn::Type`, contextual receivers such as `Self` and `self` will be replaced - /// with the given identifier prefixed with the proxy_prefix - pub fn new_from_contextual_type( - proxy_prefix: &'static str, - proxied_type: &Type, - proxied_type_path: &Path, - proxied_to_proxy_ident_map: &HashMap>, - ) -> Result { - Self::new_from_type( - proxy_prefix, - proxied_type, - Some(proxied_type_path), - proxied_to_proxy_ident_map, - false, - ) - } - - /// Constructs a new SimpleProxyType from a `syn::Type`, contextual receivers such as `Self` and `self` will be replaced - /// with the given identifier prefixed with the proxy_prefix - /// All types will be proxied with the given proxy prefix - pub fn new_from_contextual_type_proxy_all( - proxy_prefix: &'static str, - proxied_type: &Type, - proxied_type_path: &Path, - ) -> Result { - Self::new_from_type( - proxy_prefix, - proxied_type, - Some(proxied_type_path), - &Default::default(), - true, - ) - } - - /// Builds a SimpleType::ProxyType or SimpleType::Type depending on the passed data, - /// - if the proxied type identifier has a Some value in the proxied_to_proxy_ident_map map then the proxy_ident will be set to the value in the map, - /// - if it has a None value it will be set to the proxied type identifier prefixed with the proxy_prefix, - /// - If it's not in the map it's built as a SimpleType::Type - fn new_proxied_type_or_type( - proxy_prefix: &'static str, - proxied_path: Path, - proxied_to_proxy_ident_map: &HashMap>, - proxy_prefix_all: bool, - ) -> SimpleType { - let last_segment = &proxied_path.segments.last().unwrap().ident; - let replacement_ident = proxied_to_proxy_ident_map.get(last_segment); - - if proxy_prefix_all || replacement_ident.is_some() { - let proxy_ident = replacement_ident - .cloned() - .flatten() - .unwrap_or_else(|| format_ident!("{proxy_prefix}{}", last_segment)); - - SimpleType::ProxyType(ProxyType { - proxied_path, - proxy_ident, - }) - } else { - Self::Type(syn::Type::Path(TypePath { - qself: None, - path: proxied_path.clone(), - })) - } - } - - /// Constructs a new SimpleProxyType from a `syn::Type`, if `proxied_type_identifier` is given then contextual - /// receivers such as `Self` and `self` will be replaced with the given identifier prefixed with the proxy_prefix, otherwise an error will be returned. - /// types with base identifiers not in the proxied_to_proxy_ident_map list are treated as non-proxy types and will be wrapped in a SimpleProxyType::Type. - /// If the proxy_prefix_all option is passed, the ident map will be ignored and EVERY type inside will be treated as a default proxy (prefixed with the proxy prefix as well) - fn new_from_type( - proxy_prefix: &'static str, - proxied_type: &Type, - proxied_type_path: Option<&Path>, - proxied_to_proxy_ident_map: &HashMap>, - proxy_prefix_all: bool, - ) -> Result { - match proxied_type { - Type::Path(p) if p.path.is_ident("self") || p.path.is_ident("Self") => { - let proxied_path: &Path = proxied_type_path.ok_or_else(|| { - Error::new_spanned( - proxied_type, - "Did not expect contextual receiver in constructing simple proxy type" - .to_owned(), - ) - })?; - Ok(Self::new_proxied_type_or_type( - proxy_prefix, - proxied_path.clone(), - proxied_to_proxy_ident_map, - proxy_prefix_all, - )) - } - Type::Path(p) if !p.path.segments.is_empty() => { - let last_segment = p.path.segments.last().unwrap(); - if last_segment.arguments.is_empty() { - return Ok(Self::new_proxied_type_or_type( - proxy_prefix, - p.path.clone(), - proxied_to_proxy_ident_map, - proxy_prefix_all, - )); - } else if let PathArguments::AngleBracketed(args) = &last_segment.arguments { - if args.args.len() == 1 { - if let GenericArgument::Type(arg_type) = args.args.first().unwrap() { - let inner = Box::new(Self::new_from_type( - proxy_prefix, - arg_type, - proxied_type_path, - proxied_to_proxy_ident_map, - proxy_prefix_all, - )?); - return Ok(SimpleType::UnitPath(UnitPath { - std_type_ident: StdTypeIdent::from_str( - &last_segment.ident.to_string(), - ) - .ok(), - ident: last_segment.ident.clone(), - colon2_token: args.colon2_token, - lt_token: args.lt_token, - gt_token: args.gt_token, - inner, - })); - } - } else if args.args.len() == 2 { - let mut args_iter = args.args.iter(); - if let (GenericArgument::Type(left), GenericArgument::Type(right)) = - (args_iter.next().unwrap(), args_iter.next().unwrap()) - { - let left = Box::new(Self::new_from_type( - proxy_prefix, - left, - proxied_type_path, - proxied_to_proxy_ident_map, - proxy_prefix_all, - )?); - let right = Box::new(Self::new_from_type( - proxy_prefix, - right, - proxied_type_path, - proxied_to_proxy_ident_map, - proxy_prefix_all, - )?); - return Ok(SimpleType::DuoPath(DuoPath { - std_type_ident: StdTypeIdent::from_str( - &last_segment.ident.to_string(), - ) - .ok(), - ident: last_segment.ident.clone(), - colon2_token: args.colon2_token, - lt_token: args.lt_token, - gt_token: args.gt_token, - left, - right, - })); - } - } - } - Err(Error::new_spanned( - proxied_type, - "Unsupported type".to_owned(), - )) - } - Type::Reference(tr) => Ok(SimpleType::Reference(Reference { - and_token: tr.and_token, - mutability: tr.mutability, - inner: Box::new(Self::new_from_type( - proxy_prefix, - &tr.elem, - proxied_type_path, - proxied_to_proxy_ident_map, - proxy_prefix_all, - )?), - })), - Type::Infer(_) => Ok(SimpleType::Type(proxied_type.clone())), - Type::Tuple(TypeTuple { elems, .. }) if elems.is_empty() => Ok(SimpleType::Unit), - t => Ok(SimpleType::Type(t.clone())), - } - } - - /// Returns true if the type has an outer reference, (e.g. `&Type`) - pub fn has_outer_ref(&self) -> bool { - matches!(self, SimpleType::Reference { .. }) - } - - pub fn has_outer_mut_ref(&self) -> bool { - matches!(self, SimpleType::Reference (Reference{ mutability, .. }) if mutability.is_some()) - } - - /// Returns true if the type has an inner reference, (e.g. `Type<&T>`) - pub fn has_ref(&self) -> bool { - match self { - SimpleType::Unit => false, - SimpleType::UnitPath(UnitPath { inner, .. }) => inner.has_ref(), - SimpleType::DuoPath(DuoPath { left, right, .. }) => left.has_ref() || right.has_ref(), - SimpleType::Reference(_) => true, - SimpleType::ProxyType(ProxyType { .. }) => false, - SimpleType::Type(_) => false, - } - } - - /// Returns true if the type has an inner proxy type - pub fn contains_proxy_type(&self) -> bool { - match self { - SimpleType::Unit => false, - SimpleType::UnitPath(UnitPath { inner, .. }) => inner.contains_proxy_type(), - SimpleType::DuoPath(DuoPath { left, right, .. }) => { - left.contains_proxy_type() || right.contains_proxy_type() - } - SimpleType::Reference(Reference { inner, .. }) => inner.contains_proxy_type(), - SimpleType::ProxyType(_) => true, - SimpleType::Type(_) => false, - } - } -} - -pub trait VisitSimpleType -where - T: std::fmt::Debug, -{ - fn visit(&mut self, simple_type: &SimpleType) -> T { - self.visit_simple_type(simple_type, false) - } - - fn visit_simple_type(&mut self, simple_type: &SimpleType, is_child_of_reference: bool) -> T { - match simple_type { - SimpleType::Unit => self.visit_unit(is_child_of_reference), - SimpleType::UnitPath(unit_path) => { - self.visit_unit_path(unit_path, is_child_of_reference) - } - SimpleType::DuoPath(duo_path) => self.visit_duo_path(duo_path, is_child_of_reference), - SimpleType::Reference(reference) => { - self.visit_reference(reference, is_child_of_reference) - } - SimpleType::ProxyType(proxy_type) => { - self.visit_proxy_type(proxy_type, is_child_of_reference) - } - SimpleType::Type(_type) => self.visit_type(_type, is_child_of_reference), - } - } - fn visit_unit_path(&mut self, unit_path: &UnitPath, _is_child_of_reference: bool) -> T { - self.visit_simple_type(&unit_path.inner, false) - } - - fn visit_duo_path(&mut self, duo_path: &DuoPath, _is_child_of_reference: bool) -> T { - self.visit_simple_type(&duo_path.left, false); - self.visit_simple_type(&duo_path.right, false) - } - - fn visit_reference(&mut self, reference: &Reference, _is_child_of_reference: bool) -> T { - self.visit_simple_type(&reference.inner, true) - } - fn visit_unit(&mut self, is_child_of_reference: bool) -> T; - fn visit_proxy_type(&mut self, proxy_type: &ProxyType, is_child_of_reference: bool) -> T; - fn visit_type(&mut self, _type: &Type, is_child_of_reference: bool) -> T; -} - -pub struct TypeConstructorVisitor { - /// if true then leaf proxies will be converted to their proxy type, otherwise they will be converted to their proxied type - pub generate_proxy_type: bool, - pub strip_outer_ref: bool, -} - -impl TypeConstructorVisitor { - pub fn new(generate_proxy_type: bool, strip_outer_ref: bool) -> Self { - Self { - generate_proxy_type, - strip_outer_ref, - } - } -} - -impl VisitSimpleType for TypeConstructorVisitor { - fn visit_unit(&mut self, _: bool) -> Type { - Type::Tuple(TypeTuple { - paren_token: Default::default(), - elems: Default::default(), - }) - } - - fn visit_unit_path(&mut self, unit_path: &UnitPath, _: bool) -> Type { - Type::Path(TypePath { - qself: None, - path: PathSegment { - ident: unit_path.ident.clone(), - arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments { - colon2_token: unit_path.colon2_token, - lt_token: unit_path.lt_token, - args: Punctuated::from_iter([GenericArgument::Type( - self.visit_simple_type(&unit_path.inner, false), - )]), - gt_token: unit_path.gt_token, - }), - } - .into(), - }) - } - - fn visit_duo_path(&mut self, duo_path: &DuoPath, _: bool) -> Type { - let left = self.visit_simple_type(&duo_path.left, false); - let right = self.visit_simple_type(&duo_path.right, false); - - Type::Path(TypePath { - qself: None, - path: PathSegment { - ident: duo_path.ident.clone(), - arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments { - colon2_token: duo_path.colon2_token, - lt_token: duo_path.lt_token, - args: Punctuated::from_iter([ - GenericArgument::Type(left), - GenericArgument::Type(right), - ]), - gt_token: duo_path.gt_token, - }), - } - .into(), - }) - } - - fn visit_proxy_type(&mut self, proxy_type: &ProxyType, _: bool) -> Type { - if self.generate_proxy_type { - Type::Path(ident_to_type_path(proxy_type.proxy_ident.clone())) - } else { - Type::Path(TypePath { - qself: None, - path: proxy_type.proxied_path.clone(), - }) - } - } - - fn visit_type(&mut self, _type: &Type, _: bool) -> Type { - _type.clone() - } - - fn visit_reference(&mut self, reference: &Reference, _: bool) -> Type { - if self.strip_outer_ref { - self.visit_simple_type(&reference.inner, false) - } else { - self.strip_outer_ref = false; - Type::Reference(TypeReference { - and_token: reference.and_token, - lifetime: None, - mutability: reference.mutability, - elem: Box::new(self.visit_simple_type(&reference.inner, true)), - }) - } - } -} - -#[derive(FromDeriveInput)] -#[darling(attributes(proxy), forward_attrs(allow, doc, cfg))] -#[allow(clippy::manual_unwrap_or_default)] -pub struct ProxyInput { - /// The name of the type for which we are generating a proxy - pub ident: syn::Ident, - pub attrs: Vec, - - pub remote: Option, - /// The name to use for the proxy type, if not provided the language derive macro - /// will generate one using a standard prefix. - #[darling(rename = "name")] - pub proxy_name: Option, - - /// The body of the type for which we are generating a proxy - pub data: darling::ast::Data, - - /// Flags signifying which additional trait implementation should be generated on the proxy type - #[darling(default)] - pub derive: ProxyFlags, - - /// A list of multi-lang function definitions to be generated on the proxy type - #[darling(default)] - pub functions: TraitItemFnsWrapper, -} - -#[derive(Default)] -pub struct TraitItemFnsWrapper(pub Vec); - -impl FromMeta for TraitItemFnsWrapper { - fn from_string(value: &str) -> darling::Result { - let token_stream: proc_macro2::TokenStream = value.parse().map_err(syn::Error::from)?; - let trait_items_vec = vec![syn::parse2(token_stream)?]; - Ok(TraitItemFnsWrapper(trait_items_vec)) - } - - fn from_list(items: &[darling::ast::NestedMeta]) -> darling::Result { - Ok(TraitItemFnsWrapper( - items - .iter() - .map(Self::from_nested_meta) - .collect::, _>>()? - .into_iter() - .flat_map(|v| v.0.into_iter()) - .collect::>(), - )) - } -} - -impl Deref for TraitItemFnsWrapper { - type Target = Vec; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} -impl DerefMut for TraitItemFnsWrapper { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -/// Replaces every occurence of an identifier with -/// the given string while preserving the original span -pub struct IdentifierRenamingVisitor<'a> { - pub target: &'a str, - pub replacement: &'a str, -} - -impl VisitMut for IdentifierRenamingVisitor<'_> { - fn visit_ident_mut(&mut self, i: &mut Ident) { - if *i == self.target { - *i = Ident::new(self.replacement, i.span()); - } - } -} - -#[cfg(test)] -mod test { - use super::VisitSimpleType; - - struct TestVisitor; - impl VisitSimpleType for TestVisitor { - fn visit_unit(&mut self, is_child_of_reference: bool) -> bool { - is_child_of_reference - } - fn visit_proxy_type(&mut self, _: &super::ProxyType, is_child_of_reference: bool) -> bool { - is_child_of_reference - } - fn visit_type(&mut self, _: &syn::Type, is_child_of_reference: bool) -> bool { - is_child_of_reference - } - } - - #[test] - pub fn test_child_of_reference() { - let mut visitor = TestVisitor; - assert!(!visitor.visit(&super::SimpleType::Unit)); - assert!( - !visitor.visit(&super::SimpleType::ProxyType(super::ProxyType { - proxied_path: syn::Ident::new("T", proc_macro2::Span::call_site()).into(), - proxy_ident: syn::Ident::new("LuaT", proc_macro2::Span::call_site()), - })) - ); - assert!( - !visitor.visit(&super::SimpleType::Type(syn::Type::Path(syn::TypePath { - qself: None, - path: syn::Path::from(syn::Ident::new("T", proc_macro2::Span::call_site())), - }))) - ); - assert!( - visitor.visit(&super::SimpleType::Reference(super::Reference { - and_token: syn::Token![&](proc_macro2::Span::call_site()), - mutability: None, - inner: Box::new(super::SimpleType::Unit), - })) - ); - assert!( - visitor.visit(&super::SimpleType::Reference(super::Reference { - and_token: syn::Token![&](proc_macro2::Span::call_site()), - mutability: None, - inner: Box::new(super::SimpleType::ProxyType(super::ProxyType { - proxied_path: syn::Ident::new("T", proc_macro2::Span::call_site()).into(), - proxy_ident: syn::Ident::new("LuaT", proc_macro2::Span::call_site()), - })), - })) - ); - assert!( - visitor.visit(&super::SimpleType::Reference(super::Reference { - and_token: syn::Token![&](proc_macro2::Span::call_site()), - mutability: None, - inner: Box::new(super::SimpleType::Type(syn::Type::Path(syn::TypePath { - qself: None, - path: syn::Path::from(syn::Ident::new("T", proc_macro2::Span::call_site())), - }))), - })) - ); - } -} diff --git a/crates/bevy_mod_scripting_common/src/lib.rs b/crates/bevy_mod_scripting_common/src/lib.rs deleted file mode 100644 index 5d7b01f9..00000000 --- a/crates/bevy_mod_scripting_common/src/lib.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod input; -pub mod utils; diff --git a/crates/bevy_mod_scripting_common/src/utils.rs b/crates/bevy_mod_scripting_common/src/utils.rs deleted file mode 100644 index d8df6bb7..00000000 --- a/crates/bevy_mod_scripting_common/src/utils.rs +++ /dev/null @@ -1,59 +0,0 @@ -use proc_macro2::{Ident, TokenStream}; -use quote::ToTokens; -use syn::{ - parse::{Parse, ParseStream}, - Attribute, Path, PathArguments, PathSegment, Type, TypePath, -}; - -pub fn doc_attribute_to_string_lit(attrs: &Attribute) -> Option { - attrs - .meta - .require_name_value() - .map(|v| v.value.to_token_stream()) - .ok() -} - -pub fn ident_to_type_path(ident: Ident) -> TypePath { - TypePath { - qself: None, - path: Path { - leading_colon: None, - segments: [PathSegment { - ident, - arguments: PathArguments::None, - }] - .into_iter() - .collect(), - }, - } -} -/// Converts the given ToTokens into token stream, stringifies it and removes whitespace -pub fn stringify_token_group(t: &T) -> String { - let mut k = t.into_token_stream().to_string(); - k.retain(|c| !c.is_whitespace()); - k -} - -/// Converts simple type to base string (i.e. one which has a single type identifier) -pub fn type_base_string(t: &Type) -> Option { - match t { - Type::Paren(v) => type_base_string(&v.elem), - Type::Path(p) => Some(p.path.segments.last()?.ident.to_string()), - Type::Ptr(p) => type_base_string(&p.elem), - Type::Reference(r) => type_base_string(&r.elem), - Type::Slice(v) => type_base_string(&v.elem), - _ => None, - } -} - -#[derive(Default, Debug, Clone)] -pub struct EmptyToken; - -impl Parse for EmptyToken { - fn parse(_: ParseStream) -> Result { - Ok(Self) - } -} -impl ToTokens for EmptyToken { - fn to_tokens(&self, _: &mut TokenStream) {} -} diff --git a/crates/bevy_mod_scripting_core/Cargo.toml b/crates/bevy_mod_scripting_core/Cargo.toml index 7ff38397..4645480f 100644 --- a/crates/bevy_mod_scripting_core/Cargo.toml +++ b/crates/bevy_mod_scripting_core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bevy_mod_scripting_core" -version = "0.8.0" +version = "0.9.0-alpha.1" authors = ["Maksymilian Mozolewski "] edition = "2021" license = "MIT OR Apache-2.0" @@ -19,20 +19,23 @@ path = "src/lib.rs" # if enabled enables documentation updating in optimized builds doc_always = [] +# if enabled enables some common mlua trait implementations +mlua_impls = ["mlua"] +rhai_impls = ["rhai"] [dependencies] +mlua = { optional = true, workspace = true } +rhai = { optional = true, workspace = true } + bevy = { workspace = true, default-features = false, features = [ "bevy_asset", - "bevy_animation", - "bevy_core_pipeline", - "bevy_ui", - "bevy_pbr", - "bevy_render", - "bevy_text", - "bevy_sprite", + "reflect_functions", ] } -bevy_event_priority = { path = "../bevy_event_priority", version = "0.8.0" } thiserror = "1.0.31" -paste = "1.0.7" parking_lot = "0.12.1" -anyhow = "1.0.75" +dashmap = "6" +smallvec = "1.11" +itertools = "0.13" + +[dev-dependencies] +test_utils = { workspace = true } diff --git a/crates/bevy_mod_scripting_core/src/asset.rs b/crates/bevy_mod_scripting_core/src/asset.rs index 1dc86bb2..5fa3445e 100644 --- a/crates/bevy_mod_scripting_core/src/asset.rs +++ b/crates/bevy_mod_scripting_core/src/asset.rs @@ -1,8 +1,104 @@ -use bevy::asset::Asset; +use crate::{error::ScriptError, script::ScriptId}; +use bevy::{ + asset::{Asset, AssetId, AssetLoader}, + ecs::system::Resource, + reflect::TypePath, + utils::HashMap, +}; +use std::{ + borrow::Cow, + path::{Path, PathBuf}, +}; -/// All code assets share this common interface. -/// When adding a new code asset don't forget to implement asset loading -/// and inserting appropriate systems when registering with the app -pub trait CodeAsset: Asset { - fn bytes(&self) -> &[u8]; +/// 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 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 + pub preprocessor: Option Result<(), ScriptError> + Send + Sync>>, +} + +impl AssetLoader for ScriptAssetLoader { + type Asset = ScriptAsset; + + type Settings = (); + + type Error = ScriptError; + + async fn load( + &self, + reader: &mut dyn bevy::asset::io::Reader, + _settings: &Self::Settings, + load_context: &mut bevy::asset::LoadContext<'_>, + ) -> Result { + let mut content = Vec::new(); + reader + .read_to_end(&mut content) + .await + .map_err(|e| ScriptError::new_external(e).with_context(load_context.asset_path()))?; + if let Some(processor) = &self.preprocessor { + processor(&mut content)?; + } + let asset = ScriptAsset { + content: content.into_boxed_slice(), + asset_path: load_context.path().to_owned(), + language: self.language.clone(), + }; + Ok(asset) + } + + fn extensions(&self) -> &[&str] { + self.extensions + } +} + +#[derive(Clone, Copy, Resource)] +pub struct ScriptAssetSettings { + pub script_id_mapper: AssetPathToScriptIdMapper, +} + +impl Default for ScriptAssetSettings { + fn default() -> Self { + Self { + script_id_mapper: AssetPathToScriptIdMapper { + map: (|path: &Path| path.to_string_lossy().into_owned().into()), + }, + } + } +} + +/// Strategy for mapping asset paths to script ids, by default this is the identity function +#[derive(Clone, Copy)] +pub struct AssetPathToScriptIdMapper { + pub map: fn(&Path) -> ScriptId, +} + +/// 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>, +} + +impl AssetIdToScriptIdMap { + pub fn insert(&mut self, id: AssetId, path: ScriptId) { + self.map.insert(id, path); + } + + pub fn get(&self, id: AssetId) -> Option<&ScriptId> { + self.map.get(&id) + } + + pub fn remove(&mut self, id: AssetId) -> Option { + self.map.remove(&id) + } } diff --git a/crates/bevy_mod_scripting_core/src/bindings/access_map.rs b/crates/bevy_mod_scripting_core/src/bindings/access_map.rs new file mode 100644 index 00000000..8dbbc392 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/access_map.rs @@ -0,0 +1,473 @@ +use std::{sync::atomic::AtomicBool, thread::ThreadId}; + +use bevy::{ + ecs::{component::ComponentId, world::unsafe_world_cell::UnsafeWorldCell}, + prelude::Resource, +}; +use dashmap::{DashMap, Entry}; +use smallvec::SmallVec; + +use super::{ReflectAllocationId, ReflectBase}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ClaimOwner { + id: ThreadId, + location: std::panic::Location<'static>, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct AccessCount { + /// The number of readers including thread information + read_by: SmallVec<[ClaimOwner; 1]>, + /// If the current read is a write access, this will be set + written: bool, +} + +impl Default for AccessCount { + fn default() -> Self { + Self::new() + } +} + +impl AccessCount { + fn new() -> Self { + Self { + read_by: Default::default(), + written: false, + } + } + + fn can_read(&self) -> bool { + !self.written + } + + fn can_write(&self) -> bool { + self.read_by.is_empty() && !self.written + } + + fn as_location(&self) -> Option> { + self.read_by.first().map(|o| o.location) + } + + fn readers(&self) -> usize { + self.read_by.len() + } +} + +pub trait AccessMapKey { + fn as_index(&self) -> u64; + fn from_index(value: u64) -> Self; +} + +impl AccessMapKey for u64 { + fn as_index(&self) -> u64 { + *self + } + + fn from_index(value: u64) -> Self { + value + } +} + +/// Describes kinds of base value we are accessing via reflection +#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)] +pub enum ReflectAccessKind { + ComponentOrResource, + Allocation, +} + +/// Describes the id pointing to the base value we are accessing via reflection, for components and resources this is the ComponentId +/// for script owned values this is an allocationId, this is used to ensure we have permission to access the value. +#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)] +pub struct ReflectAccessId { + kind: ReflectAccessKind, + id: u64, +} + +impl AccessMapKey for ReflectAccessId { + fn as_index(&self) -> u64 { + // project two linear non-negative ranges to a single linear non-negative range + // y1 = 2x - 0 + // y2 = 2x - 1 + match self.kind { + ReflectAccessKind::ComponentOrResource => self.id * 2, + ReflectAccessKind::Allocation => self.id * 2 + 1, + } + } + + fn from_index(value: u64) -> Self { + // retrieve the kind of range based on if the value is odd or even + // y1 if even, y2 if odd + // to retrieve value of x: + // x1 = y / 2 + // x2 = (y - 1) / 2 + let (kind, id) = if value % 2 == 0 { + (ReflectAccessKind::ComponentOrResource, value / 2) + } else { + (ReflectAccessKind::Allocation, (value - 1) / 2) + }; + Self { kind, id } + } +} + +impl ReflectAccessId { + pub fn for_resource(cell: &UnsafeWorldCell) -> Option { + Some(Self { + kind: ReflectAccessKind::ComponentOrResource, + id: cell.components().resource_id::()?.index() as u64, + }) + } + + pub fn for_component( + cell: &UnsafeWorldCell, + ) -> Option { + let component_id = cell.components().component_id::()?; + + Some(Self::for_component_id(component_id)) + } + + pub fn for_allocation(id: ReflectAllocationId) -> Self { + Self { + kind: ReflectAccessKind::Allocation, + id: id.id(), + } + } + + pub fn for_component_id(id: ComponentId) -> Self { + Self { + kind: ReflectAccessKind::ComponentOrResource, + id: id.index() as u64, + } + } + + pub fn for_reference(base: ReflectBase) -> Option { + match base { + ReflectBase::Resource(id) => Some(Self::for_component_id(id)), + ReflectBase::Component(_, id) => Some(Self::for_component_id(id)), + ReflectBase::Owned(id) => Some(Self::for_allocation(id)), + } + } +} + +impl From for ReflectAccessId { + fn from(value: ComponentId) -> Self { + Self { + kind: ReflectAccessKind::ComponentOrResource, + id: value.index() as u64, + } + } +} + +impl From for ReflectAccessId { + fn from(value: ReflectAllocationId) -> Self { + Self { + kind: ReflectAccessKind::Allocation, + id: value.id(), + } + } +} + +impl From for ComponentId { + fn from(val: ReflectAccessId) -> Self { + ComponentId::new(val.id as usize) + } +} + +#[derive(Debug, Default)] +pub struct AccessMap { + individual_accesses: DashMap, + global_lock: AtomicBool, +} + +impl AccessMap { + /// Tries to claim read access, will return false if somebody else is writing to the same key, or holding a global lock + #[track_caller] + pub fn claim_read_access(&self, key: K) -> bool { + if self.global_lock.load(std::sync::atomic::Ordering::Relaxed) { + return false; + } + let key = key.as_index(); + let access = self.individual_accesses.try_entry(key); + match access.map(Entry::or_default) { + Some(mut entry) if entry.can_read() => { + entry.read_by.push(ClaimOwner { + id: std::thread::current().id(), + location: *std::panic::Location::caller(), + }); + true + } + _ => false, + } + } + + #[track_caller] + /// Tries to claim write access, will return false if somebody else is reading or writing to the same key, or holding a global lock + pub fn claim_write_access(&self, key: K) -> bool { + if self.global_lock.load(std::sync::atomic::Ordering::Relaxed) { + return false; + } + let key = key.as_index(); + let access = self.individual_accesses.try_entry(key); + match access.map(Entry::or_default) { + Some(mut entry) if entry.can_write() => { + entry.read_by.push(ClaimOwner { + id: std::thread::current().id(), + location: *std::panic::Location::caller(), + }); + entry.written = true; + true + } + _ => false, + } + } + + /// Tries to claim global access. This type of access prevents any other access from happening simulatenously + /// Will return false if anybody else is currently accessing any part of the map + pub fn claim_global_access(&self) -> bool { + self.individual_accesses.is_empty() + && self + .global_lock + .compare_exchange( + false, + true, + std::sync::atomic::Ordering::Relaxed, + std::sync::atomic::Ordering::Relaxed, + ) + .is_ok() + } + + /// Releases an access + /// + /// # Panics + /// if the access is released from a different thread than it was claimed from + pub fn release_access(&self, key: K) { + let key = key.as_index(); + let access = self.individual_accesses.entry(key); + match access { + dashmap::mapref::entry::Entry::Occupied(mut entry) => { + let entry_mut = entry.get_mut(); + entry_mut.written = false; + if let Some(p) = entry_mut.read_by.pop() { + assert!( + p.id == std::thread::current().id(), + "Access released from wrong thread, claimed at {}", + p.location.display_location() + ); + } + if entry_mut.readers() == 0 { + entry.remove(); + } + } + dashmap::mapref::entry::Entry::Vacant(_) => {} + } + } + + /// Releases a global access + pub fn release_global_access(&self) { + self.global_lock + .store(false, std::sync::atomic::Ordering::Relaxed); + } + + pub fn list_accesses(&self) -> Vec<(K, AccessCount)> { + self.individual_accesses + .iter() + .map(|e| (K::from_index(*e.key()), e.value().clone())) + .collect() + } + + pub fn count_accesses(&self) -> usize { + self.individual_accesses.len() + } + + pub fn release_all_accesses(&self) { + self.individual_accesses.clear(); + self.global_lock + .store(false, std::sync::atomic::Ordering::Relaxed); + } + + pub fn access_location( + &self, + key: K, + ) -> Option> { + self.individual_accesses + .try_get(&key.as_index()) + .try_unwrap() + .and_then(|access| access.as_location()) + } + + pub fn access_first_location(&self) -> Option> { + self.individual_accesses + .iter() + .find_map(|e| e.value().as_location()) + } +} + +pub trait DisplayCodeLocation { + fn display_location(self) -> String; +} + +impl DisplayCodeLocation for std::panic::Location<'_> { + fn display_location(self) -> String { + format!("\"{}:{}\"", self.file(), self.line()) + } +} + +impl DisplayCodeLocation for Option> { + fn display_location(self) -> String { + self.map(|l| l.display_location()) + .unwrap_or_else(|| "\"unknown location\"".to_owned()) + } +} + +#[macro_export] +macro_rules! with_access_read { + ($access_map:expr, $id:expr, $msg:expr, $body:block) => {{ + if !$access_map.claim_read_access($id) { + panic!( + "{}. Aliasing access is held somewhere else: {}", + $msg, + $crate::bindings::access_map::DisplayCodeLocation::display_location( + $access_map.access_location($id) + ) + ); + } else { + let result = $body; + $access_map.release_access($id); + result + } + }}; +} + +#[macro_export] +macro_rules! with_access_write { + ($access_map:expr, $id:expr, $msg:expr, $body:block) => { + if !$access_map.claim_write_access($id) { + panic!( + "{}. Aliasing access is held somewhere else: {}", + $msg, + $crate::bindings::access_map::DisplayCodeLocation::display_location( + $access_map.access_location($id) + ) + ); + } else { + let result = $body; + $access_map.release_access($id); + result + } + }; +} + +#[macro_export] +macro_rules! with_global_access { + ($access_map:expr, $msg:expr, $body:block) => { + if !$access_map.claim_global_access() { + panic!( + "{}. Another access is held somewhere else preventing locking the world: {}", + $msg, + $crate::bindings::access_map::DisplayCodeLocation::display_location( + $access_map.access_first_location() + ) + ); + } else { + #[allow(clippy::redundant_closure_call)] + let result = (|| $body)(); + $access_map.release_global_access(); + result + } + }; +} + +#[cfg(test)] +mod test { + use super::*; + #[test] + fn test_list_accesses() { + let access_map = AccessMap::default(); + + access_map.claim_read_access(0); + access_map.claim_write_access(1); + + let accesses = access_map.list_accesses::(); + + assert_eq!(accesses.len(), 2); + let access_0 = accesses.iter().find(|(k, _)| *k == 0).unwrap(); + let access_1 = accesses.iter().find(|(k, _)| *k == 1).unwrap(); + + assert_eq!(access_0.1.readers(), 1); + assert_eq!(access_1.1.readers(), 1); + + assert!(!access_0.1.written); + assert!(access_1.1.written); + } + + #[test] + fn test_read_access_blocks_write() { + let access_map = AccessMap::default(); + + assert!(access_map.claim_read_access(0)); + assert!(!access_map.claim_write_access(0)); + access_map.release_access(0); + assert!(access_map.claim_write_access(0)); + } + + #[test] + fn test_write_access_blocks_read() { + let access_map = AccessMap::default(); + + assert!(access_map.claim_write_access(0)); + assert!(!access_map.claim_read_access(0)); + access_map.release_access(0); + assert!(access_map.claim_read_access(0)); + } + + #[test] + fn test_global_access_blocks_all() { + let access_map = AccessMap::default(); + + assert!(access_map.claim_global_access()); + assert!(!access_map.claim_read_access(0)); + assert!(!access_map.claim_write_access(0)); + access_map.release_global_access(); + assert!(access_map.claim_write_access(0)); + access_map.release_access(0); + assert!(access_map.claim_read_access(0)); + } + + #[test] + fn any_access_blocks_global() { + let access_map = AccessMap::default(); + + assert!(access_map.claim_read_access(0)); + assert!(!access_map.claim_global_access()); + access_map.release_access(0); + + assert!(access_map.claim_write_access(0)); + assert!(!access_map.claim_global_access()); + } + + #[test] + #[should_panic] + fn releasing_read_access_from_wrong_thread_panics() { + let access_map = AccessMap::default(); + + access_map.claim_read_access(0); + std::thread::spawn(move || { + access_map.release_access(0); + }) + .join() + .unwrap(); + } + + #[test] + #[should_panic] + fn releasing_write_access_from_wrong_thread_panics() { + let access_map = AccessMap::default(); + + access_map.claim_write_access(0); + std::thread::spawn(move || { + access_map.release_access(0); + }) + .join() + .unwrap(); + } +} diff --git a/crates/bevy_mod_scripting_core/src/bindings/allocator.rs b/crates/bevy_mod_scripting_core/src/bindings/allocator.rs new file mode 100644 index 00000000..2499dd41 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/allocator.rs @@ -0,0 +1,248 @@ +use bevy::{ecs::system::Resource, reflect::PartialReflect}; +use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard}; +use std::{ + any::TypeId, + cell::UnsafeCell, + cmp::Ordering, + collections::HashMap, + fmt::{Display, Formatter}, + hash::Hasher, + sync::{atomic::AtomicU64, Arc}, +}; + +#[derive(Clone, Debug)] +pub struct ReflectAllocationId(pub(crate) Arc); +impl ReflectAllocationId { + pub fn id(&self) -> u64 { + *self.0 + } + + /// Creates a new [`ReflectAllocationId`] from its id + pub(crate) fn new(id: u64) -> Self { + Self(Arc::new(id)) + } + + pub fn strong_count(&self) -> usize { + Arc::strong_count(&self.0) + } +} + +impl std::hash::Hash for ReflectAllocationId { + fn hash(&self, state: &mut H) { + self.id().hash(state); + } +} + +impl PartialEq for ReflectAllocationId { + fn eq(&self, other: &Self) -> bool { + self.id() == other.id() + } +} + +impl Eq for ReflectAllocationId {} + +impl PartialOrd for ReflectAllocationId { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.id().cmp(&other.id())) + } +} + +impl Ord for ReflectAllocationId { + fn cmp(&self, other: &Self) -> Ordering { + self.id().cmp(&other.id()) + } +} + +/// Pointer which owns the value it points to, and will deallocate it when dropped +#[derive(Debug)] +pub struct OwningPtr { + ptr: *mut T, +} + +impl OwningPtr { + /// Creates a new OwningPtr from a raw pointer + /// # Safety + /// The pointer must come from a Box::leak call, and no more than one OwningPtr can exist for a given pointer + pub unsafe fn new(ptr: *mut T) -> Self { + Self { ptr } + } +} + +impl Drop for OwningPtr { + fn drop(&mut self) { + unsafe { + // Safety: we own the pointer, only one OwningPtr can exist for a given pointer + let _ = Box::from_raw(self.ptr); + } + } +} + +// yikes, the indirection. I need this to store boxed values too though +#[derive(Debug)] +pub struct ReflectAllocation(Box>); + +// unsafe impl Send for ReflectAllocation {} +unsafe impl Sync for ReflectAllocation {} + +impl ReflectAllocation { + pub fn get_ptr(&self) -> *mut dyn PartialReflect { + self.0.as_ref().get() + } + + pub fn new(value: Box) -> Self { + let value: Box> = unsafe { std::mem::transmute(value) }; + Self(value) + } + + /// Takes the value out of the allocation. + /// + /// # Safety + /// - Must only be done if no other references to this allocation exist at the same time + pub unsafe fn take(self) -> Box { + std::mem::transmute(self.0) + } +} + +impl Display for ReflectAllocationId { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +/// Wrapper around a [`ReflectAllocator`] which can be freely copied and shared between threads +#[derive(Debug, Resource, Clone)] +pub struct AppReflectAllocator { + pub(crate) allocator: Arc>, +} + +impl Default for AppReflectAllocator { + fn default() -> Self { + Self { + allocator: Arc::new(RwLock::new(ReflectAllocator::default())), + } + } +} + +impl AppReflectAllocator { + pub fn read(&self) -> RwLockReadGuard { + self.allocator.read() + } + + pub fn write(&self) -> RwLockWriteGuard { + self.allocator.write() + } +} + +/// Allocator used to allocate and deallocate `dyn PartialReflect` values +/// Used to be able to ensure we have a "common root" for values allocated outside the world. +#[derive(Default, Debug)] +pub struct ReflectAllocator { + // TODO: experiment with object pools, sparse set etc. + allocations: HashMap, + types: HashMap, +} + +impl ReflectAllocator { + /// Allocates a new [`Reflect`] value and returns an [`AllocationId`] which can be used to access it later. + /// Use [`Self::allocate_boxed`] if you already have an allocated boxed value. + pub fn allocate(&mut self, value: T) -> ReflectAllocationId { + self.allocate_boxed(Box::new(value)) + } + + pub fn allocate_boxed(&mut self, value: Box) -> ReflectAllocationId { + static COUNTER: AtomicU64 = AtomicU64::new(0); + + let type_id = value.get_represented_type_info().map(|i| i.type_id()); + let id = + ReflectAllocationId::new(COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed)); + let index = id.id(); + let value = ReflectAllocation::new(value); + self.allocations.insert(id.clone(), value); + if let Some(type_id) = type_id { + self.types.insert(index, type_id); + } + id + } + pub fn insert( + &mut self, + id: ReflectAllocationId, + value: ReflectAllocation, + ) -> Option { + self.allocations.insert(id, value) + } + + pub fn remove(&mut self, id: &ReflectAllocationId) -> Option { + self.allocations.remove(id) + } + + pub fn get_type_id(&self, id: &ReflectAllocationId) -> Option { + self.types.get(&id.id()).cloned() + } + + pub fn get_mut(&mut self, id: &ReflectAllocationId) -> Option<&mut ReflectAllocation> { + self.allocations.get_mut(id) + } + + pub fn get(&self, id: &ReflectAllocationId) -> Option<&ReflectAllocation> { + self.allocations.get(id) + } + + /// Deallocates the [`PartialReflect`] value with the given [`AllocationId`] + pub fn deallocate(&mut self, id: &ReflectAllocationId) { + self.allocations.remove(id); + } + + /// 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); + } + + pub fn iter_allocations( + &self, + ) -> impl Iterator { + self.allocations.iter() + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_reflect_allocator_garbage_clean() { + let mut allocator = ReflectAllocator::default(); + let id = allocator.allocate(0); + assert_eq!(allocator.allocations.len(), 1); + drop(id); + allocator.clean_garbage_allocations(); + assert_eq!(allocator.allocations.len(), 0); + } + + #[test] + fn test_reflect_allocator_allocate_clean_and_access_does_not_overwrite_id() { + let mut allocator = ReflectAllocator::default(); + let id = allocator.allocate(0); + let id2 = allocator.allocate("string"); + assert_eq!(allocator.allocations.len(), 2); + drop(id); + allocator.clean_garbage_allocations(); + assert_eq!(allocator.allocations.len(), 1); + allocator.allocate(3); + assert_eq!(allocator.allocations.len(), 2); + + // Safety: only one reference to the allocation exists + let ref_ = unsafe { &*allocator.get(&id2).unwrap().get_ptr() }; + assert!(ref_.reflect_partial_eq(&"string").unwrap()); + } + + #[test] + fn test_reflect_allocator_garbage_clean_no_garbage() { + let mut allocator = ReflectAllocator::default(); + let _id = allocator.allocate(0); + assert_eq!(allocator.allocations.len(), 1); + allocator.clean_garbage_allocations(); + assert_eq!(allocator.allocations.len(), 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 new file mode 100644 index 00000000..383e4569 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/function/from.rs @@ -0,0 +1,389 @@ +use crate::{ + bindings::{access_map::ReflectAccessId, ReflectReference, WorldGuard}, + error::InteropError, + ScriptValue, +}; +use bevy::reflect::{FromReflect, Reflect}; +use std::{ + any::TypeId, + ffi::OsString, + ops::{Deref, DerefMut}, + path::PathBuf, +}; + +/// 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 +/// a type with the lifetime of the world guard. In 99% cases you can just use `Self` as the associated type. +pub trait FromScript { + type This<'w>; + fn from_script( + value: ScriptValue, + world: WorldGuard<'_>, + ) -> Result, InteropError> + where + Self: Sized; +} + +impl FromScript for ScriptValue { + type This<'w> = Self; + fn from_script(value: ScriptValue, _world: WorldGuard) -> Result { + Ok(value) + } +} + +impl FromScript for () { + type This<'w> = Self; + fn from_script(_value: ScriptValue, _world: WorldGuard) -> Result { + Ok(()) + } +} + +impl FromScript for bool { + type This<'w> = Self; + + fn from_script( + value: ScriptValue, + world: WorldGuard<'_>, + ) -> Result, InteropError> + where + Self: Sized, + { + match value { + ScriptValue::Bool(b) => Ok(b), + ScriptValue::Reference(r) => r.downcast::(world), + _ => Err(InteropError::value_mismatch( + std::any::TypeId::of::(), + value, + )), + } + } +} + +macro_rules! impl_from_with_downcast { + ($($ty:ty),*) => { + $( + impl FromScript for $ty { + type This<'w> = Self; + fn from_script(value: ScriptValue, world: WorldGuard) -> Result { + match value { + ScriptValue::Integer(i) => Ok(i as $ty), + ScriptValue::Float(i) => Ok(i as $ty), + ScriptValue::Reference(r) => r.downcast::(world), + ScriptValue::Bool(b) => Ok(b as usize as $ty), + _ => Err(InteropError::value_mismatch(std::any::TypeId::of::(), value)), + } + } + } + )* + }; +} + +impl_from_with_downcast!(i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, f32, f64, usize, isize); + +macro_rules! impl_from_stringlike { + ($($ty:ty),*) => { + $( + impl FromScript for $ty { + type This<'w> = Self; + fn from_script(value: ScriptValue, world: WorldGuard) -> Result { + match value { + ScriptValue::String(s) => Ok(s.to_string().into()), + ScriptValue::Reference(r) => r.downcast::(world), + _ => Err(InteropError::value_mismatch(std::any::TypeId::of::(), value)), + } + } + } + )* + }; +} + +impl_from_stringlike!(String, PathBuf, OsString); + +impl FromScript for char { + type This<'w> = Self; + + fn from_script( + value: ScriptValue, + world: WorldGuard<'_>, + ) -> Result, InteropError> + where + Self: Sized, + { + match value { + ScriptValue::Integer(i) => Ok(i as u8 as char), + ScriptValue::String(c) if c.len() == 1 => Ok(c.chars().next().expect("invariant")), + ScriptValue::Reference(r) => r.downcast::(world), + _ => Err(InteropError::value_mismatch( + std::any::TypeId::of::(), + value, + )), + } + } +} + +impl FromScript for ReflectReference { + type This<'w> = Self; + fn from_script(value: ScriptValue, _world: WorldGuard) -> Result { + match value { + ScriptValue::Reference(r) => Ok(r), + _ => Err(InteropError::value_mismatch( + std::any::TypeId::of::(), + value, + )), + } + } +} + +/// A wrapper around a value of type `T`. +/// +/// This can be used to retrieve a value out of a [`ScriptValue::Reference`] corresponding to the type `T`. +/// You can also use this to return values from a script function to be allocated directly as a [`ScriptValue::Reference`]. +#[derive(Reflect)] +pub struct Val(pub T); + +impl Val { + pub fn new(value: T) -> Self { + Val(value) + } + + pub fn into_inner(self) -> T { + self.0 + } +} + +impl Deref for Val { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for Val { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From for Val { + fn from(value: T) -> Self { + Val(value) + } +} + +impl FromScript for Val { + type This<'w> = Self; + fn from_script(value: ScriptValue, world: WorldGuard) -> Result { + match value { + ScriptValue::Reference(reflect_reference) => Ok(Val(reflect_reference.with_reflect( + world.clone(), + |r| { + T::from_reflect(r).ok_or_else(|| { + InteropError::failed_from_reflect( + Some(TypeId::of::()), + format!( + "Expected '{}' but receievd: {r:?}", + std::any::type_name::() + ), + ) + }) + }, + )??)), + _ => Err(InteropError::value_mismatch( + std::any::TypeId::of::(), + value, + )), + } + } +} + +/// A wrapper around a reference to a value of type `T`. +/// +/// This can be used to retrieve a reference out of a [`ScriptValue::Reference`] corresponding to the type `T`. +/// Before downcasting the reference, it will claim write access to the object to ensure that the reference is valid. +/// +/// However, the access is NOT released when the `Mut` is dropped. This is not unsafe but can lead to deadlocks if not released later. +/// The [`ScriptFunction`] calling mechanism will take care of releasing all accesses claimed during the function call. +pub struct Ref<'w, T>(pub &'w T); + +impl Deref for Ref<'_, T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + self.0 + } +} + +impl FromScript for Ref<'_, T> { + type This<'a> = Ref<'a, T>; + + fn from_script( + value: ScriptValue, + world: WorldGuard<'_>, + ) -> Result, InteropError> { + match value { + ScriptValue::Reference(reflect_reference) => { + let raid = ReflectAccessId::for_reference(reflect_reference.base.base_id.clone()) + .ok_or_else(|| { + InteropError::unregistered_base(reflect_reference.base.clone()) + })?; + + if world.claim_read_access(raid) { + // Safety: we just claimed access + let ref_ = unsafe { reflect_reference.reflect_unsafe(world) }?; + let cast = ref_.try_downcast_ref::().ok_or_else(|| { + InteropError::type_mismatch( + std::any::TypeId::of::(), + ref_.get_represented_type_info().map(|i| i.type_id()), + ) + })?; + Ok(Ref(cast)) + } else { + Err(InteropError::cannot_claim_access( + reflect_reference.base, + world.get_access_location(raid), + )) + } + } + _ => Err(InteropError::value_mismatch( + std::any::TypeId::of::(), + value, + )), + } + } +} + +impl<'a, T> From<&'a T> for Ref<'a, T> { + fn from(value: &'a T) -> Self { + Ref(value) + } +} + +/// A wrapper around a mutable reference to a value of type `T`. +/// +/// This can be used to retrieve a mutable reference out of a [`ScriptValue::Reference`] corresponding to the type `T`. +/// Before downcasting the reference, it will claim write access to the object to ensure that the reference is valid. +/// +/// However, the access is NOT released when the `Mut` is dropped. This is not unsafe but can lead to deadlocks if not released later. +/// The [`ScriptFunction`] calling mechanism will take care of releasing all accesses claimed during the function call. +pub struct Mut<'w, T>(pub &'w mut T); + +impl Deref for Mut<'_, T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + self.0 + } +} + +impl DerefMut for Mut<'_, T> { + fn deref_mut(&mut self) -> &mut Self::Target { + self.0 + } +} + +impl<'a, T> From<&'a mut T> for Mut<'a, T> { + fn from(value: &'a mut T) -> Self { + Mut(value) + } +} + +impl FromScript for Mut<'_, T> { + type This<'w> = Mut<'w, T>; + + fn from_script( + value: ScriptValue, + world: WorldGuard<'_>, + ) -> Result, InteropError> { + match value { + ScriptValue::Reference(reflect_reference) => { + let raid = ReflectAccessId::for_reference(reflect_reference.base.base_id.clone()) + .ok_or_else(|| { + InteropError::unregistered_base(reflect_reference.base.clone()) + })?; + + if world.claim_write_access(raid) { + // Safety: we just claimed write access + let ref_ = unsafe { reflect_reference.reflect_mut_unsafe(world) }?; + let type_id = ref_.get_represented_type_info().map(|i| i.type_id()); + let cast = ref_.try_downcast_mut::().ok_or_else(|| { + InteropError::type_mismatch(std::any::TypeId::of::(), type_id) + })?; + Ok(Mut(cast)) + } else { + Err(InteropError::cannot_claim_access( + reflect_reference.base, + world.get_access_location(raid), + )) + } + } + _ => Err(InteropError::value_mismatch( + std::any::TypeId::of::(), + value, + )), + } + } +} + +impl FromScript for Option +where + for<'w> T::This<'w>: Into, +{ + type This<'w> = Self; + + fn from_script(value: ScriptValue, world: WorldGuard) -> Result { + match value { + ScriptValue::Unit => Ok(None), + _ => Ok(Some(T::from_script(value, world)?.into())), + } + } +} + +impl FromScript for Vec +where + for<'w> T::This<'w>: Into, +{ + type This<'w> = Self; + + fn from_script(value: ScriptValue, world: WorldGuard) -> Result { + match value { + ScriptValue::List(list) => { + let mut vec = Vec::with_capacity(list.len()); + for item in list { + vec.push(T::from_script(item, world.clone())?.into()); + } + Ok(vec) + } + _ => Err(InteropError::value_mismatch( + std::any::TypeId::of::>(), + value, + )), + } + } +} + +impl FromScript for [T; N] +where + for<'w> T::This<'w>: Into, +{ + type This<'w> = Self; + + fn from_script(value: ScriptValue, world: WorldGuard) -> Result { + match value { + ScriptValue::List(list) if list.len() == N => { + let converted_list = list + .into_iter() + .map(|item| T::from_script(item, world.clone()).map(Into::into)) + .collect::, _>>()? + .try_into() + .map_err(|list: Vec| InteropError::length_mismatch(N, list.len()))?; + Ok(converted_list) + } + _ => Err(InteropError::value_mismatch( + std::any::TypeId::of::<[T; N]>(), + value, + )), + } + } +} diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/from_ref.rs b/crates/bevy_mod_scripting_core/src/bindings/function/from_ref.rs new file mode 100644 index 00000000..cdab7932 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/function/from_ref.rs @@ -0,0 +1,107 @@ +use std::{any::TypeId, ffi::OsString, path::PathBuf}; + +use bevy::reflect::{DynamicEnum, DynamicList, DynamicTuple, DynamicVariant, PartialReflect}; + +use crate::{ + bindings::{function::from::FromScript, WorldGuard}, + error::InteropError, + match_by_type, + reflection_extensions::TypeInfoExtensions, + ScriptValue, +}; + +/// Converts from a [`ScriptValue`] to a value equivalent to the given [`TypeId`]. +/// +/// Type Erased version of [`super::from::FromScript`]. +pub trait FromScriptRef { + fn from_script_ref( + target: TypeId, + value: ScriptValue, + world: WorldGuard, + ) -> Result + where + Self: Sized; +} + +impl FromScriptRef for Box { + fn from_script_ref( + target: TypeId, + value: ScriptValue, + world: WorldGuard, + ) -> Result + where + Self: Sized, + { + match_by_type! ( + match target { + ta : usize => return ::from_script(value, world).map(|a| Box::new(a) as _), + tb : isize => return ::from_script(value, world).map(|a| Box::new(a) as _), + tc : u8 => return ::from_script(value, world).map(|a| Box::new(a) as _), + td : u16 => return ::from_script(value, world).map(|a| Box::new(a) as _), + te : u32 => return ::from_script(value, world).map(|a| Box::new(a) as _), + tf : u64 => return ::from_script(value, world).map(|a| Box::new(a) as _), + tg : u128 => return ::from_script(value, world).map(|a| Box::new(a) as _), + th : i8 => return ::from_script(value, world).map(|a| Box::new(a) as _), + ti : i16 => return ::from_script(value, world).map(|a| Box::new(a) as _), + tj : i32 => return ::from_script(value, world).map(|a| Box::new(a) as _), + tk : i64 => return ::from_script(value, world).map(|a| Box::new(a) as _), + tl : i128 => return ::from_script(value, world).map(|a| Box::new(a) as _), + tm : f32 => return ::from_script(value, world).map(|a| Box::new(a) as _), + tn : f64 => return ::from_script(value, world).map(|a| Box::new(a) as _), + to : bool => return ::from_script(value, world).map(|a| Box::new(a) as _), + tp : char => return ::from_script(value, world).map(|a| Box::new(a) as _), + tq : String => return ::from_script(value, world).map(|a| Box::new(a) as _), + tr : PathBuf => return ::from_script(value, world).map(|a| Box::new(a) as _), + ts : OsString=> return ::from_script(value, world).map(|a| Box::new(a) as _), + tn : () => return <()>::from_script(value, world).map(|a| Box::new(a) as _) + } + ); + + let type_registry = world.type_registry(); + let type_registry = type_registry.read(); + + let type_info = type_registry.get_type_info(target).ok_or_else(|| { + InteropError::missing_type_data( + target, + "Type was not registered, could not determine conversion strategy.".to_owned(), + ) + })?; + + if type_info.is_option() { + let inner_type = type_info.option_inner_type().expect("invariant"); + let mut dynamic_enum = match value { + ScriptValue::Unit => DynamicEnum::new("None", DynamicVariant::Unit), + _ => { + let inner = Self::from_script_ref(inner_type, value, world)?; + DynamicEnum::new( + "Some", + DynamicVariant::Tuple(DynamicTuple::from_iter(vec![inner])), + ) + } + }; + + dynamic_enum.set_represented_type(Some(type_info)); + return Ok(Box::new(dynamic_enum)); + } + + if type_info.is_list() { + let inner_type = type_info.list_inner_type().expect("invariant"); + + if let ScriptValue::List(vec) = value { + let mut dynamic_list = DynamicList::default(); + for item in vec { + let inner = Self::from_script_ref(inner_type, item, world.clone())?; + dynamic_list.push_box(inner); + } + + dynamic_list.set_represented_type(Some(type_info)); + return Ok(Box::new(dynamic_list)); + } + } + + match value { + ScriptValue::Reference(reflect_reference) => reflect_reference.to_owned_value(world), + value => Err(InteropError::value_mismatch(target, value)), + } + } +} diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/into.rs b/crates/bevy_mod_scripting_core/src/bindings/function/into.rs new file mode 100644 index 00000000..d5ab5145 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/function/into.rs @@ -0,0 +1,168 @@ +use std::{borrow::Cow, ffi::OsString, path::PathBuf}; + +use bevy::reflect::PartialReflect; + +use crate::{ + bindings::{script_value::ScriptValue, ReflectReference, WorldGuard}, + error::InteropError, + self_type_dependency_only, +}; + +use super::{ + from::Val, + script_function::{DynamicScriptFunction, DynamicScriptFunctionMut}, +}; + +pub trait IntoScript { + fn into_script(self, world: WorldGuard) -> Result; +} + +impl IntoScript for ScriptValue { + fn into_script(self, _world: WorldGuard) -> Result { + Ok(self) + } +} + +self_type_dependency_only!(ScriptValue); + +impl IntoScript for () { + fn into_script(self, _world: WorldGuard) -> Result { + Ok(ScriptValue::Unit) + } +} +self_type_dependency_only!(()); + +impl IntoScript for DynamicScriptFunctionMut { + fn into_script(self, _world: WorldGuard) -> Result { + Ok(ScriptValue::Function(self)) + } +} + +self_type_dependency_only!(DynamicScriptFunctionMut, DynamicScriptFunction); + +impl IntoScript for bool { + fn into_script(self, _world: WorldGuard) -> Result { + Ok(ScriptValue::Bool(self)) + } +} +self_type_dependency_only!(bool); + +macro_rules! impl_into_with_downcast { + ($variant:tt as $cast:ty [$($ty:ty),*]) => { + $( + impl IntoScript for $ty { + fn into_script(self, _world: WorldGuard) -> Result { + Ok(ScriptValue::$variant(self as $cast)) + } + } + )* + } + +} + +impl_into_with_downcast!(Integer as i64 [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, usize, isize]); +impl_into_with_downcast!(Float as f64 [f32, f64]); +self_type_dependency_only!( + i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, usize, isize, f32, f64 +); + +macro_rules! impl_into_stringlike { + ($id:ident,[ $(($ty:ty => $conversion:expr)),*]) => { + $( + impl IntoScript for $ty { + fn into_script(self, _world: WorldGuard) -> Result { + let $id = self; + let converted: String = $conversion; + Ok(ScriptValue::String(converted.into())) + } + } + )* + } +} + +impl_into_stringlike!( + s, + [ + (String => s), + (char => s.to_string()), + (PathBuf => s.to_string_lossy().to_string()), + (OsString => s.into_string().map_err(|e| InteropError::unsupported_operation(None, Some(Box::new(e)), "Could not convert OsString to String".to_owned()))?) + ] +); + +self_type_dependency_only!(String, char, PathBuf, OsString); + +impl IntoScript for &'static str { + fn into_script(self, _world: WorldGuard) -> Result { + Ok(ScriptValue::String(Cow::Borrowed(self))) + } +} + +self_type_dependency_only!(&'static str); + +impl IntoScript for ReflectReference { + fn into_script(self, _world: WorldGuard) -> Result { + Ok(ScriptValue::Reference(self)) + } +} + +impl IntoScript for Val { + fn into_script(self, world: WorldGuard) -> Result { + let boxed: Box = Box::new(self.0); + let allocator = world.allocator(); + let mut allocator = allocator.write(); + + Ok(ScriptValue::Reference( + ReflectReference::new_allocated_boxed(boxed, &mut allocator), + )) + } +} + +impl IntoScript for Option { + fn into_script(self, world: WorldGuard) -> Result { + match self { + Some(val) => val.into_script(world), + None => Ok(ScriptValue::Unit), + } + } +} + +impl IntoScript for Vec { + fn into_script(self, world: WorldGuard) -> Result { + let mut values = Vec::with_capacity(self.len()); + for val in self { + values.push(val.into_script(world.clone())?); + } + Ok(ScriptValue::List(values)) + } +} + +impl IntoScript for [T; N] { + fn into_script(self, world: WorldGuard) -> Result { + let mut values = Vec::with_capacity(N); + for val in self { + values.push(val.into_script(world.clone())?); + } + Ok(ScriptValue::List(values)) + } +} + +impl IntoScript for InteropError { + fn into_script(self, _world: WorldGuard) -> Result { + Ok(ScriptValue::Error(self)) + } +} + +macro_rules! impl_into_script_tuple { + ($( $ty:ident ),* ) => { + #[allow(non_snake_case)] + impl<$($ty: IntoScript),*> IntoScript for ($($ty,)*) { + fn into_script(self, world: WorldGuard) -> Result { + let ($($ty,)*) = self; + Ok(ScriptValue::List(vec![$($ty.into_script(world.clone())?),*])) + } + } +} +} + +bevy::utils::all_tuples!(impl_into_script_tuple, 1, 14, T); diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/into_ref.rs b/crates/bevy_mod_scripting_core/src/bindings/function/into_ref.rs new file mode 100644 index 00000000..f95bdb3b --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/function/into_ref.rs @@ -0,0 +1,110 @@ +use std::{ffi::OsString, path::PathBuf}; + +use bevy::reflect::{ParsedPath, PartialReflect}; + +use crate::{ + bindings::{function::into::IntoScript, ReflectReference, WorldGuard}, + error::InteropError, + reflection_extensions::{PartialReflectExt, TypeIdExtensions}, + ScriptValue, +}; + +/// Converts a value represented by a reference into a [`crate::bindings::function::ScriptValue`]. +/// Instead of a direct conversion, the trait tries to peek into the value behind the reference and find out the most suitable representation. +/// +/// Type Erased version of [`super::from::FromScript`]. +/// +/// - Primitives are converted to simple values +/// - Container types are converted to references (so the references persist after accesses inside them) +pub trait IntoScriptRef { + fn into_script_ref( + self_: ReflectReference, + world: WorldGuard, + ) -> Result; +} + +#[macro_export] +macro_rules! match_by_type { + (match $on:ident {$($id:ident : $ty:ty => $conv:expr),*}) => { + $( + #[allow(unused_variables)] + let $id = std::any::TypeId::of::<$ty>(); + )* + + match $on { + $( + $id if $id == std::any::TypeId::of::<$ty>() => {$conv}, + )* + _ => {}, + } + }; +} + +#[macro_export] +macro_rules! downcast_into_value { + ($r:ident, $ty:ty) => { + *$r.try_downcast_ref::<$ty>().ok_or_else(|| { + InteropError::type_mismatch( + std::any::TypeId::of::<$ty>(), + $r.get_represented_type_info().map(|i| i.type_id()), + ) + })? + }; +} + +impl IntoScriptRef for ReflectReference { + fn into_script_ref( + self_: ReflectReference, + world: WorldGuard, + ) -> Result { + self_.with_reflect(world.clone(), |r| into_script_ref(self_.clone(), r, world))? + } +} + +fn into_script_ref( + mut self_: ReflectReference, + r: &dyn PartialReflect, + world: WorldGuard, +) -> Result { + let type_id = r + .get_represented_type_info() + .map(|i| i.type_id()) + .or_fake_id(); + + match_by_type! ( + match type_id { + ta : usize => return downcast_into_value!(r, usize).into_script(world), + tb : isize => return downcast_into_value!(r, isize).into_script(world), + tc : u8 => return downcast_into_value!(r, u8).into_script(world), + td : u16 => return downcast_into_value!(r, u16).into_script(world), + te : u32 => return downcast_into_value!(r, u32).into_script(world), + tf : u64 => return downcast_into_value!(r, u64).into_script(world), + tg : u128 => return downcast_into_value!(r, u128).into_script(world), + th : i8 => return downcast_into_value!(r, i8).into_script(world), + ti : i16 => return downcast_into_value!(r, i16).into_script(world), + tj : i32 => return downcast_into_value!(r, i32).into_script(world), + tk : i64 => return downcast_into_value!(r, i64).into_script(world), + tl : i128 => return downcast_into_value!(r, i128).into_script(world), + tm : f32 => return downcast_into_value!(r, f32).into_script(world), + tn : f64 => return downcast_into_value!(r, f64).into_script(world), + to : bool => return downcast_into_value!(r, bool).into_script(world), + tp : char => return downcast_into_value!(r, char).into_script(world), + tq : String => return downcast_into_value!(r, String).clone().into_script(world), + tr : PathBuf => return downcast_into_value!(r, PathBuf).clone().into_script(world), + ts : OsString=> return downcast_into_value!(r, OsString).clone().into_script(world), + tn : () => return Ok(ScriptValue::Unit) + } + ); + + // either return nil or ref into + if let Ok(as_option) = r.as_option() { + return if let Some(s) = as_option { + self_.index_path(ParsedPath::parse_static(".0").expect("invariant")); + into_script_ref(self_, s, world) + } else { + Ok(ScriptValue::Unit) + }; + } + + Ok(ScriptValue::Reference(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 new file mode 100644 index 00000000..ae9f0f02 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/function/mod.rs @@ -0,0 +1,74 @@ +pub mod from; +pub mod from_ref; +pub mod into; +pub mod into_ref; +pub mod script_function; + +use script_function::{CallerContext, DynamicScriptFunction, DynamicScriptFunctionMut}; + +use crate::error::InteropError; + +use super::{ + pretty_print::DisplayWithWorld, 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()); + 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 { + 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/script_function.rs b/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs new file mode 100644 index 00000000..3eb7bf22 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs @@ -0,0 +1,502 @@ +use super::{from::FromScript, into::IntoScript}; +use crate::{ + bindings::{ + function::from::{Mut, Ref, Val}, + ReflectReference, + }, + error::InteropError, + ScriptValue, WorldCallbackAccess, +}; +use bevy::{ + prelude::{Reflect, Resource}, + reflect::{ + func::{args::GetOwnership, FunctionError}, + FromReflect, GetTypeRegistration, TypePath, TypeRegistry, Typed, + }, +}; +use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard}; +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", + note = "If you're trying to return a non-primitive type, you might need to use Val Ref or Mut wrappers" +)] +pub trait ScriptFunction<'env, Marker> { + fn into_dynamic_script_function(self) -> DynamicScriptFunction; +} + +#[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", + note = "If you're trying to return a non-primitive type, you might need to use Val Ref or Mut wrappers" +)] +pub trait ScriptFunctionMut<'env, Marker> { + fn into_dynamic_script_function_mut(self) -> DynamicScriptFunctionMut; +} + +/// Functionally identical to [`GetTypeRegistration`] but without the 'static bound +pub trait GetInnerTypeDependencies { + fn register_type_dependencies(registry: &mut TypeRegistry); +} + +#[macro_export] +macro_rules! no_type_dependencies { + ($($path:path),*) => { + $( + impl $crate::bindings::function::script_function::GetInnerTypeDependencies for $path { + fn register_type_dependencies(_registry: &mut bevy::reflect::TypeRegistry) {} + } + )* + }; +} + +#[macro_export] +macro_rules! self_type_dependency_only { + ($($path:ty),*) => { + $( + impl $crate::bindings::function::script_function::GetInnerTypeDependencies for $path { + fn register_type_dependencies(registry: &mut bevy::reflect::TypeRegistry) { + registry.register::<$path>(); + } + } + )* + }; +} + +macro_rules! recursive_type_dependencies { + ($( ($path:ty where $($bound:ident : $($bound_val:path);*),* $(,,const $const:ident : $const_ty:ty)? $(=> with $self_:ident)?) ),* ) => { + $( + impl<$($bound : $($bound_val +)*),* , $(const $const : $const_ty )?> GetInnerTypeDependencies for $path { + fn register_type_dependencies(registry: &mut TypeRegistry) { + $( + registry.register::<$bound>(); + )* + $( + registry.register::<$self_>(); + )? + } + } + )* + }; +} + +macro_rules! register_tuple_dependencies { + ($($ty:ident),*) => { + impl<$($ty: GetTypeRegistration + Typed),*> GetInnerTypeDependencies for ($($ty,)*) { + fn register_type_dependencies(registry: &mut TypeRegistry) { + $( + registry.register::<$ty>(); + )* + } + } + }; +} + +no_type_dependencies!(InteropError); +self_type_dependency_only!(WorldCallbackAccess, CallerContext, ReflectReference); + +recursive_type_dependencies!( + (Val where T: GetTypeRegistration), + (Ref<'_, T> where T: GetTypeRegistration), + (Mut<'_, T> where T: GetTypeRegistration), + (Result where T: GetTypeRegistration), + ([T; N] where T: GetTypeRegistration;Typed,, const N: usize => with Self), + (Option where T: GetTypeRegistration;FromReflect;Typed => with Self), + (Vec where T: GetTypeRegistration;FromReflect;Typed => with Self), + (HashMap where K: GetTypeRegistration;FromReflect;Typed;Hash;Eq, V: GetTypeRegistration;FromReflect;Typed => with Self) +); + +bevy::utils::all_tuples!(register_tuple_dependencies, 1, 14, T); +pub trait GetFunctionTypeDependencies { + fn register_type_dependencies(registry: &mut TypeRegistry); +} + +/// 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)] +#[reflect(opaque)] +pub struct CallerContext { + pub convert_to_0_indexed: bool, + pub self_type: Option, +} + +/// The Script Function equivalent for dynamic functions. Currently unused +#[derive(Clone, Reflect)] +#[reflect(opaque)] +pub struct DynamicScriptFunction { + name: Cow<'static, str>, + // 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 + + Send + + Sync + + 'static, + >, +} + +impl PartialEq for DynamicScriptFunction { + fn eq(&self, other: &Self) -> bool { + self.name == other.name + } +} + +#[derive(Clone, Reflect)] +#[reflect(opaque)] +pub struct DynamicScriptFunctionMut { + name: Cow<'static, str>, + func: Arc< + RwLock< + // I'd rather consume an option or something instead of having the RWLock but I just wanna get this release out + dyn FnMut(CallerContext, WorldCallbackAccess, Vec) -> ScriptValue + + Send + + Sync + + 'static, + >, + >, +} + +impl PartialEq for DynamicScriptFunctionMut { + fn eq(&self, other: &Self) -> bool { + self.name == other.name + } +} + +impl DynamicScriptFunction { + pub fn call( + &self, + context: CallerContext, + world: WorldCallbackAccess, + args: Vec, + ) -> ScriptValue { + (self.func)(context, world, args) + } + + pub fn name(&self) -> &Cow<'static, str> { + &self.name + } + + pub fn with_name>>(self, name: N) -> Self { + Self { + name: name.into(), + func: self.func, + } + } +} + +impl DynamicScriptFunctionMut { + pub fn call( + &mut self, + context: CallerContext, + world: WorldCallbackAccess, + args: Vec, + ) -> ScriptValue { + let mut write = self.func.write(); + write(context, world, args) + } + + pub fn name(&self) -> &Cow<'static, str> { + &self.name + } + + pub fn with_name>>(self, name: N) -> Self { + Self { + name: name.into(), + func: self.func, + } + } +} + +impl std::fmt::Debug for DynamicScriptFunction { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("DynamicScriptFunction") + .field("name", self.name()) + .finish() + } +} + +impl std::fmt::Debug for DynamicScriptFunctionMut { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("DynamicScriptFunctionMut") + .field("name", self.name()) + .finish() + } +} + +impl From for DynamicScriptFunction +where + F: Fn(CallerContext, WorldCallbackAccess, Vec) -> ScriptValue + + Send + + Sync + + 'static, +{ + fn from(fn_: F) -> Self { + DynamicScriptFunction { + name: std::any::type_name::().into(), + func: Arc::new(fn_), + } + } +} + +impl From for DynamicScriptFunctionMut +where + F: FnMut(CallerContext, WorldCallbackAccess, Vec) -> ScriptValue + + Send + + Sync + + 'static, +{ + fn from(fn_: F) -> Self { + DynamicScriptFunctionMut { + name: std::any::type_name::().into(), + func: Arc::new(RwLock::new(fn_)), + } + } +} + +/// Equivalent to [`AppFunctionRegistry`] but stores functions with a more convenient signature for scripting to avoid boxing every argument. +#[derive(Clone, Debug, Default, Resource)] +pub struct AppScriptFunctionRegistry(ScriptFunctionRegistryArc); + +impl Deref for AppScriptFunctionRegistry { + type Target = ScriptFunctionRegistryArc; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for AppScriptFunctionRegistry { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +#[derive(Clone, Debug, Default)] +pub struct ScriptFunctionRegistryArc(pub Arc>); + +impl ScriptFunctionRegistryArc { + pub fn read(&self) -> RwLockReadGuard { + self.0.read() + } + + pub fn write(&mut self) -> RwLockWriteGuard { + self.0.write() + } +} + +#[derive(Debug, Default)] +pub struct ScriptFunctionRegistry { + functions: HashMap, DynamicScriptFunction>, +} + +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 + F: ScriptFunction<'static, M>, + { + self.register_overload(name, func); + } + + pub fn register_overload(&mut self, 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); + return; + } + + for i in 1..16 { + let overload = format!("{name}-{i}"); + if !self.contains(&overload) { + self.register(overload, func); + return; + } + } + + panic!( + "Could not register overload for function {name}. Maximum number of overloads reached" + ); + } + + pub fn contains(&self, name: impl AsRef) -> bool { + self.functions.contains_key(name.as_ref()) + } + + pub fn get_first(&self, name: impl AsRef) -> Option<&DynamicScriptFunction> { + self.functions.get(name.as_ref()) + } + + pub fn iter_overloads( + &self, + name: impl Into>, + ) -> impl Iterator { + let name = name.into(); + (0..16) + .map(move |i| { + if i == 0 { + self.functions.get(&name) + } else { + let name: Cow<'static, str> = format!("{}-{i}", name).into(); + self.functions.get(&name) + } + }) + .take_while(|o| o.is_some()) + .map(|o| o.unwrap()) + } +} + +macro_rules! count { + () => (0usize); + ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*)); +} + +macro_rules! impl_script_function { + + ($( $param:ident ),* ) => { + // all of this is pretty heavy on the compile time. + // ideally we'd do less, but for now this will suffice + + // Fn(T1...Tn) -> O + impl_script_function!(@ ScriptFunction Fn DynamicScriptFunction into_dynamic_script_function $( $param ),* : -> O => O ); + // FnMut(T1...Tn) -> O + impl_script_function!(@ ScriptFunctionMut FnMut DynamicScriptFunctionMut into_dynamic_script_function_mut $( $param ),* : -> O => O ); + + // Fn(WorldCallbackAccess, T1...Tn) -> O + impl_script_function!(@ ScriptFunction Fn DynamicScriptFunction into_dynamic_script_function $( $param ),* : ,(callback: WorldCallbackAccess) -> O => O); + // FnMut(WorldCallbackAccess, T1...Tn) -> O + impl_script_function!(@ ScriptFunctionMut FnMut DynamicScriptFunctionMut into_dynamic_script_function_mut $( $param ),* : ,(callback: WorldCallbackAccess) -> O => O); + + // Fn(CallerContext, WorldCallbackAccess, T1...Tn) -> O + impl_script_function!(@ ScriptFunction Fn DynamicScriptFunction into_dynamic_script_function $( $param ),* : (context: CallerContext),(callback: WorldCallbackAccess) -> O => O); + // FnMut(CallerContext, WorldCallbackAccess, T1...Tn) -> O + impl_script_function!(@ ScriptFunctionMut FnMut DynamicScriptFunctionMut into_dynamic_script_function_mut $( $param ),* : (context: CallerContext),(callback: WorldCallbackAccess) -> O => O); + + // Fn(T1...Tn) -> Result + impl_script_function!(@ ScriptFunction Fn DynamicScriptFunction into_dynamic_script_function $( $param ),* : -> O => Result where s); + // FnMut(T1...Tn) -> Result + impl_script_function!(@ ScriptFunctionMut FnMut DynamicScriptFunctionMut into_dynamic_script_function_mut $( $param ),* : -> O => Result where s); + + // Fn(WorldCallbackAccess, T1...Tn) -> Result + impl_script_function!(@ ScriptFunction Fn DynamicScriptFunction into_dynamic_script_function $( $param ),* : ,(callback: WorldCallbackAccess) -> O => Result where s); + // FnMut(WorldCallbackAccess, T1...Tn) -> Result + impl_script_function!(@ ScriptFunctionMut FnMut DynamicScriptFunctionMut into_dynamic_script_function_mut $( $param ),* : ,(callback: WorldCallbackAccess) -> O => Result where s); + + // Fn(CallerContext, WorldCallbackAccess, T1...Tn) -> Result + impl_script_function!(@ ScriptFunction Fn DynamicScriptFunction into_dynamic_script_function $( $param ),* : (context: CallerContext),(callback: WorldCallbackAccess) -> O => Result where s); + // FnMut(CallerContext, WorldCallbackAccess, T1...Tn) -> Result + impl_script_function!(@ ScriptFunctionMut FnMut DynamicScriptFunctionMut into_dynamic_script_function_mut $( $param ),* : (context: CallerContext),(callback: WorldCallbackAccess) -> O => Result where s); + + + }; + + (@ $trait_type:ident $fn_type:ident $dynamic_type:ident $trait_fn_name:ident $( $param:ident ),* : $(($context:ident: $contextty:ty))? $(,($callback:ident: $callbackty:ty))? -> O => $res:ty $(where $out:ident)?) => { + #[allow(non_snake_case)] + impl< + 'env, + $( $param: FromScript, )* + O, + F + > $trait_type<'env, + fn( $($contextty,)? $( $callbackty, )? $($param ),* ) -> $res + > for F + where + O: IntoScript + TypePath + GetOwnership, + F: $fn_type( $($contextty,)? $( $callbackty, )? $($param ),* ) -> $res + Send + Sync + 'static, + $( $param::This<'env>: Into<$param>,)* + { + #[allow(unused_mut,unused_variables)] + fn $trait_fn_name(mut self) -> $dynamic_type { + let func = (move |caller_context: CallerContext, world: WorldCallbackAccess, args: Vec | { + let res: Result = (|| { + let expected_arg_count = count!($($param )*); + if args.len() < expected_arg_count { + return Err(InteropError::function_call_error(FunctionError::ArgCountMismatch{ + expected: expected_arg_count, + received: args.len() + })); + } + $( let $context = caller_context; )? + $( let $callback = world.clone(); )? + let world = world.try_read()?; + world.begin_access_scope()?; + let ret = { + let mut current_arg = 0; + let mut arg_iter = args.into_iter(); + $( + current_arg += 1; + let $param = <$param>::from_script(arg_iter.next().expect("invariant"), world.clone()) + .map_err(|e| InteropError::function_arg_conversion_error(current_arg.to_string(), e))?; + )* + let out = self( $( $context,)? $( $callback, )? $( $param.into(), )* ); + $( + let $out = out?; + let out = $out; + )? + out.into_script(world.clone()).map_err(|e| InteropError::function_arg_conversion_error("return value".to_owned(), e)) + }; + // Safety: we're not holding any references to the world, the arguments which might have aliased have been dropped + unsafe { world.end_access_scope()? }; + ret + })(); + let script_value: ScriptValue = res.into(); + script_value + }); + + func.into() + } + } + }; +} + +macro_rules! impl_script_function_type_dependencies{ + ($( $param:ident ),* ) => { + impl GetFunctionTypeDependencies O> for F + where F: Fn( $( $param ),* ) -> O + { + fn register_type_dependencies(registry: &mut TypeRegistry) { + $( + $param::register_type_dependencies(registry); + )* + + O::register_type_dependencies(registry); + } + } + }; +} + +bevy::utils::all_tuples!(impl_script_function, 0, 13, T); +bevy::utils::all_tuples!(impl_script_function_type_dependencies, 0, 13, T); + +#[cfg(test)] +mod test { + use super::*; + #[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"); + } + + #[test] + fn test_overloaded_script_function() { + let mut registry = ScriptFunctionRegistry::default(); + let fn_ = |a: usize, b: usize| a + b; + registry.register("test", fn_); + let fn_2 = |a: usize, b: i32| a + (b as usize); + registry.register("test", fn_2); + + registry.get_first("test").expect("Failed to get function"); + + assert_eq!(registry.iter_overloads("test").collect::>().len(), 2); + } +} diff --git a/crates/bevy_mod_scripting_core/src/bindings/mod.rs b/crates/bevy_mod_scripting_core/src/bindings/mod.rs new file mode 100644 index 00000000..4ce76e72 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/mod.rs @@ -0,0 +1,12 @@ +pub mod access_map; +pub mod allocator; +pub mod function; +pub mod pretty_print; +// pub mod proxy; +pub mod query; +pub mod reference; +pub mod script_value; +pub mod world; + +pub use {allocator::*, query::*, reference::*, world::*}; +// pub use {proxy::*}; diff --git a/crates/bevy_mod_scripting_core/src/bindings/pretty_print.rs b/crates/bevy_mod_scripting_core/src/bindings/pretty_print.rs new file mode 100644 index 00000000..a9ebb814 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/pretty_print.rs @@ -0,0 +1,478 @@ +use crate::reflection_extensions::{FakeType, TypeIdExtensions}; + +use super::{ + script_value::ScriptValue, ReflectBase, ReflectBaseType, ReflectReference, WorldGuard, +}; +use bevy::{ + prelude::World, + reflect::{PartialReflect, ReflectRef}, +}; +use itertools::Itertools; +use std::{any::TypeId, borrow::Cow}; + +pub struct ReflectReferencePrinter { + pub(crate) reference: ReflectReference, +} + +#[derive(Clone, Copy, Debug)] +enum BracketType { + Square, + Curly, + Round, +} + +impl BracketType { + fn open(self) -> char { + match self { + BracketType::Square => '[', + BracketType::Curly => '{', + BracketType::Round => '(', + } + } + + fn close(self) -> char { + match self { + BracketType::Square => ']', + BracketType::Curly => '}', + BracketType::Round => ')', + } + } + + fn surrounded(self, output: &mut String, f: F) { + output.push(self.open()); + f(output); + output.push(self.close()); + } +} + +macro_rules! downcast_case { + ($id:ident, $out:ident, $t:path) => {{ + $out.push_str(stringify!($t)); + $out.push('('); + if let Some($id) = $id.as_partial_reflect().try_downcast_ref::<$t>() { + $out.push_str(&format!("{:?}", $id)); + } else { + $out.push_str(""); + } + $out.push(')'); + }}; +} + +impl ReflectReferencePrinter { + const UNREGISTERED_TYPE: &'static str = "Unregistered"; + const UNKNOWN_FIELD: &'static str = ""; + + pub fn new(reference: ReflectReference) -> Self { + Self { reference } + } + + /// Given a reflect reference, prints the type path of the reference resolving the type names with short names. + /// I.e. `MyType(Component).field_name[0].field_name[1] -> FieldType::Name` + pub fn pretty_print(&self, world: Option) -> String { + let mut pretty_path = String::new(); + + pretty_path.push_str(" {}", type_path)); + } + } else { + Self::pretty_print_base(&self.reference.base, None, &mut pretty_path); + } + pretty_path.push('>'); + pretty_path + } + + /// Prints the actual value of the reference. Tries to use best available method to print the value. + pub fn pretty_print_value(&self, world: Option) -> String { + let mut output = String::new(); + + match world { + Some(world) => { + // instead of relying on type registrations, simply traverse the reflection tree and print sensible values + self.reference + .with_reflect(world, |r| { + self.pretty_print_value_inner(r, &mut output); + }) + .unwrap_or_else(|e| { + output.push_str(&format!("", e)); + }); + } + None => { + output.push_str(""); + } + } + + output + } + + fn pretty_print_base(base: &ReflectBaseType, world: Option, out: &mut String) { + let type_id = base.type_id; + let type_path = if let Some(world) = world { + type_id.display_with_world(world.clone()) + } else { + type_id.display_without_world() + }; + + let base_kind = match base.base_id { + ReflectBase::Component(e, _) => format!("Component on entity {}", e), + ReflectBase::Resource(_) => "Resource".to_owned(), + ReflectBase::Owned(ref id) => format!("Allocation({})", id), + }; + + out.push_str(&format!("{}({})", base_kind, type_path)); + } + pub fn pretty_print_value_opaque(&self, v: &dyn PartialReflect, output: &mut String) { + let type_id = v + .get_represented_type_info() + .map(|t| t.type_id()) + .or_fake_id(); + + output.push_str("Reflect("); + match type_id { + id if id == TypeId::of::() => downcast_case!(v, output, usize), + id if id == TypeId::of::() => downcast_case!(v, output, isize), + id if id == TypeId::of::() => downcast_case!(v, output, f32), + id if id == TypeId::of::() => downcast_case!(v, output, f64), + id if id == TypeId::of::() => downcast_case!(v, output, u128), + id if id == TypeId::of::() => downcast_case!(v, output, u64), + id if id == TypeId::of::() => downcast_case!(v, output, u32), + id if id == TypeId::of::() => downcast_case!(v, output, u16), + id if id == TypeId::of::() => downcast_case!(v, output, u8), + id if id == TypeId::of::() => downcast_case!(v, output, i128), + id if id == TypeId::of::() => downcast_case!(v, output, i64), + id if id == TypeId::of::() => downcast_case!(v, output, i32), + id if id == TypeId::of::() => downcast_case!(v, output, i16), + id if id == TypeId::of::() => downcast_case!(v, output, i8), + id if id == TypeId::of::() => downcast_case!(v, output, String), + id if id == TypeId::of::() => downcast_case!(v, output, bool), + _ => { + output.push_str( + v.get_represented_type_info() + .map(|t| t.type_path()) + .unwrap_or(Self::UNREGISTERED_TYPE), + ); + } + } + output.push(')'); + } + + fn pretty_print_key_values< + K: AsRef, + V: AsRef, + I: IntoIterator, V)>, + >( + bracket: BracketType, + i: I, + output: &mut String, + ) { + bracket.surrounded(output, |output| { + let mut iter = i.into_iter().peekable(); + while let Some((key, val)) = iter.next() { + if let Some(key) = key { + output.push_str(key.as_ref()); + output.push_str(": "); + } + output.push_str(val.as_ref()); + if iter.peek().is_some() { + output.push_str(", "); + } + } + }); + } + + fn pretty_print_value_struct< + 'k, + N: Iterator, + M: Iterator, + >( + &self, + field_names: N, + field_values: M, + output: &mut String, + ) { + let field_names = field_names.into_iter(); + let fields = field_values.into_iter(); + let fields_iter = fields.zip_longest(field_names).map(|e| { + let (val, name) = match e { + itertools::EitherOrBoth::Both(val, name) => (val, name), + itertools::EitherOrBoth::Left(val) => (val, Self::UNKNOWN_FIELD), + itertools::EitherOrBoth::Right(name) => (().as_partial_reflect(), name), + }; + let mut field_printed = String::new(); + self.pretty_print_value_inner(val, &mut field_printed); + (Some(name), field_printed) + }); + Self::pretty_print_key_values(BracketType::Curly, fields_iter, output); + } + + fn pretty_print_value_inner(&self, v: &dyn PartialReflect, output: &mut String) { + match v.reflect_ref() { + bevy::reflect::ReflectRef::Struct(s) => { + let field_names = s + .get_represented_struct_info() + .map(|info| info.field_names()) + .unwrap_or_default() + .iter(); + let field_values = s.iter_fields(); + + self.pretty_print_value_struct(field_names.copied(), field_values, output); + } + ReflectRef::TupleStruct(t) => { + let fields_iter = t.iter_fields().enumerate().map(|(i, val)| { + let mut field_printed = String::new(); + self.pretty_print_value_inner(val, &mut field_printed); + (Some(i.to_string()), field_printed) + }); + Self::pretty_print_key_values(BracketType::Round, fields_iter, output); + } + ReflectRef::Tuple(t) => { + let fields_iter = t.iter_fields().map(|val| { + let mut field_printed = String::new(); + self.pretty_print_value_inner(val, &mut field_printed); + (None::, field_printed) + }); + Self::pretty_print_key_values(BracketType::Round, fields_iter, output); + } + ReflectRef::List(l) => { + let fields_iter = l.iter().map(|val| { + let mut field_printed = String::new(); + self.pretty_print_value_inner(val, &mut field_printed); + (None::, field_printed) + }); + Self::pretty_print_key_values(BracketType::Square, fields_iter, output); + } + ReflectRef::Array(a) => { + let fields_iter = a.iter().map(|val| { + let mut field_printed = String::new(); + self.pretty_print_value_inner(val, &mut field_printed); + (None::, field_printed) + }); + Self::pretty_print_key_values(BracketType::Square, fields_iter, output); + } + ReflectRef::Map(m) => { + let fields_iter = m.iter().map(|(key, val)| { + let mut key_printed = String::new(); + self.pretty_print_value_inner(key, &mut key_printed); + + let mut field_printed = String::new(); + self.pretty_print_value_inner(val, &mut field_printed); + (Some(key_printed), field_printed) + }); + Self::pretty_print_key_values(BracketType::Curly, fields_iter, output); + } + ReflectRef::Set(s) => { + let fields_iter = s.iter().map(|val| { + let mut field_printed = String::new(); + self.pretty_print_value_inner(val, &mut field_printed); + (None::, field_printed) + }); + Self::pretty_print_key_values(BracketType::Curly, fields_iter, output); + } + ReflectRef::Enum(e) => { + output.push_str(&e.variant_path()); + let bracket_type = match e.variant_type() { + bevy::reflect::VariantType::Tuple => BracketType::Round, + _ => BracketType::Curly, + }; + let key_vals = e.iter_fields().map(|v| { + let mut field_printed = String::new(); + self.pretty_print_value_inner(v.value(), &mut field_printed); + (v.name(), field_printed) + }); + Self::pretty_print_key_values(bracket_type, key_vals, output); + } + ReflectRef::Opaque(o) => { + self.pretty_print_value_opaque(o, output); + } + ReflectRef::Function(f) => { + output.push_str("Function("); + output.push_str( + f.info() + .name() + .unwrap_or(&Cow::Borrowed("")) + .as_ref(), + ); + output.push(')'); + } + } + } +} + +// /// Alais for [`DisplayWithWorldAndDummy`] + [`std::fmt::Display`], ideally display should warn that it's not the full representation. +// pub trait DisplayWithWorldAndDummy: DisplayWithWorld + std::fmt::Display {} +// impl DisplayWithWorldAndDummy for T {} + +/// 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 { + fn display_without_world(&self) -> String; + + /// Display the `shallowest` representation of the type using world access. + /// For references this is the type path and the type of the value they are pointing to. + fn display_with_world(&self, world: WorldGuard) -> String; + + /// Display the most literal representation of the type using world access. + /// I.e. for references this would be the pointed to value itself. + fn display_value_with_world(&self, world: WorldGuard) -> String { + self.display_with_world(world) + } +} + +impl DisplayWithWorld for ReflectReference { + fn display_with_world(&self, world: WorldGuard) -> String { + ReflectReferencePrinter::new(self.clone()).pretty_print(Some(world)) + } + + fn display_value_with_world(&self, world: WorldGuard) -> String { + ReflectReferencePrinter::new(self.clone()).pretty_print_value(Some(world)) + } + + fn display_without_world(&self) -> String { + ReflectReferencePrinter::new(self.clone()).pretty_print(None) + } +} + +impl DisplayWithWorld for ReflectBaseType { + fn display_with_world(&self, world: WorldGuard) -> String { + let mut string = String::new(); + ReflectReferencePrinter::pretty_print_base(self, Some(world), &mut string); + string + } + + fn display_value_with_world(&self, world: WorldGuard) -> String { + self.display_with_world(world) + } + + fn display_without_world(&self) -> String { + let mut string = String::new(); + ReflectReferencePrinter::pretty_print_base(self, None, &mut string); + string + } +} + +impl DisplayWithWorld for TypeId { + fn display_with_world(&self, world: WorldGuard) -> String { + if *self == TypeId::of::() { + return "Dynamic Type".to_owned(); + } else if *self == TypeId::of::() { + // does not implement Reflect, so we do this manually + return "World".to_owned(); + } + + let type_registry = world.type_registry(); + let type_registry = type_registry.read(); + + type_registry + .get_type_info(*self) + .map(|t| t.type_path_table().path().to_owned()) + .unwrap_or_else(|| { + format!("{}({:?})", ReflectReferencePrinter::UNREGISTERED_TYPE, self) + }) + .to_string() + } + + fn display_value_with_world(&self, world: WorldGuard) -> String { + self.display_with_world(world) + } + + fn display_without_world(&self) -> String { + format!("{:?}", self) + } +} + +impl DisplayWithWorld for ScriptValue { + fn display_with_world(&self, world: WorldGuard) -> String { + match self { + ScriptValue::Reference(r) => r.display_with_world(world), + _ => self.display_value_with_world(world), + } + } + + fn display_value_with_world(&self, world: WorldGuard) -> String { + match self { + ScriptValue::Reference(r) => r.display_value_with_world(world), + ScriptValue::Function(f) => format!("Function({})", f.name()), + ScriptValue::Unit => "()".to_owned(), + ScriptValue::Bool(b) => b.to_string(), + ScriptValue::Integer(i) => i.to_string(), + ScriptValue::Float(f) => f.to_string(), + ScriptValue::String(cow) => cow.to_string(), + ScriptValue::Error(script_error) => script_error.display_with_world(world), + ScriptValue::List(vec) => vec.display_without_world(), + } + } + + fn display_without_world(&self) -> String { + match self { + ScriptValue::Unit => "()".to_owned(), + ScriptValue::Bool(b) => b.to_string(), + ScriptValue::Integer(i) => i.to_string(), + ScriptValue::Float(f) => f.to_string(), + ScriptValue::String(cow) => cow.to_string(), + ScriptValue::List(vec) => { + let mut string = String::new(); + ReflectReferencePrinter::pretty_print_key_values( + BracketType::Square, + vec.iter() + .map(|v| (None::, v.display_without_world())), + &mut string, + ); + string + } + ScriptValue::Reference(reflect_reference) => reflect_reference.display_without_world(), + ScriptValue::Function(dynamic_script_function_mut) => { + format!("Function({})", dynamic_script_function_mut.name()) + } + ScriptValue::Error(interop_error) => interop_error.display_without_world(), + } + } +} + +impl DisplayWithWorld for Vec { + fn display_with_world(&self, world: WorldGuard) -> String { + let mut string = String::new(); + BracketType::Square.surrounded(&mut string, |string| { + for (i, v) in self.iter().enumerate() { + string.push_str(&v.display_with_world(world.clone())); + if i != self.len() - 1 { + string.push_str(", "); + } + } + }); + string + } + + fn display_value_with_world(&self, world: WorldGuard) -> String { + let mut string = String::new(); + BracketType::Square.surrounded(&mut string, |string| { + for (i, v) in self.iter().enumerate() { + string.push_str(&v.display_value_with_world(world.clone())); + if i != self.len() - 1 { + string.push_str(", "); + } + } + }); + string + } + + fn display_without_world(&self) -> String { + let mut string = String::new(); + BracketType::Square.surrounded(&mut string, |string| { + for (i, v) in self.iter().enumerate() { + string.push_str(&v.display_without_world()); + if i != self.len() - 1 { + string.push_str(", "); + } + } + }); + string + } +} diff --git a/crates/bevy_mod_scripting_core/src/bindings/query.rs b/crates/bevy_mod_scripting_core/src/bindings/query.rs new file mode 100644 index 00000000..d6a438f8 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/query.rs @@ -0,0 +1,201 @@ +use super::{ReflectReference, WorldAccessGuard, WorldCallbackAccess}; +use crate::{error::InteropError, with_global_access}; +use bevy::{ + ecs::{component::ComponentId, entity::Entity}, + prelude::{EntityRef, QueryBuilder}, + reflect::{ParsedPath, Reflect, TypeRegistration}, +}; +use std::{any::TypeId, collections::VecDeque, sync::Arc}; + +/// A wrapper around a `TypeRegistration` that provides additional information about the type. +/// +/// This is used as a hook to a rust type from a scripting language. We should be able to easily convert between a type name and a [`ScriptTypeRegistration`]. +#[derive(Clone, Reflect)] +#[reflect(opaque)] +pub struct ScriptTypeRegistration { + pub(crate) registration: Arc, + pub component_id: Option, + pub resource_id: Option, +} + +impl ScriptTypeRegistration { + pub fn new( + registration: Arc, + component_id: Option, + resource_id: Option, + ) -> Self { + Self { + registration, + component_id, + resource_id, + } + } + + #[inline(always)] + pub fn short_name(&self) -> &'static str { + self.registration.type_info().type_path_table().short_path() + } + + #[inline(always)] + pub fn type_name(&self) -> &'static str { + self.registration.type_info().type_path_table().path() + } + + #[inline(always)] + pub fn type_id(&self) -> TypeId { + self.registration.type_info().type_id() + } + + /// Returns the [`ComponentId`] for this type, if it is a component. + #[inline(always)] + pub fn component_id(&self) -> Option { + self.component_id + } + + /// Returns the [`ComponentId`] for this type, if it is a resource. + #[inline(always)] + pub fn resource_id(&self) -> Option { + self.resource_id + } +} + +impl std::fmt::Debug for ScriptTypeRegistration { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("ScriptTypeRegistration") + .field(&self.registration.type_info().type_path()) + .finish() + } +} + +impl std::fmt::Display for ScriptTypeRegistration { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.registration.type_info().type_path()) + } +} + +#[derive(Clone, Default, Reflect)] +#[reflect(opaque)] +pub struct ScriptQueryBuilder { + components: Vec, + with: Vec, + without: Vec, +} + +impl ScriptQueryBuilder { + pub fn components(&mut self, components: Vec) -> &mut Self { + self.components.extend(components); + self + } + pub fn component(&mut self, component: ScriptTypeRegistration) -> &mut Self { + self.components.push(component); + self + } + + pub fn with_components(&mut self, with: Vec) -> &mut Self { + self.with.extend(with); + self + } + + pub fn with_component(&mut self, with: ScriptTypeRegistration) -> &mut Self { + self.with.push(with); + self + } + + pub fn without_components(&mut self, without: Vec) -> &mut Self { + self.without.extend(without); + self + } + + pub fn without_component(&mut self, without: ScriptTypeRegistration) -> &mut Self { + self.without.push(without); + self + } +} + +#[derive(Clone, Reflect)] +#[reflect(opaque)] +pub struct ScriptQueryResult { + pub entity: Entity, + pub components: Vec, +} + +impl WorldCallbackAccess { + pub fn query( + &self, + query: ScriptQueryBuilder, + ) -> Result, InteropError> { + // find the set of components + self.try_read().and_then(|world| world.query(query)) + } +} + +impl WorldAccessGuard<'_> { + pub fn query( + &self, + query: ScriptQueryBuilder, + ) -> Result, InteropError> { + with_global_access!(self.0.accesses, "Could not query", { + let world = unsafe { self.as_unsafe_world_cell().world_mut() }; + let mut dynamic_query = QueryBuilder::::new(world); + + // we don't actually want to fetch the data for components now, only figure out + // which entities match the query + // so we might be being slightly overkill + for c in &query.components { + dynamic_query.ref_id(c.component_id().ok_or_else(|| { + InteropError::unsupported_operation( + Some(c.type_id()), + None, + "query for component on non-component type".to_owned(), + ) + })?); + } + + for w in query.with { + dynamic_query.with_id(w.component_id.ok_or_else(|| { + InteropError::unsupported_operation( + Some(w.type_id()), + None, + "query for entity with component which is non-component type".to_owned(), + ) + })?); + } + + for without_id in query.without { + dynamic_query.without_id(without_id.component_id.ok_or_else(|| { + InteropError::unsupported_operation( + Some(without_id.type_id()), + None, + "query for entity without component which is non-component type".to_owned(), + ) + })?); + } + + let mut built_query = dynamic_query.build(); + let query_result = built_query.iter(world); + + Ok(query_result + .map(|r| { + let references: Vec<_> = query + .components + .iter() + .map(|c| ReflectReference { + base: super::ReflectBaseType { + type_id: c.type_id(), + base_id: super::ReflectBase::Component( + r.id(), + c.component_id.unwrap(), + ), + }, + reflect_path: ParsedPath(vec![]), + }) + .collect(); + ScriptQueryResult { + entity: r.id(), + components: references, + } + }) + .collect()) + }) + } +} diff --git a/crates/bevy_mod_scripting_core/src/bindings/reference.rs b/crates/bevy_mod_scripting_core/src/bindings/reference.rs new file mode 100644 index 00000000..92948b5a --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/reference.rs @@ -0,0 +1,549 @@ +//! # Motivation +//! +//! Traits and structs needed to support the creation of bindings for scripting languages. +//! reflection gives us access to `dyn PartialReflect` objects via their type name, +//! Scripting languages only really support `Clone` objects so if we want to support references, +//! we need wrapper types which have owned and ref variants. +use super::{access_map::ReflectAccessId, WorldGuard}; +use crate::{ + bindings::ReflectAllocationId, + error::InteropError, + reflection_extensions::{PartialReflectExt, TypeIdExtensions}, + with_access_read, with_access_write, ReflectAllocator, +}; +use bevy::{ + ecs::{ + change_detection::MutUntyped, component::ComponentId, entity::Entity, + world::unsafe_world_cell::UnsafeWorldCell, + }, + prelude::{Component, ReflectDefault, Resource}, + ptr::Ptr, + reflect::{ParsedPath, PartialReflect, Reflect, ReflectFromPtr, ReflectPath}, +}; +use std::{any::TypeId, fmt::Debug}; + +/// An accessor to a `dyn PartialReflect` struct, stores a base ID of the type and a reflection path +/// safe to build but to reflect on the value inside you need to ensure aliasing rules are upheld +#[derive(Debug, Clone, PartialEq, Eq, Reflect)] +#[reflect(Default)] +pub struct ReflectReference { + #[reflect(ignore)] + pub base: ReflectBaseType, + // TODO: experiment with Fixed capacity vec, boxed array etc, compromise between heap allocation and runtime cost + // needs benchmarks first though + /// The path from the top level type to the actual value we want to access + #[reflect(ignore)] + pub reflect_path: ParsedPath, +} + +impl Default for ReflectReference { + fn default() -> Self { + Self { + base: ReflectBaseType { + type_id: None::.or_fake_id(), + base_id: ReflectBase::Owned(ReflectAllocationId::new(0)), + }, + reflect_path: ParsedPath(vec![]), + } + } +} + +/// Specifies where we should source the type id from when reflecting a ReflectReference +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum TypeIdSource { + /// Use the type id the reference points to after walking the path + Tail, + /// Given the Tail referene is a container type, use the type id of the elements in the container + Element, + /// Givent the Tail reference is a container type, use the type id of the keys of the container + Key, +} + +impl ReflectReference { + /// Creates a new infinite iterator. This iterator will keep returning the next element reference forever. + pub fn into_iter_infinite(self) -> ReflectRefIter { + ReflectRefIter::new_indexed(self) + } + + /// If this is a reference to something with a length accessible via reflection, returns that length. + pub fn len(&self, world: WorldGuard) -> Result, InteropError> { + self.with_reflect(world, |r| match r.reflect_ref() { + bevy::reflect::ReflectRef::Struct(s) => Some(s.field_len()), + bevy::reflect::ReflectRef::TupleStruct(ts) => Some(ts.field_len()), + bevy::reflect::ReflectRef::Tuple(t) => Some(t.field_len()), + bevy::reflect::ReflectRef::List(l) => Some(l.len()), + bevy::reflect::ReflectRef::Array(a) => Some(a.len()), + bevy::reflect::ReflectRef::Map(m) => Some(m.len()), + bevy::reflect::ReflectRef::Set(s) => Some(s.len()), + bevy::reflect::ReflectRef::Enum(e) => Some(e.field_len()), + _ => None, + }) + } + + pub fn new_allocated( + value: T, + allocator: &mut ReflectAllocator, + ) -> ReflectReference { + let type_id = value + .get_represented_type_info() + .map(|i| i.type_id()) + .unwrap_or_else(|| { + panic!( + "Type '{}' has no represented type information to allocate with.", + std::any::type_name::() + ) + }); + let id = allocator.allocate(value); + ReflectReference { + base: ReflectBaseType { + type_id, + base_id: ReflectBase::Owned(id), + }, + reflect_path: ParsedPath(Vec::default()), + } + } + + pub fn new_allocated_boxed( + value: Box, + allocator: &mut ReflectAllocator, + ) -> ReflectReference { + let type_id = value + .get_represented_type_info() + .map(|i| i.type_id()) + .unwrap_or_else(|| { + panic!( + "Type '{}' has no represented type information to allocate with.", + std::any::type_name_of_val(value.as_ref()) + ) + }); + let id = allocator.allocate_boxed(value); + ReflectReference { + base: ReflectBaseType { + type_id, + base_id: ReflectBase::Owned(id), + }, + reflect_path: ParsedPath(Vec::default()), + } + } + + pub fn new_resource_ref(world: WorldGuard) -> Option { + let reflect_id = ReflectAccessId::for_resource::(&world.as_unsafe_world_cell())?; + Some(Self { + base: ReflectBaseType { + type_id: TypeId::of::(), + base_id: ReflectBase::Resource(reflect_id.into()), + }, + reflect_path: ParsedPath(Vec::default()), + }) + } + + pub fn new_component_ref(entity: Entity, world: WorldGuard) -> Option { + let reflect_id = ReflectAccessId::for_component::(&world.as_unsafe_world_cell())?; + Some(Self { + base: ReflectBaseType { + type_id: TypeId::of::(), + base_id: ReflectBase::Component(entity, reflect_id.into()), + }, + reflect_path: ParsedPath(Vec::default()), + }) + } + + /// Indexes into the reflect path inside this reference. + /// You can use [`Self::reflect`] and [`Self::reflect_mut`] to get the actual value. + pub fn index_path>(&mut self, index: T) { + self.reflect_path.0.extend(index.into().0); + } + + /// Tries to downcast to the specified type and cloning the value if successful. + pub fn downcast( + &self, + world: WorldGuard, + ) -> Result { + self.with_reflect(world, |r| { + r.try_downcast_ref::() + .cloned() + .ok_or_else(|| InteropError::could_not_downcast(self.clone(), TypeId::of::())) + })? + } + + /// Attempts to create a [`Box`] from the reference. This is possible using a few strategies: + /// - If the reference is to a world, a [`WorldCallbackAccess`] is created and boxed + /// - If the reference is to an allocation with no reflection path and references to it, the value is taken as is. + /// - If the reference has a [`bevy::reflect::ReflectFromReflect`] type data associated with it, the value is cloned using that impl. + /// - If all above fails, [`bevy::reflect::PartialReflect::clone_value`] is used to clone the value. + /// + pub fn to_owned_value( + &self, + world: WorldGuard, + ) -> Result, InteropError> { + if let ReflectBase::Owned(id) = &self.base.base_id { + if self.reflect_path.is_empty() && id.strong_count() == 0 { + let allocator = world.allocator(); + let mut allocator = allocator.write(); + let arc = allocator + .remove(id) + .ok_or_else(|| InteropError::garbage_collected_allocation(self.clone()))?; + + let access_id = ReflectAccessId::for_allocation(id.clone()); + if world.claim_write_access(access_id) { + // Safety: we claim write access, nobody else is accessing this + if unsafe { &*arc.get_ptr() }.try_as_reflect().is_some() { + // Safety: the only accesses exist in this function + unsafe { world.release_access(access_id) }; + return Ok(unsafe { arc.take() }); + } else { + unsafe { world.release_access(access_id) }; + } + } + allocator.insert(id.clone(), arc); + } + } + + self.with_reflect(world.clone(), |r| { + ::from_reflect_or_clone(r, world.clone()) + }) + } + + /// The way to access the value of the reference, that is the pointed-to value. + /// This method is safe to use as it ensures no-one else has aliasing access to the value at the same time. + /// + /// # Panics + /// - if the value is aliased and the access is not allowed + #[track_caller] + pub fn with_reflect O>( + &self, + world: WorldGuard, + f: F, + ) -> Result { + let access_id = ReflectAccessId::for_reference(self.base.base_id.clone()) + .ok_or_else(|| InteropError::unregistered_base(self.base.clone()))?; + with_access_read!( + world.0.accesses, + access_id, + "could not access reflect reference", + { unsafe { self.reflect_unsafe(world.clone()) }.map(f) } + ) + } + + /// The way to access the value of the reference, that is the pointed-to value. + /// This method is safe to use as it ensures no-one else has aliasing access to the value at the same time. + /// + /// # Panics + /// - if the value is aliased and the access is not allowed + #[track_caller] + pub fn with_reflect_mut O>( + &self, + world: WorldGuard, + f: F, + ) -> Result { + let access_id = ReflectAccessId::for_reference(self.base.base_id.clone()) + .ok_or_else(|| InteropError::unregistered_base(self.base.clone()))?; + with_access_write!( + world.0.accesses, + access_id, + "Could not access reflect reference mutably", + { unsafe { self.reflect_mut_unsafe(world.clone()) }.map(f) } + ) + } + + pub fn tail_type_id(&self, world: WorldGuard) -> Result, InteropError> { + if self.reflect_path.is_empty() { + return Ok(Some(self.base.type_id)); + } + self.with_reflect(world, |r| { + r.get_represented_type_info().map(|t| t.type_id()) + }) + } + + pub fn element_type_id(&self, world: WorldGuard) -> Result, InteropError> { + self.with_reflect(world, |r| r.element_type_id()) + } + + pub fn key_type_id(&self, world: WorldGuard) -> Result, InteropError> { + self.with_reflect(world, |r| r.key_type_id()) + } + + pub fn type_id_of( + &self, + source: TypeIdSource, + world: WorldGuard, + ) -> Result, InteropError> { + match source { + TypeIdSource::Tail => self.tail_type_id(world), + TypeIdSource::Element => self.element_type_id(world), + TypeIdSource::Key => self.key_type_id(world), + } + } + + /// Retrieves a reference to the underlying `dyn PartialReflect` type valid for the 'w lifetime of the world cell + /// # Safety + /// + /// - The caller must ensure the cell has permission to access the underlying value + /// - The caller must ensure no aliasing references to the same value exist at all at the same time + /// + /// To do this safely you need to use [`WorldAccessGuard::claim_read_access`] or [`WorldAccessGuard::claim_global_access`] to ensure nobody else is currently accessing the value. + pub unsafe fn reflect_unsafe<'w>( + &self, + world: WorldGuard<'w>, + ) -> Result<&'w dyn PartialReflect, InteropError> { + if let ReflectBase::Owned(id) = &self.base.base_id { + let allocator = world.allocator(); + let allocator = allocator.read(); + + let arc = allocator + .get(id) + .ok_or_else(|| InteropError::garbage_collected_allocation(self.clone()))?; + + // safety: caller promises it's fine :) + return self.walk_path(unsafe { &*arc.get_ptr() }); + } + + let type_registry = world.type_registry(); + let type_registry = type_registry.read(); + + // all Reflect types should have this derived + let from_ptr_data: &ReflectFromPtr = type_registry + .get_type_data(self.base.type_id) + .ok_or_else(|| InteropError::unregistered_base(self.base.clone()))?; + + let ptr = self + .base + .base_id + .clone() + .into_ptr(world.as_unsafe_world_cell()) + .ok_or_else(|| InteropError::unregistered_base(self.base.clone()))?; + + // (Ptr) Safety: we use the same type_id to both + // 1) retrieve the ptr + // 2) retrieve the ReflectFromPtr type data + // (UnsafeWorldCell) Safety: + // we already have access to &world so no &mut world exists + debug_assert_eq!( + from_ptr_data.type_id(), + self.base.type_id, + "Safety invariant violated" + ); + + let base = unsafe { from_ptr_data.as_reflect(ptr) }; + + drop(type_registry); + + self.walk_path(base.as_partial_reflect()) + } + + /// Retrieves mutable reference to the underlying `dyn PartialReflect` type valid for the 'w lifetime of the world cell + /// # Safety + /// - The caller must ensure the cell has permission to access the underlying value + /// - The caller must ensure no other references to the same value exist at all at the same time (even if you have the correct access) + /// + /// To do this safely you need to use [`WorldAccessGuard::claim_write_access`] or [`WorldAccessGuard::claim_global_access`] to ensure nobody else is currently accessing the value. + pub unsafe fn reflect_mut_unsafe<'w>( + &self, + world: WorldGuard<'w>, + ) -> Result<&'w mut dyn PartialReflect, InteropError> { + if let ReflectBase::Owned(id) = &self.base.base_id { + let allocator = world.allocator(); + let allocator = allocator.read(); + let arc = allocator + .get(id) + .ok_or_else(|| InteropError::garbage_collected_allocation(self.clone()))?; + + // Safety: caller promises this is fine :) + return self.walk_path_mut(unsafe { &mut *arc.get_ptr() }); + }; + + let type_registry = world.type_registry(); + let type_registry = type_registry.read(); + + // all Reflect types should have this derived + let from_ptr_data: &ReflectFromPtr = type_registry + .get_type_data(self.base.type_id) + .ok_or_else(|| InteropError::unregistered_base(self.base.clone()))?; + + let ptr = self + .base + .base_id + .clone() + .into_ptr_mut(world.as_unsafe_world_cell()) + .ok_or_else(|| InteropError::unregistered_base(self.base.clone()))?; + + // (Ptr) Safety: we use the same type_id to both + // 1) retrieve the ptr + // 2) retrieve the ReflectFromPtr type data + // (UnsafeWorldCell) Safety: + // we already have access to &world so no &mut world exists + debug_assert_eq!( + from_ptr_data.type_id(), + self.base.type_id, + "Invariant violated" + ); + let base = unsafe { from_ptr_data.as_reflect_mut(ptr.into_inner()) }; + drop(type_registry); + self.walk_path_mut(base.as_partial_reflect_mut()) + } + + fn walk_path<'a>( + &self, + root: &'a dyn PartialReflect, + ) -> Result<&'a dyn PartialReflect, InteropError> { + self.reflect_path + .reflect_element(root) + .map_err(|e| InteropError::reflection_path_error(e.to_string(), Some(self.clone()))) + } + + fn walk_path_mut<'a>( + &self, + root: &'a mut dyn PartialReflect, + ) -> Result<&'a mut dyn PartialReflect, InteropError> { + self.reflect_path + .reflect_element_mut(root) + .map_err(|e| InteropError::reflection_path_error(e.to_string(), Some(self.clone()))) + } +} + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd)] +pub struct ReflectBaseType { + pub type_id: TypeId, + pub base_id: ReflectBase, +} + +/// The Id of the kind of reflection base being pointed to +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd)] +pub enum ReflectBase { + Component(Entity, ComponentId), + Resource(ComponentId), + Owned(ReflectAllocationId), +} + +impl ReflectBase { + /// Retrieves the pointer to the underlying `dyn PartialReflect` object valid for the 'w lifteime of the world cell + /// + /// # Safety + /// - The caller must ensure the cell has permission to access the underlying value + /// - The caller must ensure no aliasing mutable references to the same value exist at the same time + pub unsafe fn into_ptr(self, world: UnsafeWorldCell<'_>) -> Option> { + match self { + ReflectBase::Component(entity, component_id) => { + // Safety: the caller ensures invariants hold + world.get_entity(entity)?.get_by_id(component_id) + } + ReflectBase::Resource(component_id) => { + // Safety: the caller ensures invariants hold + world.get_resource_by_id(component_id) + } + _ => None, + } + } + + /// Retrieves the pointer to the underlying `dyn PartialReflect` object valid for the 'w lifteime of the world cell + /// + /// # Safety + /// - The caller must ensure the cell has permission to access the underlying value + /// - The caller must ensure no aliasing references to the same value exist at all at the same time + pub unsafe fn into_ptr_mut(self, world: UnsafeWorldCell<'_>) -> Option> { + match self { + ReflectBase::Component(entity, component_id) => { + // Safety: the caller ensures invariants hold + world.get_entity(entity)?.get_mut_by_id(component_id) + } + ReflectBase::Resource(component_id) => { + // Safety: the caller ensures invariants hold + world.get_resource_mut_by_id(component_id) + } + _ => None, + } + } +} + +pub trait ReflectionPathExt { + fn convert_to_0_indexed(&mut self); + + fn is_empty(&self) -> bool; + + fn iter(&self) -> impl Iterator; +} + +impl ReflectionPathExt for ParsedPath { + /// Assumes the accesses are 1 indexed and converts them to 0 indexed + fn convert_to_0_indexed(&mut self) { + self.0.iter_mut().for_each(|a| match a.access { + bevy::reflect::Access::FieldIndex(ref mut i) => *i -= 1, + bevy::reflect::Access::TupleIndex(ref mut i) => *i -= 1, + bevy::reflect::Access::ListIndex(ref mut i) => *i -= 1, + _ => {} + }); + } + + fn is_empty(&self) -> bool { + self.0.is_empty() + } + + fn iter(&self) -> impl Iterator { + self.0.iter() + } +} + +/// A generic iterator over any reflected value. +/// Unlike a normal iterator, this one does not have a halting condition, it will keep returning elements forever. +/// The iterator does not try to access the value, it just works out the next index/key to access. +/// You will know you've reached the end when you get an error when trying to access the next element. +#[derive(Debug, Clone)] +pub struct ReflectRefIter { + pub(crate) base: ReflectReference, + // TODO: support maps etc + pub(crate) index: IterationKey, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum IterationKey { + Index(usize), +} + +impl ReflectRefIter { + pub fn new_indexed(base: ReflectReference) -> Self { + Self { + base, + index: IterationKey::Index(0), + } + } + + pub fn index(&self) -> IterationKey { + self.index.clone() + } + + /// Returns the next element in the iterator, it does not have a halting condition + pub fn next_ref(&mut self) -> (ReflectReference, IterationKey) { + let index = self.index(); + let next = match &mut self.index { + IterationKey::Index(i) => { + let mut next = self.base.clone(); + let parsed_path = + ParsedPath::parse(&format!("[{}]", *i)).expect("invariant violated"); + next.index_path(parsed_path); + *i += 1; + next + } + }; + (next, index) + } +} + +impl Iterator for ReflectRefIter { + type Item = Result; + + fn next(&mut self) -> Option { + let result: Result<_, _> = { + match &mut self.index { + IterationKey::Index(i) => { + let mut next = self.base.clone(); + let parsed_path = ParsedPath::parse(&i.to_string()).unwrap(); + next.index_path(parsed_path); + *i += 1; + Ok(next) + } + } + }; + + Some(result) + } +} diff --git a/crates/bevy_mod_scripting_core/src/bindings/script_value.rs b/crates/bevy_mod_scripting_core/src/bindings/script_value.rs new file mode 100644 index 00000000..cbf8ea36 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/script_value.rs @@ -0,0 +1,170 @@ +use std::borrow::Cow; + +use bevy::reflect::{OffsetAccess, ParsedPath, Reflect}; + +use crate::error::InteropError; + +use super::{function::script_function::DynamicScriptFunctionMut, ReflectReference}; + +/// An abstraction of values that can be passed to and from scripts. +/// This allows us to re-use logic between scripting languages. +#[derive(Debug, Clone, PartialEq, Reflect)] +#[reflect(opaque)] +pub enum ScriptValue { + /// Represents the absence of a value. + Unit, + /// Represents a boolean value. + Bool(bool), + /// Represents an integer value with at most 64 bits. + Integer(i64), + /// Represents a floating point value with at most 64 bits. + Float(f64), + /// Represents a string value. + String(Cow<'static, str>), + /// Represents a list of other things passed by value + List(Vec), + /// Represents a reference to a value. + Reference(ReflectReference), + /// A dynamic script function + Function(DynamicScriptFunctionMut), + /// Represents any error, will be thrown when returned to a script + Error(InteropError), +} + +impl ScriptValue { + pub fn type_name(&self) -> String { + match self { + ScriptValue::Unit => "Unit".to_owned(), + ScriptValue::Bool(_) => "Bool".to_owned(), + ScriptValue::Integer(_) => "Integer".to_owned(), + ScriptValue::Float(_) => "Float".to_owned(), + ScriptValue::String(_) => "String".to_owned(), + ScriptValue::List(_) => "List".to_owned(), + ScriptValue::Reference(_) => "Reference".to_owned(), + ScriptValue::Function(_) => "Function".to_owned(), + ScriptValue::Error(_) => "Error".to_owned(), + } + } +} + +impl From<()> for ScriptValue { + fn from(_: ()) -> Self { + ScriptValue::Unit + } +} + +impl From for ScriptValue { + fn from(value: bool) -> Self { + ScriptValue::Bool(value) + } +} + +impl From for ScriptValue { + fn from(value: i64) -> Self { + ScriptValue::Integer(value) + } +} + +impl From for ScriptValue { + fn from(value: f64) -> Self { + ScriptValue::Float(value) + } +} + +impl From<&'static str> for ScriptValue { + fn from(value: &'static str) -> Self { + ScriptValue::String(value.into()) + } +} + +impl From for ScriptValue { + fn from(value: String) -> Self { + ScriptValue::String(value.into()) + } +} + +impl From> for ScriptValue { + fn from(value: Cow<'static, str>) -> Self { + ScriptValue::String(value) + } +} + +impl From> for ScriptValue { + fn from(value: Vec) -> Self { + ScriptValue::List(value) + } +} + +impl From for ScriptValue { + fn from(value: ReflectReference) -> Self { + ScriptValue::Reference(value) + } +} + +impl From for ScriptValue { + fn from(value: InteropError) -> Self { + ScriptValue::Error(value) + } +} + +impl> From> for ScriptValue { + fn from(value: Option) -> Self { + match value { + Some(v) => v.into(), + None => ScriptValue::Unit, + } + } +} + +impl, E: Into> From> for ScriptValue { + fn from(value: Result) -> Self { + match value { + Ok(v) => v.into(), + Err(e) => ScriptValue::Error(e.into()), + } + } +} + +impl TryFrom for ParsedPath { + type Error = InteropError; + fn try_from(value: ScriptValue) -> Result { + Ok(match value { + ScriptValue::Integer(i) => ParsedPath::from(vec![OffsetAccess { + access: bevy::reflect::Access::ListIndex(i as usize), + offset: Some(1), + }]), + ScriptValue::Float(_) => { + return Err(InteropError::invalid_index( + value, + "Floating point numbers cannot be used to index into reflected values" + .to_owned(), + )) + } + ScriptValue::String(cow) => { + if let Some(tuple_struct_index) = cow.strip_prefix("_") { + if let Ok(index) = tuple_struct_index.parse::() { + let parsed_path = ParsedPath::from(vec![OffsetAccess { + access: bevy::reflect::Access::TupleIndex(index), + offset: Some(1), + }]); + return Ok(parsed_path); + } + } + + match cow { + Cow::Borrowed(v) => ParsedPath::parse_static(v) + .map_err(|e| InteropError::reflection_path_error(e.to_string(), None))?, + Cow::Owned(o) => ParsedPath::parse(&o) + .map_err(|e| InteropError::reflection_path_error(e.to_string(), None))?, + } + } + ScriptValue::Reference(reflect_reference) => { + return Err(InteropError::invalid_index( + ScriptValue::Reference(reflect_reference), + "References cannot be used to index into reflected values".to_owned(), + )) + } + _ => ParsedPath(vec![]), + }) + } +} diff --git a/crates/bevy_mod_scripting_core/src/bindings/world.rs b/crates/bevy_mod_scripting_core/src/bindings/world.rs new file mode 100644 index 00000000..613adab2 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/world.rs @@ -0,0 +1,1846 @@ +//! # Motivation +//! +//! Traits and structs needed to support the creation of bindings for scripting languages. +//! reflection gives us access to `dyn PartialReflect` objects via their type name, +//! Scripting languages only really support `Clone` objects so if we want to support references, +//! we need wrapper types which have owned and ref variants. + +use super::{ + access_map::{AccessCount, AccessMap, ReflectAccessId}, + AppReflectAllocator, ReflectBase, ReflectBaseType, ReflectReference, ScriptTypeRegistration, +}; +use crate::{error::InteropError, with_access_read, with_access_write, with_global_access}; +use bevy::{ + app::AppExit, + ecs::{ + component::{Component, ComponentId}, + entity::Entity, + reflect::{AppTypeRegistry, ReflectComponent, ReflectFromWorld, ReflectResource}, + system::{Commands, Resource}, + world::{unsafe_world_cell::UnsafeWorldCell, CommandQueue, Mut, World}, + }, + hierarchy::{BuildChildren, Children, DespawnRecursiveExt, Parent}, + reflect::{std_traits::ReflectDefault, ParsedPath, Reflect, TypeRegistryArc}, +}; +use std::{ + any::TypeId, + fmt::Debug, + sync::{Arc, Weak}, + time::Duration, +}; + +/// Prefer to directly using [`WorldAccessGuard`]. If the underlying type changes, this alias will be updated. +pub type WorldGuard<'w> = Arc>; +/// Similar to [`WorldGuard`], but without the arc, use for when you don't need the outer Arc. +pub type WorldGuardRef<'w> = &'w WorldAccessGuard<'w>; + +/// While [`WorldAccessGuard`] prevents aliasing at runtime and also makes sure world exists at least as long as the guard itself, +/// borrows sadly do not persist the script-host boundary :(. That is to be expected, but instead we can make an abstraction which removes the lifetime parameter, making the outer type 'static, +/// while making sure the lifetime is still satisfied! +#[derive(Clone, Debug, Reflect)] +#[reflect(opaque)] +pub struct WorldCallbackAccess(pub(crate) Weak>); + +impl WorldCallbackAccess { + /// Wraps a callback which requires access to the world in a 'static way via [`WorldCallbackAccess`]. + pub fn with_callback_access( + world: &mut World, + callback: impl FnOnce(&WorldCallbackAccess) -> T, + ) -> T { + // - the world cannot be dropped before the world drops since we have mutable reference to it in this entire function + // - nothing can alias inappropriately WorldAccessGuard since it's only instance is behind the raw Arc + let world_guard_arc = Arc::new(WorldAccessGuard::new(world)); + let world_guard = unsafe { WorldCallbackAccess::new(Arc::downgrade(&world_guard_arc)) }; + callback(&world_guard) + } + + /// Creates a new [`WorldCallbackAccess`] with an erased lifetime. + /// + /// For safe alternative see [`Self::from_guard`] + /// + /// # Safety + /// - The caller must ensure the [`WorldAccessGuard`] will not outlive the 'w lifetime + /// - In practice this means that between the moment the original Arc is dropped, the lifetime 'w must be valid + /// - I.e. you *must* drop the original [`Arc`] before the original 'w scope ends + pub unsafe fn new<'w>(world: Weak>) -> Self { + // Safety: the caller ensures `WorldAccessGuard` does not outlive the original lifetime 'w + + let world = unsafe { + std::mem::transmute::>, Weak>>( + world, + ) + }; + + Self(world) + } + + pub fn from_guard(world: WorldGuard<'_>) -> Self { + // Safety: the caller ensures `WorldAccessGuard` does not outlive the original lifetime 'w + unsafe { Self::new(Arc::downgrade(&world)) } + } + + /// Attempts to read the world access guard, if it still exists + pub fn try_read(&self) -> Result, InteropError> { + self.0 + .upgrade() + .ok_or_else(InteropError::stale_world_access) + } +} + +/// common world methods, see: +/// - [`crate::bindings::query`] for query related functionality +impl WorldCallbackAccess { + pub fn spawn(&self) -> Result { + let world = self.try_read()?; + Ok(world.spawn()) + } + + // TODO: uses `String` for type_name to avoid lifetime issues with types proxying this via macros + pub fn get_type_by_name( + &self, + type_name: String, + ) -> Result, InteropError> { + let world = self.try_read()?; + Ok(world.get_type_by_name(type_name)) + } + + pub fn add_default_component( + &self, + entity: Entity, + registration: ScriptTypeRegistration, + ) -> Result<(), InteropError> { + let world = self.try_read()?; + world.add_default_component(entity, registration) + } + + pub fn get_component( + &self, + entity: Entity, + component_id: ComponentId, + ) -> Result, InteropError> { + let world = self.try_read()?; + world.get_component(entity, component_id) + } + + pub fn has_component( + &self, + entity: Entity, + component_id: ComponentId, + ) -> Result { + let world = self.try_read()?; + world.has_component(entity, component_id) + } + + pub fn remove_component( + &self, + entity: Entity, + registration: ScriptTypeRegistration, + ) -> Result<(), InteropError> { + let world = self.try_read()?; + world.remove_component(entity, registration) + } + + pub fn get_resource( + &self, + resource_id: ComponentId, + ) -> Result, InteropError> { + let world = self.try_read()?; + world.get_resource(resource_id) + } + + pub fn remove_resource( + &self, + registration: ScriptTypeRegistration, + ) -> Result<(), InteropError> { + let world = self.try_read()?; + world.remove_resource(registration) + } + + pub fn has_resource(&self, resource_id: ComponentId) -> Result { + let world = self.try_read()?; + Ok(world.has_resource(resource_id)) + } + + pub fn has_entity(&self, entity: Entity) -> Result { + let world = self.try_read()?; + Ok(world.has_entity(entity)) + } + + pub fn get_children(&self, entity: Entity) -> Result, InteropError> { + let world = self.try_read()?; + world.get_children(entity) + } + + pub fn get_parent(&self, entity: Entity) -> Result, InteropError> { + let world = self.try_read()?; + world.get_parent(entity) + } + + pub fn push_children(&self, parent: Entity, children: &[Entity]) -> Result<(), InteropError> { + let world = self.try_read()?; + world.push_children(parent, children) + } + + pub fn remove_children(&self, parent: Entity, children: &[Entity]) -> Result<(), InteropError> { + let world = self.try_read()?; + world.remove_children(parent, children) + } + + pub fn insert_children( + &self, + parent: Entity, + index: usize, + children: &[Entity], + ) -> Result<(), InteropError> { + let world = self.try_read()?; + world.insert_children(parent, index, children) + } + + pub fn despawn_recursive(&self, entity: Entity) -> Result<(), InteropError> { + let world = self.try_read()?; + world.despawn_recursive(entity) + } + + pub fn despawn(&self, entity: Entity) -> Result<(), InteropError> { + let world = self.try_read()?; + world.despawn(entity) + } + + pub fn despawn_descendants(&self, entity: Entity) -> Result<(), InteropError> { + let world = self.try_read()?; + world.despawn_descendants(entity) + } + + pub fn exit(&self) -> Result<(), InteropError> { + let world = self.try_read()?; + world.exit(); + Ok(()) + } +} + +pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(5); +pub const DEFAULT_INTERVAL: Duration = Duration::from_millis(10); + +/// Provides safe access to the world via [`WorldAccess`] permissions, which enforce aliasing rules at runtime in multi-thread environments +#[derive(Clone)] +pub struct WorldAccessGuard<'w>(pub(crate) Arc>); + +/// Used to decrease the stack size of [`WorldAccessGuard`] +pub(crate) struct WorldAccessGuardInner<'w> { + cell: UnsafeWorldCell<'w>, + // TODO: this is fairly hefty, explore sparse sets, bit fields etc + pub(crate) accesses: AccessMap, + /// 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, +} + +impl<'w> WorldAccessGuard<'w> { + /// Creates a new [`WorldAccessGuard`] for the given mutable borrow of the world + pub fn new(world: &'w mut World) -> Self { + let type_registry = world + .get_resource::() + .expect("Type registry not present, cannot create world access guard") + .0 + .clone(); + + let allocator = world + .get_resource::() + .expect("Reflect allocator not present, cannot create world access guard") + .clone(); + + Self(Arc::new(WorldAccessGuardInner { + cell: world.as_unsafe_world_cell(), + accesses: Default::default(), + allocator, + type_registry, + })) + } + + /// Begins a new access scope. Currently this simply throws an erorr if there are any accesses held. Should only be used in a single-threaded context + pub(crate) fn begin_access_scope(&self) -> Result<(), InteropError> { + if self.0.accesses.count_accesses() != 0 { + return Err(InteropError::invalid_access_count(self.0.accesses.count_accesses(), 0, "When beginning access scope, presumably for a function call, some accesses are still held".to_owned())); + } + + Ok(()) + } + + /// Ends the access scope, releasing all accesses. Should only be used in a single-threaded context + pub(crate) unsafe fn end_access_scope(&self) -> Result<(), InteropError> { + self.0.accesses.release_all_accesses(); + + Ok(()) + } + + /// Purely debugging utility to list all accesses currently held. + pub fn list_accesses(&self) -> Vec<(ReflectAccessId, AccessCount)> { + self.0.accesses.list_accesses() + } + + /// Retrieves the underlying unsafe world cell, with no additional guarantees of safety + /// proceed with caution and only use this if you understand what you're doing + pub fn as_unsafe_world_cell(&self) -> UnsafeWorldCell<'w> { + self.0.cell + } + + /// Retrieves the underlying read only unsafe world cell, with no additional guarantees of safety + /// proceed with caution and only use this if you understand what you're doing + pub fn as_unsafe_world_cell_readonly(&self) -> UnsafeWorldCell<'w> { + self.0.cell + } + + /// Gets the component id of the given component or resource + pub fn get_component_id(&self, id: TypeId) -> Option { + self.0.cell.components().get_id(id) + } + + pub fn get_resource_id(&self, id: TypeId) -> Option { + self.0.cell.components().get_resource_id(id) + } + + pub fn get_access_location( + &self, + raid: ReflectAccessId, + ) -> Option> { + self.0.accesses.access_location(raid) + } + + #[track_caller] + pub fn claim_read_access(&self, raid: ReflectAccessId) -> bool { + self.0.accesses.claim_read_access(raid) + } + + #[track_caller] + pub fn claim_write_access(&self, raid: ReflectAccessId) -> bool { + self.0.accesses.claim_write_access(raid) + } + + /// Releases read or write access to the given type. + /// + /// # Safety + /// - This can only be called safely after all references to the type created using the access have been dropped + /// - You can only call this if you previously called one of: [`WorldAccessGuard::claim_read_access`] or [`WorldAccessGuard::claim_write_access`] + /// - The number of claim and release calls for the same id must always match + pub unsafe fn release_access(&self, raid: ReflectAccessId) { + self.0.accesses.release_access(raid) + } + + pub fn claim_global_access(&self) -> bool { + self.0.accesses.claim_global_access() + } + + /// Releases global access to the world + /// + /// # Safety + /// - This can only be called safely after all references created using the access have been dropped + pub unsafe fn release_global_access(&self) { + self.0.accesses.release_global_access() + } + + pub fn type_registry(&self) -> TypeRegistryArc { + self.0.type_registry.clone() + } + + 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 + // } + + /// Safely accesses the resource by claiming and releasing access to it. + /// + /// # Panics + /// - if the resource does not exist + pub fn with_resource(&self, f: F) -> O + where + R: Resource, + F: FnOnce(&R) -> O, + { + let access_id = ReflectAccessId::for_resource::(&self.0.cell) + .unwrap_or_else(|| panic!("Resource does not exist: {}", std::any::type_name::())); + + with_access_read!( + self.0.accesses, + access_id, + format!("Could not access resource: {}", std::any::type_name::()), + { + // Safety: we have acquired access for the duration of the closure + f(unsafe { self.0.cell.get_resource::().expect("invariant") }) + } + ) + } + + /// Safely accesses the resource by claiming and releasing access to it. + /// + /// # Panics + /// - if the resource does not exist + pub fn with_resource_mut(&self, f: F) -> O + where + R: Resource, + F: FnOnce(Mut) -> O, + { + let access_id = ReflectAccessId::for_resource::(&self.0.cell) + .unwrap_or_else(|| panic!("Resource does not exist: {}", std::any::type_name::())); + + with_access_write!( + self.0.accesses, + access_id, + format!("Could not access resource: {}", std::any::type_name::()), + { + // Safety: we have acquired access for the duration of the closure + f(unsafe { self.0.cell.get_resource_mut::().expect("invariant") }) + } + ) + } + + /// Safely accesses the component by claiming and releasing access to it. + /// + /// # Panics + /// - if the component does not exist + pub fn with_component(&self, entity: Entity, f: F) -> O + where + T: Component, + F: FnOnce(Option<&T>) -> O, + { + let access_id = ReflectAccessId::for_component::(&self.0.cell) + .unwrap_or_else(|| panic!("Component does not exist: {}", std::any::type_name::())); + + with_access_read!( + self.0.accesses, + access_id, + format!("Could not access component: {}", std::any::type_name::()), + { + // Safety: we have acquired access for the duration of the closure + f(unsafe { self.0.cell.get_entity(entity).and_then(|e| e.get::()) }) + } + ) + } + + /// Safely accesses the component by claiming and releasing access to it. + /// + /// # Panics + /// - if the component does not exist + pub fn with_component_mut(&self, entity: Entity, f: F) -> O + where + T: Component, + F: FnOnce(Option>) -> O, + { + let access_id = ReflectAccessId::for_component::(&self.0.cell) + .unwrap_or_else(|| panic!("Component does not exist: {}", std::any::type_name::())); + + with_access_write!( + self.0.accesses, + access_id, + format!("Could not access component: {}", std::any::type_name::()), + { + // Safety: we have acquired access for the duration of the closure + f(unsafe { + self.0 + .cell + .get_entity(entity) + .and_then(|e| e.get_mut::()) + }) + } + ) + } + + // #[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(), + // )) + // } + // } + + /// checks if a given entity exists and is valid + pub fn is_valid_entity(&self, entity: Entity) -> bool { + self.0.cell.get_entity(entity).is_some() + } +} + +/// Impl block for higher level world methods +impl WorldAccessGuard<'_> { + pub fn spawn(&self) -> Entity { + with_global_access!(self.0.accesses, "Could not spawn entity", { + // Safety we have global access + let entity = unsafe { self.0.cell.world_mut().spawn_empty() }; + entity.id() + }) + } + + pub fn get_type_by_name(&self, type_name: String) -> Option { + let type_registry = self.type_registry(); + let type_registry = type_registry.read(); + type_registry + .get_with_short_type_path(&type_name) + .or_else(|| type_registry.get_with_type_path(&type_name)) + .map(|registration| { + ScriptTypeRegistration::new( + Arc::new(registration.clone()), + self.get_component_id(registration.type_id()), + self.get_resource_id(registration.type_id()), + ) + }) + } + + pub fn add_default_component( + &self, + entity: Entity, + registration: ScriptTypeRegistration, + ) -> Result<(), InteropError> { + let component_data = registration + .registration + .data::() + .ok_or_else(|| { + InteropError::missing_type_data( + registration.registration.type_id(), + "ReflectComponent".to_owned(), + ) + })?; + + // we look for ReflectDefault or ReflectFromWorld data then a ReflectComponent data + let instance = if let Some(default_td) = registration.registration.data::() + { + default_td.default() + } else if let Some(from_world_td) = registration.registration.data::() { + with_global_access!(self.0.accesses, "Could not add default component", { + let world = unsafe { self.0.cell.world_mut() }; + from_world_td.from_world(world) + }) + } else { + return Err(InteropError::missing_type_data( + registration.registration.type_id(), + "ReflectDefault or ReflectFromWorld".to_owned(), + )); + }; + + // TODO: this shouldn't need entire world access it feels + with_global_access!(self.0.accesses, "Could not add default component", { + let type_registry = self.type_registry(); + let world = unsafe { self.0.cell.world_mut() }; + + let mut entity = world + .get_entity_mut(entity) + .map_err(|_| InteropError::missing_entity(entity))?; + { + let registry = type_registry.read(); + component_data.insert(&mut entity, instance.as_partial_reflect(), ®istry); + } + Ok(()) + }) + } + + pub fn get_component( + &self, + entity: Entity, + component_id: ComponentId, + ) -> Result, InteropError> { + let entity = self + .0 + .cell + .get_entity(entity) + .ok_or_else(|| InteropError::missing_entity(entity))?; + + let component_info = self + .0 + .cell + .components() + .get_info(component_id) + .ok_or_else(|| InteropError::invalid_component(component_id))?; + + if entity.contains_id(component_id) { + Ok(Some(ReflectReference { + base: ReflectBaseType { + type_id: component_info + .type_id() + .expect("Component does not have type id"), + base_id: ReflectBase::Component(entity.id(), component_id), + }, + reflect_path: ParsedPath(vec![]), + })) + } else { + Ok(None) + } + } + + pub fn has_component( + &self, + entity: Entity, + component_id: ComponentId, + ) -> Result { + let entity = self + .0 + .cell + .get_entity(entity) + .ok_or_else(|| InteropError::missing_entity(entity))?; + + Ok(entity.contains_id(component_id)) + } + + pub fn remove_component( + &self, + entity: Entity, + registration: ScriptTypeRegistration, + ) -> Result<(), InteropError> { + let component_data = registration + .registration + .data::() + .ok_or_else(|| { + InteropError::missing_type_data( + registration.registration.type_id(), + "ReflectComponent".to_owned(), + ) + })?; + + // TODO: this shouldn't need entire world access it feels + with_global_access!(self.0.accesses, "Could not remove component", { + let world = unsafe { self.0.cell.world_mut() }; + let mut entity = world + .get_entity_mut(entity) + .map_err(|_| InteropError::missing_entity(entity))?; + component_data.remove(&mut entity); + Ok(()) + }) + } + + pub fn get_resource( + &self, + resource_id: ComponentId, + ) -> Result, InteropError> { + let component_info = match self.0.cell.components().get_info(resource_id) { + Some(info) => info, + None => return Ok(None), + }; + + Ok(Some(ReflectReference { + base: ReflectBaseType { + type_id: component_info + .type_id() + .expect("Resource does not have type id"), + base_id: ReflectBase::Resource(resource_id), + }, + reflect_path: ParsedPath(vec![]), + })) + } + + pub fn remove_resource( + &self, + registration: ScriptTypeRegistration, + ) -> Result<(), InteropError> { + let component_data = registration + .registration + .data::() + .ok_or_else(|| { + InteropError::missing_type_data( + registration.registration.type_id(), + "ReflectResource".to_owned(), + ) + })?; + + // TODO: this shouldn't need entire world access it feels + with_global_access!(self.0.accesses, "Could not remove resource", { + let world = unsafe { self.0.cell.world_mut() }; + component_data.remove(world); + Ok(()) + }) + } + + pub fn has_resource(&self, resource_id: ComponentId) -> bool { + // Safety: we are not reading the value at all + let res_ptr = unsafe { self.0.cell.get_resource_by_id(resource_id) }; + res_ptr.is_some() + } + + pub fn has_entity(&self, entity: Entity) -> bool { + self.is_valid_entity(entity) + } + + pub fn get_children(&self, entity: Entity) -> Result, InteropError> { + if !self.is_valid_entity(entity) { + return Err(InteropError::missing_entity(entity)); + } + + self.with_component(entity, |c: Option<&Children>| { + Ok(c.map(|c| c.to_vec()).unwrap_or_default()) + }) + } + + pub fn get_parent(&self, entity: Entity) -> Result, InteropError> { + if !self.is_valid_entity(entity) { + return Err(InteropError::missing_entity(entity)); + } + + self.with_component(entity, |c: Option<&Parent>| Ok(c.map(|c| c.get()))) + } + + pub fn push_children(&self, parent: Entity, children: &[Entity]) -> Result<(), InteropError> { + // verify entities exist + if !self.is_valid_entity(parent) { + return Err(InteropError::missing_entity(parent)); + } + for c in children { + if !self.is_valid_entity(*c) { + return Err(InteropError::missing_entity(*c)); + } + } + + with_global_access!(self.0.accesses, "Could not push children", { + let world = unsafe { self.0.cell.world_mut() }; + let mut queue = CommandQueue::default(); + let mut commands = Commands::new(&mut queue, world); + commands.entity(parent).add_children(children); + queue.apply(world); + }); + + Ok(()) + } + + pub fn remove_children(&self, parent: Entity, children: &[Entity]) -> Result<(), InteropError> { + if !self.is_valid_entity(parent) { + return Err(InteropError::missing_entity(parent)); + } + + for c in children { + if !self.is_valid_entity(*c) { + return Err(InteropError::missing_entity(*c)); + } + } + + with_global_access!(self.0.accesses, "Could not remove children", { + let world = unsafe { self.0.cell.world_mut() }; + let mut queue = CommandQueue::default(); + let mut commands = Commands::new(&mut queue, world); + commands.entity(parent).remove_children(children); + queue.apply(world); + }); + + Ok(()) + } + + pub fn insert_children( + &self, + parent: Entity, + index: usize, + children: &[Entity], + ) -> Result<(), InteropError> { + if !self.is_valid_entity(parent) { + return Err(InteropError::missing_entity(parent)); + } + + for c in children { + if !self.is_valid_entity(*c) { + return Err(InteropError::missing_entity(*c)); + } + } + + with_global_access!(self.0.accesses, "Could not insert children", { + let world = unsafe { self.0.cell.world_mut() }; + let mut queue = CommandQueue::default(); + let mut commands = Commands::new(&mut queue, world); + commands.entity(parent).insert_children(index, children); + queue.apply(world); + }); + + Ok(()) + } + + pub fn despawn_recursive(&self, parent: Entity) -> Result<(), InteropError> { + if !self.is_valid_entity(parent) { + return Err(InteropError::missing_entity(parent)); + } + + with_global_access!(self.0.accesses, "Could not despawn entity", { + let world = unsafe { self.0.cell.world_mut() }; + let mut queue = CommandQueue::default(); + let mut commands = Commands::new(&mut queue, world); + commands.entity(parent).despawn_recursive(); + queue.apply(world); + }); + + Ok(()) + } + + pub fn despawn(&self, entity: Entity) -> Result<(), InteropError> { + if !self.is_valid_entity(entity) { + return Err(InteropError::missing_entity(entity)); + } + + with_global_access!(self.0.accesses, "Could not despawn entity", { + let world = unsafe { self.0.cell.world_mut() }; + let mut queue = CommandQueue::default(); + let mut commands = Commands::new(&mut queue, world); + commands.entity(entity).despawn(); + queue.apply(world); + }); + + Ok(()) + } + + pub fn despawn_descendants(&self, parent: Entity) -> Result<(), InteropError> { + if !self.is_valid_entity(parent) { + return Err(InteropError::missing_entity(parent)); + } + + with_global_access!(self.0.accesses, "Could not despawn descendants", { + let world = unsafe { self.0.cell.world_mut() }; + let mut queue = CommandQueue::default(); + let mut commands = Commands::new(&mut queue, world); + commands.entity(parent).despawn_descendants(); + queue.apply(world); + }); + + Ok(()) + } + + /// Sends AppExit event to the world with success status + pub fn exit(&self) { + with_global_access!(self.0.accesses, "Could not exit the app", { + let world = unsafe { self.0.cell.world_mut() }; + world.send_event(AppExit::Success); + }); + } +} + +// #[cfg(test)] +// mod test { +// use crate::bindings::ScriptTypeRegistration; +// use crate::prelude::ScriptErrorKind; +// use bevy::ecs::system::Commands; +// use bevy::hierarchy::BuildChildren; +// use bevy::reflect::{ParsedPath, Reflect}; + +// use super::*; +// use std::any::TypeId; + +// use crate::{ +// bindings::ReflectAllocator, +// bindings::{ +// DeferredReflection, ReflectBase, ReflectBaseType, ReflectReference, ReflectionPathElem, +// }, +// }; + +// use bevy::ecs::world::World; +// use test_utils::test_data::{ +// setup_world, CompWithFromWorld, GetTestComponentId, TestComponent, TestResource, +// }; + +// fn init_world() -> World { +// setup_world(|w, _| { +// w.init_resource::(); +// }) +// } + +// /// Tests that the given ref_ can be accessed and the value is as expected and access is released correctly (not for allocated values) +// fn assert_access_yields< +// O: Reflect + PartialEq + Debug, +// F: FnOnce(&mut World) -> ReflectReference, +// G: FnOnce(&WorldAccessGuard), +// >( +// init: F, +// post_check: G, +// expected: O, +// ) { +// let mut world = init_world(); +// let ref_ = init(&mut world); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let world = world.read().unwrap(); + +// // test read +// ref_.with_reflect(&world, |reflect| { +// let orig = reflect.try_downcast_ref::(); + +// let orig = match orig { +// Some(v) => v, +// None => { +// panic!( +// "Could not downcast value {reflect:?} to {}", +// std::any::type_name::() +// ) +// } +// }; + +// assert_eq!(orig, &expected); +// }); + +// assert!( +// world +// .get_component_access(TestComponent::test_component_id(), true) +// .is_some(), +// "access to component was not release correctly" +// ); + +// assert!( +// world +// .get_resource_access(TestResource::test_component_id()) +// .is_some(), +// "access to component was not release correctly" +// ); + +// post_check(&world); +// }); +// } + +// /// Tests that setting to the expected value works as well as follow up reads give the expected value +// fn assert_set_then_get_yields< +// O: Reflect + PartialEq + Debug + Clone, +// F: FnOnce(&mut World) -> ReflectReference, +// G: FnOnce(&WorldAccessGuard), +// >( +// init: F, +// post_check: G, +// expected: O, +// ) { +// let mut world = init_world(); +// let ref_ = init(&mut world); +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let world = world.read().unwrap(); +// // test set +// ref_.with_reflect_mut(&world, |reflect, _, _| { +// let orig = reflect.try_downcast_mut::(); + +// let orig = match orig { +// Some(v) => v, +// None => { +// panic!( +// "Could not downcast value {reflect:?} to {}", +// std::any::type_name::() +// ) +// } +// }; + +// *orig = expected.clone(); +// }); + +// // test read +// ref_.with_reflect(&world, |reflect, _, _| { +// let orig = reflect.try_downcast_ref::(); + +// let orig = match orig { +// Some(v) => v, +// None => { +// panic!( +// "Could not downcast value {reflect:?} to {}", +// std::any::type_name::() +// ) +// } +// }; + +// assert_eq!(orig, &expected); +// }); +// post_check(&world); +// }); +// } + +// #[test] +// fn test_component_access() { +// let init = |world: &mut World| { +// let entity = world +// .spawn(TestComponent { +// strings: vec![String::from("initial")], +// }) +// .id(); + +// ReflectReference { +// base: ReflectBaseType { +// base_id: ReflectBase::Component(entity, TestComponent::test_component_id()), +// type_id: TypeId::of::(), +// }, +// reflect_path: vec![ +// ReflectionPathElem::Reflection(ParsedPath::parse_static(".strings").unwrap()), +// ReflectionPathElem::DeferredReflection(DeferredReflection { +// get: Arc::new(|root| { +// let strings = root.try_downcast_ref::>().unwrap(); +// Ok(strings.first().unwrap()) +// }), +// get_mut: Arc::new(|root| { +// let strings = root.try_downcast_mut::>().unwrap(); +// Ok(strings.first_mut().unwrap()) +// }), +// }), +// ], +// } +// }; + +// assert_access_yields(init, |_| {}, String::from("initial")); +// assert_set_then_get_yields(init, |_| {}, String::from("set")); +// } + +// #[test] +// fn test_resource_access() { +// let init = |world: &mut World| { +// world.insert_resource(TestResource { bytes: vec![42u8] }); + +// ReflectReference { +// base: ReflectBaseType { +// base_id: ReflectBase::Resource(TestResource::test_component_id()), +// type_id: TypeId::of::(), +// }, +// reflect_path: vec![ +// ReflectionPathElem::Reflection(ParsedPath::parse_static(".bytes").unwrap()), +// ReflectionPathElem::DeferredReflection(DeferredReflection { +// get: Arc::new(|root| { +// let strings = root.try_downcast_ref::>().unwrap(); +// Ok(strings.first().unwrap()) +// }), +// get_mut: Arc::new(|root| { +// let strings = root.try_downcast_mut::>().unwrap(); +// Ok(strings.first_mut().unwrap()) +// }), +// }), +// ], +// } +// }; +// assert_access_yields(init, |_| {}, 42u8); +// assert_set_then_get_yields(init, |_| {}, 69u8); +// } + +// #[test] +// fn test_script_alloc_access() { +// let init = |world: &mut World| { +// let mut script_allocator = ReflectAllocator::default(); +// let mut ref_ = ReflectReference::new_allocated( +// TestComponent { +// strings: vec![String::from("initial")], +// }, +// &mut script_allocator, +// ); +// ref_.index_path(ParsedPath::parse_static(".strings").unwrap()); +// ref_.index_path(DeferredReflection { +// get: Arc::new(|root| { +// let strings = root.try_downcast_ref::>().unwrap(); +// Ok(strings.first().unwrap()) +// }), +// get_mut: Arc::new(|root| { +// let strings = root.try_downcast_mut::>().unwrap(); +// Ok(strings.first_mut().unwrap()) +// }), +// }); +// world.insert_resource(script_allocator); +// ref_ +// }; +// let post_check = |world: &WorldAccessGuard| { +// assert!( +// world +// .get_allocation_access(ReflectAllocationId(0)) +// .is_some(), +// "allocation access was not released correctly" +// ); +// }; +// assert_access_yields(init, post_check, String::from("initial")); +// assert_set_then_get_yields(init, post_check, String::from("set")); +// } + +// #[test] +// #[allow(clippy::drop_non_drop)] +// fn test_invalid_runtime_access() { +// let mut world = World::new(); +// let world = WorldAccessGuard::new(&mut world); +// let access = world.get_component_access(ComponentId::new(0)); +// assert!( +// world.get_component_access(ComponentId::new(0)).is_none(), +// "access was allowed to alias" +// ); +// drop(access); +// } + +// fn get_reg(world: &WorldCallbackAccess, name: &str) -> ScriptTypeRegistration { +// world +// .get_type_by_name(name.to_owned()) +// .expect("Type not found") +// } + +// fn test_comp_reg(world: &WorldCallbackAccess) -> ScriptTypeRegistration { +// world +// .get_type_by_name("TestComponent".to_owned()) +// .expect("Component not found") +// } + +// fn test_resource_reg(world: &WorldCallbackAccess) -> ScriptTypeRegistration { +// world +// .get_type_by_name("TestResource".to_owned()) +// .expect("Resource not found") +// } + +// #[test] +// fn test_get_type_by_name() { +// let mut world = init_world(); +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let comp_reg = world.get_type_by_name("TestComponent".to_owned()).unwrap(); +// let resource_reg = world.get_type_by_name("TestResource".to_owned()).unwrap(); + +// assert_eq!( +// comp_reg.registration.type_info().type_id(), +// std::any::TypeId::of::() +// ); +// assert_eq!( +// resource_reg.registration.type_info().type_id(), +// std::any::TypeId::of::() +// ); +// }); +// } + +// #[test] +// fn test_get_type_by_name_invalid() { +// let mut world = init_world(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let comp_reg = world.get_type_by_name("x".to_owned()); +// let resource_reg = world.get_type_by_name("z".to_owned()); + +// assert!(comp_reg.is_none()); +// assert!(resource_reg.is_none()); +// }); +// } + +// #[test] +// fn test_add_default_component_from_world() { +// let mut world = init_world(); + +// let entity = world.spawn_empty().id(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let comp_reg = get_reg(world, "CompWithFromWorld"); +// world.add_default_component(entity, comp_reg).unwrap() +// }); + +// assert_eq!( +// world.get_entity(entity).unwrap().get::(), +// Some(&CompWithFromWorld(String::from("FromWorld"))) +// ); +// } + +// #[test] +// fn test_add_default_component_default() { +// let mut world = init_world(); + +// let entity = world.spawn_empty().id(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let comp_reg = get_reg(world, "CompWithFromWorld"); +// world.add_default_component(entity, comp_reg).unwrap() +// }); + +// assert_eq!( +// world.get_entity(entity).unwrap().get::(), +// Some(&CompWithFromWorld(String::from("Default"))) +// ); +// } + +// #[test] +// fn test_add_default_component_missing_from_world_and_default() { +// let mut world = init_world(); + +// let entity = world.spawn_empty().id(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let comp_reg = get_reg(world, "CompWithFromWorld"); +// match world.add_default_component(entity, comp_reg.clone()) { +// Ok(_) => { +// panic!("Expected error") +// } +// Err(ScriptError(inner)) => { +// assert_eq!(inner.kind, ScriptErrorKind::RuntimeError); +// assert_eq!(inner.reason.to_string(), format!("Cannot add default component since type: `{}`, Does not have ReflectDefault or ReflectFromWorld data registered.", comp_reg.registration.type_info().type_path())); +// } +// } +// }); +// } + +// #[test] +// fn test_add_default_component_missing_component_data() { +// let mut world = init_world(); + +// let entity = world.spawn_empty().id(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let comp_reg = get_reg(world, "CompWithFromWorld"); +// match world.add_default_component(entity, comp_reg.clone()) { +// Ok(_) => { +// panic!("Expected error") +// } +// Err(ScriptError(inner)) => { +// assert_eq!(inner.kind, ScriptErrorKind::RuntimeError); +// assert_eq!(inner.reason.to_string(), format!("Cannot add default component since type: `{}`, Does not have ReflectComponent data registered.", comp_reg.registration.type_info().type_path())); +// } +// } +// }); +// } + +// #[test] +// fn test_get_component_existing() { +// let mut world = init_world(); + +// let entity = world.spawn(TestComponent { strings: vec![] }).id(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let comp_ref = world +// .get_component(entity, TestComponent::test_component_id()) +// .unwrap() +// .unwrap(); +// assert_eq!( +// comp_ref, +// ReflectReference { +// base: ReflectBaseType { +// type_id: std::any::TypeId::of::(), +// base_id: ReflectBase::Component(entity, TestComponent::test_component_id()), +// }, +// reflect_path: Default::default(), +// } +// ); +// }); +// } + +// #[test] +// fn test_get_component_missing() { +// let mut world = init_world(); + +// let entity = world.spawn_empty().id(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let comp_ref = world +// .get_component(entity, TestComponent::test_component_id()) +// .unwrap(); +// assert_eq!(comp_ref, None); +// }); +// } + +// #[test] +// fn test_get_component_missing_entity() { +// let mut world = init_world(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let comp_ref = +// world.get_component(Entity::from_raw(0), TestComponent::test_component_id()); +// match comp_ref { +// Ok(_) => { +// panic!("Expected error") +// } +// Err(e) => { +// assert_eq!(e.kind, ScriptErrorKind::RuntimeError); +// assert_eq!(e.reason.to_string(), "Entity does not exist: 0v1"); +// } +// } +// }); +// } + +// #[test] +// fn test_get_component_unregistered_component() { +// let mut world = init_world(); + +// let entity = world.spawn_empty().id(); +// let fake_id = ComponentId::new(999); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let comp_ref = world.get_component(entity, fake_id); +// match comp_ref { +// Ok(_) => { +// panic!("Expected error") +// } +// Err(e) => { +// assert_eq!(e.kind, ScriptErrorKind::RuntimeError); +// assert_eq!( +// e.reason.to_string(), +// format!("Component does not exist: {fake_id:?}"), +// ); +// } +// } +// }); +// } + +// #[test] +// fn test_remove_component() { +// let mut world = init_world(); + +// let entity = world +// .spawn(TestComponent { +// strings: vec![String::from("strings")], +// }) +// .id(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// world +// .remove_component(entity, test_comp_reg(world)) +// .unwrap(); +// }); + +// assert_eq!( +// world.get_entity(entity).unwrap().get::(), +// None +// ); +// } + +// #[test] +// fn test_remove_component_empty_idempotent() { +// let mut world = init_world(); + +// let entity = world.spawn_empty().id(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// world +// .remove_component(entity, test_comp_reg(world)) +// .unwrap(); +// }); + +// assert_eq!( +// world.get_entity(entity).unwrap().get::(), +// None +// ); +// } + +// #[test] +// fn test_remove_component_missing_comp_registration() { +// let mut world = init_world(); + +// let entity = world.spawn_empty().id(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let result = world.remove_component(entity, test_resource_reg(world)); +// match result { +// Ok(_) => { +// panic!("Expected error") +// } +// Err(e) => { +// assert_eq!(e.kind, ScriptErrorKind::RuntimeError); +// assert_eq!( +// e.reason.to_string(), +// format!("Cannot remove component since type: `{}`, Does not have ReflectComponent data registered.", test_resource_reg(world).registration.type_info().type_path()) +// ); +// } +// } +// }); + +// assert_eq!( +// world.get_entity(entity).unwrap().get::(), +// None +// ); +// } + +// #[test] +// fn test_remove_component_missing_entity() { +// let mut world = init_world(); + +// let fake_entity = Entity::from_raw(0); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let result = world.remove_component(fake_entity, test_comp_reg(world)); +// match result { +// Ok(_) => { +// panic!("Expected error") +// } +// Err(e) => { +// assert_eq!(e.kind, ScriptErrorKind::RuntimeError); +// assert_eq!(e.reason.to_string(), "Entity does not exist: 0v1"); +// } +// } +// }); +// } + +// #[test] +// fn test_get_resource_existing() { +// let mut world = init_world(); + +// world.insert_resource(TestResource { bytes: vec![1] }); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let comp_ref = world +// .get_resource(TestResource::test_component_id()) +// .unwrap() +// .unwrap(); +// assert_eq!( +// comp_ref, +// ReflectReference { +// base: ReflectBaseType { +// type_id: std::any::TypeId::of::(), +// base_id: ReflectBase::Resource(TestResource::test_component_id()), +// }, +// reflect_path: Default::default(), +// } +// ); +// }); +// } + +// #[test] +// fn test_get_resource_non_existing() { +// let mut world = init_world(); + +// let fake_comp = ComponentId::new(999); +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let comp_ref = world.get_resource(fake_comp); +// match comp_ref { +// Ok(None) => {} +// e => { +// panic!("Expected ok with none, got: {:?}", e); +// } +// } +// }); +// } + +// #[test] +// fn test_remove_resource() { +// let mut world = init_world(); + +// world.insert_resource(TestResource { bytes: vec![1] }); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// world.remove_resource(test_resource_reg(world)).unwrap(); +// }); + +// assert_eq!(world.get_resource::(), None); +// } + +// #[test] +// fn test_remove_resource_missing_idempotent() { +// let mut world = init_world(); + +// world.remove_resource::(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// world.remove_resource(test_resource_reg(world)).unwrap(); +// }); + +// assert_eq!(world.get_resource::(), None); +// } + +// #[test] +// fn test_remove_resource_missing_resource_registration() { +// let mut world = init_world(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// match world.remove_resource(test_comp_reg(world)) { +// Ok(_) => panic!("Expected error"), +// Err(e) => { +// assert_eq!(e.kind, ScriptErrorKind::RuntimeError); +// assert_eq!(e.reason.to_string(), format!("Cannot remove resource since type: `{}`, Does not have ReflectResource data registered.", test_comp_reg(world).registration.type_info().type_path())); +// } +// } +// }); +// } + +// #[test] +// fn test_has_resource_existing() { +// let mut world = init_world(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// assert!(world.has_resource(TestResource::test_component_id())); +// }); +// } + +// #[test] +// fn test_has_resource_missing() { +// let mut world = init_world(); + +// world.remove_resource::(); +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// assert!(world.has_resource(TestResource::test_component_id())); +// }); +// } + +// #[test] +// fn test_get_children_1_child() { +// let mut world = init_world(); + +// let parent = world.spawn_empty().id(); +// let child = world.spawn_empty().id(); +// let mut cmnds = CommandQueue::default(); +// let mut cmnd = Commands::new(&mut cmnds, &world); +// cmnd.entity(parent).add_children(&[child]); +// cmnds.apply(&mut world); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let children = world.get_children(parent).unwrap(); +// assert_eq!(children.len(), 1); +// assert_eq!(children[0], child); +// }); +// } + +// #[test] +// #[should_panic( +// expected = "Component not registered: `bevy_hierarchy::components::children::Children`" +// )] +// fn test_get_children_children_component_unregistered() { +// let mut world = init_world(); + +// let parent = world.spawn_empty().id(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// world.get_children(parent).unwrap(); +// }); +// } + +// #[test] +// fn test_get_children_no_children() { +// let mut world = init_world(); + +// world.register_component::(); +// let parent = world.spawn_empty().id(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let children = world.get_children(parent).unwrap(); +// assert_eq!(children.len(), 0); +// }); +// } + +// #[test] +// fn test_get_parent_1_parent() { +// let mut world = init_world(); + +// let parent = world.spawn_empty().id(); +// let child = world.spawn_empty().id(); +// let mut cmnds = CommandQueue::default(); +// let mut cmnd = Commands::new(&mut cmnds, &world); +// cmnd.entity(parent).add_children(&[child]); +// cmnds.apply(&mut world); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let found_parent = world.get_parent(child).unwrap(); +// assert_eq!(found_parent, Some(parent)); +// }); +// } + +// #[test] +// fn test_get_parent_no_parent() { +// let mut world = init_world(); + +// world.register_component::(); + +// let child = world.spawn_empty().id(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// let found_parent = world.get_parent(child).unwrap(); +// assert_eq!(found_parent, None); +// }); +// } + +// #[test] +// #[should_panic( +// expected = "Component not registered: `bevy_hierarchy::components::parent::Parent`" +// )] +// fn test_get_parent_parent_component_unregistered() { +// let mut world = init_world(); + +// let child = world.spawn_empty().id(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// world.get_parent(child).unwrap(); +// }); +// } + +// #[test] +// fn test_push_children_empty_entity() { +// let mut world = init_world(); + +// let parent = world.spawn_empty().id(); +// let child = world.spawn_empty().id(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// world.push_children(parent, &[child]).unwrap(); +// }); + +// let children = world.get::(parent).unwrap(); +// assert_eq!(children.len(), 1); +// assert_eq!(children[0], child); +// } + +// #[test] +// fn test_push_children_entity_with_1_child() { +// let mut world = init_world(); + +// let parent = world.spawn_empty().id(); +// let child = world.spawn_empty().id(); +// let mut cmnds = CommandQueue::default(); +// let mut cmnd = Commands::new(&mut cmnds, &world); +// cmnd.entity(parent).add_children(&[child]); +// cmnds.apply(&mut world); + +// let child_2 = world.spawn_empty().id(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// world.push_children(parent, &[child_2]).unwrap(); +// }); + +// let children = world.get::(parent).unwrap(); +// assert_eq!(children.len(), 2); +// assert_eq!(children[0], child); +// assert_eq!(children[1], child_2); +// } + +// #[test] +// fn test_remove_children_entity_with_1_child() { +// let mut world = init_world(); + +// let parent = world.spawn_empty().id(); +// let child = world.spawn_empty().id(); +// let mut cmnds = CommandQueue::default(); +// let mut cmnd = Commands::new(&mut cmnds, &world); +// cmnd.entity(parent).add_children(&[child]); +// cmnds.apply(&mut world); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// world.remove_children(parent, &[child]).unwrap(); +// }); + +// let children = world.get::(parent); +// assert!(children.is_none()); +// } + +// #[test] +// fn test_remove_children_remove_half_children() { +// let mut world = init_world(); + +// let parent = world.spawn_empty().id(); +// let child = world.spawn_empty().id(); +// let child_2 = world.spawn_empty().id(); +// let mut cmnds = CommandQueue::default(); +// let mut cmnd = Commands::new(&mut cmnds, &world); +// cmnd.entity(parent).add_children(&[child, child_2]); +// cmnds.apply(&mut world); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// world.remove_children(parent, &[child]).unwrap(); +// }); + +// let children = world.get::(parent).unwrap(); +// assert_eq!(children.len(), 1); +// assert_eq!(children[0], child_2); +// } + +// #[test] +// fn test_insert_children_empty() { +// let mut world = init_world(); + +// let parent = world.spawn_empty().id(); +// let child = world.spawn_empty().id(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// world.insert_children(parent, 0, &[child]).unwrap(); +// }); + +// let children = world.get::(parent).unwrap(); +// assert_eq!(children.len(), 1); +// assert_eq!(children[0], child); +// } + +// #[test] +// fn test_insert_children_middle() { +// let mut world = init_world(); + +// let parent = world.spawn_empty().id(); +// let child = world.spawn_empty().id(); +// let child_2 = world.spawn_empty().id(); +// let mut cmnds = CommandQueue::default(); +// let mut cmnd = Commands::new(&mut cmnds, &world); +// cmnd.entity(parent).add_children(&[child, child_2]); +// cmnds.apply(&mut world); + +// let child_to_insert = world.spawn_empty().id(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// world +// .insert_children(parent, 1, &[child_to_insert]) +// .unwrap(); +// }); + +// let children = world.get::(parent).unwrap(); +// assert_eq!(children.len(), 3); +// assert_eq!(children[0], child); +// assert_eq!(children[1], child_to_insert); +// assert_eq!(children[2], child_2); +// } + +// #[test] +// fn test_despawn_entity() { +// let mut world = init_world(); + +// let entity = world.spawn_empty().id(); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// world.despawn(entity).unwrap(); +// }); + +// assert!(world.get_entity(entity).is_err()); +// } + +// #[test] +// fn test_despawn_recursive() { +// let mut world = init_world(); + +// let parent = world.spawn_empty().id(); +// let child = world.spawn_empty().id(); +// let mut cmnds = CommandQueue::default(); +// let mut cmnd = Commands::new(&mut cmnds, &world); +// cmnd.entity(parent).add_children(&[child]); +// cmnds.apply(&mut world); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// world.despawn_recursive(parent).unwrap(); +// }); + +// assert!(world.get_entity(parent).is_err()); +// assert!(world.get_entity(child).is_err()); +// } + +// #[test] +// fn test_despawn_descendants() { +// let mut world = init_world(); + +// let parent = world.spawn_empty().id(); +// let child = world.spawn_empty().id(); +// let mut cmnds = CommandQueue::default(); +// let mut cmnd = Commands::new(&mut cmnds, &world); +// cmnd.entity(parent).add_children(&[child]); +// cmnds.apply(&mut world); + +// WorldCallbackAccess::with_callback_access(&mut world, |world| { +// world.despawn_descendants(parent).unwrap(); +// }); + +// assert!(world.get_entity(parent).is_ok()); +// assert!(world.get_entity(child).is_err()); +// } +// } diff --git a/crates/bevy_mod_scripting_core/src/commands.rs b/crates/bevy_mod_scripting_core/src/commands.rs new file mode 100644 index 00000000..86d289d3 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/commands.rs @@ -0,0 +1,210 @@ +use crate::{ + asset::ScriptAsset, + context::{ContextLoadingSettings, ScriptContexts}, + event::{IntoCallbackLabel, OnScriptLoaded, OnScriptUnloaded}, + handler::CallbackSettings, + runtime::RuntimeContainer, + script::{Script, ScriptId, Scripts}, + systems::handle_script_errors, + IntoScriptPluginParams, +}; +use bevy::{asset::Handle, ecs::world::Mut, log::debug, prelude::Command}; +use std::{any::type_name, marker::PhantomData}; + +pub struct DeleteScript { + pub id: ScriptId, + // hack to make this Send, C does not need to be Send since it is not stored in the command + pub _ph: PhantomData, +} + +impl DeleteScript

{ + pub fn new(id: ScriptId) -> Self { + Self { + id, + _ph: PhantomData, + } + } +} + +impl Command for DeleteScript

{ + fn apply(self, world: &mut bevy::prelude::World) { + let settings = world + .get_resource::>() + .expect("No ScriptLoadingSettings resource found") + .clone(); + + let runner = world + .get_resource::>() + .expect("No CallbackSettings resource found") + .callback_handler + .expect("No callback handler set"); + + let mut ctxts = world + .remove_non_send_resource::>() + .unwrap(); + + let mut runtime_container = world + .remove_non_send_resource::>() + .unwrap(); + + world.resource_scope(|world, mut scripts: Mut| { + if let Some(script) = scripts.scripts.remove(&self.id) { + debug!("Deleting script with id: {}", self.id); + + // first let the script uninstall itself + match (runner)( + vec![], + bevy::ecs::entity::Entity::from_raw(0), + &self.id, + &OnScriptUnloaded::into_callback_label(), + ctxts.get_mut(script.context_id).unwrap(), + &settings.context_pre_handling_initializers, + &mut runtime_container.runtime, + world, + ) { + 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()); + } + } + + let assigner = settings + .assigner + .as_ref() + .expect("Could not find context assigner in settings"); + debug!("Removing script with id: {}", self.id); + (assigner.remove)(script.context_id, &script, &mut ctxts) + } else { + bevy::log::error!( + "Attempted to delete script with id: {} but it does not exist, doing nothing!", + self.id + ); + } + }); + + world.insert_resource(settings); + world.insert_non_send_resource(ctxts); + world.insert_non_send_resource(runtime_container); + } +} + +/// Creates new script with the given ID, if a script with the given ID already exists, this is treated as an update +/// +/// If script comes from an asset, expects it to be loaded, otherwise this command will fail to process the script. +pub struct CreateOrUpdateScript { + id: ScriptId, + content: Box<[u8]>, + asset: Option>, + // Hack to make this Send, C does not need to be Send since it is not stored in the command + _ph: std::marker::PhantomData, +} + +impl CreateOrUpdateScript

{ + pub fn new(id: ScriptId, content: Box<[u8]>, asset: Option>) -> Self { + Self { + id, + content, + asset, + _ph: std::marker::PhantomData, + } + } +} + +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() + .clone(); + let mut contexts = world + .remove_non_send_resource::>() + .unwrap(); + let mut runtime = world + .remove_non_send_resource::>() + .unwrap(); + + let runner = world.get_resource::>().unwrap(); + // assign context + let assigner = settings.assigner.clone().expect("No context assigner set"); + let builder = settings.loader.clone().expect("No context loader set"); + let runner = runner.callback_handler.expect("No callback handler set"); + + world.resource_scope(|world, mut scripts: Mut| { + + // check if script already exists + + 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: {:?})", + 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); + + 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()); + return; + } + } + }; + + + if let Some(previous) = previous_context_id { + if previous != current_context_id { + debug!( + "Script is being moved to a new context with id: {}, removing up old context.", + current_context_id + ); + script.as_deref_mut().unwrap().context_id = current_context_id; + (assigner.remove)(previous, script.unwrap(), &mut contexts); + } + } + + 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()); + }, + } + + // 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); + world.insert_non_send_resource(contexts); + } +} diff --git a/crates/bevy_mod_scripting_core/src/context.rs b/crates/bevy_mod_scripting_core/src/context.rs new file mode 100644 index 00000000..b548f623 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/context.rs @@ -0,0 +1,160 @@ +use crate::{ + error::ScriptError, + script::{Script, ScriptId}, + IntoScriptPluginParams, +}; +use bevy::ecs::{entity::Entity, system::Resource, world::World}; +use std::{collections::HashMap, sync::atomic::AtomicU32}; + +pub trait Context: 'static {} +impl Context for T {} + +pub type ContextId = u32; + +#[derive(Resource)] +pub struct ScriptContexts { + pub(crate) contexts: HashMap, +} + +impl Default for ScriptContexts

{ + fn default() -> Self { + Self { + contexts: Default::default(), + } + } +} + +static CONTEXT_ID_COUNTER: AtomicU32 = AtomicU32::new(0); +impl ScriptContexts

{ + pub fn new() -> Self { + Self { + contexts: HashMap::new(), + } + } + + /// Allocates a new ContextId and inserts the context into the map + pub fn insert(&mut self, ctxt: P::C) -> ContextId { + let id = CONTEXT_ID_COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + self.contexts.insert(id, ctxt); + id + } + + /// Allocate new context id without inserting a context + pub fn allocate_id(&self) -> ContextId { + CONTEXT_ID_COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed) + } + + pub fn remove(&mut self, id: ContextId) -> Option { + self.contexts.remove(&id) + } + + pub fn get(&self, id: ContextId) -> Option<&P::C> { + self.contexts.get(&id) + } + + pub fn get_mut(&mut self, id: ContextId) -> Option<&mut P::C> { + self.contexts.get_mut(&id) + } +} + +/// Initializer run once after creating a context but before executing it for the first time +pub type ContextInitializer

= + fn(&str, &mut

::C) -> Result<(), ScriptError>; +/// Initializer run every time before executing or loading a script +pub type ContextPreHandlingInitializer

= + fn(&str, Entity, &mut

::C) -> Result<(), ScriptError>; + +#[derive(Resource)] +pub struct ContextLoadingSettings { + pub loader: Option>, + pub assigner: Option>, + pub context_initializers: Vec>, + pub context_pre_handling_initializers: Vec>, +} + +impl Default for ContextLoadingSettings

{ + fn default() -> Self { + Self { + loader: None, + assigner: None, + context_initializers: Default::default(), + context_pre_handling_initializers: Default::default(), + } + } +} + +impl Clone for ContextLoadingSettings

{ + fn clone(&self) -> Self { + Self { + loader: self.loader.clone(), + assigner: self.assigner.clone(), + context_initializers: self.context_initializers.clone(), + context_pre_handling_initializers: self.context_pre_handling_initializers.clone(), + } + } +} + +/// A strategy for loading and reloading contexts +pub struct ContextBuilder { + pub load: fn( + script: &ScriptId, + content: &[u8], + context_initializers: &[ContextInitializer

], + pre_handling_initializers: &[ContextPreHandlingInitializer

], + world: &mut World, + runtime: &mut P::R, + ) -> Result, + pub reload: fn( + script: &ScriptId, + new_content: &[u8], + context: &mut P::C, + context_initializers: &[ContextInitializer

], + pre_handling_initializers: &[ContextPreHandlingInitializer

], + world: &mut World, + runtime: &mut P::R, + ) -> Result<(), ScriptError>, +} + +impl Clone for ContextBuilder

{ + fn clone(&self) -> Self { + Self { + load: self.load, + reload: self.reload, + } + } +} + +/// A strategy for assigning contexts to new and existing but re-loaded scripts as well as for managing old contexts +pub struct ContextAssigner { + /// Assign a context to the script, if script is `None`, this is a new script, otherwise it is an existing script with a context inside `contexts`. + /// Returning None means the script should be assigned a new context + pub assign: fn( + old_script: Option<&Script>, + script_id: &ScriptId, + new_content: &[u8], + contexts: &ScriptContexts

, + ) -> Option, + + /// Handle the removal of the script, if any clean up in contexts is necessary perform it here. + /// This will also be called, when a script is assigned a contextId on reload different from the previous one + /// the context_id in that case will be the old context_id and the one stored in the script will be the old one + pub remove: fn(context_id: ContextId, script: &Script, contexts: &mut ScriptContexts

), +} + +impl Default for ContextAssigner

{ + fn default() -> Self { + Self { + assign: |old, _, _, _| old.map(|s| s.context_id), + remove: |id, _, c| _ = c.remove(id), + } + } +} + +impl Clone for ContextAssigner

{ + fn clone(&self) -> Self { + Self { + assign: self.assign, + remove: self.remove, + } + } +} diff --git a/crates/bevy_mod_scripting_core/src/docs.rs b/crates/bevy_mod_scripting_core/src/docs.rs index 8a2a2dfd..d186bcfe 100644 --- a/crates/bevy_mod_scripting_core/src/docs.rs +++ b/crates/bevy_mod_scripting_core/src/docs.rs @@ -1,10 +1,24 @@ -use crate::error::ScriptError; +use bevy::ecs::system::Resource; -/// A documentation piece exported by an `APIProvider` -pub trait DocFragment: 'static { +/// A documentation piece which can be used to make a piece of documentation, most often a module. +pub trait DocumentationFragment: 'static + Sized { + /// Merges two documentation fragments into one, retaining the title of the first fragment. fn merge(self, o: Self) -> Self; - fn gen_docs(self) -> Result<(), ScriptError>; + fn gen_docs(self) -> Result<(), Box>; /// Retrieves the name of the documentation fragment, most likely the name of your game! fn name(&self) -> &'static str; } + +#[derive(Resource)] +pub struct Documentation { + pub fragments: Vec, +} + +impl Default for Documentation { + fn default() -> Self { + Self { + fragments: Default::default(), + } + } +} diff --git a/crates/bevy_mod_scripting_core/src/error.rs b/crates/bevy_mod_scripting_core/src/error.rs index 3f0dd2be..e8902de5 100644 --- a/crates/bevy_mod_scripting_core/src/error.rs +++ b/crates/bevy_mod_scripting_core/src/error.rs @@ -1,30 +1,867 @@ -use thiserror::Error; - -#[derive(Error, Debug, Clone)] -pub enum ScriptError { - #[error("Runtime error in script `{script}` {msg}")] - RuntimeError { script: String, msg: String }, - #[error("Failed to load script asset for `{script}` {msg}")] - FailedToLoad { script: String, msg: String }, - #[error("Syntax error for script `{script}` {msg}")] - SyntaxError { script: String, msg: String }, - #[error("Callback method `{callback}` invalid for script `{script}` {msg}")] - InvalidCallback { - script: String, - callback: String, - msg: String, - }, - #[error("Failed to attach API for script `{script}` {msg}")] - FailedToAttachAPI { script: String, msg: String }, - #[error("Failed to generate documentation `{0}`")] - DocGenError(String), - #[error("{0}")] - Other(String), +use crate::bindings::{ + access_map::DisplayCodeLocation, pretty_print::DisplayWithWorld, script_value::ScriptValue, + ReflectBaseType, ReflectReference, +}; +use bevy::{ + ecs::component::ComponentId, + prelude::Entity, + reflect::{func::FunctionError, PartialReflect, Reflect}, +}; +use std::{ + any::TypeId, + fmt::{Debug, Display}, + ops::Deref, + str::Utf8Error, + sync::Arc, +}; + +pub type ScriptResult = Result; + +/// An error with an optional script Context +#[derive(Debug, Clone, PartialEq, Reflect)] +#[reflect(opaque)] +pub struct ScriptError(pub Arc); + +impl std::error::Error for ScriptError {} + +impl Deref for ScriptError { + type Target = ScriptErrorInner; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +/// The innards are separated to reduce the size of this error +#[derive(Debug)] +pub struct ScriptErrorInner { + pub script: Option, + pub context: String, + pub reason: ErrorKind, +} + +#[derive(Debug, Clone)] +pub enum ErrorKind { + Display(Arc), + WithWorld(Arc), +} + +impl DisplayWithWorld for ErrorKind { + fn display_with_world(&self, world: crate::bindings::WorldGuard) -> String { + match self { + ErrorKind::Display(e) => e.to_string(), + ErrorKind::WithWorld(e) => e.display_with_world(world), + } + } + + fn display_without_world(&self) -> String { + match self { + ErrorKind::Display(e) => e.to_string(), + ErrorKind::WithWorld(e) => e.display_without_world(), + } + } +} + +impl Display for ErrorKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.display_without_world()) + } +} + +impl PartialEq for ScriptErrorInner { + fn eq(&self, other: &Self) -> bool { + self.context == other.context + } } impl ScriptError { - /// Create new `ScriptError::Other` from another error - pub fn new_other(other: T) -> Self { - Self::Other(other.to_string()) + #[cfg(feature = "mlua_impls")] + /// Destructures mlua error into a script error, taking care to preserve as much information as possible + pub fn from_mlua_error(error: mlua::Error) -> Self { + match error { + mlua::Error::CallbackError { traceback, cause } + if matches!(cause.as_ref(), mlua::Error::ExternalError(_)) => + { + let inner = cause.deref().clone(); + Self::from_mlua_error(inner).with_context(traceback) + } + e => { + if let Some(inner) = e.downcast_ref::() { + Self::new(inner.clone()) + } else if let Some(inner) = e.downcast_ref::() { + inner.clone() + } else { + Self::new_external(e) + } + } + } + } + + pub fn new_external(reason: impl std::error::Error + Send + Sync + 'static) -> Self { + Self(Arc::new(ScriptErrorInner { + script: None, + reason: ErrorKind::Display(Arc::new(reason)), + context: Default::default(), + })) + } + + pub fn new(reason: impl DisplayWithWorld + Send + Sync + 'static) -> Self { + Self(Arc::new(ScriptErrorInner { + script: None, + reason: ErrorKind::WithWorld(Arc::new(reason)), + context: Default::default(), + })) + } + + pub fn with_script(self, script: S) -> Self { + Self(Arc::new(ScriptErrorInner { + script: Some(script.to_string()), + context: self.0.context.clone(), + reason: self.0.reason.clone(), + })) + } + + pub fn with_context(self, context: S) -> Self { + Self(Arc::new(ScriptErrorInner { + script: self.0.script.clone(), + context: format!("{}\n{}", self.0.context, context.to_string()), + reason: self.0.reason.clone(), + })) + } +} + +impl std::fmt::Display for ScriptError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.display_without_world()) + } +} + +impl DisplayWithWorld for ScriptError { + fn display_with_world(&self, world: crate::bindings::WorldGuard) -> String { + if let Some(script) = &self.0.script { + format!( + "error in script `{}`: {}.\nContext:{}", + script, + self.0.reason.display_with_world(world), + self.0.context + ) + } else { + format!( + "error: {}.\nContext:{}", + self.0.reason.display_with_world(world), + self.0.context + ) + } + } + + fn display_without_world(&self) -> String { + if let Some(script) = &self.0.script { + format!( + "error in script `{}`: {}.\nContext:{}", + script, self.0.reason, self.0.context, + ) + } else { + format!("error: {}.\nContext:{}", self.0.reason, self.0.context) + } + } +} + +#[cfg(feature = "mlua_impls")] +impl From for mlua::Error { + fn from(value: ScriptError) -> Self { + mlua::Error::external(value) + } +} + +#[cfg(feature = "mlua_impls")] +impl From for mlua::Error { + fn from(value: InteropError) -> Self { + mlua::Error::external(value) + } +} + +#[cfg(feature = "mlua_impls")] +impl From for ScriptError { + fn from(value: mlua::Error) -> Self { + ScriptError::from_mlua_error(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::new_external(value) + } +} + +#[derive(Debug, Clone, PartialEq, Reflect)] +pub struct InteropError(#[reflect(ignore)] Arc); + +impl std::error::Error for InteropError {} + +impl DisplayWithWorld for InteropError { + fn display_with_world(&self, world: crate::bindings::WorldGuard) -> String { + self.0.display_with_world(world) + } + + fn display_without_world(&self) -> String { + self.0.display_without_world() + } +} + +impl Display for InteropError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.display_without_world()) + } +} + +impl From for ScriptError { + fn from(val: InteropError) -> Self { + ScriptError::new(val) + } +} + +impl From for ScriptError { + fn from(val: Utf8Error) -> Self { + ScriptError::new_external(val) + } +} + +pub trait FlattenError { + fn flatten_interop_error(self) -> Result; +} + +impl FlattenError for Result, InteropError> { + fn flatten_interop_error(self) -> Result { + match self { + Ok(Ok(o)) => Ok(o), + Ok(Err(e)) => Err(e), + Err(e) => Err(e), + } + } +} + +impl InteropError { + /// Thrown if a callback requires world access, but is unable to do so due + /// to the world not being reachable at all via any mechanism. + pub fn missing_world() -> Self { + Self(Arc::new(InteropErrorInner::MissingWorld)) + } + + /// Thrown if a callback requires world access, but is unable to do so due + /// to the world being dropped. I.e. Symptom of a script trying to persist a world reference somewhere. + pub fn stale_world_access() -> Self { + Self(Arc::new(InteropErrorInner::StaleWorldAccess)) + } + + /// Thrown if a base type is not registered with the reflection system + /// and therefore the reference cannot be dereferenced + pub fn unregistered_base(base: ReflectBaseType) -> Self { + Self(Arc::new(InteropErrorInner::UnregisteredBase { base })) + } + + /// Thrown if a base type is not registered with the reflection system + /// with the specific type data. + pub fn missing_type_data(type_id: TypeId, type_data: String) -> Self { + Self(Arc::new(InteropErrorInner::MissingTypeData { + type_id, + type_data, + })) + } + + /// Thrown if a type cannot be converted from reflect, this can happen if the type was unable to + /// re-construct itself from a dynamic value. + pub fn failed_from_reflect(type_id: Option, reason: String) -> Self { + Self(Arc::new(InteropErrorInner::FailedFromReflect { + type_id, + reason, + })) + } + + /// Thrown if access to the given reflection base is required but cannot be claimed. + /// This is likely due to some other script already claiming access to the base. + pub fn cannot_claim_access( + base: ReflectBaseType, + location: Option>, + ) -> Self { + Self(Arc::new(InteropErrorInner::CannotClaimAccess { + base, + location, + })) + } + + /// Thrown if a conversion into the given type is impossible. + /// Should be thrown with context on the other type if possible. + pub fn impossible_conversion(into: TypeId) -> Self { + Self(Arc::new(InteropErrorInner::ImpossibleConversion { into })) + } + + /// Thrown if a conversion was not fully completed, as a better conversion exists. + /// If a function might throw this error it should be handled by the caller. + /// + /// A user seeing this error is evidence of unfinished logic. + pub fn better_conversion_exists() -> Self { + Self(Arc::new(InteropErrorInner::BetterConversionExists { + context: std::any::type_name::().to_string(), + })) + } + + /// Thrown if a value was expected to be of one type but was of another + pub fn type_mismatch(expected: TypeId, got: Option) -> Self { + Self(Arc::new(InteropErrorInner::TypeMismatch { expected, got })) + } + + /// Identical to [`InteropError::type_mismatch`] but for more abstract types + pub fn string_type_mismatch(expected: String, got: Option) -> Self { + Self(Arc::new(InteropErrorInner::StringTypeMismatch { + expected, + got, + })) + } + + /// Thrown if a [`ScriptValue`] could not be converted to the expected type + pub fn value_mismatch(expected: TypeId, got: ScriptValue) -> Self { + Self(Arc::new(InteropErrorInner::ValueMismatch { expected, got })) + } + + /// Thrown if a downcast from a reflect reference to a specific type failed + pub fn could_not_downcast(from: ReflectReference, to: TypeId) -> Self { + Self(Arc::new(InteropErrorInner::CouldNotDowncast { from, to })) + } + + /// Thrown if a garbage collected allocation was attempted to be accessed + pub fn garbage_collected_allocation(reference: ReflectReference) -> Self { + Self(Arc::new(InteropErrorInner::GarbageCollectedAllocation { + reference, + })) + } + + /// Thrown if a reflection path is invalid + pub fn reflection_path_error(error: String, reference: Option) -> Self { + Self(Arc::new(InteropErrorInner::ReflectionPathError { + error, + reference, + })) + } + + /// Thrown if an operation is not supported on the given base type, optionally with a value argument that was used to carry it out + pub fn unsupported_operation( + base: Option, + value: Option>, + operation: String, + ) -> Self { + Self(Arc::new(InteropErrorInner::UnsupportedOperation { + base, + value, + operation, + })) + } + + /// Thrown if an invalid index operation was attempted on a value + pub fn invalid_index(value: ScriptValue, reason: String) -> Self { + Self(Arc::new(InteropErrorInner::InvalidIndex { value, reason })) + } + + /// Thrown if an entity was missing or invalid + pub fn missing_entity(entity: Entity) -> Self { + Self(Arc::new(InteropErrorInner::MissingEntity { entity })) + } + + /// Thrown if a component was invalid + pub fn invalid_component(component_id: ComponentId) -> Self { + Self(Arc::new(InteropErrorInner::InvalidComponent { + component_id, + })) + } + + /// 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 { + Self(Arc::new(InteropErrorInner::FunctionInteropError { + function_name: function_name.to_string(), + on, + error, + })) + } + + /// Thrown when the error happens after a function call, and an error is thrown by bevy. + /// + /// I.e. mismatch in args, or invalid number of arguments + pub fn function_call_error(inner: FunctionError) -> Self { + Self(Arc::new(InteropErrorInner::FunctionCallError { inner })) + } + + pub fn function_arg_conversion_error(argument: String, error: InteropError) -> Self { + Self(Arc::new(InteropErrorInner::FunctionArgConversionError { + argument, + error, + })) + } + pub fn length_mismatch(expected: usize, got: usize) -> Self { + Self(Arc::new(InteropErrorInner::LengthMismatch { + expected, + got, + })) + } + + pub fn external_error(error: Box) -> Self { + Self(Arc::new(InteropErrorInner::OtherError { error })) + } + + pub fn missing_function(on: TypeId, function_name: String) -> Self { + Self(Arc::new(InteropErrorInner::MissingFunctionError { + on, + function_name, + })) + } + + pub fn invalid_access_count(count: usize, expected: usize, context: String) -> Self { + Self(Arc::new(InteropErrorInner::InvalidAccessCount { + count, + expected, + context, + })) + } + + pub fn inner(&self) -> &InteropErrorInner { + &self.0 + } + + /// Unwraps the inner error + /// + /// # Panics + /// - if there are multiple references to the inner error + pub fn into_inner(self) -> InteropErrorInner { + Arc::try_unwrap(self.0).unwrap_or_else(|a| { + Arc::try_unwrap(a).expect("tried to unwrap interop error while a copy exists") + }) + } +} + +/// For errors to do with reflection, type conversions or other interop issues +#[derive(Debug)] +pub enum InteropErrorInner { + StaleWorldAccess, + MissingWorld, + UnregisteredBase { + base: ReflectBaseType, + }, + MissingTypeData { + type_id: TypeId, + type_data: String, + }, + FailedFromReflect { + type_id: Option, + reason: String, + }, + CannotClaimAccess { + base: ReflectBaseType, + location: Option>, + }, + InvalidAccessCount { + count: usize, + expected: usize, + context: String, + }, + ImpossibleConversion { + into: TypeId, + }, + BetterConversionExists { + context: String, + }, + TypeMismatch { + expected: TypeId, + got: Option, + }, + StringTypeMismatch { + expected: String, + got: Option, + }, + ValueMismatch { + expected: TypeId, + got: ScriptValue, + }, + LengthMismatch { + expected: usize, + got: usize, + }, + CouldNotDowncast { + from: ReflectReference, + to: TypeId, + }, + GarbageCollectedAllocation { + reference: ReflectReference, + }, + ReflectionPathError { + error: String, + reference: Option, + }, + UnsupportedOperation { + base: Option, + value: Option>, + operation: String, + }, + InvalidIndex { + value: ScriptValue, + reason: String, + }, + MissingEntity { + entity: Entity, + }, + InvalidComponent { + component_id: ComponentId, + }, + FunctionCallError { + inner: FunctionError, + }, + MissingFunctionError { + on: TypeId, + function_name: String, + }, + FunctionInteropError { + function_name: String, + on: Option, + error: InteropError, + }, + FunctionArgConversionError { + argument: String, + error: InteropError, + }, + OtherError { + error: Box, + }, +} + +impl PartialEq for InteropErrorInner { + fn eq(&self, _other: &Self) -> bool { + false + } +} + +impl DisplayWithWorld for InteropErrorInner { + fn display_with_world(&self, world: crate::bindings::WorldGuard) -> String { + match self { + InteropErrorInner::MissingFunctionError { on, function_name } => { + format!( + "Could not find function: {} for type: {}", + function_name, + on.display_with_world(world) + ) + }, + InteropErrorInner::UnregisteredBase { base } => { + format!("Unregistered base type: {}", base.display_with_world(world)) + } + InteropErrorInner::CannotClaimAccess { base, location } => { + format!( + "Cannot claim access to base type: {}. The base is already claimed by something else in a way which prevents safe access. Location: {}", + base.display_with_world(world), + location.display_location() + ) + } + InteropErrorInner::ImpossibleConversion { into } => { + format!("Cannot convert to type: {}", into.display_with_world(world)) + } + InteropErrorInner::TypeMismatch { expected, got } => { + format!( + "Type mismatch, expected: {}, got: {}", + expected.display_with_world(world.clone()), + got.map(|t| t.display_with_world(world)) + .unwrap_or("None".to_owned()) + ) + } + InteropErrorInner::StringTypeMismatch { expected, got } => { + format!( + "Type mismatch, expected: {}, got: {}", + expected, + got.map(|t| t.display_with_world(world)) + .unwrap_or("None".to_owned()) + ) + } + InteropErrorInner::CouldNotDowncast { from, to } => { + format!( + "Could not downcast from: {} to: {}", + from.display_with_world(world.clone()), + to.display_with_world(world) + ) + } + InteropErrorInner::GarbageCollectedAllocation { reference } => { + format!( + "Allocation was garbage collected. Could not access reference: {} as a result.", + reference.display_with_world(world), + ) + } + InteropErrorInner::ReflectionPathError { error, reference } => { + format!( + "Error while reflecting path: {} on reference: {}", + error, + reference + .as_ref() + .map(|r| r.display_with_world(world)) + .unwrap_or("None".to_owned()), + ) + } + InteropErrorInner::MissingTypeData { type_id, type_data } => { + format!( + "Missing type data {} for type: {}. Did you register the type correctly?", + type_data, + type_id.display_with_world(world), + ) + } + InteropErrorInner::FailedFromReflect { type_id, reason } => { + format!( + "Failed to convert from reflect for type: {} with reason: {}", + type_id + .map(|t| t.display_with_world(world)) + .unwrap_or("None".to_owned()), + reason + ) + } + InteropErrorInner::ValueMismatch { expected, got } => { + format!( + "Value mismatch, expected: {}, got: {}", + expected.display_with_world(world.clone()), + got.display_with_world(world) + ) + } + InteropErrorInner::UnsupportedOperation { + base, + value, + operation, + } => { + format!( + "Unsupported operation: {} on base: {} with value: {:?}", + operation, + base.map(|t| t.display_with_world(world)) + .unwrap_or("None".to_owned()), + value + ) + } + InteropErrorInner::InvalidIndex { value, reason } => { + format!( + "Invalid index for value: {}: {}", + value.display_with_world(world), + reason + ) + } + InteropErrorInner::MissingEntity { entity } => { + format!("Missing or invalid entity: {}", entity) + } + InteropErrorInner::InvalidComponent { component_id } => { + format!("Invalid component: {:?}", component_id) + } + InteropErrorInner::StaleWorldAccess => { + "Stale world access. The world has been dropped and a script tried to access it. Do not try to store or copy the world." + .to_owned() + } + InteropErrorInner::MissingWorld => { + "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 display_name = if function_name.starts_with("TypeId") { + function_name.split("::").last().unwrap() + } else { + function_name.as_str() + }; + format!( + "Error in function {} {}: {}", + display_name, + opt_on, + error.display_with_world(world), + ) + }, + InteropErrorInner::FunctionArgConversionError { argument, error } => { + format!( + "Error converting argument {}: {}", + argument, + error.display_with_world(world) + ) + }, + InteropErrorInner::FunctionCallError { inner } => { + format!("Error in function call: {}", inner) + }, + InteropErrorInner::BetterConversionExists{ context } => { + format!("Unfinished conversion in context of: {}. A better conversion exists but caller didn't handle the case.", context) + }, + InteropErrorInner::OtherError { error } => error.to_string(), + InteropErrorInner::LengthMismatch { expected, got } => { + format!("Array/List Length mismatch, expected: {}, got: {}", expected, got) + }, + InteropErrorInner::InvalidAccessCount { count, expected, context } => { + format!("Invalid access count, expected: {}, got: {}. {}", expected, count, context) + }, + } + } + + // todo macro this + fn display_without_world(&self) -> String { + match self { + InteropErrorInner::MissingFunctionError { on, function_name } => { + format!( + "Could not find function: {} for type: {}", + function_name, + on.display_without_world() + ) + }, + InteropErrorInner::UnregisteredBase { base } => { + format!("Unregistered base type: {}", base.display_without_world()) + } + InteropErrorInner::CannotClaimAccess { base, location } => { + format!( + "Cannot claim access to base type: {}. The base is already claimed by something else in a way which prevents safe access. Location: {}", + base.display_without_world(), + location.display_location() + ) + } + InteropErrorInner::ImpossibleConversion { into } => { + format!("Cannot convert to type: {}", into.display_without_world()) + } + InteropErrorInner::TypeMismatch { expected, got } => { + format!( + "Type mismatch, expected: {}, got: {}", + expected.display_without_world(), + got.map(|t| t.display_without_world()) + .unwrap_or("None".to_owned()) + ) + } + InteropErrorInner::StringTypeMismatch { expected, got } => { + format!( + "Type mismatch, expected: {}, got: {}", + expected, + got.map(|t| t.display_without_world()) + .unwrap_or("None".to_owned()) + ) + } + InteropErrorInner::CouldNotDowncast { from, to } => { + format!( + "Could not downcast from: {} to: {}", + from.display_without_world(), + to.display_without_world() + ) + } + InteropErrorInner::GarbageCollectedAllocation { reference } => { + format!( + "Allocation was garbage collected. Could not access reference: {} as a result.", + reference.display_without_world(), + ) + } + InteropErrorInner::ReflectionPathError { error, reference } => { + format!( + "Error while reflecting path: {} on reference: {}", + error, + reference + .as_ref() + .map(|r| r.display_without_world()) + .unwrap_or("None".to_owned()), + ) + } + InteropErrorInner::MissingTypeData { type_id, type_data } => { + format!( + "Missing type data {} for type: {}. Did you register the type correctly?", + type_data, + type_id.display_without_world(), + ) + } + InteropErrorInner::FailedFromReflect { type_id, reason } => { + format!( + "Failed to convert from reflect for type: {} with reason: {}", + type_id + .map(|t| t.display_without_world()) + .unwrap_or("None".to_owned()), + reason + ) + } + InteropErrorInner::ValueMismatch { expected, got } => { + format!( + "Value mismatch, expected: {}, got: {}", + expected.display_without_world(), + got.display_without_world() + ) + } + InteropErrorInner::UnsupportedOperation { + base, + value, + operation, + } => { + format!( + "Unsupported operation: {} on base: {} with value: {:?}", + operation, + base.map(|t| t.display_without_world()) + .unwrap_or("None".to_owned()), + value + ) + } + InteropErrorInner::InvalidIndex { value, reason } => { + format!( + "Invalid index for value: {}: {}", + value.display_without_world(), + reason + ) + } + InteropErrorInner::MissingEntity { entity } => { + format!("Missing or invalid entity: {}", entity) + } + InteropErrorInner::InvalidComponent { component_id } => { + format!("Invalid component: {:?}", component_id) + } + InteropErrorInner::StaleWorldAccess => { + "Stale world access. The world has been dropped and a script tried to access it. Do not try to store or copy the world." + .to_owned() + } + InteropErrorInner::MissingWorld => { + "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") { + function_name.split("::").last().unwrap() + } else { + function_name.as_str() + }; + format!( + "Error in function {} {}: {}", + display_name, + opt_on, + error.display_without_world(), + ) + }, + InteropErrorInner::FunctionArgConversionError { argument, error } => { + format!( + "Error converting argument {}: {}", + argument, + error.display_without_world() + ) + }, + InteropErrorInner::FunctionCallError { inner } => { + format!("Error in function call: {}", inner) + }, + InteropErrorInner::BetterConversionExists{ context } => { + format!("Unfinished conversion in context of: {}. A better conversion exists but caller didn't handle the case.", context) + }, + InteropErrorInner::OtherError { error } => error.to_string(), + InteropErrorInner::LengthMismatch { expected, got } => { + format!("Array/List Length mismatch, expected: {}, got: {}", expected, got) + }, + InteropErrorInner::InvalidAccessCount { count, expected, context } => { + format!("Invalid access count, expected: {}, got: {}. {}", expected, count, context) + }, + } + } +} + +/// Purely for purposes of the automatic [`GetTypeRegistration`] impl. +impl Default for InteropErrorInner { + fn default() -> Self { + InteropErrorInner::StaleWorldAccess } } diff --git a/crates/bevy_mod_scripting_core/src/event.rs b/crates/bevy_mod_scripting_core/src/event.rs index 7ba34707..c84af073 100644 --- a/crates/bevy_mod_scripting_core/src/event.rs +++ b/crates/bevy_mod_scripting_core/src/event.rs @@ -1,6 +1,5 @@ -use bevy::prelude::Event; - -use crate::{error::ScriptError, hosts::Recipients}; +use crate::{bindings::script_value::ScriptValue, error::ScriptError, script::ScriptId}; +use bevy::{ecs::entity::Entity, prelude::Event}; /// An error coming from a script #[derive(Debug, Event)] @@ -8,15 +7,266 @@ pub struct ScriptErrorEvent { pub error: ScriptError, } -/// An event emitted when a script was loaded or re-loaded (with a hot-reload), -/// guaranteed to be sent for every script at least once and immediately after it's loaded. -#[derive(Clone, Debug, Event)] -pub struct ScriptLoaded { - pub sid: u32, +/// A string which disallows common invalid characters in callback labels, +/// particularly at the start of the string +/// +/// a valid callback label starts with a letter or underscore, and contains only ascii characters, as well as disallows some common keywords +#[derive(Clone, PartialEq, Eq, Hash, Debug)] +pub struct CallbackLabel(String); + +impl CallbackLabel { + fn filter_invalid(s: &str) -> String { + let mut out = String::with_capacity(s.len()); + let mut first = true; + for char in s.chars() { + if char == '_' + || ((!first && char.is_ascii_alphanumeric()) || char.is_ascii_alphabetic()) + { + out.push(char); + first = false; + } else { + continue; + } + } + if FORBIDDEN_KEYWORDS.contains(&s) { + String::default() + } else { + out + } + } + + pub fn new_lossy(label: &str) -> Self { + Self(Self::filter_invalid(label)) + } + + pub fn new(label: &str) -> Option { + let new_lossy = Self::new_lossy(label); + if new_lossy.0.len() != label.len() { + None + } else { + Some(new_lossy) + } + } +} + +#[macro_export] +macro_rules! callback_labels { + ($($name:ident => $label:expr),*) => { + + $( + pub struct $name; + impl $crate::event::IntoCallbackLabel for $name { + fn into_callback_label() -> $crate::event::CallbackLabel { + $label.into() + } + } + )* + }; +} + +callback_labels!( + OnScriptLoaded => "on_script_loaded", + OnScriptUnloaded => "on_script_unloaded" +); + +pub trait IntoCallbackLabel { + fn into_callback_label() -> CallbackLabel; +} + +impl From for CallbackLabel { + fn from(_: T) -> Self { + T::into_callback_label() + } +} + +impl From<&str> for CallbackLabel { + fn from(s: &str) -> Self { + Self::new_lossy(s) + } +} + +impl From for CallbackLabel { + fn from(s: String) -> Self { + Self::from(s.as_str()) + } } -/// A trait for events to be handled by scripts -pub trait ScriptEvent: Send + Sync + Clone + Event + 'static { - /// Retrieves the recipient scripts for this event - fn recipients(&self) -> &Recipients; +impl AsRef for CallbackLabel { + fn as_ref(&self) -> &str { + &self.0 + } +} + +impl std::fmt::Display for CallbackLabel { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_ref()) + } +} + +/// Describes the designated recipients of a script event +#[derive(Clone, Debug)] +pub enum Recipients { + /// The event needs to be handled by all scripts + All, + /// The event is to be handled by a specific script + Script(ScriptId), + /// The event is to be handled by all the scripts on the specified entity + Entity(Entity), +} + +/// A callback event meant to trigger a callback in a subset/set of scripts in the world with the given arguments +#[derive(Clone, Event, Debug)] +pub struct ScriptCallbackEvent { + pub label: CallbackLabel, + pub recipients: Recipients, + pub args: Vec, +} + +impl ScriptCallbackEvent { + pub fn new>( + label: L, + args: Vec, + recipients: Recipients, + ) -> Self { + Self { + label: label.into(), + args, + recipients, + } + } + + pub fn new_for_all>(label: L, args: Vec) -> Self { + Self::new(label, args, Recipients::All) + } +} + +static FORBIDDEN_KEYWORDS: [&str; 82] = [ + // Lua + "and", + "break", + "do", + "else", + "elseif", + "end", + "false", + "for", + "function", + "if", + "in", + "local", + "nil", + "not", + "or", + "repeat", + "return", + "then", + "true", + "until", + "while", + // Rhai + "true", + "false", + "let", + "const", + "is_shared", + "if", + "else", + "switch", + "do", + "while", + "loop", + "until", + "for", + "in", + "continue", + "break", + "fn", + "private", + "is_def_fn", + "this", + "return", + "throw", + "try", + "catch", + "import", + "export", + "as", + "global", + "Fn", + "call", + "curry", + "type_of", + "print", + "debug", + "eval", + "is_def_var", + "var", + "static", + "is", + "goto", + "match", + "case", + "public", + "protected", + "new", + "use", + "with", + "module", + "package", + "super", + "spawn", + "thread", + "go", + "sync", + "async", + "await", + "yield", + "default", + "void", + "null", + "nil", +]; + +#[cfg(test)] +mod test { + use super::FORBIDDEN_KEYWORDS; + + #[test] + fn test_invalid_strings() { + FORBIDDEN_KEYWORDS.iter().for_each(|keyword| { + assert_eq!(super::CallbackLabel::new(keyword), None); + }); + } + + #[test] + fn test_bad_chars() { + let bad_chars = [ + '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '+', '=', '{', '}', '[', ']', + '|', '\\', ':', ';', '"', '\'', '<', '>', ',', '.', '?', '/', '`', '~', + ]; + bad_chars.iter().for_each(|char| { + assert_eq!(super::CallbackLabel::new(&format!("bad{}", char)), None); + }); + } + + #[test] + fn bad_first_letter() { + let bad_chars = [ + '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '@', '#', '$', '%', '^', '&', '*', + '(', ')', '-', '+', '=', '{', '}', '[', ']', '|', '\\', ':', ';', '"', '\'', '<', '>', + ',', '.', '?', '/', '`', '~', + ]; + bad_chars.iter().for_each(|char| { + assert_eq!(super::CallbackLabel::new(&format!("{}bad", char)), None); + }); + } + + #[test] + fn test_valid_idents() { + let valid = ["h", "_v", "hello", "_2d", "heloo_2", "_1231412"]; + valid.iter().for_each(|ident| { + assert!(super::CallbackLabel::new(ident).is_some()); + assert_eq!(super::CallbackLabel::new_lossy(ident).as_ref(), *ident); + }); + } } diff --git a/crates/bevy_mod_scripting_core/src/handler.rs b/crates/bevy_mod_scripting_core/src/handler.rs new file mode 100644 index 00000000..fdc6784b --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/handler.rs @@ -0,0 +1,33 @@ +use crate::{ + bindings::script_value::ScriptValue, context::ContextPreHandlingInitializer, + error::ScriptError, event::CallbackLabel, script::ScriptId, IntoScriptPluginParams, +}; +use bevy::ecs::{entity::Entity, system::Resource, world::World}; + +pub trait Args: Clone + Send + Sync + 'static {} +impl Args for T {} + +pub type HandlerFn

= fn( + args: Vec, + entity: Entity, + script_id: &ScriptId, + callback: &CallbackLabel, + context: &mut

::C, + pre_handling_initializers: &[ContextPreHandlingInitializer

], + runtime: &mut

::R, + world: &mut World, +) -> Result<(), ScriptError>; + +/// A resource that holds the settings for the callback handler for a specific combination of type parameters +#[derive(Resource)] +pub struct CallbackSettings { + pub callback_handler: Option>, +} + +impl Default for CallbackSettings

{ + fn default() -> Self { + Self { + callback_handler: None, + } + } +} diff --git a/crates/bevy_mod_scripting_core/src/hosts.rs b/crates/bevy_mod_scripting_core/src/hosts.rs deleted file mode 100644 index 1225782a..00000000 --- a/crates/bevy_mod_scripting_core/src/hosts.rs +++ /dev/null @@ -1,453 +0,0 @@ -//! All script host related stuff -use bevy::{asset::Asset, ecs::schedule::ScheduleLabel, prelude::*}; -use std::{ - collections::HashMap, - iter::once, - sync::atomic::{AtomicU32, Ordering}, -}; - -use crate::{ - asset::CodeAsset, - docs::DocFragment, - error::ScriptError, - event::{ScriptEvent, ScriptLoaded}, - world::WorldPointer, - ScriptErrorEvent, -}; - -/// Describes the target set of scripts this event should -/// be handled by -#[derive(Clone, Debug)] -pub enum Recipients { - /// Send to all scripts - All, - /// Send only to scripts on the given entity - Entity(Entity), - /// Send to script with the given ID - ScriptID(u32), - // Send to script with the given name - ScriptName(String), -} - -#[derive(Debug)] -/// Data used to describe a script instance. -pub struct ScriptData<'a> { - pub sid: u32, - pub entity: Entity, - pub name: &'a str, -} - -impl Recipients { - /// Returns true if the given script is a recipient - pub fn is_recipient(&self, c: &ScriptData) -> bool { - match self { - Recipients::All => true, - Recipients::Entity(e) => e == &c.entity, - Recipients::ScriptID(i) => i == &c.sid, - Recipients::ScriptName(n) => n == c.name, - } - } -} - -impl Default for Recipients { - fn default() -> Self { - Self::All - } -} - -/// A script host is the interface between your rust application -/// and the scripts in some interpreted language. -pub trait ScriptHost: Send + Sync + 'static + Default + Resource { - /// the type of the persistent script context, representing the execution context of the script - type ScriptContext: Send + Sync + 'static; - /// the type of events picked up by lua callbacks - type ScriptEvent: ScriptEvent; - /// the type of asset representing the script files for this host - type ScriptAsset: CodeAsset; - /// the type representing the target of api providers, i.e. the - /// script engine or the script context itself - type APITarget: Send + Sync + 'static; - /// the type of each doc fragment - type DocTarget: DocFragment; - - /// Loads a script in byte array format, the script name can be used - /// to send useful errors. - fn load_script( - &mut self, - script: &[u8], - script_data: &ScriptData, - providers: &mut APIProviders, - ) -> Result; - - /// Perform one-off initialization of scripts (happens for every new or re-loaded script) - fn setup_script( - &mut self, - script_data: &ScriptData, - ctx: &mut Self::ScriptContext, - providers: &mut APIProviders, - ) -> Result<(), ScriptError>; - - /// the main point of contact with the bevy world. - /// Scripts are called with appropriate events in the event order - fn handle_events<'a>( - &mut self, - world_ptr: &mut World, - events: &[Self::ScriptEvent], - ctxs: impl Iterator, &'a mut Self::ScriptContext)>, - providers: &mut APIProviders, - ); - - /// Loads and runs script instantaneously without storing any script data into the world. - /// The script id is set to `u32::MAX`. - fn run_one_shot( - &mut self, - script: &[u8], - script_name: &str, - entity: Entity, - world: &mut World, - event: Self::ScriptEvent, - ) -> Result<(), ScriptError> { - let fd = ScriptData { - name: script_name, - sid: u32::MAX, - entity, - }; - - let mut providers: APIProviders = world.remove_resource().unwrap(); - let mut ctx = self.load_script(script, &fd, &mut providers).unwrap(); - self.setup_script(&fd, &mut ctx, &mut providers)?; - let events = [event; 1]; - - self.handle_events(world, &events, once((fd, &mut ctx)), &mut providers); - - world.insert_resource(providers); - - Ok(()) - } - - /// Registers the script host with the given app, and attaches handlers to deal with spawning/removing scripts in the given System Set. - /// - /// Ideally place after any game logic which can spawn/remove/modify scripts to avoid frame lag. (typically `PostUpdate`) - fn register_with_app(app: &mut App, schedule: impl ScheduleLabel) { - #[derive(SystemSet, Hash, Debug, Eq, PartialEq, Clone, Copy)] - struct DummySet; - - Self::register_with_app_in_set(app, schedule, DummySet); - } - - /// Similar to `register_with_app` but allows you to specify a system set to add the handler to. - fn register_with_app_in_set(app: &mut App, schedule: impl ScheduleLabel, set: impl SystemSet); -} - -/// Implementors can modify a script context in order to enable -/// API access. ScriptHosts call `attach_api` when creating scripts -pub trait APIProvider: 'static + Send + Sync { - /// the type of script engine/context the API is attached to, this must be the same as the APITarget of the ScriptHost meant to receive it. - type APITarget: Send + Sync + 'static; - /// The type of script context the APIProvider works with, must be the same as the ScriptContext of the target ScriptHost. - type ScriptContext: Send + Sync + 'static; - /// The type of documentation fragment produced by the APIProvider, must be the same as the DocTarget of the target ScriptHost. - type DocTarget: DocFragment; - - /// provide the given script context with the API permamently. - /// Depending on the host, API's may be attached on a per-script basis - /// or on a per-engine basis. Rhai for example allows you to decouple the State of each script from the - /// engine. For one-time setup use `Self::setup_script` - fn attach_api(&mut self, api: &mut Self::APITarget) -> Result<(), ScriptError>; - - /// Hook executed every time a script is about to handle events, most notably used to "refresh" world pointers - fn setup_script_runtime( - &mut self, - _world_ptr: WorldPointer, - _script_data: &ScriptData, - _ctx: &mut Self::ScriptContext, - ) -> Result<(), ScriptError> { - Ok(()) - } - - /// Setup meant to be executed once for every single script. Use this if you need to consistently setup scripts. - /// For API's use `Self::attach_api` instead. - fn setup_script( - &mut self, - _script_data: &ScriptData, - _ctx: &mut Self::ScriptContext, - ) -> Result<(), ScriptError> { - Ok(()) - } - - /// Generate a piece of documentation to be merged with the other documentation fragments - /// provided by other API providers - fn get_doc_fragment(&self) -> Option { - None - } - - /// Some providers might provide additional types which need to be registered - /// with the reflection API to work. - fn register_with_app(&self, _app: &mut App) {} -} - -#[derive(Resource)] -/// Stores many API providers -pub struct APIProviders { - pub providers: Vec< - Box< - dyn APIProvider< - APITarget = T::APITarget, - DocTarget = T::DocTarget, - ScriptContext = T::ScriptContext, - >, - >, - >, -} - -impl Default for APIProviders { - fn default() -> Self { - Self { - providers: Default::default(), - } - } -} - -impl APIProviders { - pub fn attach_all(&mut self, ctx: &mut T::APITarget) -> Result<(), ScriptError> { - for p in self.providers.iter_mut() { - p.attach_api(ctx)?; - } - - Ok(()) - } - - pub fn setup_runtime_all( - &mut self, - world_ptr: WorldPointer, - script_data: &ScriptData, - ctx: &mut T::ScriptContext, - ) -> Result<(), ScriptError> { - for p in self.providers.iter_mut() { - p.setup_script_runtime(world_ptr.clone(), script_data, ctx)?; - } - - Ok(()) - } - - pub fn setup_all( - &mut self, - script_data: &ScriptData, - ctx: &mut T::ScriptContext, - ) -> Result<(), ScriptError> { - for p in self.providers.iter_mut() { - p.setup_script(script_data, ctx)?; - } - - Ok(()) - } - - pub fn gen_all(&self) -> Result<(), ScriptError> { - let mut d: Option = None; - for p in self.providers.iter() { - if let Some(f) = p.get_doc_fragment() { - if let Some(prev) = d { - d = Some(prev.merge(f)) - } else { - d = Some(f) - } - } - } - d.map(|d| d.gen_docs()).unwrap_or_else(|| Ok(())) - } -} - -/// A resource storing the script contexts for each script instance. -/// The reason we need this is to split the world borrow in our handle event systems, but this -/// has the added benefit that users don't see the contexts at all, and we can provide -/// generic handling for each new/removed script in one place. -/// -/// We keep this public for now since there is no API for communicating with scripts -/// outside of events. Later this might change. -#[derive(Resource)] -pub struct ScriptContexts { - /// holds script contexts for all scripts given their instance ids. - /// This also stores contexts which are not fully loaded hence the Option - pub context_entities: HashMap, String)>, -} - -impl Default for ScriptContexts { - fn default() -> Self { - Self { - context_entities: Default::default(), - } - } -} - -impl ScriptContexts { - pub fn script_owner(&self, script_id: u32) -> Option { - self.context_entities.get(&script_id).map(|(e, _c, _n)| *e) - } - - pub fn insert_context(&mut self, fd: ScriptData, ctx: Option) { - self.context_entities - .insert(fd.sid, (fd.entity, ctx, fd.name.to_owned())); - } - - pub fn remove_context(&mut self, script_id: u32) { - self.context_entities.remove(&script_id); - } - - pub fn has_context(&self, script_id: u32) -> bool { - self.context_entities - .get(&script_id) - .map_or(false, |(_, c, _)| c.is_some()) - } - - pub fn is_empty(&self) -> bool { - self.context_entities.is_empty() - } -} - -/// A struct defining an instance of a script asset. -/// Multiple instances of the same script can exist on the same entity -#[derive(Debug, Reflect)] -pub struct Script { - /// a strong handle to the script asset - handle: Handle, - - /// the name of the script, usually its file name + relative asset path - name: String, - - /// uniquely identifies the script instance (scripts which use the same asset don't necessarily have the same ID) - id: u32, -} - -static COUNTER: AtomicU32 = AtomicU32::new(0); - -impl Script { - /// creates a new script instance with the given name and asset handle - /// automatically gives this script instance a unique ID. - /// No two scripts instances ever share the same ID - pub fn new(name: String, handle: Handle) -> Self { - Self { - handle, - name, - id: COUNTER.fetch_add(1, Ordering::Relaxed), - } - } - - #[inline(always)] - /// returns the name of the script - pub fn name(&self) -> &str { - &self.name - } - - #[inline(always)] - /// returns the asset handle which this script is executing - pub fn handle(&self) -> &Handle { - &self.handle - } - - #[inline(always)] - /// returns the unique ID of this script instance - pub fn id(&self) -> u32 { - self.id - } - - /// reloads the script by deleting the old context and inserting a new one - /// if the script context never existed, it will after this call. - pub(crate) fn reload_script( - host: &mut H, - script: &Script, - script_assets: &Assets, - providers: &mut APIProviders, - contexts: &mut ScriptContexts, - event_writer: &mut EventWriter, - error_writer: &mut EventWriter, - ) { - debug!("reloading script {}", script.id); - - // retrieve owning entity - if let Some(entity) = contexts.script_owner(script.id()) { - // remove old context - contexts.remove_context(script.id()); - // insert new re-loaded context - Self::insert_new_script_context::( - host, - script, - entity, - script_assets, - providers, - contexts, - event_writer, - error_writer, - ); - } else { - // remove old context - contexts.remove_context(script.id()); - } - } - - /// checks if a script has loaded, and if so loads (`ScriptHost::load_script`), - /// sets up (`ScriptHost::setup_script`) and inserts its new context into the contexts resource - /// otherwise inserts None. Sends ScriptLoaded event if the script was loaded - pub(crate) fn insert_new_script_context( - host: &mut H, - new_script: &Script, - entity: Entity, - script_assets: &Assets, - providers: &mut APIProviders, - contexts: &mut ScriptContexts, - event_writer: &mut EventWriter, - error_writer: &mut EventWriter, - ) { - let fd = ScriptData { - sid: new_script.id(), - entity, - name: new_script.name(), - }; - - let script = match script_assets.get(&new_script.handle) { - Some(s) => s, - None => { - // not loaded yet - debug!("Inserted script which hasn't loaded yet {:?}", fd); - contexts.insert_context(fd, None); - return; - } - }; - debug!("Inserted script {:?}", fd); - - match host.load_script(script.bytes(), &fd, providers) { - Ok(mut ctx) => { - host.setup_script(&fd, &mut ctx, providers) - .expect("Failed to setup script"); - contexts.insert_context(fd, Some(ctx)); - event_writer.send(ScriptLoaded { - sid: new_script.id(), - }); - } - Err(e) => { - warn! {"Error in loading script {}:\n{}", &new_script.name,e} - // this script will now never execute, unless manually reloaded - // but contexts are left in a valid state - contexts.insert_context(fd, None); - error_writer.send(ScriptErrorEvent { error: e }); - } - } - } -} - -#[derive(Component, Debug, Reflect)] -#[reflect(Component, Default)] -/// The component storing many scripts. -/// Scripts receive information about the entity they are attached to -/// Scripts have unique identifiers and hence multiple copies of the same script -/// can be attached to the same entity -pub struct ScriptCollection { - pub scripts: Vec>, -} - -impl Default for ScriptCollection { - fn default() -> Self { - Self { - scripts: Default::default(), - } - } -} diff --git a/crates/bevy_mod_scripting_core/src/lib.rs b/crates/bevy_mod_scripting_core/src/lib.rs index 2022dad3..450913eb 100644 --- a/crates/bevy_mod_scripting_core/src/lib.rs +++ b/crates/bevy_mod_scripting_core/src/lib.rs @@ -1,211 +1,263 @@ -use crate::{ - event::ScriptErrorEvent, - hosts::{APIProvider, APIProviders, ScriptHost}, +#![allow(clippy::arc_with_non_send_sync)] + +use crate::event::ScriptErrorEvent; +use asset::{AssetIdToScriptIdMap, ScriptAsset, ScriptAssetLoader, ScriptAssetSettings}; +use bevy::prelude::*; +use bindings::{ + function::script_function::AppScriptFunctionRegistry, script_value::ScriptValue, + AppReflectAllocator, ReflectAllocator, ReflectReference, ScriptTypeRegistration, + WorldCallbackAccess, +}; +use context::{ + Context, ContextAssigner, ContextBuilder, ContextInitializer, ContextLoadingSettings, + ContextPreHandlingInitializer, ScriptContexts, }; -use bevy::{ecs::schedule::ScheduleLabel, prelude::*}; -use event::ScriptLoaded; -use systems::script_event_handler; +use docs::{Documentation, DocumentationFragment}; +use event::ScriptCallbackEvent; +use handler::{CallbackSettings, HandlerFn}; + +use runtime::{Runtime, RuntimeContainer, RuntimeInitializer, RuntimeSettings}; +use script::Scripts; +use systems::{garbage_collector, initialize_runtime, sync_script_data}; pub mod asset; +pub mod bindings; +pub mod commands; +pub mod context; pub mod docs; pub mod error; pub mod event; -pub mod hosts; +pub mod handler; +pub mod reflection_extensions; +pub mod runtime; +pub mod script; pub mod systems; pub mod world; -pub mod prelude { - // general - pub use { - crate::asset::CodeAsset, - crate::docs::DocFragment, - crate::error::ScriptError, - crate::event::{ScriptErrorEvent, ScriptEvent}, - crate::hosts::{ - APIProvider, APIProviders, Recipients, Script, ScriptCollection, ScriptContexts, - ScriptData, ScriptHost, - }, - crate::systems::script_event_handler, - crate::{ - AddScriptApiProvider, AddScriptHost, AddScriptHostHandler, GenDocumentation, - ScriptingPlugin, - }, - bevy_event_priority::{ - AddPriorityEvent, PriorityEvent, PriorityEventReader, PriorityEventWriter, - PriorityEvents, PriorityIterator, - }, - }; -} -pub use bevy_event_priority as events; - -#[derive(Default)] -/// Bevy plugin enabling run-time scripting -pub struct ScriptingPlugin; -impl Plugin for ScriptingPlugin { - fn build(&self, app: &mut bevy::prelude::App) { - app.add_event::(); - } +/// 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 { + type C: Context; + type R: Runtime; } -pub trait GenDocumentation { - fn update_documentation(&mut self) -> &mut Self; +/// 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 + pub callback_handler: Option>, + /// The context builder for loading contexts + 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>, } -impl GenDocumentation for App { - /// Updates/Generates documentation and any other artifacts required for script API's. Disabled in optimized builds unless `doc_always` feature is enabled. - fn update_documentation(&mut self) -> &mut Self { - #[cfg(any(debug_assertions, feature = "doc_always"))] - { - info!("Generating documentation"); - let w = &mut self.world_mut(); - let providers: &APIProviders = w.resource(); - if let Err(e) = providers.gen_all() { - error!("{}", e); - } - info!("Documentation generated"); +impl Default for ScriptingPlugin

+where + P::R: Default, +{ + fn default() -> Self { + Self { + runtime_builder: P::R::default, + runtime_settings: Default::default(), + callback_handler: Default::default(), + context_builder: Default::default(), + context_assigner: Default::default(), } + } +} - self +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 { + language: "<>".into(), + extensions: &[], + preprocessor: None, + }) + .insert_resource(self.runtime_settings.as_ref().cloned().unwrap_or_default()) + .init_resource::() + .insert_non_send_resource::>(RuntimeContainer { + runtime: (self.runtime_builder)(), + }) + .init_non_send_resource::>() + .insert_resource::>(CallbackSettings { + callback_handler: self.callback_handler, + }) + .insert_resource::>(ContextLoadingSettings { + loader: self.context_builder.clone(), + 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_types(app); } } -/// Trait for app builder notation -pub trait AddScriptHost { - /// registers the given script host with your app, - /// the given system set will contain systems handling script loading, re-loading, removal etc. - /// This system set will also send events related to the script lifecycle. - /// - /// Note: any systems which need to run the same frame a script is loaded must run after this set. - fn add_script_host(&mut self, schedule: impl ScheduleLabel) -> &mut Self; - - /// Similar to `add_script_host` but allows you to specify a system set to add the script host to. - fn add_script_host_to_set( +/// Register all types that need to be accessed via reflection +fn register_types(app: &mut App) { + app.register_type::(); + app.register_type::(); + app.register_type::(); + app.register_type::(); +} + +pub trait AddRuntimeInitializer { + fn add_runtime_initializer( &mut self, - schedule: impl ScheduleLabel, - set: impl SystemSet, + initializer: RuntimeInitializer

, ) -> &mut Self; } -impl AddScriptHost for App { - fn add_script_host_to_set( +impl AddRuntimeInitializer for App { + fn add_runtime_initializer( &mut self, - schedule: impl ScheduleLabel, - set: impl SystemSet, - ) -> &mut Self - where - T: ScriptHost, - { - T::register_with_app_in_set(self, schedule, set); - self.init_resource::(); - self.add_event::(); - self - } - - fn add_script_host(&mut self, schedule: impl ScheduleLabel) -> &mut Self - where - T: ScriptHost, - { - T::register_with_app(self, schedule); - self.init_resource::(); - self.add_event::(); + initializer: RuntimeInitializer

, + ) -> &mut Self { + if !self.world_mut().contains_resource::>() { + self.world_mut().init_resource::>(); + } + self.world_mut() + .resource_mut::>() + .as_mut() + .initializers + .push(initializer); self } } -pub trait AddScriptApiProvider { - fn add_api_provider( +pub trait AddContextInitializer { + fn add_context_initializer( &mut self, - provider: Box< - dyn APIProvider< - APITarget = T::APITarget, - DocTarget = T::DocTarget, - ScriptContext = T::ScriptContext, - >, - >, + initializer: ContextInitializer

, ) -> &mut Self; } -impl AddScriptApiProvider for App { - fn add_api_provider( +impl AddContextInitializer for App { + fn add_context_initializer( &mut self, - provider: Box< - dyn APIProvider< - APITarget = T::APITarget, - DocTarget = T::DocTarget, - ScriptContext = T::ScriptContext, - >, - >, + initializer: ContextInitializer

, ) -> &mut Self { - provider.register_with_app(self); - let w = &mut self.world_mut(); - let providers: &mut APIProviders = &mut w.resource_mut(); - providers.providers.push(provider); + self.world_mut() + .init_resource::>(); + self.world_mut() + .resource_mut::>() + .as_mut() + .context_initializers + .push(initializer); self } } -pub trait AddScriptHostHandler { - /// Enables this script host to handle events with priorities in the range [0,min_prio] (inclusive), - /// during from within the given set. - /// - /// Note: this is identical to adding the script_event_handler system manually, so if you require more complex setup, you can use the following: - /// ```rust,ignore - /// self.add_systems( - /// MySchedule, - /// script_event_handler:: - /// ); - /// ``` - /// - /// Think of event handler systems as event sinks, which collect and "unpack" the instructions in each event every frame. - /// Because events are also prioritised, you can enforce a particular order of execution for your events (within each frame) - /// regardless of where they were fired from. - /// - /// A good example of this is Unity [game loop's](https://docs.unity3d.com/Manual/ExecutionOrder.html) `onUpdate` and `onFixedUpdate`. - /// FixedUpdate runs *before* any physics while Update runs after physics and input events. - /// - /// In this crate you can achieve this by using a separate system set before and after your physics, - /// then assigning event priorities such that your events are forced to run at the points you want them to, for example: - /// - /// PrePhysics priority range [0,1] - /// PostPhysics priority range [2,4] - /// - /// | Priority | Handler | Event | - /// | -------- | ----------- | ------------ | - /// | 0 | PrePhysics | Start 0 | - /// | 1 | PrePhysics | FixedUpdate 1 | - /// | 2 | PostPhysics | OnCollision 2 | - /// | 3 | PostPhysics | OnMouse 3 | - /// | 4 | PostPhysics | Update 4 | - /// - /// Note: in this example, if your FixedUpdate event is fired *after* the handler system set has run, it will be discarded (since other handlers discard events of higher priority). - fn add_script_handler( - &mut self, - schedule: impl ScheduleLabel, - ) -> &mut Self; - - /// The same as `add_script_handler` but allows you to specify a system set to add the handler to. - fn add_script_handler_to_set( +pub trait AddContextPreHandlingInitializer { + fn add_context_pre_handling_initializer( &mut self, - schedule: impl ScheduleLabel, - set: impl SystemSet, + initializer: ContextPreHandlingInitializer

, ) -> &mut Self; } -impl AddScriptHostHandler for App { - fn add_script_handler_to_set( +impl AddContextPreHandlingInitializer for App { + fn add_context_pre_handling_initializer( &mut self, - schedule: impl ScheduleLabel, - set: impl SystemSet, + initializer: ContextPreHandlingInitializer

, ) -> &mut Self { - self.add_systems(schedule, script_event_handler::.in_set(set)); + self.world_mut() + .resource_mut::>() + .as_mut() + .context_pre_handling_initializers + .push(initializer); self } +} - fn add_script_handler( - &mut self, - schedule: impl ScheduleLabel, - ) -> &mut Self { - self.add_systems(schedule, script_event_handler::); +pub trait StoreDocumentation { + /// Adds a documentation fragment to the documentation store. + fn add_documentation_fragment(&mut self, fragment: D) -> &mut Self; + /// Consumes all the stored documentation fragments, and merges them into one, then generates the documentation. + fn generate_docs(&mut self) -> Result<(), Box>; +} + +impl StoreDocumentation for App { + fn add_documentation_fragment(&mut self, fragment: D) -> &mut Self { + self.world_mut() + .init_non_send_resource::>(); + self.world_mut() + .non_send_resource_mut::>() + .as_mut() + .fragments + .push(fragment); self } + + fn generate_docs(&mut self) -> Result<(), Box> { + let mut docs = match self + .world_mut() + .remove_non_send_resource::>() + { + Some(docs) => docs, + None => return Ok(()), + }; + + let mut top_fragment = match docs.fragments.pop() { + Some(fragment) => fragment, + None => return Ok(()), + }; + + for fragment in docs.fragments.into_iter() { + top_fragment = top_fragment.merge(fragment); + } + + top_fragment.gen_docs() + } +} + +#[cfg(test)] +mod test { + use asset::AssetIdToScriptIdMap; + + use super::*; + + #[test] + fn test_default_scripting_plugin_initializes_all_resources_correctly() { + let mut app = App::new(); + + #[derive(Default, Clone)] + struct C; + #[derive(Default, Clone)] + struct R; + + struct Plugin; + + impl IntoScriptPluginParams for Plugin { + type C = C; + type R = R; + } + + app.add_plugins(AssetPlugin::default()); + app.add_plugins(ScriptingPlugin::::default()); + + assert!(app.world().contains_resource::()); + assert!(app.world().contains_resource::()); + assert!(app.world().contains_resource::()); + assert!(app.world().contains_resource::>()); + assert!(app.world().contains_resource::>()); + assert!(app + .world() + .contains_resource::>()); + assert!(app.world().contains_non_send::>()); + assert!(app.world().contains_non_send::>()); + assert!(app.world().contains_resource::()); + } } diff --git a/crates/bevy_mod_scripting_core/src/reflection_extensions.rs b/crates/bevy_mod_scripting_core/src/reflection_extensions.rs new file mode 100644 index 00000000..29d8dfa3 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/reflection_extensions.rs @@ -0,0 +1,657 @@ +use crate::{ + bindings::{ReflectReference, WorldGuard}, + error::InteropError, +}; +use bevy::reflect::{ + func::Return, FromReflect, PartialReflect, Reflect, ReflectFromReflect, ReflectMut, TypeInfo, +}; +use std::{ + any::{Any, TypeId}, + cmp::max, +}; +/// Extension trait for [`PartialReflect`] providing additional functionality for working with specific types. +pub trait PartialReflectExt { + fn try_remove_boxed( + &mut self, + key: Box, + ) -> Result>, InteropError>; + + fn convert_to_0_indexed_key(&mut self); + + fn from_reflect_or_clone( + reflect: &dyn PartialReflect, + world: WorldGuard, + ) -> Box; + fn allocate_cloned(&self, world: WorldGuard) -> ReflectReference; + fn allocate(boxed: Box, world: WorldGuard) -> ReflectReference; + + /// Check if the represented type is from the given crate and has the given type identifier, + /// returns false if not representing any type or if the type is not from the given crate or does not have the given type identifier. + fn is_type(&self, crate_name: Option<&str>, type_ident: &str) -> bool; + + /// Equivalent to [`PartialReflectExt::is_type`] but returns an appropriate error if the type is not the expected one. + fn expect_type(&self, crate_name: Option<&str>, type_ident: &str) -> Result<(), InteropError>; + + /// If the type is an option, returns either the inner value or None if the option is None. + /// Errors if the type is not an option. + fn as_option(&self) -> Result, InteropError>; + + /// Similar to [`PartialReflectExt::as_option`] but for mutable references. + fn as_option_mut(&mut self) -> Result, InteropError>; + + /// If the type is an iterable list-like type, returns an iterator over the elements. + fn as_list(&self) -> Result, InteropError>; + + /// If the type is a usize, returns the value as a usize otherwise throws a convenient error + fn as_usize(&self) -> Result; + + /// If the type is an iterable list-like type, sets the elements of the list to the elements of the other list-like type. + /// This acts as a set operation, so the left list will have the same length as the right list after this operation. + fn set_as_list< + F: Fn(&mut dyn PartialReflect, &dyn PartialReflect) -> Result<(), InteropError>, + >( + &mut self, + other: Box, + apply: F, + ) -> Result<(), InteropError>; + + /// Inserts into the type at the given key, if the type supports inserting with the given key + fn try_insert_boxed( + &mut self, + index: Box, + value: Box, + ) -> Result<(), InteropError>; + + /// Tries to insert the given value into the type, if the type is a container type. + /// The insertion will happen at the natural `end` of the container. + /// For lists, this is the length of the list. + /// For sets, this will simply insert the value into the set. + /// For maps, there is no natural `end`, so the push will error out + fn try_push_boxed(&mut self, value: Box) -> Result<(), InteropError>; + + // If the type has a natural last element to pop, pops the last element and returns it as a boxed value. + fn try_pop_boxed(&mut self) -> Result, InteropError>; + + /// If the type is a container type, empties the contents + fn try_clear(&mut self) -> Result<(), InteropError>; + + /// If the type is a container type, returns the type id of the elements in the container. + /// For maps, this is the type id of the values. + fn element_type_id(&self) -> Option; + + /// If the type is a container type, returns the type id of the keys in the container. + /// For lists and arrays, this is the type id of usize. + /// For maps, this is the type id of the keys. + fn key_type_id(&self) -> Option; + + /// Tries to construct the concrete underlying type from a possibly untyped reference + fn from_reflect( + reflect: &dyn PartialReflect, + world: WorldGuard, + ) -> Result, InteropError>; +} +pub trait TypeIdExtensions { + fn or_fake_id(&self) -> TypeId; +} + +pub(crate) struct FakeType; + +impl TypeIdExtensions for Option { + fn or_fake_id(&self) -> TypeId { + match self { + Some(t) => *t, + None => TypeId::of::(), + } + } +} + +impl PartialReflectExt for T { + fn is_type(&self, crate_name: Option<&str>, type_ident: &str) -> bool { + self.get_represented_type_info().is_some_and(|v| { + let table = v.type_path_table(); + table.crate_name() == crate_name && table.ident() == Some(type_ident) + }) + } + + fn expect_type(&self, crate_name: Option<&str>, type_ident: &str) -> Result<(), InteropError> { + if !self.is_type(crate_name, type_ident) { + return Err(InteropError::string_type_mismatch( + type_ident.to_owned(), + self.get_represented_type_info().map(|ti| ti.type_id()), + )); + } + Ok(()) + } + + fn as_option(&self) -> Result, InteropError> { + if let bevy::reflect::ReflectRef::Enum(e) = self.reflect_ref() { + if let Some(field) = e.field_at(0) { + return Ok(Some(field)); + } else { + return Ok(None); + } + } + + Err(InteropError::string_type_mismatch( + "Option".to_owned(), + self.get_represented_type_info().map(|ti| ti.type_id()), + )) + } + + fn as_option_mut(&mut self) -> Result, InteropError> { + let type_info = self.get_represented_type_info().map(|ti| ti.type_path()); + match self.reflect_mut() { + bevy::reflect::ReflectMut::Enum(e) => { + if let Some(field) = e.field_at_mut(0) { + Ok(Some(field)) + } else { + Ok(None) + } + } + _ => Err(InteropError::string_type_mismatch( + "Option".to_owned(), + type_info.map(|t| t.type_id()), + )), + } + } + + fn as_list(&self) -> Result, InteropError> { + if let bevy::reflect::ReflectRef::List(l) = self.reflect_ref() { + Ok(l.iter()) + } else { + Err(InteropError::string_type_mismatch( + "List".to_owned(), + self.get_represented_type_info().map(|ti| ti.type_id()), + )) + } + } + + fn set_as_list< + F: Fn(&mut dyn PartialReflect, &dyn PartialReflect) -> Result<(), InteropError>, + >( + &mut self, + mut other: Box, + apply: F, + ) -> Result<(), InteropError> { + match (self.reflect_mut(), other.reflect_mut()) { + (ReflectMut::List(l), ReflectMut::List(r)) => { + let to_be_inserted_elems = max(r.len() as isize - l.len() as isize, 0) as usize; + let apply_range = 0..(r.len() - to_be_inserted_elems); + + // remove in reverse order + (r.len()..l.len()).rev().for_each(|i| { + l.remove(i); + }); + + // pop then insert in reverse order of popping (last elem -> first elem to insert) + let to_insert = (0..to_be_inserted_elems) + .rev() + .map(|_| r.pop().expect("invariant")) + .collect::>(); + + to_insert.into_iter().rev().for_each(|e| { + l.push(e); + }); + + // at this point l is at least as long as r + + // apply to existing elements in the list + for i in apply_range { + apply( + l.get_mut(i).expect("invariant"), + r.get(i).expect("invariant"), + )?; + } + + Ok(()) + } + (ReflectMut::List(_), _) => Err(InteropError::string_type_mismatch( + "List".to_owned(), + other.get_represented_type_info().map(|ti| ti.type_id()), + )), + (_, _) => Err(InteropError::string_type_mismatch( + "List".to_owned(), + self.get_represented_type_info().map(|ti| ti.type_id()), + )), + } + } + + fn as_usize(&self) -> Result { + self.as_partial_reflect() + .try_downcast_ref::() + .copied() + .ok_or_else(|| { + InteropError::type_mismatch( + TypeId::of::(), + self.get_represented_type_info().map(|ti| ti.type_id()), + ) + }) + } + + fn try_insert_boxed( + &mut self, + key: Box, + value: Box, + ) -> Result<(), InteropError> { + match self.reflect_mut() { + bevy::reflect::ReflectMut::List(l) => { + l.insert(key.as_usize()?, value); + Ok(()) + } + bevy::reflect::ReflectMut::Map(m) => { + m.insert_boxed(key, value); + Ok(()) + } + bevy::reflect::ReflectMut::Set(s) => { + s.insert_boxed(value); + Ok(()) + } + _ => Err(InteropError::unsupported_operation( + self.get_represented_type_info().map(|ti| ti.type_id()), + Some(value), + "insert".to_owned(), + )), + } + } + + fn try_push_boxed(&mut self, value: Box) -> Result<(), InteropError> { + match self.reflect_mut() { + bevy::reflect::ReflectMut::List(l) => { + l.push(value); + Ok(()) + } + bevy::reflect::ReflectMut::Set(s) => { + s.insert_boxed(value); + Ok(()) + } + _ => Err(InteropError::unsupported_operation( + self.get_represented_type_info().map(|ti| ti.type_id()), + Some(value), + "push".to_owned(), + )), + } + } + + fn convert_to_0_indexed_key(&mut self) { + if let Some(type_id) = self.get_represented_type_info().map(|ti| ti.type_id()) { + if type_id == TypeId::of::() { + let self_ = self + .as_partial_reflect_mut() + .try_downcast_mut::() + .expect("invariant"); + + *self_ = self_.saturating_sub(1); + } + } + } + + fn try_clear(&mut self) -> Result<(), InteropError> { + match self.reflect_mut() { + bevy::reflect::ReflectMut::List(l) => { + let _ = l.drain(); + Ok(()) + } + bevy::reflect::ReflectMut::Map(m) => { + let _ = m.drain(); + Ok(()) + } + bevy::reflect::ReflectMut::Set(s) => { + let _ = s.drain(); + Ok(()) + } + _ => Err(InteropError::unsupported_operation( + self.get_represented_type_info().map(|ti| ti.type_id()), + None, + "clear".to_owned(), + )), + } + } + + fn try_pop_boxed(&mut self) -> Result, InteropError> { + match self.reflect_mut() { + bevy::reflect::ReflectMut::List(l) => l.pop().ok_or_else(|| { + InteropError::unsupported_operation( + self.get_represented_type_info().map(|ti| ti.type_id()), + None, + "pop from empty list".to_owned(), + ) + }), + _ => Err(InteropError::unsupported_operation( + self.get_represented_type_info().map(|ti| ti.type_id()), + None, + "pop".to_owned(), + )), + } + } + + fn try_remove_boxed( + &mut self, + key: Box, + ) -> Result>, InteropError> { + match self.reflect_mut() { + bevy::reflect::ReflectMut::List(l) => Ok(Some(l.remove(key.as_usize()?))), + bevy::reflect::ReflectMut::Map(m) => Ok(m.remove(key.as_partial_reflect())), + bevy::reflect::ReflectMut::Set(s) => { + let removed = s.remove(key.as_partial_reflect()); + Ok(removed.then_some(key)) + } + _ => Err(InteropError::unsupported_operation( + self.get_represented_type_info().map(|ti| ti.type_id()), + Some(key), + "remove".to_owned(), + )), + } + } + + fn element_type_id(&self) -> Option { + let elem: TypeId = match self.get_represented_type_info()? { + bevy::reflect::TypeInfo::List(list_info) => list_info.item_ty().id(), + bevy::reflect::TypeInfo::Array(array_info) => array_info.item_ty().id(), + bevy::reflect::TypeInfo::Map(map_info) => map_info.value_ty().id(), + bevy::reflect::TypeInfo::Set(set_info) => set_info.value_ty().id(), + _ => return None, + }; + Some(elem) + } + + fn key_type_id(&self) -> Option { + let key: TypeId = match self.get_represented_type_info()? { + bevy::reflect::TypeInfo::Map(map_info) => map_info.key_ty().id(), + bevy::reflect::TypeInfo::List(_) | bevy::reflect::TypeInfo::Array(_) => { + TypeId::of::() + } + _ => return None, + }; + Some(key) + } + + fn from_reflect( + reflect: &dyn PartialReflect, + world: WorldGuard, + ) -> Result, InteropError> { + let type_info = reflect.get_represented_type_info().ok_or_else(|| { + InteropError::failed_from_reflect( + None, + "tried to construct a concrete type from dynamic type with no type information" + .to_owned(), + ) + })?; + let type_id = type_info.type_id(); + + let type_registry = world.type_registry(); + let type_registry = type_registry.read(); + + let from_reflect_type_data: &ReflectFromReflect = + type_registry.get_type_data(type_id).ok_or_else(|| { + InteropError::missing_type_data(type_id, "ReflectFromReflect".to_owned()) + })?; + from_reflect_type_data.from_reflect(reflect).ok_or_else(|| { + InteropError::failed_from_reflect( + Some(type_id), + "from_reflect returned None".to_owned(), + ) + }) + } + + /// Try creating an owned partial reflect from a reference. Will try using [`ReflectFromReflect`] first, and if that fails, will clone the value using [`PartialReflect::clone_value`]. + fn from_reflect_or_clone( + reflect: &dyn PartialReflect, + world: WorldGuard, + ) -> Box { + // try from reflect + match ::from_reflect(reflect, world.clone()) { + Ok(v) => v.into_partial_reflect(), + Err(_) => reflect.clone_value(), + } + } + + fn allocate(boxed: Box, world: WorldGuard) -> ReflectReference { + let allocator = world.allocator(); + let mut allocator = allocator.write(); + ReflectReference::new_allocated_boxed(boxed, &mut allocator) + } + + fn allocate_cloned(&self, world: WorldGuard) -> ReflectReference { + let boxed = self.clone_value(); + Self::allocate(boxed, world) + } +} + +pub trait TypeInfoExtensions { + fn list_inner_type(&self) -> Option; + fn is_list(&self) -> bool; + fn is_option(&self) -> bool; + fn option_inner_type(&self) -> Option; + fn is_type(&self, crate_name: Option<&str>, type_ident: &str) -> bool; +} + +impl TypeInfoExtensions for TypeInfo { + fn is_option(&self) -> bool { + self.is_type(Some("core"), "Option") + } + + fn is_list(&self) -> bool { + matches!(self, TypeInfo::List(_)) + } + + fn option_inner_type(&self) -> Option { + if self.is_option() { + self.generics().first().map(|g| g.type_id()) + } else { + None + } + } + + fn list_inner_type(&self) -> Option { + Some(self.as_list().ok()?.item_ty().id()) + } + + fn is_type(&self, crate_name: Option<&str>, type_ident: &str) -> bool { + self.type_path_table().ident() == Some(type_ident) + && self.type_path_table().crate_name() == crate_name + } +} + +pub trait ReturnValExt<'a> { + fn try_into_or_boxed( + self, + ) -> Result>; + fn as_ref(&'a self) -> &'a dyn PartialReflect; +} + +impl<'a> ReturnValExt<'a> for Return<'a> { + fn as_ref(&'a self) -> &'a dyn PartialReflect { + match self { + Return::Owned(f) => f.as_partial_reflect(), + Return::Ref(r) => r.as_partial_reflect(), + Return::Mut(r) => r.as_partial_reflect(), + } + } + + fn try_into_or_boxed( + self, + ) -> Result> { + match self { + Return::Owned(partial_reflect) => partial_reflect.try_take::(), + Return::Ref(r) => T::from_reflect(r).ok_or_else(|| r.clone_value()), + Return::Mut(r) => T::from_reflect(r).ok_or_else(|| r.clone_value()), + } + } +} + +#[cfg(test)] +mod test { + use bevy::reflect::{DynamicMap, Map}; + + use super::*; + + #[test] + fn test_type_info_is_option() { + let type_info = Some("hello").get_represented_type_info().unwrap(); + assert!(type_info.is_option()); + } + + #[test] + fn test_type_info_is_type() { + let type_info = Some("hello").get_represented_type_info().unwrap(); + assert!(type_info.is_type(Some("core"), "Option")); + } + + #[test] + fn test_type_no_crate() { + assert!(42.is_type(None, "i32")); + assert!(42.expect_type(None, "i32").is_ok()); + } + + #[test] + fn test_is_type_with_crate() { + assert!(Some(42).is_type(Some("core"), "Option")); + assert!(Some(42).expect_type(Some("core"), "Option").is_ok()); + } + + #[test] + fn test_is_type_negative() { + assert!(!Some(42).is_type(Some("std"), "Option")); + } + + #[test] + fn test_as_option_some() { + assert_eq!( + &42, + Some(42) + .as_option() + .unwrap() + .unwrap() + .try_downcast_ref::() + .unwrap() + ); + } + + #[test] + fn test_as_option_none() { + assert!(None::.as_option().unwrap().is_none()); + } + + #[test] + fn test_as_list() { + let list = vec![1, 2, 3]; + let list_ref: &dyn PartialReflect = &list; + let iter = list_ref + .as_list() + .unwrap() + .map(|r| *r.try_downcast_ref::().unwrap()) + .collect::>(); + assert_eq!(list, iter); + } + + #[test] + fn test_set_as_list_equal_length() { + let mut list = vec![1, 2, 3]; + let other = vec![4, 5, 6]; + let other_ref: Box = Box::new(other.clone()); + list.set_as_list(other_ref, |l, r| { + *l.try_downcast_mut::().unwrap() = *r.try_downcast_ref::().unwrap(); + Ok(()) + }) + .unwrap(); + assert_eq!(other, list); + } + + #[test] + fn test_set_as_list_shortening() { + let mut list = vec![1, 2, 3]; + let other = vec![4, 5]; + let other_ref: Box = Box::new(other.clone()); + list.set_as_list(other_ref, |l, r| { + *l.try_downcast_mut::().unwrap() = *r.try_downcast_ref::().unwrap(); + Ok(()) + }) + .unwrap(); + assert_eq!(other, list); + } + + #[test] + fn test_set_as_list_lengthening() { + let mut list = vec![1, 2]; + let other = vec![4, 5, 6]; + let other_ref: Box = Box::new(other.clone()); + list.set_as_list(other_ref, |l, r| { + *l.try_downcast_mut::().unwrap() = *r.try_downcast_ref::().unwrap(); + Ok(()) + }) + .unwrap(); + assert_eq!(other, list); + } + + #[test] + fn test_set_as_list_empty() { + let mut list = vec![1, 2]; + let other = Vec::::default(); + let other_ref: Box = Box::new(other.clone()); + list.set_as_list(other_ref, |l, r| { + *l.try_downcast_mut::().unwrap() = *r.try_downcast_ref::().unwrap(); + Ok(()) + }) + .unwrap(); + assert_eq!(other, list); + } + + #[test] + fn test_set_as_list_targe_empty() { + let mut list = Vec::::default(); + let other = vec![1]; + let other_ref: Box = Box::new(other.clone()); + list.set_as_list(other_ref, |l, r| { + *l.try_downcast_mut::().unwrap() = *r.try_downcast_ref::().unwrap(); + Ok(()) + }) + .unwrap(); + assert_eq!(other, list); + } + + #[test] + fn test_try_insert_vec() { + let mut list = vec![1, 2, 3]; + let value = 4; + let value_ref: Box = Box::new(value); + list.try_insert_boxed(Box::new(1usize), value_ref).unwrap(); + assert_eq!(vec![1, 4, 2, 3], list); + } + + #[test] + fn test_try_insert_map() { + let mut map = std::collections::HashMap::::default(); + let value = 4; + let value_ref: Box = Box::new(value); + map.insert(1, 2); + map.insert(2, 3); + map.insert(3, 4); + map.try_insert_boxed(Box::new(1), value_ref).unwrap(); + assert_eq!(4, map[&1]); + } + + #[test] + fn test_try_insert_set() { + let mut set = std::collections::HashSet::::default(); + let value = 4; + let value_ref: Box = Box::new(value); + set.insert(1); + set.insert(2); + set.insert(3); + set.try_insert_boxed(Box::new(1), value_ref).unwrap(); + assert!(set.contains(&4)); + } + + #[test] + fn test_try_insert_dynamic_map_into_map_of_maps() { + let mut map = + std::collections::HashMap::>::default(); + let value = DynamicMap::from_iter(vec![(1, 2), (2, 3), (3, 4)]); + let value_ref: Box = Box::new(value.clone_dynamic()); + map.insert(1, std::collections::HashMap::::default()); + map.insert(2, std::collections::HashMap::::default()); + map.insert(3, std::collections::HashMap::::default()); + map.try_insert_boxed(Box::new(1), value_ref).unwrap(); + assert!(value.reflect_partial_eq(&map[&1]).unwrap()); + } +} diff --git a/crates/bevy_mod_scripting_core/src/runtime.rs b/crates/bevy_mod_scripting_core/src/runtime.rs new file mode 100644 index 00000000..8f0a6aa1 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/runtime.rs @@ -0,0 +1,37 @@ +//! "Runtime" here refers to the execution evironment of scripts. This might be the VM executing bytecode or the interpreter executing source code. +//! The important thing is that there is only one runtime which is used to execute all scripts of a particular type or `context`. + +use crate::IntoScriptPluginParams; +use bevy::ecs::system::Resource; + +pub trait Runtime: 'static {} +impl Runtime for T {} + +pub type RuntimeInitializer

= fn(&mut

::R); + +#[derive(Resource)] +pub struct RuntimeSettings { + pub initializers: Vec>, +} + +impl Default for RuntimeSettings

{ + fn default() -> Self { + Self { + initializers: Default::default(), + } + } +} + +impl Clone for RuntimeSettings

{ + fn clone(&self) -> Self { + Self { + initializers: self.initializers.clone(), + } + } +} + +/// Stores a particular runtime. +#[derive(Resource)] +pub struct RuntimeContainer { + pub runtime: P::R, +} diff --git a/crates/bevy_mod_scripting_core/src/script.rs b/crates/bevy_mod_scripting_core/src/script.rs new file mode 100644 index 00000000..0afcc20b --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/script.rs @@ -0,0 +1,40 @@ +//! 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}; + +pub type ScriptId = Cow<'static, str>; + +#[derive(bevy::ecs::component::Component, Reflect, Clone)] +pub struct ScriptComponent(pub Vec); + +impl Deref for ScriptComponent { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl ScriptComponent { + pub fn new(components: Vec) -> Self { + Self(components) + } +} + +/// All the scripts which are currently loaded or loading and their mapping to contexts +#[derive(Resource, Default, Clone)] +pub struct Scripts { + pub(crate) scripts: HashMap, +} + +/// A script +#[derive(Clone)] +pub struct Script { + pub id: ScriptId, + /// the asset holding the content of the script if it comes from an asset + pub asset: Option>, + /// The id of the context this script is currently assigned to + pub context_id: ContextId, +} diff --git a/crates/bevy_mod_scripting_core/src/systems.rs b/crates/bevy_mod_scripting_core/src/systems.rs index d7512a41..632a5ac8 100644 --- a/crates/bevy_mod_scripting_core/src/systems.rs +++ b/crates/bevy_mod_scripting_core/src/systems.rs @@ -1,233 +1,470 @@ -use std::collections::HashSet; - -use bevy::{ecs::system::SystemState, prelude::*}; -use bevy_event_priority::PriorityEventReader; - use crate::{ - event::ScriptLoaded, - prelude::{APIProviders, Script, ScriptCollection, ScriptContexts, ScriptData, ScriptHost}, - ScriptErrorEvent, + asset::{AssetIdToScriptIdMap, ScriptAsset, ScriptAssetSettings}, + bindings::{pretty_print::DisplayWithWorld, AppReflectAllocator, WorldAccessGuard, WorldGuard}, + commands::{CreateOrUpdateScript, DeleteScript}, + context::{ContextLoadingSettings, ScriptContexts}, + error::ScriptError, + event::{IntoCallbackLabel, ScriptCallbackEvent, ScriptErrorEvent}, + handler::CallbackSettings, + runtime::{RuntimeContainer, RuntimeSettings}, + script::{ScriptComponent, Scripts}, + IntoScriptPluginParams, }; +use bevy::{ecs::system::SystemState, prelude::*}; +use std::any::type_name; -/// Labels for scripting related systems -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, SystemSet)] -pub enum ScriptSystemSet { - /// event handling systems are always marked with this label - EventHandling, +/// Cleans up dangling script allocations +pub fn garbage_collector(allocator: ResMut) { + let mut allocator = allocator.write(); + allocator.clean_garbage_allocations() } -/// Handles creating contexts for new/modified scripts -/// Scripts are likely not loaded instantly at this point, so most of the time -/// this system simply inserts an empty context -pub fn script_add_synchronizer( - query: Query< - ( - Entity, - &ScriptCollection, - Ref>, - ), - Changed>, - >, - mut host: ResMut, - mut providers: ResMut>, - script_assets: Res>, - mut contexts: ResMut>, - mut event_writer: EventWriter, - mut error_writer: EventWriter, +pub fn initialize_runtime( + mut runtime: NonSendMut>, + settings: Res>, ) { - debug!("Handling addition/modification of scripts"); - - query.iter().for_each(|(entity, new_scripts, tracker)| { - if tracker.is_added() { - new_scripts.scripts.iter().for_each(|new_script| { - Script::::insert_new_script_context::( - &mut host, - new_script, - entity, - &script_assets, - &mut providers, - &mut contexts, - &mut event_writer, - &mut error_writer, - ) - }) - } else { - // changed but structure already exists in contexts - // find out what's changed - // we only care about added or removed scripts here - // if the script asset gets changed we deal with that elsewhere + for initializer in settings.initializers.iter() { + (initializer)(&mut runtime.runtime); + } +} - let context_ids = contexts - .context_entities - .iter() - .filter_map(|(sid, (e, _, _))| if *e == entity { Some(sid) } else { None }) - .cloned() - .collect::>(); - let script_ids = new_scripts - .scripts - .iter() - .map(|s| s.id()) - .collect::>(); +/// Processes and reacts appropriately to script asset events, and queues commands to update the internal script state +pub fn sync_script_data( + mut events: EventReader>, + script_assets: Res>, + asset_settings: Res, + mut asset_path_map: ResMut, + mut commands: Commands, +) { + for event in events.read() { + trace!("Received script asset event: {:?}", event); + let (id, remove) = 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 removed_scripts = context_ids.difference(&script_ids); - let added_scripts = script_ids.difference(&context_ids); + 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, + None => { + // this can happen if an asset is loaded and immediately unloaded, we can ignore this + continue; + } + }; - for r in removed_scripts { - contexts.remove_context(*r); - } + 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()); - for a in added_scripts { - let script = new_scripts.scripts.iter().find(|e| &e.id() == a).unwrap(); - Script::::insert_new_script_context::( - &mut host, - script, - entity, - &script_assets, - &mut providers, - &mut contexts, - &mut event_writer, - &mut error_writer, - ) + script_id } + }; + + 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; + } + }; + 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)); } - }) + } } -/// Handles the removal of script components and their contexts -pub fn script_remove_synchronizer( - mut query: RemovedComponents>, - mut contexts: ResMut>, -) { - for v in query.read() { - // we know that this entity used to have a script component - // ergo a script context must exist in ctxts, remove all scripts on the entity - let script_ids = contexts - .context_entities - .iter() - .filter_map(|(script_id, (entity, ..))| { - (entity.index() == v.index()).then_some(*script_id) - }) - .collect::>(); - for script_id in script_ids { - contexts.remove_context(script_id); +macro_rules! push_err_and_continue { + ($errors:ident, $expr:expr) => { + match $expr { + Ok(v) => v, + Err(e) => { + $errors.push(e); + continue; + } } - } + }; } -/// Reloads hot-reloaded scripts, or loads missing contexts for scripts which were added but not loaded -pub fn script_hot_reload_handler( - mut events: EventReader>, - mut host: ResMut, - scripts: Query<&ScriptCollection>, - script_assets: Res>, - mut providers: ResMut>, - mut contexts: ResMut>, - mut event_writer: EventWriter, - mut error_writer: EventWriter, +/// Passes events with the specified label to the script callback with the same name and runs the callback +pub fn event_handler( + world: &mut World, + params: &mut SystemState<( + EventReader, + Res>, + Res>, + Res, + Query<(Entity, Ref)>, + )>, ) { - for e in events.read() { - let (handle, created) = match e { - AssetEvent::Modified { id } => (id, false), - AssetEvent::Added { id } => (id, true), - _ => continue, - }; + trace!("Handling events with label `{}`", L::into_callback_label()); + + let mut runtime_container = world + .remove_non_send_resource::>() + .unwrap_or_else(|| { + panic!( + "No runtime container for runtime {} found. Was the scripting plugin initialized correctly?", + type_name::() + ) + }); + let runtime = &mut runtime_container.runtime; + let mut script_contexts = world + .remove_non_send_resource::>() + .unwrap_or_else(|| panic!("No script contexts found for context {}", type_name::

())); - // find script using this handle by handle id - // whether this script was modified or created - // if a script exists with this handle, we should reload it to load in a new context - // which at this point will be either None or Some(outdated context) - // both ways are fine - for scripts in scripts.iter() { - for script in &scripts.scripts { - // the script could have well loaded in the same frame that it was added - // in that case it will have a context attached and we do not want to reload it - if script.handle().id() == *handle - && !(contexts.has_context(script.id()) && created) - { - Script::::reload_script::( - &mut host, - script, - &script_assets, - &mut providers, - &mut contexts, - &mut event_writer, - &mut error_writer, - ); + let (mut script_events, callback_settings, context_settings, scripts, entities) = + params.get_mut(world); + + let handler = *callback_settings + .callback_handler + .as_ref() + .unwrap_or_else(|| { + panic!( + "No handler registered for - Runtime: {}, Context: {}", + type_name::(), + type_name::() + ) + }); + let pre_handling_initializers = context_settings.context_pre_handling_initializers.clone(); + let scripts = scripts.clone(); + let mut errors = Vec::default(); + + let events = script_events.read().cloned().collect::>(); + let entity_scripts = entities + .iter() + .map(|(e, s)| (e, s.0.clone())) + .collect::>(); + + for event in events + .into_iter() + .filter(|e| e.label == L::into_callback_label()) + { + for (entity, entity_scripts) in entity_scripts.iter() { + for script_id in entity_scripts.iter() { + match &event.recipients { + crate::event::Recipients::Script(target_script_id) + if target_script_id != script_id => + { + continue + } + crate::event::Recipients::Entity(target_entity) if target_entity != entity => { + continue + } + _ => (), } + debug!( + "Handling event for script {} on entity {:?}", + script_id, entity + ); + let script = match scripts.scripts.get(script_id) { + Some(s) => s, + None => { + trace!( + "Script `{}` on entity `{:?}` is either still loading or doesn't exist, ignoring.", + script_id, entity + ); + continue; + } + }; + let ctxt = script_contexts + .contexts + .get_mut(&script.context_id) + .unwrap(); + + let handler_result = (handler)( + event.args.clone(), + *entity, + &script.id, + &L::into_callback_label(), + ctxt, + &pre_handling_initializers, + runtime, + world, + ) + .map_err(|e| { + e.with_script(script.id.clone()).with_context(format!( + "Event handling for: Runtime {}, Context: {}", + type_name::(), + type_name::(), + )) + }); + + push_err_and_continue!(errors, handler_result) } } } + + world.insert_non_send_resource(runtime_container); + world.insert_non_send_resource(script_contexts); + + handle_script_errors(world, errors.into_iter()); } -/// Lets the script host handle all script events -pub fn script_event_handler(world: &mut World) { - // we need to collect the events to drop the borrow of the world - let mut state: CachedScriptState = world.remove_resource().unwrap(); +/// Handles errors caused by script execution and sends them to the error event channel +pub(crate) fn handle_script_errors + Clone>( + world: &mut World, + errors: I, +) { + let mut error_events = world + .get_resource_mut::>() + .expect("Missing events resource"); - let events = state - .event_state - .get_mut(world) - .0 - .iter_prio_range(MAX, MIN) - .collect::>(); + for error in errors.clone() { + error_events.send(ScriptErrorEvent { error }); + } + + for error in errors { + let arc_world = WorldGuard::new(WorldAccessGuard::new(world)); + bevy::log::error!("{}", error.display_with_world(arc_world)); + } +} + +#[cfg(test)] +mod test { + use std::{borrow::Cow, collections::HashMap}; - world.insert_resource(state); + use crate::{ + bindings::script_value::ScriptValue, + event::CallbackLabel, + handler::HandlerFn, + script::{Script, ScriptId}, + }; - // should help a lot with performance on frames where no events are fired - if events.is_empty() { - return; + use super::*; + struct OnTestCallback; + + impl IntoCallbackLabel for OnTestCallback { + fn into_callback_label() -> CallbackLabel { + "OnTest".into() + } } - let mut ctxts: ScriptContexts = world.remove_resource().unwrap(); - - let mut host: H = world.remove_resource().unwrap(); - let mut providers: APIProviders = world.remove_resource().unwrap(); - - // we need a resource scope to be able to simultaneously access the contexts as well - // as provide world access to scripts - // afaik there is not really a better way to do this in bevy just now - let ctx_iter = ctxts - .context_entities - .iter_mut() - .filter_map(|(sid, (entity, o, name))| { - let ctx = match o { - Some(v) => v, - None => return None, - }; + struct TestPlugin; - Some(( - ScriptData { - sid: *sid, - entity: *entity, - name, - }, - ctx, - )) + impl IntoScriptPluginParams for TestPlugin { + type C = TestContext; + type R = TestRuntime; + } + + struct TestRuntime { + pub invocations: Vec<(Entity, ScriptId)>, + } + + struct TestContext { + pub invocations: Vec, + } + + fn setup_app( + handler_fn: HandlerFn

, + runtime: P::R, + contexts: HashMap, + scripts: HashMap, + ) -> App { + let mut app = App::new(); + + app.add_event::(); + app.add_event::(); + app.insert_resource::>(CallbackSettings { + callback_handler: Some(handler_fn), + }); + app.add_systems(Update, event_handler::); + app.insert_resource::(Scripts { scripts }); + app.insert_non_send_resource(RuntimeContainer::

{ runtime }); + app.insert_non_send_resource(ScriptContexts::

{ contexts }); + app.insert_resource(ContextLoadingSettings::

{ + loader: None, + assigner: None, + context_initializers: vec![], + context_pre_handling_initializers: vec![], }); + app.finish(); + app.cleanup(); + app + } + + #[test] + fn test_handler_called_with_right_args() { + let test_script_id = Cow::Borrowed("test_script"); + let test_ctxt_id = 0; + let test_script = Script { + id: test_script_id.clone(), + asset: None, + context_id: test_ctxt_id, + }; + let scripts = HashMap::from_iter(vec![(test_script_id.clone(), test_script.clone())]); + let contexts = HashMap::from_iter(vec![( + test_ctxt_id, + TestContext { + invocations: vec![], + }, + )]); + let runtime = TestRuntime { + invocations: vec![], + }; + let mut app = setup_app::( + |args, entity, script, _, ctxt, _, runtime, _| { + ctxt.invocations.extend(args); + runtime.invocations.push((entity, script.clone())); + Ok(()) + }, + runtime, + contexts, + scripts, + ); + let test_entity_id = app + .world_mut() + .spawn(ScriptComponent(vec![test_script_id.clone()])) + .id(); - // safety: we have unique access to world, future accesses are protected - // by the lock in the pointer - host.handle_events(world, &events, ctx_iter, &mut providers); + app.world_mut().send_event(ScriptCallbackEvent::new_for_all( + OnTestCallback::into_callback_label(), + vec![ScriptValue::String("test_args".into())], + )); + app.update(); - world.insert_resource(ctxts); - world.insert_resource(host); - world.insert_resource(providers); -} + let test_context = app + .world() + .get_non_send_resource::>() + .unwrap(); + let test_runtime = app + .world() + .get_non_send_resource::>() + .unwrap(); -#[derive(Resource)] -/// system state for exclusive systems dealing with script events -pub struct CachedScriptState { - pub event_state: SystemState<( - PriorityEventReader<'static, 'static, H::ScriptEvent>, - EventWriter<'static, ScriptErrorEvent>, - EventReader<'static, 'static, ScriptLoaded>, - )>, -} + assert_eq!( + test_context + .contexts + .get(&test_ctxt_id) + .unwrap() + .invocations, + vec![ScriptValue::String("test_args".into())] + ); -impl FromWorld for CachedScriptState { - fn from_world(world: &mut World) -> Self { - Self { - event_state: SystemState::new(world), - } + assert_eq!( + test_runtime + .runtime + .invocations + .iter() + .map(|(e, s)| (*e, s.clone())) + .collect::>(), + vec![(test_entity_id, test_script_id.clone())] + ); + } + + #[test] + fn test_handler_called_on_right_recipients() { + let test_script_id = Cow::Borrowed("test_script"); + let test_ctxt_id = 0; + let test_script = Script { + id: test_script_id.clone(), + asset: None, + context_id: test_ctxt_id, + }; + let scripts = HashMap::from_iter(vec![ + (test_script_id.clone(), test_script.clone()), + ( + "wrong".into(), + Script { + id: "wrong".into(), + asset: None, + context_id: 1, + }, + ), + ]); + let contexts = HashMap::from_iter(vec![ + ( + test_ctxt_id, + TestContext { + invocations: vec![], + }, + ), + ( + 1, + TestContext { + invocations: vec![], + }, + ), + ]); + let runtime = TestRuntime { + invocations: vec![], + }; + let mut app = setup_app::( + |args, entity, script, _, ctxt, _, runtime, _| { + ctxt.invocations.extend(args); + runtime.invocations.push((entity, script.clone())); + Ok(()) + }, + runtime, + contexts, + scripts, + ); + let test_entity_id = app + .world_mut() + .spawn(ScriptComponent(vec![test_script_id.clone()])) + .id(); + + app.world_mut().send_event(ScriptCallbackEvent::new( + OnTestCallback::into_callback_label(), + vec![ScriptValue::String("test_args_script".into())], + crate::event::Recipients::Script(test_script_id.clone()), + )); + + app.world_mut().send_event(ScriptCallbackEvent::new( + OnTestCallback::into_callback_label(), + vec![ScriptValue::String("test_args_entity".into())], + crate::event::Recipients::Entity(test_entity_id), + )); + + app.update(); + + let test_context = app + .world() + .get_non_send_resource::>() + .unwrap(); + let test_runtime = app + .world() + .get_non_send_resource::>() + .unwrap(); + + assert_eq!( + test_context + .contexts + .get(&test_ctxt_id) + .unwrap() + .invocations, + vec![ + ScriptValue::String("test_args_script".into()), + ScriptValue::String("test_args_entity".into()) + ] + ); + + assert_eq!( + test_runtime + .runtime + .invocations + .iter() + .map(|(e, s)| (*e, s.clone())) + .collect::>(), + vec![ + (test_entity_id, test_script_id.clone()), + (test_entity_id, test_script_id.clone()) + ] + ); } } diff --git a/crates/bevy_mod_scripting_core/src/world.rs b/crates/bevy_mod_scripting_core/src/world.rs index f16d38bf..2dee3cc4 100644 --- a/crates/bevy_mod_scripting_core/src/world.rs +++ b/crates/bevy_mod_scripting_core/src/world.rs @@ -1,10 +1,9 @@ -use std::ops::Deref; -use std::sync::Arc; - 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 /// diff --git a/crates/bevy_mod_scripting_functions/Cargo.toml b/crates/bevy_mod_scripting_functions/Cargo.toml new file mode 100644 index 00000000..2d733efd --- /dev/null +++ b/crates/bevy_mod_scripting_functions/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "bevy_mod_scripting_functions" +version = "0.9.0-alpha.1" +edition = "2021" +authors = ["Maksymilian Mozolewski "] +license = "MIT OR Apache-2.0" +description = "Necessary functionality for Lua support with bevy_mod_scripting" +repository = "https://github.com/makspll/bevy_mod_scripting" +homepage = "https://github.com/makspll/bevy_mod_scripting" +keywords = ["bevy", "gamedev", "scripting", "rhai"] +categories = ["game-development"] +readme = "readme.md" + +[features] +core_functions = [] +bevy_bindings = [] + + +[dependencies] +bevy = { workspace = true, features = [ + "reflect_functions", + "bevy_asset", + "bevy_animation", + "bevy_core_pipeline", + "bevy_ui", + "bevy_pbr", + "bevy_render", + "bevy_text", + "bevy_sprite", + "file_watcher", + "multi_threaded" +] } +uuid = "*" +smol_str = "0.2.2" +bevy_mod_scripting_core = { workspace = true } diff --git a/crates/bevy_event_priority/readme.md b/crates/bevy_mod_scripting_functions/readme.md similarity index 75% rename from crates/bevy_event_priority/readme.md rename to crates/bevy_mod_scripting_functions/readme.md index d29e4756..e28c0107 100644 --- a/crates/bevy_event_priority/readme.md +++ b/crates/bevy_mod_scripting_functions/readme.md @@ -1,3 +1,3 @@ -# bevy_event_priority +# bevy_mod_scripting_lua_functions This crate is a part of the ["bevy_mod_scripting" workspace](https://github.com/makspll/bevy_mod_scripting). \ No newline at end of file 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 new file mode 100644 index 00000000..e66a541e --- /dev/null +++ b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_core.rs @@ -0,0 +1,41 @@ +// @generated by cargo bevy-api-gen generate, modify the templates not this file +#![allow(clippy::all)] +#![allow(unused, deprecated, dead_code)] +#![cfg_attr(rustfmt, rustfmt_skip)] +use super::bevy_ecs::*; +use super::bevy_reflect::*; +use bevy_mod_scripting_core::{ + AddContextInitializer, StoreDocumentation, + bindings::{ReflectReference, function::from::{Ref, Mut, Val}}, +}; +use crate::*; +pub struct BevyCoreScriptingPlugin; +impl ::bevy::app::Plugin for BevyCoreScriptingPlugin { + fn build(&self, app: &mut ::bevy::prelude::App) { + let mut world = app.world_mut(); + NamespaceBuilder::<::bevy::core::prelude::Name>::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 + }, + ); + } +} 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 new file mode 100644 index 00000000..6dfeb8d0 --- /dev/null +++ b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_ecs.rs @@ -0,0 +1,382 @@ +// @generated by cargo bevy-api-gen generate, modify the templates not this file +#![allow(clippy::all)] +#![allow(unused, deprecated, dead_code)] +#![cfg_attr(rustfmt, rustfmt_skip)] +use super::bevy_reflect::*; +use bevy_mod_scripting_core::{ + AddContextInitializer, StoreDocumentation, + bindings::{ReflectReference, function::from::{Ref, Mut, Val}}, +}; +use crate::*; +pub struct BevyEcsScriptingPlugin; +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| { + let output: Val = bevy::ecs::entity::Entity::from_raw( + index, + ) + .into(); + output + }, + ) + .register( + "to_bits", + |_self: Val| { + let output: u64 = bevy::ecs::entity::Entity::to_bits( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_bits", + |bits: u64| { + let output: Val = bevy::ecs::entity::Entity::from_bits( + bits, + ) + .into(); + output + }, + ) + .register( + "index", + |_self: Val| { + let output: u32 = bevy::ecs::entity::Entity::index( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "generation", + |_self: Val| { + let output: u32 = bevy::ecs::entity::Entity::generation( + _self.into_inner(), + ) + .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( + "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( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .into(); + output + }, + ) + .register( + "new", + |index: usize| { + let output: Val = bevy::ecs::component::ComponentId::new( + index, + ) + .into(); + output + }, + ) + .register( + "index", + |_self: Val| { + let output: usize = bevy::ecs::component::ComponentId::index( + _self.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::ecs::component::Tick>::new(world) + .register( + "new", + |tick: u32| { + let output: Val = bevy::ecs::component::Tick::new( + tick, + ) + .into(); + output + }, + ) + .register( + "get", + |_self: Val| { + let output: u32 = bevy::ecs::component::Tick::get(_self.into_inner()) + .into(); + output + }, + ) + .register( + "set", + |mut _self: Mut, tick: u32| { + let output: () = bevy::ecs::component::Tick::set(&mut _self, tick) + .into(); + output + }, + ) + .register( + "is_newer_than", + | + _self: Val, + last_run: Val, + this_run: Val| + { + let output: bool = bevy::ecs::component::Tick::is_newer_than( + _self.into_inner(), + last_run.into_inner(), + this_run.into_inner(), + ) + .into(); + output + }, + ) + .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( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::ecs::component::ComponentTicks>::new(world) + .register( + "is_added", + | + _self: Ref, + last_run: Val, + this_run: Val| + { + let output: bool = bevy::ecs::component::ComponentTicks::is_added( + &_self, + last_run.into_inner(), + this_run.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_changed", + | + _self: Ref, + last_run: Val, + this_run: Val| + { + let output: bool = bevy::ecs::component::ComponentTicks::is_changed( + &_self, + last_run.into_inner(), + this_run.into_inner(), + ) + .into(); + output + }, + ) + .register( + "new", + |change_tick: Val| { + let output: Val = bevy::ecs::component::ComponentTicks::new( + change_tick.into_inner(), + ) + .into(); + output + }, + ) + .register( + "set_changed", + | + mut _self: Mut, + change_tick: Val| + { + let output: () = bevy::ecs::component::ComponentTicks::set_changed( + &mut _self, + change_tick.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::ecs::identifier::Identifier>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "low", + |_self: Val| { + let output: u32 = bevy::ecs::identifier::Identifier::low( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "masked_high", + |_self: Val| { + let output: u32 = bevy::ecs::identifier::Identifier::masked_high( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "to_bits", + |_self: Val| { + let output: u64 = bevy::ecs::identifier::Identifier::to_bits( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_bits", + |value: u64| { + let output: Val = bevy::ecs::identifier::Identifier::from_bits( + value, + ) + .into(); + output + }, + ) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::ecs::entity::EntityHash>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::< + ::bevy::ecs::removal_detection::RemovedComponentEntity, + >::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val< + bevy::ecs::removal_detection::RemovedComponentEntity, + > = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::ecs::system::SystemIdMarker>::new(world); + } +} 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 new file mode 100644 index 00000000..efb3bc53 --- /dev/null +++ b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_hierarchy.rs @@ -0,0 +1,93 @@ +// @generated by cargo bevy-api-gen generate, modify the templates not this file +#![allow(clippy::all)] +#![allow(unused, deprecated, dead_code)] +#![cfg_attr(rustfmt, rustfmt_skip)] +use super::bevy_ecs::*; +use super::bevy_reflect::*; +use super::bevy_core::*; +use bevy_mod_scripting_core::{ + AddContextInitializer, StoreDocumentation, + bindings::{ReflectReference, function::from::{Ref, Mut, Val}}, +}; +use crate::*; +pub struct BevyHierarchyScriptingPlugin; +impl ::bevy::app::Plugin for BevyHierarchyScriptingPlugin { + fn build(&self, app: &mut ::bevy::prelude::App) { + let mut world = app.world_mut(); + NamespaceBuilder::<::bevy::hierarchy::prelude::Children>::new(world) + .register( + "swap", + | + mut _self: Mut, + a_index: usize, + b_index: usize| + { + let output: () = bevy::hierarchy::prelude::Children::swap( + &mut _self, + a_index, + b_index, + ) + .into(); + output + }, + ); + 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", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::hierarchy::HierarchyEvent>::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( + "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_input.rs b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_input.rs new file mode 100644 index 00000000..85c1f1ba --- /dev/null +++ b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_input.rs @@ -0,0 +1,1399 @@ +// @generated by cargo bevy-api-gen generate, modify the templates not this file +#![allow(clippy::all)] +#![allow(unused, deprecated, dead_code)] +#![cfg_attr(rustfmt, rustfmt_skip)] +use super::bevy_ecs::*; +use super::bevy_reflect::*; +use super::bevy_core::*; +use super::bevy_math::*; +use bevy_mod_scripting_core::{ + AddContextInitializer, StoreDocumentation, + bindings::{ReflectReference, function::from::{Ref, Mut, Val}}, +}; +use crate::*; +pub struct BevyInputScriptingPlugin; +impl ::bevy::app::Plugin for BevyInputScriptingPlugin { + fn build(&self, app: &mut ::bevy::prelude::App) { + let mut world = app.world_mut(); + NamespaceBuilder::<::bevy::input::gamepad::Gamepad>::new(world) + .register( + "vendor_id", + |_self: Ref| { + let output: std::option::Option = bevy::input::gamepad::Gamepad::vendor_id( + &_self, + ) + .into(); + output + }, + ) + .register( + "product_id", + |_self: Ref| { + let output: std::option::Option = bevy::input::gamepad::Gamepad::product_id( + &_self, + ) + .into(); + output + }, + ) + .register( + "pressed", + | + _self: Ref, + button_type: Val| + { + let output: bool = bevy::input::gamepad::Gamepad::pressed( + &_self, + button_type.into_inner(), + ) + .into(); + output + }, + ) + .register( + "just_pressed", + | + _self: Ref, + button_type: Val| + { + let output: bool = bevy::input::gamepad::Gamepad::just_pressed( + &_self, + button_type.into_inner(), + ) + .into(); + output + }, + ) + .register( + "just_released", + | + _self: Ref, + button_type: Val| + { + let output: bool = bevy::input::gamepad::Gamepad::just_released( + &_self, + button_type.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::input::gamepad::GamepadAxis>::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( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::input::gamepad::GamepadButton>::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( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::input::gamepad::GamepadSettings>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + 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", + | + _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::input::mouse::MouseButton>::new(world) + .register( + "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, + ) + .into(); + output + }, + ) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::input::touch::TouchInput>::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 + }, + ); + NamespaceBuilder::<::bevy::input::keyboard::KeyboardFocusLost>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .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::input::keyboard::KeyboardInput>::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( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::input::mouse::AccumulatedMouseMotion>::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 + }, + ); + NamespaceBuilder::<::bevy::input::mouse::AccumulatedMouseScroll>::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 + }, + ); + NamespaceBuilder::<::bevy::input::mouse::MouseButtonInput>::new(world) + .register( + "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, + ) + .into(); + output + }, + ) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::input::mouse::MouseMotion>::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 + }, + ); + NamespaceBuilder::<::bevy::input::mouse::MouseWheel>::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 + }, + ); + NamespaceBuilder::<::bevy::input::gamepad::GamepadAxisChangedEvent>::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 + }, + ); + NamespaceBuilder::<::bevy::input::gamepad::GamepadButtonChangedEvent>::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 + }, + ); + NamespaceBuilder::< + ::bevy::input::gamepad::GamepadButtonStateChangedEvent, + >::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( + "clone", + |_self: Ref| { + let output: Val< + bevy::input::gamepad::GamepadButtonStateChangedEvent, + > = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::input::gamepad::GamepadConnection>::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 + }, + ); + NamespaceBuilder::<::bevy::input::gamepad::GamepadConnectionEvent>::new(world) + .register( + "connected", + |_self: Ref| { + let output: bool = bevy::input::gamepad::GamepadConnectionEvent::connected( + &_self, + ) + .into(); + output + }, + ) + .register( + "disconnected", + |_self: Ref| { + let output: bool = bevy::input::gamepad::GamepadConnectionEvent::disconnected( + &_self, + ) + .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 + }, + ); + NamespaceBuilder::<::bevy::input::gamepad::GamepadEvent>::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 + }, + ); + NamespaceBuilder::<::bevy::input::gamepad::GamepadInput>::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( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::input::gamepad::GamepadRumbleRequest>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::< + ::bevy::input::gamepad::RawGamepadAxisChangedEvent, + >::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 + }, + ); + NamespaceBuilder::< + ::bevy::input::gamepad::RawGamepadButtonChangedEvent, + >::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val< + bevy::input::gamepad::RawGamepadButtonChangedEvent, + > = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::input::gamepad::RawGamepadEvent>::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 + }, + ); + NamespaceBuilder::<::bevy::input::gestures::PinchGesture>::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 + }, + ); + NamespaceBuilder::<::bevy::input::gestures::RotationGesture>::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 + }, + ); + 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, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::input::gestures::PanGesture>::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 + }, + ); + NamespaceBuilder::<::bevy::input::ButtonState>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .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 + }, + ) + .register( + "is_pressed", + |_self: Ref| { + let output: bool = bevy::input::ButtonState::is_pressed(&_self) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::input::gamepad::ButtonSettings>::new(world) + .register( + "is_pressed", + |_self: Ref, value: f32| { + let output: bool = bevy::input::gamepad::ButtonSettings::is_pressed( + &_self, + value, + ) + .into(); + output + }, + ) + .register( + "is_released", + |_self: Ref, value: f32| { + let output: bool = bevy::input::gamepad::ButtonSettings::is_released( + &_self, + value, + ) + .into(); + output + }, + ) + .register( + "press_threshold", + |_self: Ref| { + let output: f32 = bevy::input::gamepad::ButtonSettings::press_threshold( + &_self, + ) + .into(); + output + }, + ) + .register( + "set_press_threshold", + |mut _self: Mut, value: f32| { + let output: f32 = bevy::input::gamepad::ButtonSettings::set_press_threshold( + &mut _self, + value, + ) + .into(); + output + }, + ) + .register( + "release_threshold", + |_self: Ref| { + let output: f32 = bevy::input::gamepad::ButtonSettings::release_threshold( + &_self, + ) + .into(); + output + }, + ) + .register( + "set_release_threshold", + |mut _self: Mut, value: f32| { + let output: f32 = bevy::input::gamepad::ButtonSettings::set_release_threshold( + &mut _self, + value, + ) + .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::input::gamepad::AxisSettings>::new(world) + .register( + "livezone_upperbound", + |_self: Ref| { + let output: f32 = bevy::input::gamepad::AxisSettings::livezone_upperbound( + &_self, + ) + .into(); + output + }, + ) + .register( + "set_livezone_upperbound", + |mut _self: Mut, value: f32| { + let output: f32 = bevy::input::gamepad::AxisSettings::set_livezone_upperbound( + &mut _self, + value, + ) + .into(); + output + }, + ) + .register( + "deadzone_upperbound", + |_self: Ref| { + let output: f32 = bevy::input::gamepad::AxisSettings::deadzone_upperbound( + &_self, + ) + .into(); + output + }, + ) + .register( + "set_deadzone_upperbound", + |mut _self: Mut, value: f32| { + let output: f32 = bevy::input::gamepad::AxisSettings::set_deadzone_upperbound( + &mut _self, + value, + ) + .into(); + output + }, + ) + .register( + "livezone_lowerbound", + |_self: Ref| { + let output: f32 = bevy::input::gamepad::AxisSettings::livezone_lowerbound( + &_self, + ) + .into(); + output + }, + ) + .register( + "set_livezone_lowerbound", + |mut _self: Mut, value: f32| { + let output: f32 = bevy::input::gamepad::AxisSettings::set_livezone_lowerbound( + &mut _self, + value, + ) + .into(); + output + }, + ) + .register( + "deadzone_lowerbound", + |_self: Ref| { + let output: f32 = bevy::input::gamepad::AxisSettings::deadzone_lowerbound( + &_self, + ) + .into(); + output + }, + ) + .register( + "set_deadzone_lowerbound", + |mut _self: Mut, value: f32| { + let output: f32 = bevy::input::gamepad::AxisSettings::set_deadzone_lowerbound( + &mut _self, + value, + ) + .into(); + output + }, + ) + .register( + "threshold", + |_self: Ref| { + let output: f32 = bevy::input::gamepad::AxisSettings::threshold( + &_self, + ) + .into(); + output + }, + ) + .register( + "set_threshold", + |mut _self: Mut, value: f32| { + let output: f32 = bevy::input::gamepad::AxisSettings::set_threshold( + &mut _self, + value, + ) + .into(); + output + }, + ) + .register( + "clamp", + |_self: Ref, new_value: f32| { + let output: f32 = bevy::input::gamepad::AxisSettings::clamp( + &_self, + new_value, + ) + .into(); + output + }, + ) + .register( + "filter", + | + _self: Ref, + new_value: f32, + old_value: std::option::Option| + { + let output: std::option::Option = bevy::input::gamepad::AxisSettings::filter( + &_self, + new_value, + old_value, + ) + .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::input::gamepad::ButtonAxisSettings>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "filter", + | + _self: Ref, + new_value: f32, + old_value: std::option::Option| + { + let output: std::option::Option = bevy::input::gamepad::ButtonAxisSettings::filter( + &_self, + new_value, + old_value, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::input::gamepad::GamepadRumbleIntensity>::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( + "weak_motor", + |intensity: f32| { + let output: Val = bevy::input::gamepad::GamepadRumbleIntensity::weak_motor( + intensity, + ) + .into(); + output + }, + ) + .register( + "strong_motor", + |intensity: f32| { + let output: Val = bevy::input::gamepad::GamepadRumbleIntensity::strong_motor( + intensity, + ) + .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, + ) + .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::input::keyboard::NativeKeyCode>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .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::input::keyboard::NativeKey>::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( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::input::mouse::MouseScrollUnit>::new(world) + .register( + "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, + ) + .into(); + output + }, + ) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::input::touch::TouchPhase>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .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::input::touch::ForceTouch>::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 + }, + ); + } +} 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 new file mode 100644 index 00000000..2d1c322f --- /dev/null +++ b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_math.rs @@ -0,0 +1,3449 @@ +// @generated by cargo bevy-api-gen generate, modify the templates not this file +#![allow(clippy::all)] +#![allow(unused, deprecated, dead_code)] +#![cfg_attr(rustfmt, rustfmt_skip)] +use super::bevy_reflect::*; +use bevy_mod_scripting_core::{ + AddContextInitializer, StoreDocumentation, + bindings::{ReflectReference, function::from::{Ref, Mut, Val}}, +}; +use crate::*; +pub struct BevyMathScriptingPlugin; +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", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) + .register( + "ratio", + |_self: Ref| { + let output: f32 = bevy::math::AspectRatio::ratio(&_self).into(); + output + }, + ) + .register( + "inverse", + |_self: Ref| { + let output: Val = bevy::math::AspectRatio::inverse( + &_self, + ) + .into(); + output + }, + ) + .register( + "is_landscape", + |_self: Ref| { + let output: bool = bevy::math::AspectRatio::is_landscape(&_self) + .into(); + output + }, + ) + .register( + "is_portrait", + |_self: Ref| { + let output: bool = bevy::math::AspectRatio::is_portrait(&_self) + .into(); + output + }, + ) + .register( + "is_square", + |_self: Ref| { + let output: bool = bevy::math::AspectRatio::is_square(&_self).into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::CompassOctant>::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( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::CompassQuadrant>::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( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::Isometry2d>::new(world) + .register( + "from_rotation", + |rotation: Val| { + let output: Val = bevy::math::Isometry2d::from_rotation( + rotation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_xy", + |x: f32, y: f32| { + let output: Val = bevy::math::Isometry2d::from_xy( + x, + y, + ) + .into(); + output + }, + ) + .register( + "inverse", + |_self: Ref| { + let output: Val = bevy::math::Isometry2d::inverse( + &_self, + ) + .into(); + output + }, + ) + .register( + "inverse_mul", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Isometry2d::inverse_mul( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "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( + "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::Isometry3d>::new(world) + .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| { + let output: Val = bevy::math::Isometry3d::from_xyz( + x, + y, + z, + ) + .into(); + output + }, + ) + .register( + "inverse", + |_self: Ref| { + let output: Val = bevy::math::Isometry3d::inverse( + &_self, + ) + .into(); + output + }, + ) + .register( + "inverse_mul", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Isometry3d::inverse_mul( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "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| { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::Ray3d>::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 + }, + ); + 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| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "radians", + |radians: f32| { + let output: Val = bevy::math::Rot2::radians( + radians, + ) + .into(); + output + }, + ) + .register( + "degrees", + |degrees: f32| { + let output: Val = bevy::math::Rot2::degrees( + degrees, + ) + .into(); + output + }, + ) + .register( + "turn_fraction", + |fraction: f32| { + let output: Val = bevy::math::Rot2::turn_fraction( + fraction, + ) + .into(); + output + }, + ) + .register( + "from_sin_cos", + |sin: f32, cos: f32| { + let output: Val = bevy::math::Rot2::from_sin_cos( + sin, + cos, + ) + .into(); + output + }, + ) + .register( + "as_radians", + |_self: Val| { + let output: f32 = bevy::math::Rot2::as_radians(_self.into_inner()) + .into(); + output + }, + ) + .register( + "as_degrees", + |_self: Val| { + let output: f32 = bevy::math::Rot2::as_degrees(_self.into_inner()) + .into(); + output + }, + ) + .register( + "as_turn_fraction", + |_self: Val| { + let output: f32 = bevy::math::Rot2::as_turn_fraction( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "sin_cos", + |_self: Val| { + let output: (f32, f32) = bevy::math::Rot2::sin_cos( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length", + |_self: Val| { + let output: f32 = bevy::math::Rot2::length(_self.into_inner()) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: f32 = bevy::math::Rot2::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_recip", + |_self: Val| { + let output: f32 = bevy::math::Rot2::length_recip(_self.into_inner()) + .into(); + output + }, + ) + .register( + "normalize", + |_self: Val| { + let output: Val = bevy::math::Rot2::normalize( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "fast_renormalize", + |_self: Val| { + let output: Val = bevy::math::Rot2::fast_renormalize( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Val| { + let output: bool = bevy::math::Rot2::is_finite(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_nan", + |_self: Val| { + let output: bool = bevy::math::Rot2::is_nan(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_normalized", + |_self: Val| { + let output: bool = bevy::math::Rot2::is_normalized( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_near_identity", + |_self: Val| { + let output: bool = bevy::math::Rot2::is_near_identity( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "angle_between", + |_self: Val, other: Val| { + let output: f32 = bevy::math::Rot2::angle_between( + _self.into_inner(), + other.into_inner(), + ) + .into(); + output + }, + ) + .register( + "angle_to", + |_self: Val, other: Val| { + let output: f32 = bevy::math::Rot2::angle_to( + _self.into_inner(), + other.into_inner(), + ) + .into(); + output + }, + ) + .register( + "inverse", + |_self: Val| { + let output: Val = bevy::math::Rot2::inverse( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "nlerp", + |_self: Val, end: Val, s: f32| { + let output: Val = bevy::math::Rot2::nlerp( + _self.into_inner(), + end.into_inner(), + s, + ) + .into(); + output + }, + ) + .register( + "slerp", + |_self: Val, end: Val, s: f32| { + let output: Val = bevy::math::Rot2::slerp( + _self.into_inner(), + end.into_inner(), + s, + ) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::prelude::Dir2>::new(world) + .register( + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) + .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 + }, + ) + .register( + "from_xy_unchecked", + |x: f32, y: f32| { + let output: Val = bevy::math::prelude::Dir2::from_xy_unchecked( + x, + y, + ) + .into(); + output + }, + ) + .register( + "slerp", + | + _self: Val, + rhs: Val, + s: f32| + { + let output: Val = bevy::math::prelude::Dir2::slerp( + _self.into_inner(), + rhs.into_inner(), + s, + ) + .into(); + output + }, + ) + .register( + "rotation_to", + | + _self: Val, + other: Val| + { + let output: Val = bevy::math::prelude::Dir2::rotation_to( + _self.into_inner(), + other.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rotation_from", + | + _self: Val, + other: Val| + { + let output: Val = bevy::math::prelude::Dir2::rotation_from( + _self.into_inner(), + other.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rotation_from_x", + |_self: Val| { + let output: Val = bevy::math::prelude::Dir2::rotation_from_x( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rotation_to_x", + |_self: Val| { + let output: Val = bevy::math::prelude::Dir2::rotation_to_x( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rotation_from_y", + |_self: Val| { + let output: Val = bevy::math::prelude::Dir2::rotation_from_y( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rotation_to_y", + |_self: Val| { + let output: Val = bevy::math::prelude::Dir2::rotation_to_y( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "fast_renormalize", + |_self: Val| { + let output: Val = bevy::math::prelude::Dir2::fast_renormalize( + _self.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::prelude::Dir3>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "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 + }, + ) + .register( + "from_xyz_unchecked", + |x: f32, y: f32, z: f32| { + let output: Val = bevy::math::prelude::Dir3::from_xyz_unchecked( + x, + y, + z, + ) + .into(); + output + }, + ) + .register( + "slerp", + | + _self: Val, + rhs: Val, + s: f32| + { + let output: Val = bevy::math::prelude::Dir3::slerp( + _self.into_inner(), + rhs.into_inner(), + s, + ) + .into(); + output + }, + ) + .register( + "fast_renormalize", + |_self: Val| { + let output: Val = bevy::math::prelude::Dir3::fast_renormalize( + _self.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::prelude::Dir3A>::new(world) + .register( + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) + .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( + _self.into_inner(), + rhs.into_inner(), + s, + ) + .into(); + output + }, + ) + .register( + "fast_renormalize", + |_self: Val| { + let output: Val = bevy::math::prelude::Dir3A::fast_renormalize( + _self.into_inner(), + ) + .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::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| { + let output: Val = bevy::math::prelude::IRect::new( + x0, + y0, + x1, + y1, + ) + .into(); + output + }, + ) + .register( + "is_empty", + |_self: Ref| { + let output: bool = bevy::math::prelude::IRect::is_empty(&_self) + .into(); + output + }, + ) + .register( + "width", + |_self: Ref| { + let output: i32 = bevy::math::prelude::IRect::width(&_self).into(); + output + }, + ) + .register( + "height", + |_self: Ref| { + let output: i32 = bevy::math::prelude::IRect::height(&_self).into(); + output + }, + ) + .register( + "union", + | + _self: Ref, + other: Val| + { + let output: Val = bevy::math::prelude::IRect::union( + &_self, + other.into_inner(), + ) + .into(); + output + }, + ) + .register( + "intersect", + | + _self: Ref, + other: Val| + { + let output: Val = bevy::math::prelude::IRect::intersect( + &_self, + other.into_inner(), + ) + .into(); + output + }, + ) + .register( + "inflate", + |_self: Ref, expansion: i32| { + let output: Val = bevy::math::prelude::IRect::inflate( + &_self, + expansion, + ) + .into(); + output + }, + ) + .register( + "as_rect", + |_self: Ref| { + let output: Val = bevy::math::prelude::IRect::as_rect( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_urect", + |_self: Ref| { + let output: Val = bevy::math::prelude::IRect::as_urect( + &_self, + ) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::prelude::Rect>::new(world) + .register( + "new", + |x0: f32, y0: f32, x1: f32, y1: f32| { + let output: Val = bevy::math::prelude::Rect::new( + x0, + y0, + x1, + y1, + ) + .into(); + output + }, + ) + .register( + "is_empty", + |_self: Ref| { + let output: bool = bevy::math::prelude::Rect::is_empty(&_self) + .into(); + output + }, + ) + .register( + "width", + |_self: Ref| { + let output: f32 = bevy::math::prelude::Rect::width(&_self).into(); + output + }, + ) + .register( + "height", + |_self: Ref| { + let output: f32 = bevy::math::prelude::Rect::height(&_self).into(); + output + }, + ) + .register( + "union", + | + _self: Ref, + other: Val| + { + let output: Val = bevy::math::prelude::Rect::union( + &_self, + other.into_inner(), + ) + .into(); + output + }, + ) + .register( + "intersect", + | + _self: Ref, + other: Val| + { + let output: Val = bevy::math::prelude::Rect::intersect( + &_self, + other.into_inner(), + ) + .into(); + output + }, + ) + .register( + "inflate", + |_self: Ref, expansion: f32| { + let output: Val = bevy::math::prelude::Rect::inflate( + &_self, + expansion, + ) + .into(); + output + }, + ) + .register( + "normalize", + | + _self: Ref, + other: Val| + { + let output: Val = bevy::math::prelude::Rect::normalize( + &_self, + other.into_inner(), + ) + .into(); + output + }, + ) + .register( + "as_irect", + |_self: Ref| { + let output: Val = bevy::math::prelude::Rect::as_irect( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_urect", + |_self: Ref| { + let output: Val = bevy::math::prelude::Rect::as_urect( + &_self, + ) + .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::prelude::URect>::new(world) + .register( + "new", + |x0: u32, y0: u32, x1: u32, y1: u32| { + let output: Val = bevy::math::prelude::URect::new( + x0, + y0, + x1, + y1, + ) + .into(); + output + }, + ) + .register( + "is_empty", + |_self: Ref| { + let output: bool = bevy::math::prelude::URect::is_empty(&_self) + .into(); + output + }, + ) + .register( + "width", + |_self: Ref| { + let output: u32 = bevy::math::prelude::URect::width(&_self).into(); + output + }, + ) + .register( + "height", + |_self: Ref| { + let output: u32 = bevy::math::prelude::URect::height(&_self).into(); + output + }, + ) + .register( + "union", + | + _self: Ref, + other: Val| + { + let output: Val = bevy::math::prelude::URect::union( + &_self, + other.into_inner(), + ) + .into(); + output + }, + ) + .register( + "intersect", + | + _self: Ref, + other: Val| + { + let output: Val = bevy::math::prelude::URect::intersect( + &_self, + other.into_inner(), + ) + .into(); + output + }, + ) + .register( + "inflate", + |_self: Ref, expansion: i32| { + let output: Val = bevy::math::prelude::URect::inflate( + &_self, + expansion, + ) + .into(); + output + }, + ) + .register( + "as_rect", + |_self: Ref| { + let output: Val = bevy::math::prelude::URect::as_rect( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_irect", + |_self: Ref| { + let output: Val = bevy::math::prelude::URect::as_irect( + &_self, + ) + .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 + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::Affine3>::new(world); + NamespaceBuilder::<::bevy::math::bounding::Aabb2d>::new(world) + .register( + "bounding_circle", + |_self: Ref| { + let output: Val = bevy::math::bounding::Aabb2d::bounding_circle( + &_self, + ) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::bounding::BoundingCircle>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "radius", + |_self: Ref| { + let output: f32 = bevy::math::bounding::BoundingCircle::radius( + &_self, + ) + .into(); + output + }, + ) + .register( + "aabb_2d", + |_self: Ref| { + let output: Val = bevy::math::bounding::BoundingCircle::aabb_2d( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::primitives::Circle>::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( + "new", + |radius: f32| { + let output: Val = bevy::math::primitives::Circle::new( + radius, + ) + .into(); + output + }, + ) + .register( + "diameter", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Circle::diameter(&_self) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::primitives::Annulus>::new(world) + .register( + "new", + |inner_radius: f32, outer_radius: f32| { + let output: Val = bevy::math::primitives::Annulus::new( + inner_radius, + outer_radius, + ) + .into(); + output + }, + ) + .register( + "diameter", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Annulus::diameter(&_self) + .into(); + output + }, + ) + .register( + "thickness", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Annulus::thickness(&_self) + .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::Arc2d>::new(world) + .register( + "new", + |radius: f32, half_angle: f32| { + let output: Val = bevy::math::primitives::Arc2d::new( + radius, + half_angle, + ) + .into(); + output + }, + ) + .register( + "from_radians", + |radius: f32, angle: f32| { + let output: Val = bevy::math::primitives::Arc2d::from_radians( + radius, + angle, + ) + .into(); + output + }, + ) + .register( + "from_degrees", + |radius: f32, angle: f32| { + let output: Val = bevy::math::primitives::Arc2d::from_degrees( + radius, + angle, + ) + .into(); + output + }, + ) + .register( + "from_turns", + |radius: f32, fraction: f32| { + let output: Val = bevy::math::primitives::Arc2d::from_turns( + radius, + fraction, + ) + .into(); + output + }, + ) + .register( + "angle", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Arc2d::angle(&_self) + .into(); + output + }, + ) + .register( + "length", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Arc2d::length(&_self) + .into(); + output + }, + ) + .register( + "half_chord_length", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Arc2d::half_chord_length( + &_self, + ) + .into(); + output + }, + ) + .register( + "chord_length", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Arc2d::chord_length(&_self) + .into(); + output + }, + ) + .register( + "apothem", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Arc2d::apothem(&_self) + .into(); + output + }, + ) + .register( + "sagitta", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Arc2d::sagitta(&_self) + .into(); + output + }, + ) + .register( + "is_minor", + |_self: Ref| { + let output: bool = bevy::math::primitives::Arc2d::is_minor(&_self) + .into(); + output + }, + ) + .register( + "is_major", + |_self: Ref| { + let output: bool = bevy::math::primitives::Arc2d::is_major(&_self) + .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 + }, + ); + NamespaceBuilder::<::bevy::math::primitives::Capsule2d>::new(world) + .register( + "new", + |radius: f32, length: f32| { + let output: Val = bevy::math::primitives::Capsule2d::new( + radius, + length, + ) + .into(); + output + }, + ) + .register( + "to_inner_rectangle", + |_self: Ref| { + let output: Val = bevy::math::primitives::Capsule2d::to_inner_rectangle( + &_self, + ) + .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 + }, + ); + NamespaceBuilder::<::bevy::math::primitives::CircularSector>::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( + "new", + |radius: f32, angle: f32| { + let output: Val = bevy::math::primitives::CircularSector::new( + radius, + angle, + ) + .into(); + output + }, + ) + .register( + "from_radians", + |radius: f32, angle: f32| { + let output: Val = bevy::math::primitives::CircularSector::from_radians( + radius, + angle, + ) + .into(); + output + }, + ) + .register( + "from_degrees", + |radius: f32, angle: f32| { + let output: Val = bevy::math::primitives::CircularSector::from_degrees( + radius, + angle, + ) + .into(); + output + }, + ) + .register( + "from_turns", + |radius: f32, fraction: f32| { + let output: Val = bevy::math::primitives::CircularSector::from_turns( + radius, + fraction, + ) + .into(); + output + }, + ) + .register( + "half_angle", + |_self: Ref| { + let output: f32 = bevy::math::primitives::CircularSector::half_angle( + &_self, + ) + .into(); + output + }, + ) + .register( + "angle", + |_self: Ref| { + let output: f32 = bevy::math::primitives::CircularSector::angle( + &_self, + ) + .into(); + output + }, + ) + .register( + "radius", + |_self: Ref| { + let output: f32 = bevy::math::primitives::CircularSector::radius( + &_self, + ) + .into(); + output + }, + ) + .register( + "arc_length", + |_self: Ref| { + let output: f32 = bevy::math::primitives::CircularSector::arc_length( + &_self, + ) + .into(); + output + }, + ) + .register( + "half_chord_length", + |_self: Ref| { + let output: f32 = bevy::math::primitives::CircularSector::half_chord_length( + &_self, + ) + .into(); + output + }, + ) + .register( + "chord_length", + |_self: Ref| { + let output: f32 = bevy::math::primitives::CircularSector::chord_length( + &_self, + ) + .into(); + output + }, + ) + .register( + "apothem", + |_self: Ref| { + let output: f32 = bevy::math::primitives::CircularSector::apothem( + &_self, + ) + .into(); + output + }, + ) + .register( + "sagitta", + |_self: Ref| { + let output: f32 = bevy::math::primitives::CircularSector::sagitta( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::primitives::CircularSegment>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "new", + |radius: f32, angle: f32| { + let output: Val = bevy::math::primitives::CircularSegment::new( + radius, + angle, + ) + .into(); + output + }, + ) + .register( + "from_radians", + |radius: f32, angle: f32| { + let output: Val = bevy::math::primitives::CircularSegment::from_radians( + radius, + angle, + ) + .into(); + output + }, + ) + .register( + "from_degrees", + |radius: f32, angle: f32| { + let output: Val = bevy::math::primitives::CircularSegment::from_degrees( + radius, + angle, + ) + .into(); + output + }, + ) + .register( + "from_turns", + |radius: f32, fraction: f32| { + let output: Val = bevy::math::primitives::CircularSegment::from_turns( + radius, + fraction, + ) + .into(); + output + }, + ) + .register( + "half_angle", + |_self: Ref| { + let output: f32 = bevy::math::primitives::CircularSegment::half_angle( + &_self, + ) + .into(); + output + }, + ) + .register( + "angle", + |_self: Ref| { + let output: f32 = bevy::math::primitives::CircularSegment::angle( + &_self, + ) + .into(); + output + }, + ) + .register( + "radius", + |_self: Ref| { + let output: f32 = bevy::math::primitives::CircularSegment::radius( + &_self, + ) + .into(); + output + }, + ) + .register( + "arc_length", + |_self: Ref| { + let output: f32 = bevy::math::primitives::CircularSegment::arc_length( + &_self, + ) + .into(); + output + }, + ) + .register( + "half_chord_length", + |_self: Ref| { + let output: f32 = bevy::math::primitives::CircularSegment::half_chord_length( + &_self, + ) + .into(); + output + }, + ) + .register( + "chord_length", + |_self: Ref| { + let output: f32 = bevy::math::primitives::CircularSegment::chord_length( + &_self, + ) + .into(); + output + }, + ) + .register( + "apothem", + |_self: Ref| { + let output: f32 = bevy::math::primitives::CircularSegment::apothem( + &_self, + ) + .into(); + output + }, + ) + .register( + "sagitta", + |_self: Ref| { + let output: f32 = bevy::math::primitives::CircularSegment::sagitta( + &_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( + "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( + "new", + |half_width: f32, half_height: f32| { + let output: Val = bevy::math::primitives::Ellipse::new( + half_width, + half_height, + ) + .into(); + output + }, + ) + .register( + "eccentricity", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Ellipse::eccentricity( + &_self, + ) + .into(); + output + }, + ) + .register( + "focal_length", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Ellipse::focal_length( + &_self, + ) + .into(); + output + }, + ) + .register( + "semi_major", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Ellipse::semi_major(&_self) + .into(); + output + }, + ) + .register( + "semi_minor", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Ellipse::semi_minor(&_self) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::primitives::Line2d>::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 + }, + ); + NamespaceBuilder::<::bevy::math::primitives::Plane2d>::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 + }, + ); + NamespaceBuilder::<::bevy::math::primitives::Rectangle>::new(world) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) + .register( + "new", + |width: f32, height: f32| { + let output: Val = bevy::math::primitives::Rectangle::new( + width, + height, + ) + .into(); + output + }, + ) + .register( + "from_length", + |length: f32| { + let output: Val = bevy::math::primitives::Rectangle::from_length( + length, + ) + .into(); + 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| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) + .register( + "new", + |circumradius: f32, sides: u32| { + let output: Val = bevy::math::primitives::RegularPolygon::new( + circumradius, + sides, + ) + .into(); + output + }, + ) + .register( + "circumradius", + |_self: Ref| { + let output: f32 = bevy::math::primitives::RegularPolygon::circumradius( + &_self, + ) + .into(); + output + }, + ) + .register( + "inradius", + |_self: Ref| { + let output: f32 = bevy::math::primitives::RegularPolygon::inradius( + &_self, + ) + .into(); + output + }, + ) + .register( + "side_length", + |_self: Ref| { + let output: f32 = bevy::math::primitives::RegularPolygon::side_length( + &_self, + ) + .into(); + output + }, + ) + .register( + "internal_angle_degrees", + |_self: Ref| { + let output: f32 = bevy::math::primitives::RegularPolygon::internal_angle_degrees( + &_self, + ) + .into(); + output + }, + ) + .register( + "internal_angle_radians", + |_self: Ref| { + let output: f32 = bevy::math::primitives::RegularPolygon::internal_angle_radians( + &_self, + ) + .into(); + output + }, + ) + .register( + "external_angle_degrees", + |_self: Ref| { + let output: f32 = bevy::math::primitives::RegularPolygon::external_angle_degrees( + &_self, + ) + .into(); + output + }, + ) + .register( + "external_angle_radians", + |_self: Ref| { + let output: f32 = bevy::math::primitives::RegularPolygon::external_angle_radians( + &_self, + ) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::primitives::Rhombus>::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( + "new", + |horizontal_diagonal: f32, vertical_diagonal: f32| { + let output: Val = bevy::math::primitives::Rhombus::new( + horizontal_diagonal, + vertical_diagonal, + ) + .into(); + output + }, + ) + .register( + "from_side", + |side: f32| { + let output: Val = bevy::math::primitives::Rhombus::from_side( + side, + ) + .into(); + output + }, + ) + .register( + "from_inradius", + |inradius: f32| { + let output: Val = bevy::math::primitives::Rhombus::from_inradius( + inradius, + ) + .into(); + output + }, + ) + .register( + "side", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Rhombus::side(&_self) + .into(); + output + }, + ) + .register( + "circumradius", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Rhombus::circumradius( + &_self, + ) + .into(); + output + }, + ) + .register( + "inradius", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Rhombus::inradius(&_self) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::primitives::Segment2d>::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( + "new", + |direction: Val, length: f32| { + let output: Val = bevy::math::primitives::Segment2d::new( + direction.into_inner(), + length, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::primitives::Triangle2d>::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( + "is_degenerate", + |_self: Ref| { + let output: bool = bevy::math::primitives::Triangle2d::is_degenerate( + &_self, + ) + .into(); + output + }, + ) + .register( + "is_acute", + |_self: Ref| { + let output: bool = bevy::math::primitives::Triangle2d::is_acute( + &_self, + ) + .into(); + output + }, + ) + .register( + "is_obtuse", + |_self: Ref| { + let output: bool = bevy::math::primitives::Triangle2d::is_obtuse( + &_self, + ) + .into(); + output + }, + ) + .register( + "reverse", + |mut _self: Mut| { + let output: () = bevy::math::primitives::Triangle2d::reverse( + &mut _self, + ) + .into(); + output + }, + ) + .register( + "reversed", + |_self: Val| { + let output: Val = bevy::math::primitives::Triangle2d::reversed( + _self.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::bounding::Aabb3d>::new(world) + .register( + "bounding_sphere", + |_self: Ref| { + let output: Val = bevy::math::bounding::Aabb3d::bounding_sphere( + &_self, + ) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::bounding::BoundingSphere>::new(world) + .register( + "radius", + |_self: Ref| { + let output: f32 = bevy::math::bounding::BoundingSphere::radius( + &_self, + ) + .into(); + output + }, + ) + .register( + "aabb_3d", + |_self: Ref| { + let output: Val = bevy::math::bounding::BoundingSphere::aabb_3d( + &_self, + ) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::primitives::Sphere>::new(world) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) + .register( + "new", + |radius: f32| { + let output: Val = bevy::math::primitives::Sphere::new( + radius, + ) + .into(); + output + }, + ) + .register( + "diameter", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Sphere::diameter(&_self) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::primitives::Cuboid>::new(world) + .register( + "new", + |x_length: f32, y_length: f32, z_length: f32| { + let output: Val = bevy::math::primitives::Cuboid::new( + x_length, + y_length, + z_length, + ) + .into(); + output + }, + ) + .register( + "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) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::primitives::Cylinder>::new(world) + .register( + "new", + |radius: f32, height: f32| { + let output: Val = bevy::math::primitives::Cylinder::new( + radius, + height, + ) + .into(); + output + }, + ) + .register( + "base", + |_self: Ref| { + let output: Val = bevy::math::primitives::Cylinder::base( + &_self, + ) + .into(); + output + }, + ) + .register( + "lateral_area", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Cylinder::lateral_area( + &_self, + ) + .into(); + output + }, + ) + .register( + "base_area", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Cylinder::base_area(&_self) + .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::Capsule3d>::new(world) + .register( + "new", + |radius: f32, length: f32| { + let output: Val = bevy::math::primitives::Capsule3d::new( + radius, + length, + ) + .into(); + output + }, + ) + .register( + "to_cylinder", + |_self: Ref| { + let output: Val = bevy::math::primitives::Capsule3d::to_cylinder( + &_self, + ) + .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 + }, + ); + NamespaceBuilder::<::bevy::math::primitives::Cone>::new(world) + .register( + "new", + |radius: f32, height: f32| { + let output: Val = bevy::math::primitives::Cone::new( + radius, + height, + ) + .into(); + output + }, + ) + .register( + "base", + |_self: Ref| { + let output: Val = bevy::math::primitives::Cone::base( + &_self, + ) + .into(); + output + }, + ) + .register( + "slant_height", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Cone::slant_height(&_self) + .into(); + output + }, + ) + .register( + "lateral_area", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Cone::lateral_area(&_self) + .into(); + output + }, + ) + .register( + "base_area", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Cone::base_area(&_self) + .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::ConicalFrustum>::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 + }, + ); + NamespaceBuilder::<::bevy::math::primitives::InfinitePlane3d>::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 + }, + ); + NamespaceBuilder::<::bevy::math::primitives::Line3d>::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 + }, + ); + NamespaceBuilder::<::bevy::math::primitives::Segment3d>::new(world) + .register( + "new", + |direction: Val, length: f32| { + let output: Val = bevy::math::primitives::Segment3d::new( + direction.into_inner(), + length, + ) + .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 + }, + ); + 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| { + let output: Val = bevy::math::primitives::Torus::new( + inner_radius, + outer_radius, + ) + .into(); + output + }, + ) + .register( + "inner_radius", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Torus::inner_radius(&_self) + .into(); + output + }, + ) + .register( + "outer_radius", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Torus::outer_radius(&_self) + .into(); + output + }, + ) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::primitives::Triangle3d>::new(world) + .register( + "is_degenerate", + |_self: Ref| { + let output: bool = bevy::math::primitives::Triangle3d::is_degenerate( + &_self, + ) + .into(); + output + }, + ) + .register( + "is_acute", + |_self: Ref| { + let output: bool = bevy::math::primitives::Triangle3d::is_acute( + &_self, + ) + .into(); + output + }, + ) + .register( + "is_obtuse", + |_self: Ref| { + let output: bool = bevy::math::primitives::Triangle3d::is_obtuse( + &_self, + ) + .into(); + output + }, + ) + .register( + "reverse", + |mut _self: Mut| { + let output: () = bevy::math::primitives::Triangle3d::reverse( + &mut _self, + ) + .into(); + output + }, + ) + .register( + "reversed", + |_self: Val| { + let output: Val = bevy::math::primitives::Triangle3d::reversed( + _self.into_inner(), + ) + .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 + }, + ); + NamespaceBuilder::<::bevy::math::bounding::RayCast2d>::new(world) + .register( + "from_ray", + |ray: Val, max: f32| { + let output: Val = bevy::math::bounding::RayCast2d::from_ray( + ray.into_inner(), + max, + ) + .into(); + output + }, + ) + .register( + "aabb_intersection_at", + | + _self: Ref, + aabb: Ref| + { + let output: std::option::Option = bevy::math::bounding::RayCast2d::aabb_intersection_at( + &_self, + &aabb, + ) + .into(); + output + }, + ) + .register( + "circle_intersection_at", + | + _self: Ref, + circle: Ref| + { + let output: std::option::Option = bevy::math::bounding::RayCast2d::circle_intersection_at( + &_self, + &circle, + ) + .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", + | + aabb: Val, + ray: Val, + max: f32| + { + let output: Val = bevy::math::bounding::AabbCast2d::from_ray( + aabb.into_inner(), + ray.into_inner(), + max, + ) + .into(); + output + }, + ) + .register( + "aabb_collision_at", + | + _self: Ref, + aabb: Val| + { + let output: std::option::Option = bevy::math::bounding::AabbCast2d::aabb_collision_at( + &_self, + aabb.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::bounding::BoundingCircleCast>::new(world) + .register( + "from_ray", + | + circle: Val, + ray: Val, + max: f32| + { + let output: Val = bevy::math::bounding::BoundingCircleCast::from_ray( + circle.into_inner(), + ray.into_inner(), + max, + ) + .into(); + output + }, + ) + .register( + "circle_collision_at", + | + _self: Ref, + circle: Val| + { + let output: std::option::Option = bevy::math::bounding::BoundingCircleCast::circle_collision_at( + &_self, + circle.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::bounding::RayCast3d>::new(world) + .register( + "from_ray", + |ray: Val, max: f32| { + let output: Val = bevy::math::bounding::RayCast3d::from_ray( + ray.into_inner(), + max, + ) + .into(); + output + }, + ) + .register( + "aabb_intersection_at", + | + _self: Ref, + aabb: Ref| + { + let output: std::option::Option = bevy::math::bounding::RayCast3d::aabb_intersection_at( + &_self, + &aabb, + ) + .into(); + output + }, + ) + .register( + "sphere_intersection_at", + | + _self: Ref, + sphere: Ref| + { + let output: std::option::Option = bevy::math::bounding::RayCast3d::sphere_intersection_at( + &_self, + &sphere, + ) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::bounding::AabbCast3d>::new(world) + .register( + "from_ray", + | + aabb: Val, + ray: Val, + max: f32| + { + let output: Val = bevy::math::bounding::AabbCast3d::from_ray( + aabb.into_inner(), + ray.into_inner(), + max, + ) + .into(); + output + }, + ) + .register( + "aabb_collision_at", + | + _self: Ref, + aabb: Val| + { + let output: std::option::Option = bevy::math::bounding::AabbCast3d::aabb_collision_at( + &_self, + aabb.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::bounding::BoundingSphereCast>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "from_ray", + | + sphere: Val, + ray: Val, + max: f32| + { + let output: Val = bevy::math::bounding::BoundingSphereCast::from_ray( + sphere.into_inner(), + ray.into_inner(), + max, + ) + .into(); + output + }, + ) + .register( + "sphere_collision_at", + | + _self: Ref, + sphere: Val| + { + let output: std::option::Option = bevy::math::bounding::BoundingSphereCast::sphere_collision_at( + &_self, + sphere.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::curve::interval::Interval>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "start", + |_self: Val| { + let output: f32 = bevy::math::curve::interval::Interval::start( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "end", + |_self: Val| { + let output: f32 = bevy::math::curve::interval::Interval::end( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length", + |_self: Val| { + let output: f32 = bevy::math::curve::interval::Interval::length( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_bounded", + |_self: Val| { + let output: bool = bevy::math::curve::interval::Interval::is_bounded( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "has_finite_start", + |_self: Val| { + let output: bool = bevy::math::curve::interval::Interval::has_finite_start( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "has_finite_end", + |_self: Val| { + let output: bool = bevy::math::curve::interval::Interval::has_finite_end( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "contains", + |_self: Val, item: f32| { + let output: bool = bevy::math::curve::interval::Interval::contains( + _self.into_inner(), + item, + ) + .into(); + output + }, + ) + .register( + "contains_interval", + | + _self: Val, + other: Val| + { + let output: bool = bevy::math::curve::interval::Interval::contains_interval( + _self.into_inner(), + other.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + |_self: Val, value: f32| { + let output: f32 = bevy::math::curve::interval::Interval::clamp( + _self.into_inner(), + value, + ) + .into(); + output + }, + ) + .register( + "eq", + | + _self: Ref, + other: Ref| + { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::FloatOrd>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "lt", + |_self: Ref, other: Ref| { + let output: bool = >::lt(&_self, &other) + .into(); + output + }, + ) + .register( + "le", + |_self: Ref, other: Ref| { + let output: bool = >::le(&_self, &other) + .into(); + output + }, + ) + .register( + "gt", + |_self: Ref, other: Ref| { + let output: bool = >::gt(&_self, &other) + .into(); + output + }, + ) + .register( + "ge", + |_self: Ref, other: Ref| { + let output: bool = >::ge(&_self, &other) + .into(); + output + }, + ) + .register( + "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::primitives::Plane3d>::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 + }, + ); + NamespaceBuilder::<::bevy::math::primitives::Tetrahedron>::new(world) + .register( + "signed_volume", + |_self: Ref| { + let output: f32 = bevy::math::primitives::Tetrahedron::signed_volume( + &_self, + ) + .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 + }, + ); + NamespaceBuilder::<::bevy::math::curve::easing::EaseFunction>::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 + }, + ); + } +} 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 new file mode 100644 index 00000000..2104e1c9 --- /dev/null +++ b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_reflect.rs @@ -0,0 +1,22065 @@ +// @generated by cargo bevy-api-gen generate, modify the templates not this file +#![allow(clippy::all)] +#![allow(unused, deprecated, dead_code)] +#![cfg_attr(rustfmt, rustfmt_skip)] +use bevy_mod_scripting_core::{ + AddContextInitializer, StoreDocumentation, + bindings::{ReflectReference, function::from::{Ref, Mut, Val}}, +}; +use crate::*; +pub struct BevyReflectScriptingPlugin; +impl ::bevy::app::Plugin for BevyReflectScriptingPlugin { + fn build(&self, app: &mut ::bevy::prelude::App) { + let mut world = app.world_mut(); + NamespaceBuilder::<::std::sync::atomic::AtomicBool>::new(world) + .register( + "new", + |v: bool| { + let output: Val = std::sync::atomic::AtomicBool::new( + v, + ) + .into(); + output + }, + ) + .register( + "into_inner", + |_self: Val| { + let output: bool = std::sync::atomic::AtomicBool::into_inner( + _self.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::std::sync::atomic::AtomicI16>::new(world) + .register( + "new", + |v: i16| { + let output: Val = std::sync::atomic::AtomicI16::new( + v, + ) + .into(); + output + }, + ) + .register( + "into_inner", + |_self: Val| { + let output: i16 = std::sync::atomic::AtomicI16::into_inner( + _self.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::std::sync::atomic::AtomicI32>::new(world) + .register( + "new", + |v: i32| { + let output: Val = std::sync::atomic::AtomicI32::new( + v, + ) + .into(); + output + }, + ) + .register( + "into_inner", + |_self: Val| { + let output: i32 = std::sync::atomic::AtomicI32::into_inner( + _self.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::std::sync::atomic::AtomicI64>::new(world) + .register( + "new", + |v: i64| { + let output: Val = std::sync::atomic::AtomicI64::new( + v, + ) + .into(); + output + }, + ) + .register( + "into_inner", + |_self: Val| { + let output: i64 = std::sync::atomic::AtomicI64::into_inner( + _self.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::std::sync::atomic::AtomicI8>::new(world) + .register( + "new", + |v: i8| { + let output: Val = std::sync::atomic::AtomicI8::new( + v, + ) + .into(); + output + }, + ) + .register( + "into_inner", + |_self: Val| { + let output: i8 = std::sync::atomic::AtomicI8::into_inner( + _self.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::std::sync::atomic::AtomicIsize>::new(world) + .register( + "new", + |v: isize| { + let output: Val = std::sync::atomic::AtomicIsize::new( + v, + ) + .into(); + output + }, + ) + .register( + "into_inner", + |_self: Val| { + let output: isize = std::sync::atomic::AtomicIsize::into_inner( + _self.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::std::sync::atomic::AtomicU16>::new(world) + .register( + "new", + |v: u16| { + let output: Val = std::sync::atomic::AtomicU16::new( + v, + ) + .into(); + output + }, + ) + .register( + "into_inner", + |_self: Val| { + let output: u16 = std::sync::atomic::AtomicU16::into_inner( + _self.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::std::sync::atomic::AtomicU32>::new(world) + .register( + "new", + |v: u32| { + let output: Val = std::sync::atomic::AtomicU32::new( + v, + ) + .into(); + output + }, + ) + .register( + "into_inner", + |_self: Val| { + let output: u32 = std::sync::atomic::AtomicU32::into_inner( + _self.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::std::sync::atomic::AtomicU64>::new(world) + .register( + "new", + |v: u64| { + let output: Val = std::sync::atomic::AtomicU64::new( + v, + ) + .into(); + output + }, + ) + .register( + "into_inner", + |_self: Val| { + let output: u64 = std::sync::atomic::AtomicU64::into_inner( + _self.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::std::sync::atomic::AtomicU8>::new(world) + .register( + "new", + |v: u8| { + let output: Val = std::sync::atomic::AtomicU8::new( + v, + ) + .into(); + output + }, + ) + .register( + "into_inner", + |_self: Val| { + let output: u8 = std::sync::atomic::AtomicU8::into_inner( + _self.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::std::sync::atomic::AtomicUsize>::new(world) + .register( + "new", + |v: usize| { + let output: Val = std::sync::atomic::AtomicUsize::new( + v, + ) + .into(); + output + }, + ) + .register( + "into_inner", + |_self: Val| { + let output: usize = std::sync::atomic::AtomicUsize::into_inner( + _self.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::utils::Duration>::new(world) + .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 + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .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: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: u32| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "new", + |secs: u64, nanos: u32| { + let output: Val = bevy::utils::Duration::new( + secs, + nanos, + ) + .into(); + output + }, + ) + .register( + "from_secs", + |secs: u64| { + let output: Val = bevy::utils::Duration::from_secs( + secs, + ) + .into(); + output + }, + ) + .register( + "from_millis", + |millis: u64| { + let output: Val = bevy::utils::Duration::from_millis( + millis, + ) + .into(); + output + }, + ) + .register( + "from_micros", + |micros: u64| { + let output: Val = bevy::utils::Duration::from_micros( + micros, + ) + .into(); + output + }, + ) + .register( + "from_nanos", + |nanos: u64| { + let output: Val = bevy::utils::Duration::from_nanos( + nanos, + ) + .into(); + output + }, + ) + .register( + "is_zero", + |_self: Ref| { + let output: bool = bevy::utils::Duration::is_zero(&_self).into(); + output + }, + ) + .register( + "as_secs", + |_self: Ref| { + let output: u64 = bevy::utils::Duration::as_secs(&_self).into(); + output + }, + ) + .register( + "subsec_millis", + |_self: Ref| { + let output: u32 = bevy::utils::Duration::subsec_millis(&_self) + .into(); + output + }, + ) + .register( + "subsec_micros", + |_self: Ref| { + let output: u32 = bevy::utils::Duration::subsec_micros(&_self) + .into(); + output + }, + ) + .register( + "subsec_nanos", + |_self: Ref| { + let output: u32 = bevy::utils::Duration::subsec_nanos(&_self).into(); + output + }, + ) + .register( + "as_millis", + |_self: Ref| { + let output: u128 = bevy::utils::Duration::as_millis(&_self).into(); + output + }, + ) + .register( + "as_micros", + |_self: Ref| { + let output: u128 = bevy::utils::Duration::as_micros(&_self).into(); + output + }, + ) + .register( + "as_nanos", + |_self: Ref| { + let output: u128 = bevy::utils::Duration::as_nanos(&_self).into(); + output + }, + ) + .register( + "abs_diff", + |_self: Val, other: Val| { + let output: Val = bevy::utils::Duration::abs_diff( + _self.into_inner(), + other.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::utils::Duration::saturating_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::utils::Duration::saturating_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_mul", + |_self: Val, rhs: u32| { + let output: Val = bevy::utils::Duration::saturating_mul( + _self.into_inner(), + rhs, + ) + .into(); + output + }, + ) + .register( + "as_secs_f64", + |_self: Ref| { + let output: f64 = bevy::utils::Duration::as_secs_f64(&_self).into(); + output + }, + ) + .register( + "as_secs_f32", + |_self: Ref| { + let output: f32 = bevy::utils::Duration::as_secs_f32(&_self).into(); + output + }, + ) + .register( + "from_secs_f64", + |secs: f64| { + let output: Val = bevy::utils::Duration::from_secs_f64( + secs, + ) + .into(); + output + }, + ) + .register( + "from_secs_f32", + |secs: f32| { + let output: Val = bevy::utils::Duration::from_secs_f32( + secs, + ) + .into(); + output + }, + ) + .register( + "mul_f64", + |_self: Val, rhs: f64| { + let output: Val = bevy::utils::Duration::mul_f64( + _self.into_inner(), + rhs, + ) + .into(); + output + }, + ) + .register( + "mul_f32", + |_self: Val, rhs: f32| { + let output: Val = bevy::utils::Duration::mul_f32( + _self.into_inner(), + rhs, + ) + .into(); + output + }, + ) + .register( + "div_f64", + |_self: Val, rhs: f64| { + let output: Val = bevy::utils::Duration::div_f64( + _self.into_inner(), + rhs, + ) + .into(); + output + }, + ) + .register( + "div_f32", + |_self: Val, rhs: f32| { + let output: Val = bevy::utils::Duration::div_f32( + _self.into_inner(), + rhs, + ) + .into(); + output + }, + ) + .register( + "div_duration_f64", + |_self: Val, rhs: Val| { + let output: f64 = bevy::utils::Duration::div_duration_f64( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "div_duration_f32", + |_self: Val, rhs: Val| { + let output: f32 = bevy::utils::Duration::div_duration_f32( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::utils::Instant>::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( + "sub", + |_self: Val, other: Val| { + let output: Val = >::sub(_self.into_inner(), other.into_inner()) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, other: Val| { + let output: Val = >::sub(_self.into_inner(), other.into_inner()) + .into(); + output + }, + ) + .register( + "now", + || { + let output: Val = bevy::utils::Instant::now() + .into(); + output + }, + ) + .register( + "duration_since", + |_self: Ref, earlier: Val| { + let output: Val = bevy::utils::Instant::duration_since( + &_self, + earlier.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_duration_since", + |_self: Ref, earlier: Val| { + let output: Val = bevy::utils::Instant::saturating_duration_since( + &_self, + earlier.into_inner(), + ) + .into(); + output + }, + ) + .register( + "elapsed", + |_self: Ref| { + let output: Val = bevy::utils::Instant::elapsed( + &_self, + ) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, other: Val| { + let output: Val = >::add(_self.into_inner(), other.into_inner()) + .into(); + output + }, + ); + NamespaceBuilder::<::std::ops::RangeFull>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .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::Quat>::new(world) + .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( + "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( + "mul", + |_self: 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) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: Val| { + let output: Val = >::sub(_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( + "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| { + let output: Val = bevy::math::Quat::from_xyzw( + x, + y, + z, + w, + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [f32; 4]| { + let output: Val = bevy::math::Quat::from_array(a) + .into(); + output + }, + ) + .register( + "from_vec4", + |v: Val| { + let output: Val = bevy::math::Quat::from_vec4( + v.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_axis_angle", + |axis: Val, angle: f32| { + let output: Val = bevy::math::Quat::from_axis_angle( + axis.into_inner(), + angle, + ) + .into(); + output + }, + ) + .register( + "from_scaled_axis", + |v: Val| { + let output: Val = bevy::math::Quat::from_scaled_axis( + v.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_rotation_x", + |angle: f32| { + let output: Val = bevy::math::Quat::from_rotation_x( + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_y", + |angle: f32| { + let output: Val = bevy::math::Quat::from_rotation_y( + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_z", + |angle: f32| { + let output: Val = bevy::math::Quat::from_rotation_z( + angle, + ) + .into(); + output + }, + ) + .register( + "from_euler", + |euler: Val, a: f32, b: f32, c: f32| { + let output: Val = bevy::math::Quat::from_euler( + euler.into_inner(), + a, + b, + c, + ) + .into(); + output + }, + ) + .register( + "from_mat3", + |mat: Ref| { + let output: Val = bevy::math::Quat::from_mat3(&mat) + .into(); + output + }, + ) + .register( + "from_mat3a", + |mat: Ref| { + let output: Val = bevy::math::Quat::from_mat3a( + &mat, + ) + .into(); + output + }, + ) + .register( + "from_mat4", + |mat: Ref| { + let output: Val = bevy::math::Quat::from_mat4(&mat) + .into(); + output + }, + ) + .register( + "from_rotation_arc", + |from: Val, to: Val| { + let output: Val = bevy::math::Quat::from_rotation_arc( + from.into_inner(), + to.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_rotation_arc_colinear", + |from: Val, to: Val| { + let output: Val = bevy::math::Quat::from_rotation_arc_colinear( + from.into_inner(), + to.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_rotation_arc_2d", + |from: Val, to: Val| { + let output: Val = bevy::math::Quat::from_rotation_arc_2d( + from.into_inner(), + to.into_inner(), + ) + .into(); + output + }, + ) + .register( + "to_scaled_axis", + |_self: Val| { + let output: Val = bevy::math::Quat::to_scaled_axis( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "to_euler", + |_self: Val, order: Val| { + let output: (f32, f32, f32) = bevy::math::Quat::to_euler( + _self.into_inner(), + order.into_inner(), + ) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [f32; 4] = bevy::math::Quat::to_array(&_self).into(); + output + }, + ) + .register( + "xyz", + |_self: Val| { + let output: Val = bevy::math::Quat::xyz( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "conjugate", + |_self: Val| { + let output: Val = bevy::math::Quat::conjugate( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "inverse", + |_self: Val| { + let output: Val = bevy::math::Quat::inverse( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Quat::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length", + |_self: Val| { + let output: f32 = bevy::math::Quat::length(_self.into_inner()) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: f32 = bevy::math::Quat::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_recip", + |_self: Val| { + let output: f32 = bevy::math::Quat::length_recip(_self.into_inner()) + .into(); + output + }, + ) + .register( + "normalize", + |_self: Val| { + let output: Val = bevy::math::Quat::normalize( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Val| { + let output: bool = bevy::math::Quat::is_finite(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_nan", + |_self: Val| { + let output: bool = bevy::math::Quat::is_nan(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_normalized", + |_self: Val| { + let output: bool = bevy::math::Quat::is_normalized( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_near_identity", + |_self: Val| { + let output: bool = bevy::math::Quat::is_near_identity( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "angle_between", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Quat::angle_between( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rotate_towards", + | + _self: Ref, + rhs: Val, + max_angle: f32| + { + let output: Val = bevy::math::Quat::rotate_towards( + &_self, + rhs.into_inner(), + max_angle, + ) + .into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Val, + rhs: Val, + max_abs_diff: f32| + { + let output: bool = bevy::math::Quat::abs_diff_eq( + _self.into_inner(), + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .register( + "lerp", + |_self: Val, end: Val, s: f32| { + let output: Val = bevy::math::Quat::lerp( + _self.into_inner(), + end.into_inner(), + s, + ) + .into(); + output + }, + ) + .register( + "slerp", + |_self: Val, end: Val, s: f32| { + let output: Val = bevy::math::Quat::slerp( + _self.into_inner(), + end.into_inner(), + s, + ) + .into(); + output + }, + ) + .register( + "mul_vec3", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Quat::mul_vec3( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul_quat", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Quat::mul_quat( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_affine3", + |a: Ref| { + let output: Val = bevy::math::Quat::from_affine3( + &a, + ) + .into(); + output + }, + ) + .register( + "mul_vec3a", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Quat::mul_vec3a( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "as_dquat", + |_self: Val| { + let output: Val = bevy::math::Quat::as_dquat( + _self.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::Vec3>::new(world) + .register( + "sub", + |_self: Val, rhs: f32| { + 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 + }, + ) + .register( + "add", + |_self: Val, rhs: Val| { + let output: Val = >::add(_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( + "sub", + |_self: Val, rhs: Ref| { + 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: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: f32| { + let output: Val = >::add(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "new", + |x: f32, y: f32, z: f32| { + let output: Val = bevy::math::Vec3::new(x, y, z) + .into(); + output + }, + ) + .register( + "splat", + |v: f32| { + let output: Val = bevy::math::Vec3::splat(v) + .into(); + output + }, + ) + .register( + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::Vec3::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::Vec3::from_array(a) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [f32; 3] = bevy::math::Vec3::to_array(&_self).into(); + output + }, + ) + .register( + "extend", + |_self: Val, w: f32| { + let output: Val = bevy::math::Vec3::extend( + _self.into_inner(), + w, + ) + .into(); + output + }, + ) + .register( + "truncate", + |_self: Val| { + let output: Val = bevy::math::Vec3::truncate( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: f32| { + let output: Val = bevy::math::Vec3::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: f32| { + let output: Val = bevy::math::Vec3::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "with_z", + |_self: Val, z: f32| { + let output: Val = bevy::math::Vec3::with_z( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Vec3::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cross", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3::cross( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::Vec3::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: f32 = bevy::math::Vec3::min_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: f32 = bevy::math::Vec3::max_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: f32 = bevy::math::Vec3::element_sum(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: f32 = bevy::math::Vec3::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs", + |_self: Val| { + let output: Val = bevy::math::Vec3::abs( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "signum", + |_self: Val| { + let output: Val = bevy::math::Vec3::signum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "copysign", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3::copysign( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_negative_bitmask", + |_self: Val| { + let output: u32 = bevy::math::Vec3::is_negative_bitmask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Val| { + let output: bool = bevy::math::Vec3::is_finite(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_finite_mask", + |_self: Val| { + let output: Val = bevy::math::Vec3::is_finite_mask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_nan", + |_self: Val| { + let output: bool = bevy::math::Vec3::is_nan(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_nan_mask", + |_self: Val| { + let output: Val = bevy::math::Vec3::is_nan_mask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length", + |_self: Val| { + let output: f32 = bevy::math::Vec3::length(_self.into_inner()) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: f32 = bevy::math::Vec3::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_recip", + |_self: Val| { + let output: f32 = bevy::math::Vec3::length_recip(_self.into_inner()) + .into(); + output + }, + ) + .register( + "distance", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Vec3::distance( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "distance_squared", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Vec3::distance_squared( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "div_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3::div_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rem_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3::rem_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize", + |_self: Val| { + let output: Val = bevy::math::Vec3::normalize( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize_or", + |_self: Val, fallback: Val| { + let output: Val = bevy::math::Vec3::normalize_or( + _self.into_inner(), + fallback.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize_or_zero", + |_self: Val| { + let output: Val = bevy::math::Vec3::normalize_or_zero( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_normalized", + |_self: Val| { + let output: bool = bevy::math::Vec3::is_normalized( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "project_onto", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3::project_onto( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reject_from", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3::reject_from( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "project_onto_normalized", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3::project_onto_normalized( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reject_from_normalized", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3::reject_from_normalized( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "round", + |_self: Val| { + let output: Val = bevy::math::Vec3::round( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "floor", + |_self: Val| { + let output: Val = bevy::math::Vec3::floor( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "ceil", + |_self: Val| { + let output: Val = bevy::math::Vec3::ceil( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "trunc", + |_self: Val| { + let output: Val = bevy::math::Vec3::trunc( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "fract", + |_self: Val| { + let output: Val = bevy::math::Vec3::fract( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "fract_gl", + |_self: Val| { + let output: Val = bevy::math::Vec3::fract_gl( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "exp", + |_self: Val| { + let output: Val = bevy::math::Vec3::exp( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "powf", + |_self: Val, n: f32| { + let output: Val = bevy::math::Vec3::powf( + _self.into_inner(), + n, + ) + .into(); + output + }, + ) + .register( + "recip", + |_self: Val| { + let output: Val = bevy::math::Vec3::recip( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "lerp", + |_self: Val, rhs: Val, s: f32| { + let output: Val = bevy::math::Vec3::lerp( + _self.into_inner(), + rhs.into_inner(), + s, + ) + .into(); + output + }, + ) + .register( + "move_towards", + |_self: Ref, rhs: Val, d: f32| { + let output: Val = bevy::math::Vec3::move_towards( + &_self, + rhs.into_inner(), + d, + ) + .into(); + output + }, + ) + .register( + "midpoint", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3::midpoint( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Val, + rhs: Val, + max_abs_diff: f32| + { + let output: bool = bevy::math::Vec3::abs_diff_eq( + _self.into_inner(), + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .register( + "clamp_length", + |_self: Val, min: f32, max: f32| { + let output: Val = bevy::math::Vec3::clamp_length( + _self.into_inner(), + min, + max, + ) + .into(); + output + }, + ) + .register( + "clamp_length_max", + |_self: Val, max: f32| { + let output: Val = bevy::math::Vec3::clamp_length_max( + _self.into_inner(), + max, + ) + .into(); + output + }, + ) + .register( + "clamp_length_min", + |_self: Val, min: f32| { + let output: Val = bevy::math::Vec3::clamp_length_min( + _self.into_inner(), + min, + ) + .into(); + output + }, + ) + .register( + "mul_add", + | + _self: Val, + a: Val, + b: Val| + { + let output: Val = bevy::math::Vec3::mul_add( + _self.into_inner(), + a.into_inner(), + b.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reflect", + |_self: Val, normal: Val| { + let output: Val = bevy::math::Vec3::reflect( + _self.into_inner(), + normal.into_inner(), + ) + .into(); + output + }, + ) + .register( + "refract", + |_self: Val, normal: Val, eta: f32| { + let output: Val = bevy::math::Vec3::refract( + _self.into_inner(), + normal.into_inner(), + eta, + ) + .into(); + output + }, + ) + .register( + "angle_between", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Vec3::angle_between( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "any_orthogonal_vector", + |_self: Ref| { + let output: Val = bevy::math::Vec3::any_orthogonal_vector( + &_self, + ) + .into(); + output + }, + ) + .register( + "any_orthonormal_vector", + |_self: Ref| { + let output: Val = bevy::math::Vec3::any_orthonormal_vector( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_dvec3", + |_self: Ref| { + let output: Val = bevy::math::Vec3::as_dvec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_ivec3", + |_self: Ref| { + let output: Val = bevy::math::Vec3::as_ivec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_uvec3", + |_self: Ref| { + let output: Val = bevy::math::Vec3::as_uvec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_i64vec3", + |_self: Ref| { + let output: Val = bevy::math::Vec3::as_i64vec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_u64vec3", + |_self: Ref| { + let output: Val = bevy::math::Vec3::as_u64vec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: Ref| { + 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: 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) + .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| { + let output: bool = >::eq(&_self, &other) + .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| { + let output: Val = bevy::math::IVec2::new(x, y) + .into(); + output + }, + ) + .register( + "splat", + |v: i32| { + let output: Val = bevy::math::IVec2::splat(v) + .into(); + output + }, + ) + .register( + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::IVec2::select( + mask.into_inner(), + if_true.into_inner(), + if_false.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [i32; 2]| { + let output: Val = bevy::math::IVec2::from_array(a) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [i32; 2] = bevy::math::IVec2::to_array(&_self).into(); + output + }, + ) + .register( + "extend", + |_self: Val, z: i32| { + let output: Val = bevy::math::IVec2::extend( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: i32| { + let output: Val = bevy::math::IVec2::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: i32| { + let output: Val = bevy::math::IVec2::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: i32 = bevy::math::IVec2::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::IVec2::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: i32 = bevy::math::IVec2::min_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: i32 = bevy::math::IVec2::max_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: i32 = bevy::math::IVec2::element_sum(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: i32 = bevy::math::IVec2::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs", + |_self: Val| { + let output: Val = bevy::math::IVec2::abs( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "signum", + |_self: Val| { + let output: Val = bevy::math::IVec2::signum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_negative_bitmask", + |_self: Val| { + let output: u32 = bevy::math::IVec2::is_negative_bitmask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: i32 = bevy::math::IVec2::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "distance_squared", + |_self: Val, rhs: Val| { + let output: i32 = bevy::math::IVec2::distance_squared( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "div_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::div_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rem_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::rem_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "perp", + |_self: Val| { + let output: Val = bevy::math::IVec2::perp( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "perp_dot", + |_self: Val, rhs: Val| { + let output: i32 = bevy::math::IVec2::perp_dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rotate", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::rotate( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "as_vec2", + |_self: Ref| { + let output: Val = bevy::math::IVec2::as_vec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_dvec2", + |_self: Ref| { + let output: Val = bevy::math::IVec2::as_dvec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_uvec2", + |_self: Ref| { + let output: Val = bevy::math::IVec2::as_uvec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_i64vec2", + |_self: Ref| { + let output: Val = bevy::math::IVec2::as_i64vec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_u64vec2", + |_self: Ref| { + let output: Val = bevy::math::IVec2::as_u64vec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "wrapping_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::wrapping_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::wrapping_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::wrapping_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::wrapping_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::saturating_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::saturating_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::saturating_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::saturating_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_add_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::wrapping_add_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_sub_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::wrapping_sub_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::saturating_add_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec2::saturating_sub_unsigned( + _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( + "mul", + |_self: Val, rhs: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .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", + |_self: Val, rhs: Ref| { + let output: Val = >::rem(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: i32| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: i32| { + 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( + "add", + |_self: Val, rhs: Ref| { + let output: Val = >::add(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: i32| { + let output: Val = >::add(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: i32| { + 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( + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: Val| { + let output: Val = >::div(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .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) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: i32| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: i32| { + let output: Val = >::rem(_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: Val| { + let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "new", + |x: i32, y: i32, z: i32| { + let output: Val = bevy::math::IVec3::new(x, y, z) + .into(); + output + }, + ) + .register( + "splat", + |v: i32| { + let output: Val = bevy::math::IVec3::splat(v) + .into(); + output + }, + ) + .register( + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::IVec3::select( + mask.into_inner(), + if_true.into_inner(), + if_false.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [i32; 3]| { + let output: Val = bevy::math::IVec3::from_array(a) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [i32; 3] = bevy::math::IVec3::to_array(&_self).into(); + output + }, + ) + .register( + "extend", + |_self: Val, w: i32| { + let output: Val = bevy::math::IVec3::extend( + _self.into_inner(), + w, + ) + .into(); + output + }, + ) + .register( + "truncate", + |_self: Val| { + let output: Val = bevy::math::IVec3::truncate( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: i32| { + let output: Val = bevy::math::IVec3::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: i32| { + let output: Val = bevy::math::IVec3::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "with_z", + |_self: Val, z: i32| { + let output: Val = bevy::math::IVec3::with_z( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: i32 = bevy::math::IVec3::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cross", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::cross( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::IVec3::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: i32 = bevy::math::IVec3::min_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: i32 = bevy::math::IVec3::max_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: i32 = bevy::math::IVec3::element_sum(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: i32 = bevy::math::IVec3::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs", + |_self: Val| { + let output: Val = bevy::math::IVec3::abs( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "signum", + |_self: Val| { + let output: Val = bevy::math::IVec3::signum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_negative_bitmask", + |_self: Val| { + let output: u32 = bevy::math::IVec3::is_negative_bitmask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: i32 = bevy::math::IVec3::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "distance_squared", + |_self: Val, rhs: Val| { + let output: i32 = bevy::math::IVec3::distance_squared( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "div_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::div_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rem_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::rem_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "as_vec3", + |_self: Ref| { + let output: Val = bevy::math::IVec3::as_vec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_vec3a", + |_self: Ref| { + let output: Val = bevy::math::IVec3::as_vec3a( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_dvec3", + |_self: Ref| { + let output: Val = bevy::math::IVec3::as_dvec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_uvec3", + |_self: Ref| { + let output: Val = bevy::math::IVec3::as_uvec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_i64vec3", + |_self: Ref| { + let output: Val = bevy::math::IVec3::as_i64vec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_u64vec3", + |_self: Ref| { + let output: Val = bevy::math::IVec3::as_u64vec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "wrapping_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::wrapping_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::wrapping_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::wrapping_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::wrapping_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::saturating_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::saturating_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::saturating_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::saturating_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_add_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::wrapping_add_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_sub_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::wrapping_sub_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::saturating_add_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec3::saturating_sub_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: i32| { + 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( + "rem", + |_self: Val, rhs: Ref| { + 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( + "sub", + |_self: Val, rhs: i32| { + 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( + "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( + "add", + |_self: Val, rhs: i32| { + let output: Val = >::add(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: Ref| { + let output: Val = >::add(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) + .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( + "div", + |_self: Val, rhs: Ref| { + let output: Val = >::div(_self.into_inner(), &rhs) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::IVec4>::new(world) + .register( + "rem", + |_self: Val, rhs: i32| { + let output: Val = >::rem(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "new", + |x: i32, y: i32, z: i32, w: i32| { + let output: Val = bevy::math::IVec4::new( + x, + y, + z, + w, + ) + .into(); + output + }, + ) + .register( + "splat", + |v: i32| { + let output: Val = bevy::math::IVec4::splat(v) + .into(); + output + }, + ) + .register( + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::IVec4::select( + mask.into_inner(), + if_true.into_inner(), + if_false.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [i32; 4]| { + let output: Val = bevy::math::IVec4::from_array(a) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [i32; 4] = bevy::math::IVec4::to_array(&_self).into(); + output + }, + ) + .register( + "truncate", + |_self: Val| { + let output: Val = bevy::math::IVec4::truncate( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: i32| { + let output: Val = bevy::math::IVec4::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: i32| { + let output: Val = bevy::math::IVec4::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "with_z", + |_self: Val, z: i32| { + let output: Val = bevy::math::IVec4::with_z( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "with_w", + |_self: Val, w: i32| { + let output: Val = bevy::math::IVec4::with_w( + _self.into_inner(), + w, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: i32 = bevy::math::IVec4::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::IVec4::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: i32 = bevy::math::IVec4::min_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: i32 = bevy::math::IVec4::max_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: i32 = bevy::math::IVec4::element_sum(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: i32 = bevy::math::IVec4::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs", + |_self: Val| { + let output: Val = bevy::math::IVec4::abs( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "signum", + |_self: Val| { + let output: Val = bevy::math::IVec4::signum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_negative_bitmask", + |_self: Val| { + let output: u32 = bevy::math::IVec4::is_negative_bitmask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: i32 = bevy::math::IVec4::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "distance_squared", + |_self: Val, rhs: Val| { + let output: i32 = bevy::math::IVec4::distance_squared( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "div_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::div_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rem_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::rem_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "as_vec4", + |_self: Ref| { + let output: Val = bevy::math::IVec4::as_vec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_dvec4", + |_self: Ref| { + let output: Val = bevy::math::IVec4::as_dvec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_uvec4", + |_self: Ref| { + let output: Val = bevy::math::IVec4::as_uvec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_i64vec4", + |_self: Ref| { + let output: Val = bevy::math::IVec4::as_i64vec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_u64vec4", + |_self: Ref| { + let output: Val = bevy::math::IVec4::as_u64vec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "wrapping_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::wrapping_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::wrapping_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::wrapping_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::wrapping_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::saturating_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::saturating_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::saturating_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::saturating_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_add_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::wrapping_add_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_sub_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::wrapping_sub_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::saturating_add_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::IVec4::saturating_sub_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: i32| { + 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( + "add", + |_self: Val, rhs: Ref| { + let output: Val = >::add(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: i32| { + 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: 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( + "mul", + |_self: Val, rhs: i32| { + let output: Val = >::mul(_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( + "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: 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) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: Ref| { + let output: Val = >::sub(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: Val| { + let output: Val = >::div(_self.into_inner(), rhs.into_inner()) + .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| { + let output: Val = >::rem(_self.into_inner(), &rhs) + .into(); + 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| { + let output: Val = bevy::math::I64Vec2::new(x, y) + .into(); + output + }, + ) + .register( + "splat", + |v: i64| { + let output: Val = bevy::math::I64Vec2::splat(v) + .into(); + output + }, + ) + .register( + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::I64Vec2::select( + mask.into_inner(), + if_true.into_inner(), + if_false.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [i64; 2]| { + let output: Val = bevy::math::I64Vec2::from_array( + a, + ) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [i64; 2] = bevy::math::I64Vec2::to_array(&_self).into(); + output + }, + ) + .register( + "extend", + |_self: Val, z: i64| { + let output: Val = bevy::math::I64Vec2::extend( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: i64| { + let output: Val = bevy::math::I64Vec2::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: i64| { + let output: Val = bevy::math::I64Vec2::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: i64 = bevy::math::I64Vec2::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::I64Vec2::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: i64 = bevy::math::I64Vec2::min_element( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: i64 = bevy::math::I64Vec2::max_element( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: i64 = bevy::math::I64Vec2::element_sum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: i64 = bevy::math::I64Vec2::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs", + |_self: Val| { + let output: Val = bevy::math::I64Vec2::abs( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "signum", + |_self: Val| { + let output: Val = bevy::math::I64Vec2::signum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_negative_bitmask", + |_self: Val| { + let output: u32 = bevy::math::I64Vec2::is_negative_bitmask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: i64 = bevy::math::I64Vec2::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "distance_squared", + |_self: Val, rhs: Val| { + let output: i64 = bevy::math::I64Vec2::distance_squared( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "div_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::div_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rem_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::rem_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "perp", + |_self: Val| { + let output: Val = bevy::math::I64Vec2::perp( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "perp_dot", + |_self: Val, rhs: Val| { + let output: i64 = bevy::math::I64Vec2::perp_dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rotate", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::rotate( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "as_vec2", + |_self: Ref| { + let output: Val = bevy::math::I64Vec2::as_vec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_dvec2", + |_self: Ref| { + let output: Val = bevy::math::I64Vec2::as_dvec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_ivec2", + |_self: Ref| { + let output: Val = bevy::math::I64Vec2::as_ivec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_uvec2", + |_self: Ref| { + let output: Val = bevy::math::I64Vec2::as_uvec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_u64vec2", + |_self: Ref| { + let output: Val = bevy::math::I64Vec2::as_u64vec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "wrapping_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::wrapping_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::wrapping_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::wrapping_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::wrapping_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::saturating_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::saturating_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::saturating_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::saturating_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_add_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::wrapping_add_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_sub_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::wrapping_sub_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::saturating_add_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec2::saturating_sub_unsigned( + _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( + "rem", + |_self: Val, rhs: Val| { + let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: i64| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: i64| { + 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( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::I64Vec3>::new(world) + .register( + "rem", + |_self: Val, rhs: i64| { + 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( + "sub", + |_self: Val, rhs: i64| { + let output: Val = >::sub(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: Ref| { + let output: Val = >::rem(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "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( + "new", + |x: i64, y: i64, z: i64| { + let output: Val = bevy::math::I64Vec3::new( + x, + y, + z, + ) + .into(); + output + }, + ) + .register( + "splat", + |v: i64| { + let output: Val = bevy::math::I64Vec3::splat(v) + .into(); + output + }, + ) + .register( + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::I64Vec3::select( + mask.into_inner(), + if_true.into_inner(), + if_false.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [i64; 3]| { + let output: Val = bevy::math::I64Vec3::from_array( + a, + ) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [i64; 3] = bevy::math::I64Vec3::to_array(&_self).into(); + output + }, + ) + .register( + "extend", + |_self: Val, w: i64| { + let output: Val = bevy::math::I64Vec3::extend( + _self.into_inner(), + w, + ) + .into(); + output + }, + ) + .register( + "truncate", + |_self: Val| { + let output: Val = bevy::math::I64Vec3::truncate( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: i64| { + let output: Val = bevy::math::I64Vec3::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: i64| { + let output: Val = bevy::math::I64Vec3::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "with_z", + |_self: Val, z: i64| { + let output: Val = bevy::math::I64Vec3::with_z( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: i64 = bevy::math::I64Vec3::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cross", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::cross( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::I64Vec3::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: i64 = bevy::math::I64Vec3::min_element( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: i64 = bevy::math::I64Vec3::max_element( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: i64 = bevy::math::I64Vec3::element_sum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: i64 = bevy::math::I64Vec3::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs", + |_self: Val| { + let output: Val = bevy::math::I64Vec3::abs( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "signum", + |_self: Val| { + let output: Val = bevy::math::I64Vec3::signum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_negative_bitmask", + |_self: Val| { + let output: u32 = bevy::math::I64Vec3::is_negative_bitmask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: i64 = bevy::math::I64Vec3::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "distance_squared", + |_self: Val, rhs: Val| { + let output: i64 = bevy::math::I64Vec3::distance_squared( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "div_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::div_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rem_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::rem_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "as_vec3", + |_self: Ref| { + let output: Val = bevy::math::I64Vec3::as_vec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_vec3a", + |_self: Ref| { + let output: Val = bevy::math::I64Vec3::as_vec3a( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_dvec3", + |_self: Ref| { + let output: Val = bevy::math::I64Vec3::as_dvec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_ivec3", + |_self: Ref| { + let output: Val = bevy::math::I64Vec3::as_ivec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_uvec3", + |_self: Ref| { + let output: Val = bevy::math::I64Vec3::as_uvec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_u64vec3", + |_self: Ref| { + let output: Val = bevy::math::I64Vec3::as_u64vec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "wrapping_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::wrapping_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::wrapping_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::wrapping_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::wrapping_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::saturating_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::saturating_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::saturating_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::saturating_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_add_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::wrapping_add_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_sub_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::wrapping_sub_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::saturating_add_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec3::saturating_sub_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: Ref| { + let output: Val = >::add(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: i64| { + 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( + &_self, + ) + .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: i64| { + let output: Val = >::div(_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: Val| { + let output: Val = >::sub(_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( + "mul", + |_self: 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 + }, + ) + .register( + "mul", + |_self: Val, rhs: i64| { + let output: Val = >::mul(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::I64Vec4>::new(world) + .register( + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: Ref| { + let output: Val = >::div(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: i64| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: Ref| { + let output: Val = >::rem(_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( + "add", + |_self: Val, rhs: i64| { + let output: Val = >::add(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: Val| { + let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: i64| { + 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()) + .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: 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| { + let output: Val = bevy::math::I64Vec4::new( + x, + y, + z, + w, + ) + .into(); + output + }, + ) + .register( + "splat", + |v: i64| { + let output: Val = bevy::math::I64Vec4::splat(v) + .into(); + output + }, + ) + .register( + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::I64Vec4::select( + mask.into_inner(), + if_true.into_inner(), + if_false.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [i64; 4]| { + let output: Val = bevy::math::I64Vec4::from_array( + a, + ) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [i64; 4] = bevy::math::I64Vec4::to_array(&_self).into(); + output + }, + ) + .register( + "truncate", + |_self: Val| { + let output: Val = bevy::math::I64Vec4::truncate( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: i64| { + let output: Val = bevy::math::I64Vec4::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: i64| { + let output: Val = bevy::math::I64Vec4::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "with_z", + |_self: Val, z: i64| { + let output: Val = bevy::math::I64Vec4::with_z( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "with_w", + |_self: Val, w: i64| { + let output: Val = bevy::math::I64Vec4::with_w( + _self.into_inner(), + w, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: i64 = bevy::math::I64Vec4::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::I64Vec4::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: i64 = bevy::math::I64Vec4::min_element( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: i64 = bevy::math::I64Vec4::max_element( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: i64 = bevy::math::I64Vec4::element_sum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: i64 = bevy::math::I64Vec4::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs", + |_self: Val| { + let output: Val = bevy::math::I64Vec4::abs( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "signum", + |_self: Val| { + let output: Val = bevy::math::I64Vec4::signum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_negative_bitmask", + |_self: Val| { + let output: u32 = bevy::math::I64Vec4::is_negative_bitmask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: i64 = bevy::math::I64Vec4::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "distance_squared", + |_self: Val, rhs: Val| { + let output: i64 = bevy::math::I64Vec4::distance_squared( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "div_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::div_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rem_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::rem_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "as_vec4", + |_self: Ref| { + let output: Val = bevy::math::I64Vec4::as_vec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_dvec4", + |_self: Ref| { + let output: Val = bevy::math::I64Vec4::as_dvec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_ivec4", + |_self: Ref| { + let output: Val = bevy::math::I64Vec4::as_ivec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_uvec4", + |_self: Ref| { + let output: Val = bevy::math::I64Vec4::as_uvec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_u64vec4", + |_self: Ref| { + let output: Val = bevy::math::I64Vec4::as_u64vec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "wrapping_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::wrapping_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::wrapping_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::wrapping_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::wrapping_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::saturating_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::saturating_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::saturating_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::saturating_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_add_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::wrapping_add_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_sub_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::wrapping_sub_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::saturating_add_unsigned( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub_unsigned", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::I64Vec4::saturating_sub_unsigned( + _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( + "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) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: Ref| { + let output: Val = >::div(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: u32| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "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( + "sub", + |_self: Val, rhs: Ref| { + let output: Val = >::sub(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: Ref| { + let output: Val = >::rem(_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: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "add", + |_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( + "rem", + |_self: Val, rhs: u32| { + 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( + "mul", + |_self: Val, rhs: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "add", + |_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( + &_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(), + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [u32; 2]| { + let output: Val = bevy::math::UVec2::from_array(a) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [u32; 2] = bevy::math::UVec2::to_array(&_self).into(); + output + }, + ) + .register( + "extend", + |_self: Val, z: u32| { + let output: Val = bevy::math::UVec2::extend( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: u32| { + let output: Val = bevy::math::UVec2::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: u32| { + let output: Val = bevy::math::UVec2::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: u32 = bevy::math::UVec2::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::UVec2::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: u32 = bevy::math::UVec2::min_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: u32 = bevy::math::UVec2::max_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: u32 = bevy::math::UVec2::element_sum(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: u32 = bevy::math::UVec2::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: u32 = bevy::math::UVec2::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "as_vec2", + |_self: Ref| { + let output: Val = bevy::math::UVec2::as_vec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_dvec2", + |_self: Ref| { + let output: Val = bevy::math::UVec2::as_dvec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_ivec2", + |_self: Ref| { + let output: Val = bevy::math::UVec2::as_ivec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_i64vec2", + |_self: Ref| { + let output: Val = bevy::math::UVec2::as_i64vec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_u64vec2", + |_self: Ref| { + let output: Val = bevy::math::UVec2::as_u64vec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "wrapping_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::wrapping_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::wrapping_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::wrapping_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::wrapping_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::saturating_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::saturating_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::saturating_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::saturating_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_add_signed", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::wrapping_add_signed( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add_signed", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec2::saturating_add_signed( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::UVec3>::new(world) + .register( + "add", + |_self: Val, rhs: Ref| { + 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( + &_self, + ) + .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: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "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( + "mul", + |_self: Val, rhs: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: u32| { + let output: Val = >::mul(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "new", + |x: u32, y: u32, z: u32| { + let output: Val = bevy::math::UVec3::new(x, y, z) + .into(); + output + }, + ) + .register( + "splat", + |v: u32| { + let output: Val = bevy::math::UVec3::splat(v) + .into(); + output + }, + ) + .register( + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::UVec3::select( + mask.into_inner(), + if_true.into_inner(), + if_false.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [u32; 3]| { + let output: Val = bevy::math::UVec3::from_array(a) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [u32; 3] = bevy::math::UVec3::to_array(&_self).into(); + output + }, + ) + .register( + "extend", + |_self: Val, w: u32| { + let output: Val = bevy::math::UVec3::extend( + _self.into_inner(), + w, + ) + .into(); + output + }, + ) + .register( + "truncate", + |_self: Val| { + let output: Val = bevy::math::UVec3::truncate( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: u32| { + let output: Val = bevy::math::UVec3::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: u32| { + let output: Val = bevy::math::UVec3::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "with_z", + |_self: Val, z: u32| { + let output: Val = bevy::math::UVec3::with_z( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: u32 = bevy::math::UVec3::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cross", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::cross( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::UVec3::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: u32 = bevy::math::UVec3::min_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: u32 = bevy::math::UVec3::max_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: u32 = bevy::math::UVec3::element_sum(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: u32 = bevy::math::UVec3::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: u32 = bevy::math::UVec3::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "as_vec3", + |_self: Ref| { + let output: Val = bevy::math::UVec3::as_vec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_vec3a", + |_self: Ref| { + let output: Val = bevy::math::UVec3::as_vec3a( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_dvec3", + |_self: Ref| { + let output: Val = bevy::math::UVec3::as_dvec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_ivec3", + |_self: Ref| { + let output: Val = bevy::math::UVec3::as_ivec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_i64vec3", + |_self: Ref| { + let output: Val = bevy::math::UVec3::as_i64vec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_u64vec3", + |_self: Ref| { + let output: Val = bevy::math::UVec3::as_u64vec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "wrapping_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::wrapping_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::wrapping_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::wrapping_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::wrapping_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::saturating_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::saturating_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::saturating_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::saturating_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_add_signed", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::wrapping_add_signed( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add_signed", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec3::saturating_add_signed( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: u32| { + let output: Val = >::sub(_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( + "rem", + |_self: Val, rhs: Ref| { + let output: Val = >::rem(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) + .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: 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: Ref| { + let output: Val = >::sub(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "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) + .into(); + output + }, + ); + 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", + |_self: Val, rhs: u32| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .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()) + .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: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "new", + |x: u32, y: u32, z: u32, w: u32| { + let output: Val = bevy::math::UVec4::new( + x, + y, + z, + w, + ) + .into(); + output + }, + ) + .register( + "splat", + |v: u32| { + let output: Val = bevy::math::UVec4::splat(v) + .into(); + output + }, + ) + .register( + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::UVec4::select( + mask.into_inner(), + if_true.into_inner(), + if_false.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [u32; 4]| { + let output: Val = bevy::math::UVec4::from_array(a) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [u32; 4] = bevy::math::UVec4::to_array(&_self).into(); + output + }, + ) + .register( + "truncate", + |_self: Val| { + let output: Val = bevy::math::UVec4::truncate( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: u32| { + let output: Val = bevy::math::UVec4::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: u32| { + let output: Val = bevy::math::UVec4::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "with_z", + |_self: Val, z: u32| { + let output: Val = bevy::math::UVec4::with_z( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "with_w", + |_self: Val, w: u32| { + let output: Val = bevy::math::UVec4::with_w( + _self.into_inner(), + w, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: u32 = bevy::math::UVec4::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::UVec4::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: u32 = bevy::math::UVec4::min_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: u32 = bevy::math::UVec4::max_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: u32 = bevy::math::UVec4::element_sum(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: u32 = bevy::math::UVec4::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: u32 = bevy::math::UVec4::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "as_vec4", + |_self: Ref| { + let output: Val = bevy::math::UVec4::as_vec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_dvec4", + |_self: Ref| { + let output: Val = bevy::math::UVec4::as_dvec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_ivec4", + |_self: Ref| { + let output: Val = bevy::math::UVec4::as_ivec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_i64vec4", + |_self: Ref| { + let output: Val = bevy::math::UVec4::as_i64vec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_u64vec4", + |_self: Ref| { + let output: Val = bevy::math::UVec4::as_u64vec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "wrapping_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::wrapping_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::wrapping_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::wrapping_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::wrapping_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::saturating_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::saturating_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::saturating_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::saturating_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_add_signed", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::wrapping_add_signed( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add_signed", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::UVec4::saturating_add_signed( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .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) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: Val| { + let output: Val = >::div(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: u32| { + 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( + "div", + |_self: Val, rhs: Ref| { + 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 + }, + ) + .register( + "rem", + |_self: Val, rhs: u32| { + 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( + "add", + |_self: Val, rhs: u32| { + let output: Val = >::add(_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) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: Val| { + let output: Val = >::rem(_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( + "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( + "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( + "sub", + |_self: Val, rhs: u64| { + let output: Val = >::sub(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: Ref| { + let output: Val = >::rem(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: u64| { + let output: Val = >::add(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: Ref| { + let output: Val = >::div(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "new", + |x: u64, y: u64| { + let output: Val = bevy::math::U64Vec2::new(x, y) + .into(); + output + }, + ) + .register( + "splat", + |v: u64| { + let output: Val = bevy::math::U64Vec2::splat(v) + .into(); + output + }, + ) + .register( + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::U64Vec2::select( + mask.into_inner(), + if_true.into_inner(), + if_false.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [u64; 2]| { + let output: Val = bevy::math::U64Vec2::from_array( + a, + ) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [u64; 2] = bevy::math::U64Vec2::to_array(&_self).into(); + output + }, + ) + .register( + "extend", + |_self: Val, z: u64| { + let output: Val = bevy::math::U64Vec2::extend( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: u64| { + let output: Val = bevy::math::U64Vec2::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: u64| { + let output: Val = bevy::math::U64Vec2::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: u64 = bevy::math::U64Vec2::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::U64Vec2::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: u64 = bevy::math::U64Vec2::min_element( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: u64 = bevy::math::U64Vec2::max_element( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: u64 = bevy::math::U64Vec2::element_sum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: u64 = bevy::math::U64Vec2::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: u64 = bevy::math::U64Vec2::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "as_vec2", + |_self: Ref| { + let output: Val = bevy::math::U64Vec2::as_vec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_dvec2", + |_self: Ref| { + let output: Val = bevy::math::U64Vec2::as_dvec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_ivec2", + |_self: Ref| { + let output: Val = bevy::math::U64Vec2::as_ivec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_uvec2", + |_self: Ref| { + let output: Val = bevy::math::U64Vec2::as_uvec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_i64vec2", + |_self: Ref| { + let output: Val = bevy::math::U64Vec2::as_i64vec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "wrapping_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::wrapping_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::wrapping_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::wrapping_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::wrapping_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::saturating_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::saturating_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::saturating_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::saturating_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_add_signed", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::wrapping_add_signed( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add_signed", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec2::saturating_add_signed( + _self.into_inner(), + rhs.into_inner(), + ) + .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( + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: u64| { + let output: Val = >::rem(_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( + "sub", + |_self: 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| { + let output: Val = >::mul(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: u64| { + let output: Val = >::sub(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "new", + |x: u64, y: u64, z: u64| { + let output: Val = bevy::math::U64Vec3::new( + x, + y, + z, + ) + .into(); + output + }, + ) + .register( + "splat", + |v: u64| { + let output: Val = bevy::math::U64Vec3::splat(v) + .into(); + output + }, + ) + .register( + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::U64Vec3::select( + mask.into_inner(), + if_true.into_inner(), + if_false.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [u64; 3]| { + let output: Val = bevy::math::U64Vec3::from_array( + a, + ) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [u64; 3] = bevy::math::U64Vec3::to_array(&_self).into(); + output + }, + ) + .register( + "extend", + |_self: Val, w: u64| { + let output: Val = bevy::math::U64Vec3::extend( + _self.into_inner(), + w, + ) + .into(); + output + }, + ) + .register( + "truncate", + |_self: Val| { + let output: Val = bevy::math::U64Vec3::truncate( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: u64| { + let output: Val = bevy::math::U64Vec3::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: u64| { + let output: Val = bevy::math::U64Vec3::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "with_z", + |_self: Val, z: u64| { + let output: Val = bevy::math::U64Vec3::with_z( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: u64 = bevy::math::U64Vec3::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cross", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::cross( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::U64Vec3::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: u64 = bevy::math::U64Vec3::min_element( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: u64 = bevy::math::U64Vec3::max_element( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: u64 = bevy::math::U64Vec3::element_sum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: u64 = bevy::math::U64Vec3::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: u64 = bevy::math::U64Vec3::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "as_vec3", + |_self: Ref| { + let output: Val = bevy::math::U64Vec3::as_vec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_vec3a", + |_self: Ref| { + let output: Val = bevy::math::U64Vec3::as_vec3a( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_dvec3", + |_self: Ref| { + let output: Val = bevy::math::U64Vec3::as_dvec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_ivec3", + |_self: Ref| { + let output: Val = bevy::math::U64Vec3::as_ivec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_uvec3", + |_self: Ref| { + let output: Val = bevy::math::U64Vec3::as_uvec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_i64vec3", + |_self: Ref| { + let output: Val = bevy::math::U64Vec3::as_i64vec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "wrapping_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::wrapping_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::wrapping_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::wrapping_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::wrapping_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::saturating_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::saturating_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::saturating_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::saturating_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_add_signed", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::wrapping_add_signed( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add_signed", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec3::saturating_add_signed( + _self.into_inner(), + rhs.into_inner(), + ) + .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()) + .into(); + output + }, + ) + .register( + "rem", + |_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) + .into(); + output + }, + ) + .register( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .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", + |_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) + .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( + "rem", + |_self: Val, rhs: Val| { + let output: Val = >::rem(_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: u64| { + 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( + "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( + "div", + |_self: Val, rhs: Val| { + let output: Val = >::div(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "new", + |x: u64, y: u64, z: u64, w: u64| { + let output: Val = bevy::math::U64Vec4::new( + x, + y, + z, + w, + ) + .into(); + output + }, + ) + .register( + "splat", + |v: u64| { + let output: Val = bevy::math::U64Vec4::splat(v) + .into(); + output + }, + ) + .register( + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::U64Vec4::select( + mask.into_inner(), + if_true.into_inner(), + if_false.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [u64; 4]| { + let output: Val = bevy::math::U64Vec4::from_array( + a, + ) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [u64; 4] = bevy::math::U64Vec4::to_array(&_self).into(); + output + }, + ) + .register( + "truncate", + |_self: Val| { + let output: Val = bevy::math::U64Vec4::truncate( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: u64| { + let output: Val = bevy::math::U64Vec4::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: u64| { + let output: Val = bevy::math::U64Vec4::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "with_z", + |_self: Val, z: u64| { + let output: Val = bevy::math::U64Vec4::with_z( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "with_w", + |_self: Val, w: u64| { + let output: Val = bevy::math::U64Vec4::with_w( + _self.into_inner(), + w, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: u64 = bevy::math::U64Vec4::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::U64Vec4::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: u64 = bevy::math::U64Vec4::min_element( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: u64 = bevy::math::U64Vec4::max_element( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: u64 = bevy::math::U64Vec4::element_sum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: u64 = bevy::math::U64Vec4::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: u64 = bevy::math::U64Vec4::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "as_vec4", + |_self: Ref| { + let output: Val = bevy::math::U64Vec4::as_vec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_dvec4", + |_self: Ref| { + let output: Val = bevy::math::U64Vec4::as_dvec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_ivec4", + |_self: Ref| { + let output: Val = bevy::math::U64Vec4::as_ivec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_uvec4", + |_self: Ref| { + let output: Val = bevy::math::U64Vec4::as_uvec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_i64vec4", + |_self: Ref| { + let output: Val = bevy::math::U64Vec4::as_i64vec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "wrapping_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::wrapping_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::wrapping_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::wrapping_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::wrapping_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::saturating_add( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_sub", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::saturating_sub( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_mul", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::saturating_mul( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_div", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::saturating_div( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "wrapping_add_signed", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::wrapping_add_signed( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "saturating_add_signed", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::U64Vec4::saturating_add_signed( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .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 = >::eq(&_self, &other) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: u64| { + let output: Val = >::sub(_self.into_inner(), rhs) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::Vec2>::new(world) + .register( + "div", + |_self: Val, rhs: Ref| { + 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: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: Ref| { + let output: Val = >::sub(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) + .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( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "new", + |x: f32, y: f32| { + let output: Val = bevy::math::Vec2::new(x, y) + .into(); + output + }, + ) + .register( + "splat", + |v: f32| { + let output: Val = bevy::math::Vec2::splat(v) + .into(); + output + }, + ) + .register( + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::Vec2::select( + mask.into_inner(), + if_true.into_inner(), + if_false.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [f32; 2]| { + let output: Val = bevy::math::Vec2::from_array(a) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [f32; 2] = bevy::math::Vec2::to_array(&_self).into(); + output + }, + ) + .register( + "extend", + |_self: Val, z: f32| { + let output: Val = bevy::math::Vec2::extend( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: f32| { + let output: Val = bevy::math::Vec2::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: f32| { + let output: Val = bevy::math::Vec2::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Vec2::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec2::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec2::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec2::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::Vec2::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: f32 = bevy::math::Vec2::min_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: f32 = bevy::math::Vec2::max_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: f32 = bevy::math::Vec2::element_sum(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: f32 = bevy::math::Vec2::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec2::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec2::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec2::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec2::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec2::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec2::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs", + |_self: Val| { + let output: Val = bevy::math::Vec2::abs( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "signum", + |_self: Val| { + let output: Val = bevy::math::Vec2::signum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "copysign", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec2::copysign( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_negative_bitmask", + |_self: Val| { + let output: u32 = bevy::math::Vec2::is_negative_bitmask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Val| { + let output: bool = bevy::math::Vec2::is_finite(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_finite_mask", + |_self: Val| { + let output: Val = bevy::math::Vec2::is_finite_mask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_nan", + |_self: Val| { + let output: bool = bevy::math::Vec2::is_nan(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_nan_mask", + |_self: Val| { + let output: Val = bevy::math::Vec2::is_nan_mask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length", + |_self: Val| { + let output: f32 = bevy::math::Vec2::length(_self.into_inner()) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: f32 = bevy::math::Vec2::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_recip", + |_self: Val| { + let output: f32 = bevy::math::Vec2::length_recip(_self.into_inner()) + .into(); + output + }, + ) + .register( + "distance", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Vec2::distance( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "distance_squared", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Vec2::distance_squared( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "div_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec2::div_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rem_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec2::rem_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize", + |_self: Val| { + let output: Val = bevy::math::Vec2::normalize( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize_or", + |_self: Val, fallback: Val| { + let output: Val = bevy::math::Vec2::normalize_or( + _self.into_inner(), + fallback.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize_or_zero", + |_self: Val| { + let output: Val = bevy::math::Vec2::normalize_or_zero( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_normalized", + |_self: Val| { + let output: bool = bevy::math::Vec2::is_normalized( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "project_onto", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec2::project_onto( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reject_from", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec2::reject_from( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "project_onto_normalized", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec2::project_onto_normalized( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reject_from_normalized", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec2::reject_from_normalized( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "round", + |_self: Val| { + let output: Val = bevy::math::Vec2::round( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "floor", + |_self: Val| { + let output: Val = bevy::math::Vec2::floor( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "ceil", + |_self: Val| { + let output: Val = bevy::math::Vec2::ceil( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "trunc", + |_self: Val| { + let output: Val = bevy::math::Vec2::trunc( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "fract", + |_self: Val| { + let output: Val = bevy::math::Vec2::fract( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "fract_gl", + |_self: Val| { + let output: Val = bevy::math::Vec2::fract_gl( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "exp", + |_self: Val| { + let output: Val = bevy::math::Vec2::exp( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "powf", + |_self: Val, n: f32| { + let output: Val = bevy::math::Vec2::powf( + _self.into_inner(), + n, + ) + .into(); + output + }, + ) + .register( + "recip", + |_self: Val| { + let output: Val = bevy::math::Vec2::recip( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "lerp", + |_self: Val, rhs: Val, s: f32| { + let output: Val = bevy::math::Vec2::lerp( + _self.into_inner(), + rhs.into_inner(), + s, + ) + .into(); + output + }, + ) + .register( + "move_towards", + |_self: Ref, rhs: Val, d: f32| { + let output: Val = bevy::math::Vec2::move_towards( + &_self, + rhs.into_inner(), + d, + ) + .into(); + output + }, + ) + .register( + "midpoint", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec2::midpoint( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Val, + rhs: Val, + max_abs_diff: f32| + { + let output: bool = bevy::math::Vec2::abs_diff_eq( + _self.into_inner(), + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .register( + "clamp_length", + |_self: Val, min: f32, max: f32| { + let output: Val = bevy::math::Vec2::clamp_length( + _self.into_inner(), + min, + max, + ) + .into(); + output + }, + ) + .register( + "clamp_length_max", + |_self: Val, max: f32| { + let output: Val = bevy::math::Vec2::clamp_length_max( + _self.into_inner(), + max, + ) + .into(); + output + }, + ) + .register( + "clamp_length_min", + |_self: Val, min: f32| { + let output: Val = bevy::math::Vec2::clamp_length_min( + _self.into_inner(), + min, + ) + .into(); + output + }, + ) + .register( + "mul_add", + | + _self: Val, + a: Val, + b: Val| + { + let output: Val = bevy::math::Vec2::mul_add( + _self.into_inner(), + a.into_inner(), + b.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reflect", + |_self: Val, normal: Val| { + let output: Val = bevy::math::Vec2::reflect( + _self.into_inner(), + normal.into_inner(), + ) + .into(); + output + }, + ) + .register( + "refract", + |_self: Val, normal: Val, eta: f32| { + let output: Val = bevy::math::Vec2::refract( + _self.into_inner(), + normal.into_inner(), + eta, + ) + .into(); + output + }, + ) + .register( + "from_angle", + |angle: f32| { + let output: Val = bevy::math::Vec2::from_angle( + angle, + ) + .into(); + output + }, + ) + .register( + "to_angle", + |_self: Val| { + let output: f32 = bevy::math::Vec2::to_angle(_self.into_inner()) + .into(); + output + }, + ) + .register( + "angle_between", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Vec2::angle_between( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "angle_to", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Vec2::angle_to( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "perp", + |_self: Val| { + let output: Val = bevy::math::Vec2::perp( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "perp_dot", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Vec2::perp_dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rotate", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec2::rotate( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rotate_towards", + | + _self: Ref, + rhs: Val, + max_angle: f32| + { + let output: Val = bevy::math::Vec2::rotate_towards( + &_self, + rhs.into_inner(), + max_angle, + ) + .into(); + output + }, + ) + .register( + "as_dvec2", + |_self: Ref| { + let output: Val = bevy::math::Vec2::as_dvec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_ivec2", + |_self: Ref| { + let output: Val = bevy::math::Vec2::as_ivec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_uvec2", + |_self: Ref| { + let output: Val = bevy::math::Vec2::as_uvec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_i64vec2", + |_self: Ref| { + let output: Val = bevy::math::Vec2::as_i64vec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_u64vec2", + |_self: Ref| { + let output: Val = bevy::math::Vec2::as_u64vec2( + &_self, + ) + .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: Val| { + let output: Val = >::mul(_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( + "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( + "add", + |_self: Val, rhs: f32| { + let output: Val = >::add(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: f32| { + 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( + "sub", + |_self: Val, rhs: f32| { + let output: Val = >::sub(_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::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(); + output + }, + ) + .register( + "from_vec4", + |v: Val| { + let output: Val = bevy::math::Vec3A::from_vec4( + v.into_inner(), + ) + .into(); + output + }, + ) + .register( + "extend", + |_self: Val, w: f32| { + let output: Val = bevy::math::Vec3A::extend( + _self.into_inner(), + w, + ) + .into(); + output + }, + ) + .register( + "truncate", + |_self: Val| { + let output: Val = bevy::math::Vec3A::truncate( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: f32| { + let output: Val = bevy::math::Vec3A::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: f32| { + let output: Val = bevy::math::Vec3A::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "with_z", + |_self: Val, z: f32| { + let output: Val = bevy::math::Vec3A::with_z( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Vec3A::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3A::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cross", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3A::cross( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3A::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3A::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::Vec3A::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: f32 = bevy::math::Vec3A::min_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: f32 = bevy::math::Vec3A::max_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: f32 = bevy::math::Vec3A::element_sum(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: f32 = bevy::math::Vec3A::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3A::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3A::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3A::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3A::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3A::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3A::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs", + |_self: Val| { + let output: Val = bevy::math::Vec3A::abs( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "signum", + |_self: Val| { + let output: Val = bevy::math::Vec3A::signum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "copysign", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3A::copysign( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_negative_bitmask", + |_self: Val| { + let output: u32 = bevy::math::Vec3A::is_negative_bitmask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Val| { + let output: bool = bevy::math::Vec3A::is_finite(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_finite_mask", + |_self: Val| { + let output: Val = bevy::math::Vec3A::is_finite_mask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_nan", + |_self: Val| { + let output: bool = bevy::math::Vec3A::is_nan(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_nan_mask", + |_self: Val| { + let output: Val = bevy::math::Vec3A::is_nan_mask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length", + |_self: Val| { + let output: f32 = bevy::math::Vec3A::length(_self.into_inner()) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: f32 = bevy::math::Vec3A::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_recip", + |_self: Val| { + let output: f32 = bevy::math::Vec3A::length_recip(_self.into_inner()) + .into(); + output + }, + ) + .register( + "distance", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Vec3A::distance( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "distance_squared", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Vec3A::distance_squared( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "div_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3A::div_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rem_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3A::rem_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize", + |_self: Val| { + let output: Val = bevy::math::Vec3A::normalize( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize_or", + |_self: Val, fallback: Val| { + let output: Val = bevy::math::Vec3A::normalize_or( + _self.into_inner(), + fallback.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize_or_zero", + |_self: Val| { + let output: Val = bevy::math::Vec3A::normalize_or_zero( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_normalized", + |_self: Val| { + let output: bool = bevy::math::Vec3A::is_normalized( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "project_onto", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3A::project_onto( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reject_from", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3A::reject_from( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "project_onto_normalized", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3A::project_onto_normalized( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reject_from_normalized", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3A::reject_from_normalized( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "round", + |_self: Val| { + let output: Val = bevy::math::Vec3A::round( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "floor", + |_self: Val| { + let output: Val = bevy::math::Vec3A::floor( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "ceil", + |_self: Val| { + let output: Val = bevy::math::Vec3A::ceil( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "trunc", + |_self: Val| { + let output: Val = bevy::math::Vec3A::trunc( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "fract", + |_self: Val| { + let output: Val = bevy::math::Vec3A::fract( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "fract_gl", + |_self: Val| { + let output: Val = bevy::math::Vec3A::fract_gl( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "exp", + |_self: Val| { + let output: Val = bevy::math::Vec3A::exp( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "powf", + |_self: Val, n: f32| { + let output: Val = bevy::math::Vec3A::powf( + _self.into_inner(), + n, + ) + .into(); + output + }, + ) + .register( + "recip", + |_self: Val| { + let output: Val = bevy::math::Vec3A::recip( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "lerp", + |_self: Val, rhs: Val, s: f32| { + let output: Val = bevy::math::Vec3A::lerp( + _self.into_inner(), + rhs.into_inner(), + s, + ) + .into(); + output + }, + ) + .register( + "move_towards", + |_self: Ref, rhs: Val, d: f32| { + let output: Val = bevy::math::Vec3A::move_towards( + &_self, + rhs.into_inner(), + d, + ) + .into(); + output + }, + ) + .register( + "midpoint", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec3A::midpoint( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Val, + rhs: Val, + max_abs_diff: f32| + { + let output: bool = bevy::math::Vec3A::abs_diff_eq( + _self.into_inner(), + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .register( + "clamp_length", + |_self: Val, min: f32, max: f32| { + let output: Val = bevy::math::Vec3A::clamp_length( + _self.into_inner(), + min, + max, + ) + .into(); + output + }, + ) + .register( + "clamp_length_max", + |_self: Val, max: f32| { + let output: Val = bevy::math::Vec3A::clamp_length_max( + _self.into_inner(), + max, + ) + .into(); + output + }, + ) + .register( + "clamp_length_min", + |_self: Val, min: f32| { + let output: Val = bevy::math::Vec3A::clamp_length_min( + _self.into_inner(), + min, + ) + .into(); + output + }, + ) + .register( + "mul_add", + | + _self: Val, + a: Val, + b: Val| + { + let output: Val = bevy::math::Vec3A::mul_add( + _self.into_inner(), + a.into_inner(), + b.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reflect", + |_self: Val, normal: Val| { + let output: Val = bevy::math::Vec3A::reflect( + _self.into_inner(), + normal.into_inner(), + ) + .into(); + output + }, + ) + .register( + "refract", + | + _self: Val, + normal: Val, + eta: f32| + { + let output: Val = bevy::math::Vec3A::refract( + _self.into_inner(), + normal.into_inner(), + eta, + ) + .into(); + output + }, + ) + .register( + "angle_between", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Vec3A::angle_between( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "any_orthogonal_vector", + |_self: Ref| { + let output: Val = bevy::math::Vec3A::any_orthogonal_vector( + &_self, + ) + .into(); + output + }, + ) + .register( + "any_orthonormal_vector", + |_self: Ref| { + let output: Val = bevy::math::Vec3A::any_orthonormal_vector( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_dvec3", + |_self: Ref| { + let output: Val = bevy::math::Vec3A::as_dvec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_ivec3", + |_self: Ref| { + let output: Val = bevy::math::Vec3A::as_ivec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_uvec3", + |_self: Ref| { + let output: Val = bevy::math::Vec3A::as_uvec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_i64vec3", + |_self: Ref| { + let output: Val = bevy::math::Vec3A::as_i64vec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_u64vec3", + |_self: Ref| { + let output: Val = bevy::math::Vec3A::as_u64vec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: Ref| { + let output: Val = >::sub(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "mul", + |_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) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: f32| { + 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()) + .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( + "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) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: Ref| { + let output: Val = >::div(_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) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "eq", + |_self: Ref, rhs: Ref| { + let output: bool = >::eq(&_self, &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| { + let output: Val = >::div(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: Ref| { + let output: Val = >::add(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: f32| { + let output: Val = >::add(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: f32| { + let output: Val = >::sub(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "new", + |x: f32, y: f32, z: f32, w: f32| { + let output: Val = bevy::math::Vec4::new(x, y, z, w) + .into(); + output + }, + ) + .register( + "splat", + |v: f32| { + let output: Val = bevy::math::Vec4::splat(v) + .into(); + output + }, + ) + .register( + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::Vec4::select( + mask.into_inner(), + if_true.into_inner(), + if_false.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [f32; 4]| { + let output: Val = bevy::math::Vec4::from_array(a) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [f32; 4] = bevy::math::Vec4::to_array(&_self).into(); + output + }, + ) + .register( + "truncate", + |_self: Val| { + let output: Val = bevy::math::Vec4::truncate( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: f32| { + let output: Val = bevy::math::Vec4::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: f32| { + let output: Val = bevy::math::Vec4::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "with_z", + |_self: Val, z: f32| { + let output: Val = bevy::math::Vec4::with_z( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "with_w", + |_self: Val, w: f32| { + let output: Val = bevy::math::Vec4::with_w( + _self.into_inner(), + w, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Vec4::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec4::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec4::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec4::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::Vec4::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: f32 = bevy::math::Vec4::min_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: f32 = bevy::math::Vec4::max_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: f32 = bevy::math::Vec4::element_sum(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: f32 = bevy::math::Vec4::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec4::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec4::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec4::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec4::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec4::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec4::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs", + |_self: Val| { + let output: Val = bevy::math::Vec4::abs( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "signum", + |_self: Val| { + let output: Val = bevy::math::Vec4::signum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "copysign", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec4::copysign( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_negative_bitmask", + |_self: Val| { + let output: u32 = bevy::math::Vec4::is_negative_bitmask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Val| { + let output: bool = bevy::math::Vec4::is_finite(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_finite_mask", + |_self: Val| { + let output: Val = bevy::math::Vec4::is_finite_mask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_nan", + |_self: Val| { + let output: bool = bevy::math::Vec4::is_nan(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_nan_mask", + |_self: Val| { + let output: Val = bevy::math::Vec4::is_nan_mask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length", + |_self: Val| { + let output: f32 = bevy::math::Vec4::length(_self.into_inner()) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: f32 = bevy::math::Vec4::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_recip", + |_self: Val| { + let output: f32 = bevy::math::Vec4::length_recip(_self.into_inner()) + .into(); + output + }, + ) + .register( + "distance", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Vec4::distance( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "distance_squared", + |_self: Val, rhs: Val| { + let output: f32 = bevy::math::Vec4::distance_squared( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "div_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec4::div_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rem_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec4::rem_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize", + |_self: Val| { + let output: Val = bevy::math::Vec4::normalize( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize_or", + |_self: Val, fallback: Val| { + let output: Val = bevy::math::Vec4::normalize_or( + _self.into_inner(), + fallback.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize_or_zero", + |_self: Val| { + let output: Val = bevy::math::Vec4::normalize_or_zero( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_normalized", + |_self: Val| { + let output: bool = bevy::math::Vec4::is_normalized( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "project_onto", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec4::project_onto( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reject_from", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec4::reject_from( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "project_onto_normalized", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec4::project_onto_normalized( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reject_from_normalized", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec4::reject_from_normalized( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "round", + |_self: Val| { + let output: Val = bevy::math::Vec4::round( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "floor", + |_self: Val| { + let output: Val = bevy::math::Vec4::floor( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "ceil", + |_self: Val| { + let output: Val = bevy::math::Vec4::ceil( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "trunc", + |_self: Val| { + let output: Val = bevy::math::Vec4::trunc( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "fract", + |_self: Val| { + let output: Val = bevy::math::Vec4::fract( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "fract_gl", + |_self: Val| { + let output: Val = bevy::math::Vec4::fract_gl( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "exp", + |_self: Val| { + let output: Val = bevy::math::Vec4::exp( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "powf", + |_self: Val, n: f32| { + let output: Val = bevy::math::Vec4::powf( + _self.into_inner(), + n, + ) + .into(); + output + }, + ) + .register( + "recip", + |_self: Val| { + let output: Val = bevy::math::Vec4::recip( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "lerp", + |_self: Val, rhs: Val, s: f32| { + let output: Val = bevy::math::Vec4::lerp( + _self.into_inner(), + rhs.into_inner(), + s, + ) + .into(); + output + }, + ) + .register( + "move_towards", + |_self: Ref, rhs: Val, d: f32| { + let output: Val = bevy::math::Vec4::move_towards( + &_self, + rhs.into_inner(), + d, + ) + .into(); + output + }, + ) + .register( + "midpoint", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::Vec4::midpoint( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Val, + rhs: Val, + max_abs_diff: f32| + { + let output: bool = bevy::math::Vec4::abs_diff_eq( + _self.into_inner(), + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .register( + "clamp_length", + |_self: Val, min: f32, max: f32| { + let output: Val = bevy::math::Vec4::clamp_length( + _self.into_inner(), + min, + max, + ) + .into(); + output + }, + ) + .register( + "clamp_length_max", + |_self: Val, max: f32| { + let output: Val = bevy::math::Vec4::clamp_length_max( + _self.into_inner(), + max, + ) + .into(); + output + }, + ) + .register( + "clamp_length_min", + |_self: Val, min: f32| { + let output: Val = bevy::math::Vec4::clamp_length_min( + _self.into_inner(), + min, + ) + .into(); + output + }, + ) + .register( + "mul_add", + | + _self: Val, + a: Val, + b: Val| + { + let output: Val = bevy::math::Vec4::mul_add( + _self.into_inner(), + a.into_inner(), + b.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reflect", + |_self: Val, normal: Val| { + let output: Val = bevy::math::Vec4::reflect( + _self.into_inner(), + normal.into_inner(), + ) + .into(); + output + }, + ) + .register( + "refract", + |_self: Val, normal: Val, eta: f32| { + let output: Val = bevy::math::Vec4::refract( + _self.into_inner(), + normal.into_inner(), + eta, + ) + .into(); + output + }, + ) + .register( + "as_dvec4", + |_self: Ref| { + let output: Val = bevy::math::Vec4::as_dvec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_ivec4", + |_self: Ref| { + let output: Val = bevy::math::Vec4::as_ivec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_uvec4", + |_self: Ref| { + let output: Val = bevy::math::Vec4::as_uvec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_i64vec4", + |_self: Ref| { + let output: Val = bevy::math::Vec4::as_i64vec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_u64vec4", + |_self: Ref| { + let output: Val = bevy::math::Vec4::as_u64vec4( + &_self, + ) + .into(); + output + }, + ) + .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()) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: f32| { + let output: Val = >::rem(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "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| { + 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", + |x: bool, y: bool| { + let output: Val = bevy::math::BVec2::new(x, y) + .into(); + output + }, + ) + .register( + "splat", + |v: bool| { + let output: Val = bevy::math::BVec2::splat(v) + .into(); + output + }, + ) + .register( + "from_array", + |a: [bool; 2]| { + let output: Val = bevy::math::BVec2::from_array(a) + .into(); + output + }, + ) + .register( + "bitmask", + |_self: Val| { + let output: u32 = bevy::math::BVec2::bitmask(_self.into_inner()) + .into(); + output + }, + ) + .register( + "any", + |_self: Val| { + let output: bool = bevy::math::BVec2::any(_self.into_inner()).into(); + output + }, + ) + .register( + "all", + |_self: Val| { + let output: bool = bevy::math::BVec2::all(_self.into_inner()).into(); + output + }, + ) + .register( + "test", + |_self: Ref, index: usize| { + let output: bool = bevy::math::BVec2::test(&_self, index).into(); + output + }, + ) + .register( + "set", + |mut _self: Mut, index: usize, value: bool| { + let output: () = bevy::math::BVec2::set(&mut _self, index, value) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::BVec3>::new(world) + .register( + "new", + |x: bool, y: bool, z: bool| { + let output: Val = bevy::math::BVec3::new(x, y, z) + .into(); + output + }, + ) + .register( + "splat", + |v: bool| { + let output: Val = bevy::math::BVec3::splat(v) + .into(); + output + }, + ) + .register( + "from_array", + |a: [bool; 3]| { + let output: Val = bevy::math::BVec3::from_array(a) + .into(); + output + }, + ) + .register( + "bitmask", + |_self: Val| { + let output: u32 = bevy::math::BVec3::bitmask(_self.into_inner()) + .into(); + output + }, + ) + .register( + "any", + |_self: Val| { + let output: bool = bevy::math::BVec3::any(_self.into_inner()).into(); + output + }, + ) + .register( + "all", + |_self: Val| { + let output: bool = bevy::math::BVec3::all(_self.into_inner()).into(); + output + }, + ) + .register( + "test", + |_self: Ref, index: usize| { + let output: bool = bevy::math::BVec3::test(&_self, index).into(); + output + }, + ) + .register( + "set", + |mut _self: Mut, index: usize, value: bool| { + let output: () = bevy::math::BVec3::set(&mut _self, index, value) + .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( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::BVec4>::new(world) + .register( + "new", + |x: bool, y: bool, z: bool, w: bool| { + let output: Val = bevy::math::BVec4::new( + x, + y, + z, + w, + ) + .into(); + output + }, + ) + .register( + "splat", + |v: bool| { + let output: Val = bevy::math::BVec4::splat(v) + .into(); + output + }, + ) + .register( + "from_array", + |a: [bool; 4]| { + let output: Val = bevy::math::BVec4::from_array(a) + .into(); + output + }, + ) + .register( + "bitmask", + |_self: Val| { + let output: u32 = bevy::math::BVec4::bitmask(_self.into_inner()) + .into(); + output + }, + ) + .register( + "any", + |_self: Val| { + let output: bool = bevy::math::BVec4::any(_self.into_inner()).into(); + output + }, + ) + .register( + "all", + |_self: Val| { + let output: bool = bevy::math::BVec4::all(_self.into_inner()).into(); + output + }, + ) + .register( + "test", + |_self: Ref, index: usize| { + let output: bool = bevy::math::BVec4::test(&_self, index).into(); + output + }, + ) + .register( + "set", + |mut _self: Mut, index: usize, value: bool| { + let output: () = bevy::math::BVec4::set(&mut _self, index, value) + .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 + }, + ) + .register( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::DVec2>::new(world) + .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( + "sub", + |_self: Val, rhs: f64| { + let output: Val = >::sub(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: f64| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: Ref| { + let output: Val = >::div(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "rem", + |_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()) + .into(); + output + }, + ) + .register( + "new", + |x: f64, y: f64| { + let output: Val = bevy::math::DVec2::new(x, y) + .into(); + output + }, + ) + .register( + "splat", + |v: f64| { + let output: Val = bevy::math::DVec2::splat(v) + .into(); + output + }, + ) + .register( + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::DVec2::select( + mask.into_inner(), + if_true.into_inner(), + if_false.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [f64; 2]| { + let output: Val = bevy::math::DVec2::from_array(a) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [f64; 2] = bevy::math::DVec2::to_array(&_self).into(); + output + }, + ) + .register( + "extend", + |_self: Val, z: f64| { + let output: Val = bevy::math::DVec2::extend( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: f64| { + let output: Val = bevy::math::DVec2::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: f64| { + let output: Val = bevy::math::DVec2::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: f64 = bevy::math::DVec2::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec2::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec2::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec2::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::DVec2::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: f64 = bevy::math::DVec2::min_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: f64 = bevy::math::DVec2::max_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: f64 = bevy::math::DVec2::element_sum(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: f64 = bevy::math::DVec2::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec2::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec2::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec2::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec2::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec2::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec2::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs", + |_self: Val| { + let output: Val = bevy::math::DVec2::abs( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "signum", + |_self: Val| { + let output: Val = bevy::math::DVec2::signum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "copysign", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec2::copysign( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_negative_bitmask", + |_self: Val| { + let output: u32 = bevy::math::DVec2::is_negative_bitmask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Val| { + let output: bool = bevy::math::DVec2::is_finite(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_finite_mask", + |_self: Val| { + let output: Val = bevy::math::DVec2::is_finite_mask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_nan", + |_self: Val| { + let output: bool = bevy::math::DVec2::is_nan(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_nan_mask", + |_self: Val| { + let output: Val = bevy::math::DVec2::is_nan_mask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length", + |_self: Val| { + let output: f64 = bevy::math::DVec2::length(_self.into_inner()) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: f64 = bevy::math::DVec2::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_recip", + |_self: Val| { + let output: f64 = bevy::math::DVec2::length_recip(_self.into_inner()) + .into(); + output + }, + ) + .register( + "distance", + |_self: Val, rhs: Val| { + let output: f64 = bevy::math::DVec2::distance( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "distance_squared", + |_self: Val, rhs: Val| { + let output: f64 = bevy::math::DVec2::distance_squared( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "div_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec2::div_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rem_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec2::rem_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize", + |_self: Val| { + let output: Val = bevy::math::DVec2::normalize( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize_or", + |_self: Val, fallback: Val| { + let output: Val = bevy::math::DVec2::normalize_or( + _self.into_inner(), + fallback.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize_or_zero", + |_self: Val| { + let output: Val = bevy::math::DVec2::normalize_or_zero( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_normalized", + |_self: Val| { + let output: bool = bevy::math::DVec2::is_normalized( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "project_onto", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec2::project_onto( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reject_from", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec2::reject_from( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "project_onto_normalized", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec2::project_onto_normalized( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reject_from_normalized", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec2::reject_from_normalized( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "round", + |_self: Val| { + let output: Val = bevy::math::DVec2::round( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "floor", + |_self: Val| { + let output: Val = bevy::math::DVec2::floor( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "ceil", + |_self: Val| { + let output: Val = bevy::math::DVec2::ceil( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "trunc", + |_self: Val| { + let output: Val = bevy::math::DVec2::trunc( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "fract", + |_self: Val| { + let output: Val = bevy::math::DVec2::fract( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "fract_gl", + |_self: Val| { + let output: Val = bevy::math::DVec2::fract_gl( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "exp", + |_self: Val| { + let output: Val = bevy::math::DVec2::exp( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "powf", + |_self: Val, n: f64| { + let output: Val = bevy::math::DVec2::powf( + _self.into_inner(), + n, + ) + .into(); + output + }, + ) + .register( + "recip", + |_self: Val| { + let output: Val = bevy::math::DVec2::recip( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "lerp", + |_self: Val, rhs: Val, s: f64| { + let output: Val = bevy::math::DVec2::lerp( + _self.into_inner(), + rhs.into_inner(), + s, + ) + .into(); + output + }, + ) + .register( + "move_towards", + |_self: Ref, rhs: Val, d: f64| { + let output: Val = bevy::math::DVec2::move_towards( + &_self, + rhs.into_inner(), + d, + ) + .into(); + output + }, + ) + .register( + "midpoint", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec2::midpoint( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Val, + rhs: Val, + max_abs_diff: f64| + { + let output: bool = bevy::math::DVec2::abs_diff_eq( + _self.into_inner(), + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .register( + "clamp_length", + |_self: Val, min: f64, max: f64| { + let output: Val = bevy::math::DVec2::clamp_length( + _self.into_inner(), + min, + max, + ) + .into(); + output + }, + ) + .register( + "clamp_length_max", + |_self: Val, max: f64| { + let output: Val = bevy::math::DVec2::clamp_length_max( + _self.into_inner(), + max, + ) + .into(); + output + }, + ) + .register( + "clamp_length_min", + |_self: Val, min: f64| { + let output: Val = bevy::math::DVec2::clamp_length_min( + _self.into_inner(), + min, + ) + .into(); + output + }, + ) + .register( + "mul_add", + | + _self: Val, + a: Val, + b: Val| + { + let output: Val = bevy::math::DVec2::mul_add( + _self.into_inner(), + a.into_inner(), + b.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reflect", + |_self: Val, normal: Val| { + let output: Val = bevy::math::DVec2::reflect( + _self.into_inner(), + normal.into_inner(), + ) + .into(); + output + }, + ) + .register( + "refract", + | + _self: Val, + normal: Val, + eta: f64| + { + let output: Val = bevy::math::DVec2::refract( + _self.into_inner(), + normal.into_inner(), + eta, + ) + .into(); + output + }, + ) + .register( + "from_angle", + |angle: f64| { + let output: Val = bevy::math::DVec2::from_angle( + angle, + ) + .into(); + output + }, + ) + .register( + "to_angle", + |_self: Val| { + let output: f64 = bevy::math::DVec2::to_angle(_self.into_inner()) + .into(); + output + }, + ) + .register( + "angle_between", + |_self: Val, rhs: Val| { + let output: f64 = bevy::math::DVec2::angle_between( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "angle_to", + |_self: Val, rhs: Val| { + let output: f64 = bevy::math::DVec2::angle_to( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "perp", + |_self: Val| { + let output: Val = bevy::math::DVec2::perp( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "perp_dot", + |_self: Val, rhs: Val| { + let output: f64 = bevy::math::DVec2::perp_dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rotate", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec2::rotate( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rotate_towards", + | + _self: Ref, + rhs: Val, + max_angle: f64| + { + let output: Val = bevy::math::DVec2::rotate_towards( + &_self, + rhs.into_inner(), + max_angle, + ) + .into(); + output + }, + ) + .register( + "as_vec2", + |_self: Ref| { + let output: Val = bevy::math::DVec2::as_vec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_ivec2", + |_self: Ref| { + let output: Val = bevy::math::DVec2::as_ivec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_uvec2", + |_self: Ref| { + let output: Val = bevy::math::DVec2::as_uvec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_i64vec2", + |_self: Ref| { + let output: Val = bevy::math::DVec2::as_i64vec2( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_u64vec2", + |_self: Ref| { + let output: Val = bevy::math::DVec2::as_u64vec2( + &_self, + ) + .into(); + 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| { + let output: Val = >::rem(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: f64| { + let output: Val = >::add(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "rem", + |_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()) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: f64| { + let output: Val = >::mul(_self.into_inner(), rhs) + .into(); + output + }, + ) + .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) + .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| { + let output: Val = ::neg( + _self.into_inner(), + ) + .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()) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: Ref| { + let output: Val = >::sub(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "new", + |x: f64, y: f64, z: f64| { + let output: Val = bevy::math::DVec3::new(x, y, z) + .into(); + output + }, + ) + .register( + "splat", + |v: f64| { + let output: Val = bevy::math::DVec3::splat(v) + .into(); + output + }, + ) + .register( + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::DVec3::select( + mask.into_inner(), + if_true.into_inner(), + if_false.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [f64; 3]| { + let output: Val = bevy::math::DVec3::from_array(a) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [f64; 3] = bevy::math::DVec3::to_array(&_self).into(); + output + }, + ) + .register( + "extend", + |_self: Val, w: f64| { + let output: Val = bevy::math::DVec3::extend( + _self.into_inner(), + w, + ) + .into(); + output + }, + ) + .register( + "truncate", + |_self: Val| { + let output: Val = bevy::math::DVec3::truncate( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: f64| { + let output: Val = bevy::math::DVec3::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: f64| { + let output: Val = bevy::math::DVec3::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "with_z", + |_self: Val, z: f64| { + let output: Val = bevy::math::DVec3::with_z( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: f64 = bevy::math::DVec3::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec3::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cross", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec3::cross( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec3::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec3::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::DVec3::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: f64 = bevy::math::DVec3::min_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: f64 = bevy::math::DVec3::max_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: f64 = bevy::math::DVec3::element_sum(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: f64 = bevy::math::DVec3::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec3::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec3::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec3::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec3::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec3::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec3::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs", + |_self: Val| { + let output: Val = bevy::math::DVec3::abs( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "signum", + |_self: Val| { + let output: Val = bevy::math::DVec3::signum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "copysign", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec3::copysign( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_negative_bitmask", + |_self: Val| { + let output: u32 = bevy::math::DVec3::is_negative_bitmask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Val| { + let output: bool = bevy::math::DVec3::is_finite(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_finite_mask", + |_self: Val| { + let output: Val = bevy::math::DVec3::is_finite_mask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_nan", + |_self: Val| { + let output: bool = bevy::math::DVec3::is_nan(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_nan_mask", + |_self: Val| { + let output: Val = bevy::math::DVec3::is_nan_mask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length", + |_self: Val| { + let output: f64 = bevy::math::DVec3::length(_self.into_inner()) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: f64 = bevy::math::DVec3::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_recip", + |_self: Val| { + let output: f64 = bevy::math::DVec3::length_recip(_self.into_inner()) + .into(); + output + }, + ) + .register( + "distance", + |_self: Val, rhs: Val| { + let output: f64 = bevy::math::DVec3::distance( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "distance_squared", + |_self: Val, rhs: Val| { + let output: f64 = bevy::math::DVec3::distance_squared( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "div_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec3::div_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rem_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec3::rem_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize", + |_self: Val| { + let output: Val = bevy::math::DVec3::normalize( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize_or", + |_self: Val, fallback: Val| { + let output: Val = bevy::math::DVec3::normalize_or( + _self.into_inner(), + fallback.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize_or_zero", + |_self: Val| { + let output: Val = bevy::math::DVec3::normalize_or_zero( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_normalized", + |_self: Val| { + let output: bool = bevy::math::DVec3::is_normalized( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "project_onto", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec3::project_onto( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reject_from", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec3::reject_from( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "project_onto_normalized", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec3::project_onto_normalized( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reject_from_normalized", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec3::reject_from_normalized( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "round", + |_self: Val| { + let output: Val = bevy::math::DVec3::round( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "floor", + |_self: Val| { + let output: Val = bevy::math::DVec3::floor( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "ceil", + |_self: Val| { + let output: Val = bevy::math::DVec3::ceil( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "trunc", + |_self: Val| { + let output: Val = bevy::math::DVec3::trunc( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "fract", + |_self: Val| { + let output: Val = bevy::math::DVec3::fract( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "fract_gl", + |_self: Val| { + let output: Val = bevy::math::DVec3::fract_gl( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "exp", + |_self: Val| { + let output: Val = bevy::math::DVec3::exp( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "powf", + |_self: Val, n: f64| { + let output: Val = bevy::math::DVec3::powf( + _self.into_inner(), + n, + ) + .into(); + output + }, + ) + .register( + "recip", + |_self: Val| { + let output: Val = bevy::math::DVec3::recip( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "lerp", + |_self: Val, rhs: Val, s: f64| { + let output: Val = bevy::math::DVec3::lerp( + _self.into_inner(), + rhs.into_inner(), + s, + ) + .into(); + output + }, + ) + .register( + "move_towards", + |_self: Ref, rhs: Val, d: f64| { + let output: Val = bevy::math::DVec3::move_towards( + &_self, + rhs.into_inner(), + d, + ) + .into(); + output + }, + ) + .register( + "midpoint", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec3::midpoint( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Val, + rhs: Val, + max_abs_diff: f64| + { + let output: bool = bevy::math::DVec3::abs_diff_eq( + _self.into_inner(), + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .register( + "clamp_length", + |_self: Val, min: f64, max: f64| { + let output: Val = bevy::math::DVec3::clamp_length( + _self.into_inner(), + min, + max, + ) + .into(); + output + }, + ) + .register( + "clamp_length_max", + |_self: Val, max: f64| { + let output: Val = bevy::math::DVec3::clamp_length_max( + _self.into_inner(), + max, + ) + .into(); + output + }, + ) + .register( + "clamp_length_min", + |_self: Val, min: f64| { + let output: Val = bevy::math::DVec3::clamp_length_min( + _self.into_inner(), + min, + ) + .into(); + output + }, + ) + .register( + "mul_add", + | + _self: Val, + a: Val, + b: Val| + { + let output: Val = bevy::math::DVec3::mul_add( + _self.into_inner(), + a.into_inner(), + b.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reflect", + |_self: Val, normal: Val| { + let output: Val = bevy::math::DVec3::reflect( + _self.into_inner(), + normal.into_inner(), + ) + .into(); + output + }, + ) + .register( + "refract", + | + _self: Val, + normal: Val, + eta: f64| + { + let output: Val = bevy::math::DVec3::refract( + _self.into_inner(), + normal.into_inner(), + eta, + ) + .into(); + output + }, + ) + .register( + "angle_between", + |_self: Val, rhs: Val| { + let output: f64 = bevy::math::DVec3::angle_between( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "any_orthogonal_vector", + |_self: Ref| { + let output: Val = bevy::math::DVec3::any_orthogonal_vector( + &_self, + ) + .into(); + output + }, + ) + .register( + "any_orthonormal_vector", + |_self: Ref| { + let output: Val = bevy::math::DVec3::any_orthonormal_vector( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_vec3", + |_self: Ref| { + let output: Val = bevy::math::DVec3::as_vec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_vec3a", + |_self: Ref| { + let output: Val = bevy::math::DVec3::as_vec3a( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_ivec3", + |_self: Ref| { + let output: Val = bevy::math::DVec3::as_ivec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_uvec3", + |_self: Ref| { + let output: Val = bevy::math::DVec3::as_uvec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_i64vec3", + |_self: Ref| { + let output: Val = bevy::math::DVec3::as_i64vec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_u64vec3", + |_self: Ref| { + let output: Val = bevy::math::DVec3::as_u64vec3( + &_self, + ) + .into(); + output + }, + ) + .register( + "sub", + |_self: Val, rhs: f64| { + let output: Val = >::sub(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: f64| { + 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()) + .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) + .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: f64| { + let output: Val = >::add(_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: Ref| { + let output: Val = >::mul(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: f64| { + 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( + "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::DVec4>::new(world) + .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: f64| { + let output: Val = >::sub(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: f64| { + 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: Ref| { + let output: Val = >::rem(_self.into_inner(), &rhs) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: f64| { + let output: Val = >::mul(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "rem", + |_self: Val, rhs: f64| { + 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( + "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( + "div", + |_self: Val, rhs: Ref| { + 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( + "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 + }, + ) + .register( + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "new", + |x: f64, y: f64, z: f64, w: f64| { + let output: Val = bevy::math::DVec4::new( + x, + y, + z, + w, + ) + .into(); + output + }, + ) + .register( + "splat", + |v: f64| { + let output: Val = bevy::math::DVec4::splat(v) + .into(); + output + }, + ) + .register( + "select", + | + mask: Val, + if_true: Val, + if_false: Val| + { + let output: Val = bevy::math::DVec4::select( + mask.into_inner(), + if_true.into_inner(), + if_false.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [f64; 4]| { + let output: Val = bevy::math::DVec4::from_array(a) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [f64; 4] = bevy::math::DVec4::to_array(&_self).into(); + output + }, + ) + .register( + "truncate", + |_self: Val| { + let output: Val = bevy::math::DVec4::truncate( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "with_x", + |_self: Val, x: f64| { + let output: Val = bevy::math::DVec4::with_x( + _self.into_inner(), + x, + ) + .into(); + output + }, + ) + .register( + "with_y", + |_self: Val, y: f64| { + let output: Val = bevy::math::DVec4::with_y( + _self.into_inner(), + y, + ) + .into(); + output + }, + ) + .register( + "with_z", + |_self: Val, z: f64| { + let output: Val = bevy::math::DVec4::with_z( + _self.into_inner(), + z, + ) + .into(); + output + }, + ) + .register( + "with_w", + |_self: Val, w: f64| { + let output: Val = bevy::math::DVec4::with_w( + _self.into_inner(), + w, + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: f64 = bevy::math::DVec4::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot_into_vec", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec4::dot_into_vec( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec4::min( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "max", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec4::max( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "clamp", + | + _self: Val, + min: Val, + max: Val| + { + let output: Val = bevy::math::DVec4::clamp( + _self.into_inner(), + min.into_inner(), + max.into_inner(), + ) + .into(); + output + }, + ) + .register( + "min_element", + |_self: Val| { + let output: f64 = bevy::math::DVec4::min_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "max_element", + |_self: Val| { + let output: f64 = bevy::math::DVec4::max_element(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_sum", + |_self: Val| { + let output: f64 = bevy::math::DVec4::element_sum(_self.into_inner()) + .into(); + output + }, + ) + .register( + "element_product", + |_self: Val| { + let output: f64 = bevy::math::DVec4::element_product( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpeq", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec4::cmpeq( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpne", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec4::cmpne( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpge", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec4::cmpge( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmpgt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec4::cmpgt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmple", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec4::cmple( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "cmplt", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec4::cmplt( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs", + |_self: Val| { + let output: Val = bevy::math::DVec4::abs( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "signum", + |_self: Val| { + let output: Val = bevy::math::DVec4::signum( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "copysign", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec4::copysign( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_negative_bitmask", + |_self: Val| { + let output: u32 = bevy::math::DVec4::is_negative_bitmask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Val| { + let output: bool = bevy::math::DVec4::is_finite(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_finite_mask", + |_self: Val| { + let output: Val = bevy::math::DVec4::is_finite_mask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_nan", + |_self: Val| { + let output: bool = bevy::math::DVec4::is_nan(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_nan_mask", + |_self: Val| { + let output: Val = bevy::math::DVec4::is_nan_mask( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length", + |_self: Val| { + let output: f64 = bevy::math::DVec4::length(_self.into_inner()) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: f64 = bevy::math::DVec4::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_recip", + |_self: Val| { + let output: f64 = bevy::math::DVec4::length_recip(_self.into_inner()) + .into(); + output + }, + ) + .register( + "distance", + |_self: Val, rhs: Val| { + let output: f64 = bevy::math::DVec4::distance( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "distance_squared", + |_self: Val, rhs: Val| { + let output: f64 = bevy::math::DVec4::distance_squared( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "div_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec4::div_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rem_euclid", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec4::rem_euclid( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize", + |_self: Val| { + let output: Val = bevy::math::DVec4::normalize( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize_or", + |_self: Val, fallback: Val| { + let output: Val = bevy::math::DVec4::normalize_or( + _self.into_inner(), + fallback.into_inner(), + ) + .into(); + output + }, + ) + .register( + "normalize_or_zero", + |_self: Val| { + let output: Val = bevy::math::DVec4::normalize_or_zero( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_normalized", + |_self: Val| { + let output: bool = bevy::math::DVec4::is_normalized( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "project_onto", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec4::project_onto( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reject_from", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec4::reject_from( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "project_onto_normalized", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec4::project_onto_normalized( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reject_from_normalized", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec4::reject_from_normalized( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "round", + |_self: Val| { + let output: Val = bevy::math::DVec4::round( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "floor", + |_self: Val| { + let output: Val = bevy::math::DVec4::floor( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "ceil", + |_self: Val| { + let output: Val = bevy::math::DVec4::ceil( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "trunc", + |_self: Val| { + let output: Val = bevy::math::DVec4::trunc( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "fract", + |_self: Val| { + let output: Val = bevy::math::DVec4::fract( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "fract_gl", + |_self: Val| { + let output: Val = bevy::math::DVec4::fract_gl( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "exp", + |_self: Val| { + let output: Val = bevy::math::DVec4::exp( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "powf", + |_self: Val, n: f64| { + let output: Val = bevy::math::DVec4::powf( + _self.into_inner(), + n, + ) + .into(); + output + }, + ) + .register( + "recip", + |_self: Val| { + let output: Val = bevy::math::DVec4::recip( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "lerp", + |_self: Val, rhs: Val, s: f64| { + let output: Val = bevy::math::DVec4::lerp( + _self.into_inner(), + rhs.into_inner(), + s, + ) + .into(); + output + }, + ) + .register( + "move_towards", + |_self: Ref, rhs: Val, d: f64| { + let output: Val = bevy::math::DVec4::move_towards( + &_self, + rhs.into_inner(), + d, + ) + .into(); + output + }, + ) + .register( + "midpoint", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DVec4::midpoint( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Val, + rhs: Val, + max_abs_diff: f64| + { + let output: bool = bevy::math::DVec4::abs_diff_eq( + _self.into_inner(), + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .register( + "clamp_length", + |_self: Val, min: f64, max: f64| { + let output: Val = bevy::math::DVec4::clamp_length( + _self.into_inner(), + min, + max, + ) + .into(); + output + }, + ) + .register( + "clamp_length_max", + |_self: Val, max: f64| { + let output: Val = bevy::math::DVec4::clamp_length_max( + _self.into_inner(), + max, + ) + .into(); + output + }, + ) + .register( + "clamp_length_min", + |_self: Val, min: f64| { + let output: Val = bevy::math::DVec4::clamp_length_min( + _self.into_inner(), + min, + ) + .into(); + output + }, + ) + .register( + "mul_add", + | + _self: Val, + a: Val, + b: Val| + { + let output: Val = bevy::math::DVec4::mul_add( + _self.into_inner(), + a.into_inner(), + b.into_inner(), + ) + .into(); + output + }, + ) + .register( + "reflect", + |_self: Val, normal: Val| { + let output: Val = bevy::math::DVec4::reflect( + _self.into_inner(), + normal.into_inner(), + ) + .into(); + output + }, + ) + .register( + "refract", + | + _self: Val, + normal: Val, + eta: f64| + { + let output: Val = bevy::math::DVec4::refract( + _self.into_inner(), + normal.into_inner(), + eta, + ) + .into(); + output + }, + ) + .register( + "as_vec4", + |_self: Ref| { + let output: Val = bevy::math::DVec4::as_vec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_ivec4", + |_self: Ref| { + let output: Val = bevy::math::DVec4::as_ivec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_uvec4", + |_self: Ref| { + let output: Val = bevy::math::DVec4::as_uvec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_i64vec4", + |_self: Ref| { + let output: Val = bevy::math::DVec4::as_i64vec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "as_u64vec4", + |_self: Ref| { + let output: Val = bevy::math::DVec4::as_u64vec4( + &_self, + ) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: f64| { + let output: Val = >::add(_self.into_inner(), rhs) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::Mat2>::new(world) + .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( + "sub", + |_self: Val, rhs: Val| { + let output: Val = >::sub(_self.into_inner(), rhs.into_inner()) + .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(), + ) + .into(); + output + }, + ) + .register( + "to_cols_array", + |_self: Ref| { + let output: [f32; 4] = bevy::math::Mat2::to_cols_array(&_self) + .into(); + output + }, + ) + .register( + "to_cols_array_2d", + |_self: Ref| { + let output: [[f32; 2]; 2] = bevy::math::Mat2::to_cols_array_2d( + &_self, + ) + .into(); + output + }, + ) + .register( + "from_diagonal", + |diagonal: Val| { + let output: Val = bevy::math::Mat2::from_diagonal( + diagonal.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_scale_angle", + |scale: Val, angle: f32| { + let output: Val = bevy::math::Mat2::from_scale_angle( + scale.into_inner(), + angle, + ) + .into(); + output + }, + ) + .register( + "from_angle", + |angle: f32| { + let output: Val = bevy::math::Mat2::from_angle( + angle, + ) + .into(); + output + }, + ) + .register( + "from_mat3", + |m: Val| { + let output: Val = bevy::math::Mat2::from_mat3( + m.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat3_minor", + |m: Val, i: usize, j: usize| { + let output: Val = bevy::math::Mat2::from_mat3_minor( + m.into_inner(), + i, + j, + ) + .into(); + output + }, + ) + .register( + "from_mat3a", + |m: Val| { + let output: Val = bevy::math::Mat2::from_mat3a( + m.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat3a_minor", + |m: Val, i: usize, j: usize| { + let output: Val = bevy::math::Mat2::from_mat3a_minor( + m.into_inner(), + i, + j, + ) + .into(); + output + }, + ) + .register( + "col", + |_self: Ref, index: usize| { + let output: Val = bevy::math::Mat2::col( + &_self, + index, + ) + .into(); + output + }, + ) + .register( + "row", + |_self: Ref, index: usize| { + let output: Val = bevy::math::Mat2::row( + &_self, + index, + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Ref| { + let output: bool = bevy::math::Mat2::is_finite(&_self).into(); + output + }, + ) + .register( + "is_nan", + |_self: Ref| { + let output: bool = bevy::math::Mat2::is_nan(&_self).into(); + output + }, + ) + .register( + "transpose", + |_self: Ref| { + let output: Val = bevy::math::Mat2::transpose( + &_self, + ) + .into(); + output + }, + ) + .register( + "determinant", + |_self: Ref| { + let output: f32 = bevy::math::Mat2::determinant(&_self).into(); + output + }, + ) + .register( + "inverse", + |_self: Ref| { + let output: Val = bevy::math::Mat2::inverse(&_self) + .into(); + output + }, + ) + .register( + "mul_vec2", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Mat2::mul_vec2( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul_mat2", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::Mat2::mul_mat2( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "add_mat2", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::Mat2::add_mat2( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "sub_mat2", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::Mat2::sub_mat2( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "mul_scalar", + |_self: Ref, rhs: f32| { + let output: Val = bevy::math::Mat2::mul_scalar( + &_self, + rhs, + ) + .into(); + output + }, + ) + .register( + "div_scalar", + |_self: Ref, rhs: f32| { + let output: Val = bevy::math::Mat2::div_scalar( + &_self, + rhs, + ) + .into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Ref, + rhs: Val, + max_abs_diff: f32| + { + let output: bool = bevy::math::Mat2::abs_diff_eq( + &_self, + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .register( + "abs", + |_self: Ref| { + let output: Val = bevy::math::Mat2::abs(&_self) + .into(); + output + }, + ) + .register( + "as_dmat2", + |_self: Ref| { + let output: Val = bevy::math::Mat2::as_dmat2( + &_self, + ) + .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 + }, + ) + .register( + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) + .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( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::Mat3>::new(world) + .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( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "from_cols", + | + x_axis: Val, + y_axis: Val, + z_axis: Val| + { + let output: Val = bevy::math::Mat3::from_cols( + x_axis.into_inner(), + y_axis.into_inner(), + z_axis.into_inner(), + ) + .into(); + output + }, + ) + .register( + "to_cols_array", + |_self: Ref| { + let output: [f32; 9] = bevy::math::Mat3::to_cols_array(&_self) + .into(); + output + }, + ) + .register( + "to_cols_array_2d", + |_self: Ref| { + let output: [[f32; 3]; 3] = bevy::math::Mat3::to_cols_array_2d( + &_self, + ) + .into(); + output + }, + ) + .register( + "from_diagonal", + |diagonal: Val| { + let output: Val = bevy::math::Mat3::from_diagonal( + diagonal.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat4", + |m: Val| { + let output: Val = bevy::math::Mat3::from_mat4( + m.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat4_minor", + |m: Val, i: usize, j: usize| { + let output: Val = bevy::math::Mat3::from_mat4_minor( + m.into_inner(), + i, + j, + ) + .into(); + output + }, + ) + .register( + "from_quat", + |rotation: Val| { + let output: Val = bevy::math::Mat3::from_quat( + rotation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_axis_angle", + |axis: Val, angle: f32| { + let output: Val = bevy::math::Mat3::from_axis_angle( + axis.into_inner(), + angle, + ) + .into(); + output + }, + ) + .register( + "from_euler", + |order: Val, a: f32, b: f32, c: f32| { + let output: Val = bevy::math::Mat3::from_euler( + order.into_inner(), + a, + b, + c, + ) + .into(); + output + }, + ) + .register( + "to_euler", + |_self: Ref, order: Val| { + let output: (f32, f32, f32) = bevy::math::Mat3::to_euler( + &_self, + order.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_rotation_x", + |angle: f32| { + let output: Val = bevy::math::Mat3::from_rotation_x( + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_y", + |angle: f32| { + let output: Val = bevy::math::Mat3::from_rotation_y( + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_z", + |angle: f32| { + let output: Val = bevy::math::Mat3::from_rotation_z( + angle, + ) + .into(); + output + }, + ) + .register( + "from_translation", + |translation: Val| { + let output: Val = bevy::math::Mat3::from_translation( + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_angle", + |angle: f32| { + let output: Val = bevy::math::Mat3::from_angle( + angle, + ) + .into(); + output + }, + ) + .register( + "from_scale_angle_translation", + | + scale: Val, + angle: f32, + translation: Val| + { + let output: Val = bevy::math::Mat3::from_scale_angle_translation( + scale.into_inner(), + angle, + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_scale", + |scale: Val| { + let output: Val = bevy::math::Mat3::from_scale( + scale.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat2", + |m: Val| { + let output: Val = bevy::math::Mat3::from_mat2( + m.into_inner(), + ) + .into(); + output + }, + ) + .register( + "col", + |_self: Ref, index: usize| { + let output: Val = bevy::math::Mat3::col( + &_self, + index, + ) + .into(); + output + }, + ) + .register( + "row", + |_self: Ref, index: usize| { + let output: Val = bevy::math::Mat3::row( + &_self, + index, + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Ref| { + let output: bool = bevy::math::Mat3::is_finite(&_self).into(); + output + }, + ) + .register( + "is_nan", + |_self: Ref| { + let output: bool = bevy::math::Mat3::is_nan(&_self).into(); + output + }, + ) + .register( + "transpose", + |_self: Ref| { + let output: Val = bevy::math::Mat3::transpose( + &_self, + ) + .into(); + output + }, + ) + .register( + "determinant", + |_self: Ref| { + let output: f32 = bevy::math::Mat3::determinant(&_self).into(); + output + }, + ) + .register( + "inverse", + |_self: Ref| { + let output: Val = bevy::math::Mat3::inverse(&_self) + .into(); + output + }, + ) + .register( + "transform_point2", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Mat3::transform_point2( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_vector2", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Mat3::transform_vector2( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul_vec3", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Mat3::mul_vec3( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul_vec3a", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Mat3::mul_vec3a( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul_mat3", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::Mat3::mul_mat3( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "add_mat3", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::Mat3::add_mat3( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "sub_mat3", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::Mat3::sub_mat3( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "mul_scalar", + |_self: Ref, rhs: f32| { + let output: Val = bevy::math::Mat3::mul_scalar( + &_self, + rhs, + ) + .into(); + output + }, + ) + .register( + "div_scalar", + |_self: Ref, rhs: f32| { + let output: Val = bevy::math::Mat3::div_scalar( + &_self, + rhs, + ) + .into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Ref, + rhs: Val, + max_abs_diff: f32| + { + let output: bool = bevy::math::Mat3::abs_diff_eq( + &_self, + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .register( + "abs", + |_self: Ref| { + let output: Val = bevy::math::Mat3::abs(&_self) + .into(); + output + }, + ) + .register( + "as_dmat3", + |_self: Ref| { + let output: Val = bevy::math::Mat3::as_dmat3( + &_self, + ) + .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( + "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( + "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()) + .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 + }, + ); + NamespaceBuilder::<::bevy::math::Mat3A>::new(world) + .register( + "div", + |_self: Val, rhs: f32| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .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( + "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( + "from_cols", + | + x_axis: Val, + y_axis: Val, + z_axis: Val| + { + let output: Val = bevy::math::Mat3A::from_cols( + x_axis.into_inner(), + y_axis.into_inner(), + z_axis.into_inner(), + ) + .into(); + output + }, + ) + .register( + "to_cols_array", + |_self: Ref| { + let output: [f32; 9] = bevy::math::Mat3A::to_cols_array(&_self) + .into(); + output + }, + ) + .register( + "to_cols_array_2d", + |_self: Ref| { + let output: [[f32; 3]; 3] = bevy::math::Mat3A::to_cols_array_2d( + &_self, + ) + .into(); + output + }, + ) + .register( + "from_diagonal", + |diagonal: Val| { + let output: Val = bevy::math::Mat3A::from_diagonal( + diagonal.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat4", + |m: Val| { + let output: Val = bevy::math::Mat3A::from_mat4( + m.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat4_minor", + |m: Val, i: usize, j: usize| { + let output: Val = bevy::math::Mat3A::from_mat4_minor( + m.into_inner(), + i, + j, + ) + .into(); + output + }, + ) + .register( + "from_quat", + |rotation: Val| { + let output: Val = bevy::math::Mat3A::from_quat( + rotation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_axis_angle", + |axis: Val, angle: f32| { + let output: Val = bevy::math::Mat3A::from_axis_angle( + axis.into_inner(), + angle, + ) + .into(); + output + }, + ) + .register( + "from_euler", + |order: Val, a: f32, b: f32, c: f32| { + let output: Val = bevy::math::Mat3A::from_euler( + order.into_inner(), + a, + b, + c, + ) + .into(); + output + }, + ) + .register( + "to_euler", + |_self: Ref, order: Val| { + let output: (f32, f32, f32) = bevy::math::Mat3A::to_euler( + &_self, + order.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_rotation_x", + |angle: f32| { + let output: Val = bevy::math::Mat3A::from_rotation_x( + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_y", + |angle: f32| { + let output: Val = bevy::math::Mat3A::from_rotation_y( + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_z", + |angle: f32| { + let output: Val = bevy::math::Mat3A::from_rotation_z( + angle, + ) + .into(); + output + }, + ) + .register( + "from_translation", + |translation: Val| { + let output: Val = bevy::math::Mat3A::from_translation( + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_angle", + |angle: f32| { + let output: Val = bevy::math::Mat3A::from_angle( + angle, + ) + .into(); + output + }, + ) + .register( + "from_scale_angle_translation", + | + scale: Val, + angle: f32, + translation: Val| + { + let output: Val = bevy::math::Mat3A::from_scale_angle_translation( + scale.into_inner(), + angle, + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_scale", + |scale: Val| { + let output: Val = bevy::math::Mat3A::from_scale( + scale.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat2", + |m: Val| { + let output: Val = bevy::math::Mat3A::from_mat2( + m.into_inner(), + ) + .into(); + output + }, + ) + .register( + "col", + |_self: Ref, index: usize| { + let output: Val = bevy::math::Mat3A::col( + &_self, + index, + ) + .into(); + output + }, + ) + .register( + "row", + |_self: Ref, index: usize| { + let output: Val = bevy::math::Mat3A::row( + &_self, + index, + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Ref| { + let output: bool = bevy::math::Mat3A::is_finite(&_self).into(); + output + }, + ) + .register( + "is_nan", + |_self: Ref| { + let output: bool = bevy::math::Mat3A::is_nan(&_self).into(); + output + }, + ) + .register( + "transpose", + |_self: Ref| { + let output: Val = bevy::math::Mat3A::transpose( + &_self, + ) + .into(); + output + }, + ) + .register( + "determinant", + |_self: Ref| { + let output: f32 = bevy::math::Mat3A::determinant(&_self).into(); + output + }, + ) + .register( + "inverse", + |_self: Ref| { + let output: Val = bevy::math::Mat3A::inverse( + &_self, + ) + .into(); + output + }, + ) + .register( + "transform_point2", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Mat3A::transform_point2( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_vector2", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Mat3A::transform_vector2( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul_vec3", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Mat3A::mul_vec3( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul_vec3a", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Mat3A::mul_vec3a( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul_mat3", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::Mat3A::mul_mat3( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "add_mat3", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::Mat3A::add_mat3( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "sub_mat3", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::Mat3A::sub_mat3( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "mul_scalar", + |_self: Ref, rhs: f32| { + let output: Val = bevy::math::Mat3A::mul_scalar( + &_self, + rhs, + ) + .into(); + output + }, + ) + .register( + "div_scalar", + |_self: Ref, rhs: f32| { + let output: Val = bevy::math::Mat3A::div_scalar( + &_self, + rhs, + ) + .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(), + ) + .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( + "from_cols", + | + x_axis: Val, + y_axis: Val, + z_axis: Val, + w_axis: Val| + { + let output: Val = bevy::math::Mat4::from_cols( + x_axis.into_inner(), + y_axis.into_inner(), + z_axis.into_inner(), + w_axis.into_inner(), + ) + .into(); + output + }, + ) + .register( + "to_cols_array", + |_self: Ref| { + let output: [f32; 16] = bevy::math::Mat4::to_cols_array(&_self) + .into(); + output + }, + ) + .register( + "to_cols_array_2d", + |_self: Ref| { + let output: [[f32; 4]; 4] = bevy::math::Mat4::to_cols_array_2d( + &_self, + ) + .into(); + output + }, + ) + .register( + "from_diagonal", + |diagonal: Val| { + let output: Val = bevy::math::Mat4::from_diagonal( + diagonal.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_scale_rotation_translation", + | + scale: Val, + rotation: Val, + translation: Val| + { + let output: Val = bevy::math::Mat4::from_scale_rotation_translation( + scale.into_inner(), + rotation.into_inner(), + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_rotation_translation", + |rotation: Val, translation: Val| { + let output: Val = bevy::math::Mat4::from_rotation_translation( + rotation.into_inner(), + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_quat", + |rotation: Val| { + let output: Val = bevy::math::Mat4::from_quat( + rotation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat3", + |m: Val| { + let output: Val = bevy::math::Mat4::from_mat3( + m.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat3a", + |m: Val| { + let output: Val = bevy::math::Mat4::from_mat3a( + m.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_translation", + |translation: Val| { + let output: Val = bevy::math::Mat4::from_translation( + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_axis_angle", + |axis: Val, angle: f32| { + let output: Val = bevy::math::Mat4::from_axis_angle( + axis.into_inner(), + angle, + ) + .into(); + output + }, + ) + .register( + "from_euler", + |order: Val, a: f32, b: f32, c: f32| { + let output: Val = bevy::math::Mat4::from_euler( + order.into_inner(), + a, + b, + c, + ) + .into(); + output + }, + ) + .register( + "to_euler", + |_self: Ref, order: Val| { + let output: (f32, f32, f32) = bevy::math::Mat4::to_euler( + &_self, + order.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_rotation_x", + |angle: f32| { + let output: Val = bevy::math::Mat4::from_rotation_x( + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_y", + |angle: f32| { + let output: Val = bevy::math::Mat4::from_rotation_y( + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_z", + |angle: f32| { + let output: Val = bevy::math::Mat4::from_rotation_z( + angle, + ) + .into(); + output + }, + ) + .register( + "from_scale", + |scale: Val| { + let output: Val = bevy::math::Mat4::from_scale( + scale.into_inner(), + ) + .into(); + output + }, + ) + .register( + "col", + |_self: Ref, index: usize| { + let output: Val = bevy::math::Mat4::col( + &_self, + index, + ) + .into(); + output + }, + ) + .register( + "row", + |_self: Ref, index: usize| { + let output: Val = bevy::math::Mat4::row( + &_self, + index, + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Ref| { + let output: bool = bevy::math::Mat4::is_finite(&_self).into(); + output + }, + ) + .register( + "is_nan", + |_self: Ref| { + let output: bool = bevy::math::Mat4::is_nan(&_self).into(); + output + }, + ) + .register( + "transpose", + |_self: Ref| { + let output: Val = bevy::math::Mat4::transpose( + &_self, + ) + .into(); + output + }, + ) + .register( + "determinant", + |_self: Ref| { + let output: f32 = bevy::math::Mat4::determinant(&_self).into(); + output + }, + ) + .register( + "inverse", + |_self: Ref| { + let output: Val = bevy::math::Mat4::inverse(&_self) + .into(); + output + }, + ) + .register( + "look_to_lh", + | + eye: Val, + dir: Val, + up: Val| + { + let output: Val = bevy::math::Mat4::look_to_lh( + eye.into_inner(), + dir.into_inner(), + up.into_inner(), + ) + .into(); + output + }, + ) + .register( + "look_to_rh", + | + eye: Val, + dir: Val, + up: Val| + { + let output: Val = bevy::math::Mat4::look_to_rh( + eye.into_inner(), + dir.into_inner(), + up.into_inner(), + ) + .into(); + output + }, + ) + .register( + "look_at_lh", + | + eye: Val, + center: Val, + up: Val| + { + let output: Val = bevy::math::Mat4::look_at_lh( + eye.into_inner(), + center.into_inner(), + up.into_inner(), + ) + .into(); + output + }, + ) + .register( + "look_at_rh", + | + eye: Val, + center: Val, + up: Val| + { + let output: Val = bevy::math::Mat4::look_at_rh( + eye.into_inner(), + center.into_inner(), + up.into_inner(), + ) + .into(); + output + }, + ) + .register( + "perspective_rh_gl", + |fov_y_radians: f32, aspect_ratio: f32, z_near: f32, z_far: f32| { + let output: Val = bevy::math::Mat4::perspective_rh_gl( + fov_y_radians, + aspect_ratio, + z_near, + z_far, + ) + .into(); + output + }, + ) + .register( + "perspective_lh", + |fov_y_radians: f32, aspect_ratio: f32, z_near: f32, z_far: f32| { + let output: Val = bevy::math::Mat4::perspective_lh( + fov_y_radians, + aspect_ratio, + z_near, + z_far, + ) + .into(); + output + }, + ) + .register( + "perspective_rh", + |fov_y_radians: f32, aspect_ratio: f32, z_near: f32, z_far: f32| { + let output: Val = bevy::math::Mat4::perspective_rh( + fov_y_radians, + aspect_ratio, + z_near, + z_far, + ) + .into(); + output + }, + ) + .register( + "perspective_infinite_lh", + |fov_y_radians: f32, aspect_ratio: f32, z_near: f32| { + let output: Val = bevy::math::Mat4::perspective_infinite_lh( + fov_y_radians, + aspect_ratio, + z_near, + ) + .into(); + output + }, + ) + .register( + "perspective_infinite_reverse_lh", + |fov_y_radians: f32, aspect_ratio: f32, z_near: f32| { + let output: Val = bevy::math::Mat4::perspective_infinite_reverse_lh( + fov_y_radians, + aspect_ratio, + z_near, + ) + .into(); + output + }, + ) + .register( + "perspective_infinite_rh", + |fov_y_radians: f32, aspect_ratio: f32, z_near: f32| { + let output: Val = bevy::math::Mat4::perspective_infinite_rh( + fov_y_radians, + aspect_ratio, + z_near, + ) + .into(); + output + }, + ) + .register( + "perspective_infinite_reverse_rh", + |fov_y_radians: f32, aspect_ratio: f32, z_near: f32| { + let output: Val = bevy::math::Mat4::perspective_infinite_reverse_rh( + fov_y_radians, + aspect_ratio, + z_near, + ) + .into(); + output + }, + ) + .register( + "orthographic_rh_gl", + |left: f32, right: f32, bottom: f32, top: f32, near: f32, far: f32| { + let output: Val = bevy::math::Mat4::orthographic_rh_gl( + left, + right, + bottom, + top, + near, + far, + ) + .into(); + output + }, + ) + .register( + "orthographic_lh", + |left: f32, right: f32, bottom: f32, top: f32, near: f32, far: f32| { + let output: Val = bevy::math::Mat4::orthographic_lh( + left, + right, + bottom, + top, + near, + far, + ) + .into(); + output + }, + ) + .register( + "orthographic_rh", + |left: f32, right: f32, bottom: f32, top: f32, near: f32, far: f32| { + let output: Val = bevy::math::Mat4::orthographic_rh( + left, + right, + bottom, + top, + near, + far, + ) + .into(); + output + }, + ) + .register( + "project_point3", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Mat4::project_point3( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_point3", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Mat4::transform_point3( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_vector3", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Mat4::transform_vector3( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "project_point3a", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Mat4::project_point3a( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_point3a", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Mat4::transform_point3a( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_vector3a", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Mat4::transform_vector3a( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul_vec4", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Mat4::mul_vec4( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul_mat4", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::Mat4::mul_mat4( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "add_mat4", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::Mat4::add_mat4( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "sub_mat4", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::Mat4::sub_mat4( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "mul_scalar", + |_self: Ref, rhs: f32| { + let output: Val = bevy::math::Mat4::mul_scalar( + &_self, + rhs, + ) + .into(); + output + }, + ) + .register( + "div_scalar", + |_self: Ref, rhs: f32| { + let output: Val = bevy::math::Mat4::div_scalar( + &_self, + rhs, + ) + .into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Ref, + rhs: Val, + max_abs_diff: f32| + { + let output: bool = bevy::math::Mat4::abs_diff_eq( + &_self, + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .register( + "abs", + |_self: Ref| { + let output: Val = bevy::math::Mat4::abs(&_self) + .into(); + output + }, + ) + .register( + "as_dmat4", + |_self: Ref| { + let output: Val = bevy::math::Mat4::as_dmat4( + &_self, + ) + .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: f32| { + let output: Val = >::mul(_self.into_inner(), rhs) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::DMat2>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: f64| { + let output: Val = >::mul(_self.into_inner(), rhs) + .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()) + .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: 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()) + .into(); + output + }, + ) + .register( + "eq", + |_self: Ref, rhs: Ref| { + let output: bool = >::eq(&_self, &rhs) + .into(); + output + }, + ) + .register( + "from_cols", + |x_axis: Val, y_axis: Val| { + let output: Val = bevy::math::DMat2::from_cols( + x_axis.into_inner(), + y_axis.into_inner(), + ) + .into(); + output + }, + ) + .register( + "to_cols_array", + |_self: Ref| { + let output: [f64; 4] = bevy::math::DMat2::to_cols_array(&_self) + .into(); + output + }, + ) + .register( + "to_cols_array_2d", + |_self: Ref| { + let output: [[f64; 2]; 2] = bevy::math::DMat2::to_cols_array_2d( + &_self, + ) + .into(); + output + }, + ) + .register( + "from_diagonal", + |diagonal: Val| { + let output: Val = bevy::math::DMat2::from_diagonal( + diagonal.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_scale_angle", + |scale: Val, angle: f64| { + let output: Val = bevy::math::DMat2::from_scale_angle( + scale.into_inner(), + angle, + ) + .into(); + output + }, + ) + .register( + "from_angle", + |angle: f64| { + let output: Val = bevy::math::DMat2::from_angle( + angle, + ) + .into(); + output + }, + ) + .register( + "from_mat3", + |m: Val| { + let output: Val = bevy::math::DMat2::from_mat3( + m.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat3_minor", + |m: Val, i: usize, j: usize| { + let output: Val = bevy::math::DMat2::from_mat3_minor( + m.into_inner(), + i, + j, + ) + .into(); + output + }, + ) + .register( + "col", + |_self: Ref, index: usize| { + let output: Val = bevy::math::DMat2::col( + &_self, + index, + ) + .into(); + output + }, + ) + .register( + "row", + |_self: Ref, index: usize| { + let output: Val = bevy::math::DMat2::row( + &_self, + index, + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Ref| { + let output: bool = bevy::math::DMat2::is_finite(&_self).into(); + output + }, + ) + .register( + "is_nan", + |_self: Ref| { + let output: bool = bevy::math::DMat2::is_nan(&_self).into(); + output + }, + ) + .register( + "transpose", + |_self: Ref| { + let output: Val = bevy::math::DMat2::transpose( + &_self, + ) + .into(); + output + }, + ) + .register( + "determinant", + |_self: Ref| { + let output: f64 = bevy::math::DMat2::determinant(&_self).into(); + output + }, + ) + .register( + "inverse", + |_self: Ref| { + let output: Val = bevy::math::DMat2::inverse( + &_self, + ) + .into(); + output + }, + ) + .register( + "mul_vec2", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::DMat2::mul_vec2( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul_mat2", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::DMat2::mul_mat2( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "add_mat2", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::DMat2::add_mat2( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "sub_mat2", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::DMat2::sub_mat2( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "mul_scalar", + |_self: Ref, rhs: f64| { + let output: Val = bevy::math::DMat2::mul_scalar( + &_self, + rhs, + ) + .into(); + output + }, + ) + .register( + "div_scalar", + |_self: Ref, rhs: f64| { + let output: Val = bevy::math::DMat2::div_scalar( + &_self, + rhs, + ) + .into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Ref, + rhs: Val, + max_abs_diff: f64| + { + let output: bool = bevy::math::DMat2::abs_diff_eq( + &_self, + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .register( + "abs", + |_self: Ref| { + let output: Val = bevy::math::DMat2::abs(&_self) + .into(); + output + }, + ) + .register( + "as_mat2", + |_self: Ref| { + let output: Val = bevy::math::DMat2::as_mat2( + &_self, + ) + .into(); + output + }, + ) + .register( + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::DMat3>::new(world) + .register( + "mul", + |_self: Val, rhs: f64| { + let output: Val = >::mul(_self.into_inner(), rhs) + .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 + }, + ) + .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( + "from_cols", + | + x_axis: Val, + y_axis: Val, + z_axis: Val| + { + let output: Val = bevy::math::DMat3::from_cols( + x_axis.into_inner(), + y_axis.into_inner(), + z_axis.into_inner(), + ) + .into(); + output + }, + ) + .register( + "to_cols_array", + |_self: Ref| { + let output: [f64; 9] = bevy::math::DMat3::to_cols_array(&_self) + .into(); + output + }, + ) + .register( + "to_cols_array_2d", + |_self: Ref| { + let output: [[f64; 3]; 3] = bevy::math::DMat3::to_cols_array_2d( + &_self, + ) + .into(); + output + }, + ) + .register( + "from_diagonal", + |diagonal: Val| { + let output: Val = bevy::math::DMat3::from_diagonal( + diagonal.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat4", + |m: Val| { + let output: Val = bevy::math::DMat3::from_mat4( + m.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat4_minor", + |m: Val, i: usize, j: usize| { + let output: Val = bevy::math::DMat3::from_mat4_minor( + m.into_inner(), + i, + j, + ) + .into(); + output + }, + ) + .register( + "from_quat", + |rotation: Val| { + let output: Val = bevy::math::DMat3::from_quat( + rotation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_axis_angle", + |axis: Val, angle: f64| { + let output: Val = bevy::math::DMat3::from_axis_angle( + axis.into_inner(), + angle, + ) + .into(); + output + }, + ) + .register( + "from_euler", + |order: Val, a: f64, b: f64, c: f64| { + let output: Val = bevy::math::DMat3::from_euler( + order.into_inner(), + a, + b, + c, + ) + .into(); + output + }, + ) + .register( + "to_euler", + |_self: Ref, order: Val| { + let output: (f64, f64, f64) = bevy::math::DMat3::to_euler( + &_self, + order.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_rotation_x", + |angle: f64| { + let output: Val = bevy::math::DMat3::from_rotation_x( + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_y", + |angle: f64| { + let output: Val = bevy::math::DMat3::from_rotation_y( + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_z", + |angle: f64| { + let output: Val = bevy::math::DMat3::from_rotation_z( + angle, + ) + .into(); + output + }, + ) + .register( + "from_translation", + |translation: Val| { + let output: Val = bevy::math::DMat3::from_translation( + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_angle", + |angle: f64| { + let output: Val = bevy::math::DMat3::from_angle( + angle, + ) + .into(); + output + }, + ) + .register( + "from_scale_angle_translation", + | + scale: Val, + angle: f64, + translation: Val| + { + let output: Val = bevy::math::DMat3::from_scale_angle_translation( + scale.into_inner(), + angle, + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_scale", + |scale: Val| { + let output: Val = bevy::math::DMat3::from_scale( + scale.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat2", + |m: Val| { + let output: Val = bevy::math::DMat3::from_mat2( + m.into_inner(), + ) + .into(); + output + }, + ) + .register( + "col", + |_self: Ref, index: usize| { + let output: Val = bevy::math::DMat3::col( + &_self, + index, + ) + .into(); + output + }, + ) + .register( + "row", + |_self: Ref, index: usize| { + let output: Val = bevy::math::DMat3::row( + &_self, + index, + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Ref| { + let output: bool = bevy::math::DMat3::is_finite(&_self).into(); + output + }, + ) + .register( + "is_nan", + |_self: Ref| { + let output: bool = bevy::math::DMat3::is_nan(&_self).into(); + output + }, + ) + .register( + "transpose", + |_self: Ref| { + let output: Val = bevy::math::DMat3::transpose( + &_self, + ) + .into(); + output + }, + ) + .register( + "determinant", + |_self: Ref| { + let output: f64 = bevy::math::DMat3::determinant(&_self).into(); + output + }, + ) + .register( + "inverse", + |_self: Ref| { + let output: Val = bevy::math::DMat3::inverse( + &_self, + ) + .into(); + output + }, + ) + .register( + "transform_point2", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::DMat3::transform_point2( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_vector2", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::DMat3::transform_vector2( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul_vec3", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::DMat3::mul_vec3( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul_mat3", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::DMat3::mul_mat3( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "add_mat3", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::DMat3::add_mat3( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "sub_mat3", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::DMat3::sub_mat3( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "mul_scalar", + |_self: Ref, rhs: f64| { + let output: Val = bevy::math::DMat3::mul_scalar( + &_self, + rhs, + ) + .into(); + output + }, + ) + .register( + "div_scalar", + |_self: Ref, rhs: f64| { + let output: Val = bevy::math::DMat3::div_scalar( + &_self, + rhs, + ) + .into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Ref, + rhs: Val, + max_abs_diff: f64| + { + let output: bool = bevy::math::DMat3::abs_diff_eq( + &_self, + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .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()) + .into(); + 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| { + let output: bool = >::eq(&_self, &rhs) + .into(); + output + }, + ) + .register( + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::DMat4>::new(world) + .register( + "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()) + .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( + "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) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ) + .register( + "from_cols", + | + x_axis: Val, + y_axis: Val, + z_axis: Val, + w_axis: Val| + { + let output: Val = bevy::math::DMat4::from_cols( + x_axis.into_inner(), + y_axis.into_inner(), + z_axis.into_inner(), + w_axis.into_inner(), + ) + .into(); + output + }, + ) + .register( + "to_cols_array", + |_self: Ref| { + let output: [f64; 16] = bevy::math::DMat4::to_cols_array(&_self) + .into(); + output + }, + ) + .register( + "to_cols_array_2d", + |_self: Ref| { + let output: [[f64; 4]; 4] = bevy::math::DMat4::to_cols_array_2d( + &_self, + ) + .into(); + output + }, + ) + .register( + "from_diagonal", + |diagonal: Val| { + let output: Val = bevy::math::DMat4::from_diagonal( + diagonal.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_scale_rotation_translation", + | + scale: Val, + rotation: Val, + translation: Val| + { + let output: Val = bevy::math::DMat4::from_scale_rotation_translation( + scale.into_inner(), + rotation.into_inner(), + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_rotation_translation", + |rotation: Val, translation: Val| { + let output: Val = bevy::math::DMat4::from_rotation_translation( + rotation.into_inner(), + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_quat", + |rotation: Val| { + let output: Val = bevy::math::DMat4::from_quat( + rotation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat3", + |m: Val| { + let output: Val = bevy::math::DMat4::from_mat3( + m.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_translation", + |translation: Val| { + let output: Val = bevy::math::DMat4::from_translation( + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_axis_angle", + |axis: Val, angle: f64| { + let output: Val = bevy::math::DMat4::from_axis_angle( + axis.into_inner(), + angle, + ) + .into(); + output + }, + ) + .register( + "from_euler", + |order: Val, a: f64, b: f64, c: f64| { + let output: Val = bevy::math::DMat4::from_euler( + order.into_inner(), + a, + b, + c, + ) + .into(); + output + }, + ) + .register( + "to_euler", + |_self: Ref, order: Val| { + let output: (f64, f64, f64) = bevy::math::DMat4::to_euler( + &_self, + order.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_rotation_x", + |angle: f64| { + let output: Val = bevy::math::DMat4::from_rotation_x( + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_y", + |angle: f64| { + let output: Val = bevy::math::DMat4::from_rotation_y( + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_z", + |angle: f64| { + let output: Val = bevy::math::DMat4::from_rotation_z( + angle, + ) + .into(); + output + }, + ) + .register( + "from_scale", + |scale: Val| { + let output: Val = bevy::math::DMat4::from_scale( + scale.into_inner(), + ) + .into(); + output + }, + ) + .register( + "col", + |_self: Ref, index: usize| { + let output: Val = bevy::math::DMat4::col( + &_self, + index, + ) + .into(); + output + }, + ) + .register( + "row", + |_self: Ref, index: usize| { + let output: Val = bevy::math::DMat4::row( + &_self, + index, + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Ref| { + let output: bool = bevy::math::DMat4::is_finite(&_self).into(); + output + }, + ) + .register( + "is_nan", + |_self: Ref| { + let output: bool = bevy::math::DMat4::is_nan(&_self).into(); + output + }, + ) + .register( + "transpose", + |_self: Ref| { + let output: Val = bevy::math::DMat4::transpose( + &_self, + ) + .into(); + output + }, + ) + .register( + "determinant", + |_self: Ref| { + let output: f64 = bevy::math::DMat4::determinant(&_self).into(); + output + }, + ) + .register( + "inverse", + |_self: Ref| { + let output: Val = bevy::math::DMat4::inverse( + &_self, + ) + .into(); + output + }, + ) + .register( + "look_to_lh", + | + eye: Val, + dir: Val, + up: Val| + { + let output: Val = bevy::math::DMat4::look_to_lh( + eye.into_inner(), + dir.into_inner(), + up.into_inner(), + ) + .into(); + output + }, + ) + .register( + "look_to_rh", + | + eye: Val, + dir: Val, + up: Val| + { + let output: Val = bevy::math::DMat4::look_to_rh( + eye.into_inner(), + dir.into_inner(), + up.into_inner(), + ) + .into(); + output + }, + ) + .register( + "look_at_lh", + | + eye: Val, + center: Val, + up: Val| + { + let output: Val = bevy::math::DMat4::look_at_lh( + eye.into_inner(), + center.into_inner(), + up.into_inner(), + ) + .into(); + output + }, + ) + .register( + "look_at_rh", + | + eye: Val, + center: Val, + up: Val| + { + let output: Val = bevy::math::DMat4::look_at_rh( + eye.into_inner(), + center.into_inner(), + up.into_inner(), + ) + .into(); + output + }, + ) + .register( + "perspective_rh_gl", + |fov_y_radians: f64, aspect_ratio: f64, z_near: f64, z_far: f64| { + let output: Val = bevy::math::DMat4::perspective_rh_gl( + fov_y_radians, + aspect_ratio, + z_near, + z_far, + ) + .into(); + output + }, + ) + .register( + "perspective_lh", + |fov_y_radians: f64, aspect_ratio: f64, z_near: f64, z_far: f64| { + let output: Val = bevy::math::DMat4::perspective_lh( + fov_y_radians, + aspect_ratio, + z_near, + z_far, + ) + .into(); + output + }, + ) + .register( + "perspective_rh", + |fov_y_radians: f64, aspect_ratio: f64, z_near: f64, z_far: f64| { + let output: Val = bevy::math::DMat4::perspective_rh( + fov_y_radians, + aspect_ratio, + z_near, + z_far, + ) + .into(); + output + }, + ) + .register( + "perspective_infinite_lh", + |fov_y_radians: f64, aspect_ratio: f64, z_near: f64| { + let output: Val = bevy::math::DMat4::perspective_infinite_lh( + fov_y_radians, + aspect_ratio, + z_near, + ) + .into(); + output + }, + ) + .register( + "perspective_infinite_reverse_lh", + |fov_y_radians: f64, aspect_ratio: f64, z_near: f64| { + let output: Val = bevy::math::DMat4::perspective_infinite_reverse_lh( + fov_y_radians, + aspect_ratio, + z_near, + ) + .into(); + output + }, + ) + .register( + "perspective_infinite_rh", + |fov_y_radians: f64, aspect_ratio: f64, z_near: f64| { + let output: Val = bevy::math::DMat4::perspective_infinite_rh( + fov_y_radians, + aspect_ratio, + z_near, + ) + .into(); + output + }, + ) + .register( + "perspective_infinite_reverse_rh", + |fov_y_radians: f64, aspect_ratio: f64, z_near: f64| { + let output: Val = bevy::math::DMat4::perspective_infinite_reverse_rh( + fov_y_radians, + aspect_ratio, + z_near, + ) + .into(); + output + }, + ) + .register( + "orthographic_rh_gl", + |left: f64, right: f64, bottom: f64, top: f64, near: f64, far: f64| { + let output: Val = bevy::math::DMat4::orthographic_rh_gl( + left, + right, + bottom, + top, + near, + far, + ) + .into(); + output + }, + ) + .register( + "orthographic_lh", + |left: f64, right: f64, bottom: f64, top: f64, near: f64, far: f64| { + let output: Val = bevy::math::DMat4::orthographic_lh( + left, + right, + bottom, + top, + near, + far, + ) + .into(); + output + }, + ) + .register( + "orthographic_rh", + |left: f64, right: f64, bottom: f64, top: f64, near: f64, far: f64| { + let output: Val = bevy::math::DMat4::orthographic_rh( + left, + right, + bottom, + top, + near, + far, + ) + .into(); + output + }, + ) + .register( + "project_point3", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::DMat4::project_point3( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_point3", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::DMat4::transform_point3( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_vector3", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::DMat4::transform_vector3( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul_vec4", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::DMat4::mul_vec4( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul_mat4", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::DMat4::mul_mat4( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "add_mat4", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::DMat4::add_mat4( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "sub_mat4", + |_self: Ref, rhs: Ref| { + let output: Val = bevy::math::DMat4::sub_mat4( + &_self, + &rhs, + ) + .into(); + output + }, + ) + .register( + "mul_scalar", + |_self: Ref, rhs: f64| { + let output: Val = bevy::math::DMat4::mul_scalar( + &_self, + rhs, + ) + .into(); + output + }, + ) + .register( + "div_scalar", + |_self: Ref, rhs: f64| { + let output: Val = bevy::math::DMat4::div_scalar( + &_self, + rhs, + ) + .into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Ref, + rhs: Val, + max_abs_diff: f64| + { + let output: bool = bevy::math::DMat4::abs_diff_eq( + &_self, + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .register( + "abs", + |_self: Ref| { + let output: Val = bevy::math::DMat4::abs(&_self) + .into(); + output + }, + ) + .register( + "as_mat4", + |_self: Ref| { + let output: Val = bevy::math::DMat4::as_mat4( + &_self, + ) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: f64| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "neg", + |_self: Val| { + let output: Val = ::neg( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "add", + |_self: Val, rhs: Val| { + let output: Val = >::add(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::Affine2>::new(world) + .register( + "from_cols", + | + x_axis: Val, + y_axis: Val, + z_axis: Val| + { + let output: Val = bevy::math::Affine2::from_cols( + x_axis.into_inner(), + y_axis.into_inner(), + z_axis.into_inner(), + ) + .into(); + output + }, + ) + .register( + "to_cols_array", + |_self: Ref| { + let output: [f32; 6] = bevy::math::Affine2::to_cols_array(&_self) + .into(); + output + }, + ) + .register( + "to_cols_array_2d", + |_self: Ref| { + let output: [[f32; 2]; 3] = bevy::math::Affine2::to_cols_array_2d( + &_self, + ) + .into(); + output + }, + ) + .register( + "from_scale", + |scale: Val| { + let output: Val = bevy::math::Affine2::from_scale( + scale.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_angle", + |angle: f32| { + let output: Val = bevy::math::Affine2::from_angle( + angle, + ) + .into(); + output + }, + ) + .register( + "from_translation", + |translation: Val| { + let output: Val = bevy::math::Affine2::from_translation( + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat2", + |matrix2: Val| { + let output: Val = bevy::math::Affine2::from_mat2( + matrix2.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat2_translation", + |matrix2: Val, translation: Val| { + let output: Val = bevy::math::Affine2::from_mat2_translation( + matrix2.into_inner(), + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_scale_angle_translation", + | + scale: Val, + angle: f32, + translation: Val| + { + let output: Val = bevy::math::Affine2::from_scale_angle_translation( + scale.into_inner(), + angle, + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_angle_translation", + |angle: f32, translation: Val| { + let output: Val = bevy::math::Affine2::from_angle_translation( + angle, + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat3", + |m: Val| { + let output: Val = bevy::math::Affine2::from_mat3( + m.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat3a", + |m: Val| { + let output: Val = bevy::math::Affine2::from_mat3a( + m.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_point2", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Affine2::transform_point2( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_vector2", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Affine2::transform_vector2( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Ref| { + let output: bool = bevy::math::Affine2::is_finite(&_self).into(); + output + }, + ) + .register( + "is_nan", + |_self: Ref| { + let output: bool = bevy::math::Affine2::is_nan(&_self).into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Ref, + rhs: Val, + max_abs_diff: f32| + { + let output: bool = bevy::math::Affine2::abs_diff_eq( + &_self, + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .register( + "inverse", + |_self: Ref| { + let output: Val = bevy::math::Affine2::inverse( + &_self, + ) + .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( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_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, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::Affine3A>::new(world) + .register( + "from_cols", + | + x_axis: Val, + y_axis: Val, + z_axis: Val, + w_axis: Val| + { + let output: Val = bevy::math::Affine3A::from_cols( + x_axis.into_inner(), + y_axis.into_inner(), + z_axis.into_inner(), + w_axis.into_inner(), + ) + .into(); + output + }, + ) + .register( + "to_cols_array", + |_self: Ref| { + let output: [f32; 12] = bevy::math::Affine3A::to_cols_array(&_self) + .into(); + output + }, + ) + .register( + "to_cols_array_2d", + |_self: Ref| { + let output: [[f32; 3]; 4] = bevy::math::Affine3A::to_cols_array_2d( + &_self, + ) + .into(); + output + }, + ) + .register( + "from_scale", + |scale: Val| { + let output: Val = bevy::math::Affine3A::from_scale( + scale.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_quat", + |rotation: Val| { + let output: Val = bevy::math::Affine3A::from_quat( + rotation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_axis_angle", + |axis: Val, angle: f32| { + let output: Val = bevy::math::Affine3A::from_axis_angle( + axis.into_inner(), + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_x", + |angle: f32| { + let output: Val = bevy::math::Affine3A::from_rotation_x( + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_y", + |angle: f32| { + let output: Val = bevy::math::Affine3A::from_rotation_y( + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_z", + |angle: f32| { + let output: Val = bevy::math::Affine3A::from_rotation_z( + angle, + ) + .into(); + output + }, + ) + .register( + "from_translation", + |translation: Val| { + let output: Val = bevy::math::Affine3A::from_translation( + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat3", + |mat3: Val| { + let output: Val = bevy::math::Affine3A::from_mat3( + mat3.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat3_translation", + |mat3: Val, translation: Val| { + let output: Val = bevy::math::Affine3A::from_mat3_translation( + mat3.into_inner(), + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_scale_rotation_translation", + | + scale: Val, + rotation: Val, + translation: Val| + { + let output: Val = bevy::math::Affine3A::from_scale_rotation_translation( + scale.into_inner(), + rotation.into_inner(), + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_rotation_translation", + |rotation: Val, translation: Val| { + let output: Val = bevy::math::Affine3A::from_rotation_translation( + rotation.into_inner(), + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat4", + |m: Val| { + let output: Val = bevy::math::Affine3A::from_mat4( + m.into_inner(), + ) + .into(); + output + }, + ) + .register( + "look_to_lh", + | + eye: Val, + dir: Val, + up: Val| + { + let output: Val = bevy::math::Affine3A::look_to_lh( + eye.into_inner(), + dir.into_inner(), + up.into_inner(), + ) + .into(); + output + }, + ) + .register( + "look_to_rh", + | + eye: Val, + dir: Val, + up: Val| + { + let output: Val = bevy::math::Affine3A::look_to_rh( + eye.into_inner(), + dir.into_inner(), + up.into_inner(), + ) + .into(); + output + }, + ) + .register( + "look_at_lh", + | + eye: Val, + center: Val, + up: Val| + { + let output: Val = bevy::math::Affine3A::look_at_lh( + eye.into_inner(), + center.into_inner(), + up.into_inner(), + ) + .into(); + output + }, + ) + .register( + "look_at_rh", + | + eye: Val, + center: Val, + up: Val| + { + let output: Val = bevy::math::Affine3A::look_at_rh( + eye.into_inner(), + center.into_inner(), + up.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_point3", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Affine3A::transform_point3( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_vector3", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Affine3A::transform_vector3( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_point3a", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Affine3A::transform_point3a( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_vector3a", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::Affine3A::transform_vector3a( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Ref| { + let output: bool = bevy::math::Affine3A::is_finite(&_self).into(); + output + }, + ) + .register( + "is_nan", + |_self: Ref| { + let output: bool = bevy::math::Affine3A::is_nan(&_self).into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Ref, + rhs: Val, + max_abs_diff: f32| + { + let output: bool = bevy::math::Affine3A::abs_diff_eq( + &_self, + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .register( + "inverse", + |_self: Ref| { + let output: Val = bevy::math::Affine3A::inverse( + &_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, 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( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::DAffine2>::new(world) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_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, + ) + .into(); + output + }, + ) + .register( + "from_cols", + | + x_axis: Val, + y_axis: Val, + z_axis: Val| + { + let output: Val = bevy::math::DAffine2::from_cols( + x_axis.into_inner(), + y_axis.into_inner(), + z_axis.into_inner(), + ) + .into(); + output + }, + ) + .register( + "to_cols_array", + |_self: Ref| { + let output: [f64; 6] = bevy::math::DAffine2::to_cols_array(&_self) + .into(); + output + }, + ) + .register( + "to_cols_array_2d", + |_self: Ref| { + let output: [[f64; 2]; 3] = bevy::math::DAffine2::to_cols_array_2d( + &_self, + ) + .into(); + output + }, + ) + .register( + "from_scale", + |scale: Val| { + let output: Val = bevy::math::DAffine2::from_scale( + scale.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_angle", + |angle: f64| { + let output: Val = bevy::math::DAffine2::from_angle( + angle, + ) + .into(); + output + }, + ) + .register( + "from_translation", + |translation: Val| { + let output: Val = bevy::math::DAffine2::from_translation( + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat2", + |matrix2: Val| { + let output: Val = bevy::math::DAffine2::from_mat2( + matrix2.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat2_translation", + |matrix2: Val, translation: Val| { + let output: Val = bevy::math::DAffine2::from_mat2_translation( + matrix2.into_inner(), + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_scale_angle_translation", + | + scale: Val, + angle: f64, + translation: Val| + { + let output: Val = bevy::math::DAffine2::from_scale_angle_translation( + scale.into_inner(), + angle, + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_angle_translation", + |angle: f64, translation: Val| { + let output: Val = bevy::math::DAffine2::from_angle_translation( + angle, + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat3", + |m: Val| { + let output: Val = bevy::math::DAffine2::from_mat3( + m.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_point2", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::DAffine2::transform_point2( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_vector2", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::DAffine2::transform_vector2( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Ref| { + let output: bool = bevy::math::DAffine2::is_finite(&_self).into(); + output + }, + ) + .register( + "is_nan", + |_self: Ref| { + let output: bool = bevy::math::DAffine2::is_nan(&_self).into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Ref, + rhs: Val, + max_abs_diff: f64| + { + let output: bool = bevy::math::DAffine2::abs_diff_eq( + &_self, + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .register( + "inverse", + |_self: Ref| { + let output: Val = bevy::math::DAffine2::inverse( + &_self, + ) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .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| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "eq", + |_self: Ref, rhs: Ref| { + let output: bool = >::eq(&_self, &rhs) + .into(); + output + }, + ) + .register( + "from_cols", + | + x_axis: Val, + y_axis: Val, + z_axis: Val, + w_axis: Val| + { + let output: Val = bevy::math::DAffine3::from_cols( + x_axis.into_inner(), + y_axis.into_inner(), + z_axis.into_inner(), + w_axis.into_inner(), + ) + .into(); + output + }, + ) + .register( + "to_cols_array", + |_self: Ref| { + let output: [f64; 12] = bevy::math::DAffine3::to_cols_array(&_self) + .into(); + output + }, + ) + .register( + "to_cols_array_2d", + |_self: Ref| { + let output: [[f64; 3]; 4] = bevy::math::DAffine3::to_cols_array_2d( + &_self, + ) + .into(); + output + }, + ) + .register( + "from_scale", + |scale: Val| { + let output: Val = bevy::math::DAffine3::from_scale( + scale.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_quat", + |rotation: Val| { + let output: Val = bevy::math::DAffine3::from_quat( + rotation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_axis_angle", + |axis: Val, angle: f64| { + let output: Val = bevy::math::DAffine3::from_axis_angle( + axis.into_inner(), + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_x", + |angle: f64| { + let output: Val = bevy::math::DAffine3::from_rotation_x( + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_y", + |angle: f64| { + let output: Val = bevy::math::DAffine3::from_rotation_y( + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_z", + |angle: f64| { + let output: Val = bevy::math::DAffine3::from_rotation_z( + angle, + ) + .into(); + output + }, + ) + .register( + "from_translation", + |translation: Val| { + let output: Val = bevy::math::DAffine3::from_translation( + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat3", + |mat3: Val| { + let output: Val = bevy::math::DAffine3::from_mat3( + mat3.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat3_translation", + |mat3: Val, translation: Val| { + let output: Val = bevy::math::DAffine3::from_mat3_translation( + mat3.into_inner(), + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_scale_rotation_translation", + | + scale: Val, + rotation: Val, + translation: Val| + { + let output: Val = bevy::math::DAffine3::from_scale_rotation_translation( + scale.into_inner(), + rotation.into_inner(), + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_rotation_translation", + |rotation: Val, translation: Val| { + let output: Val = bevy::math::DAffine3::from_rotation_translation( + rotation.into_inner(), + translation.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_mat4", + |m: Val| { + let output: Val = bevy::math::DAffine3::from_mat4( + m.into_inner(), + ) + .into(); + output + }, + ) + .register( + "look_to_lh", + | + eye: Val, + dir: Val, + up: Val| + { + let output: Val = bevy::math::DAffine3::look_to_lh( + eye.into_inner(), + dir.into_inner(), + up.into_inner(), + ) + .into(); + output + }, + ) + .register( + "look_to_rh", + | + eye: Val, + dir: Val, + up: Val| + { + let output: Val = bevy::math::DAffine3::look_to_rh( + eye.into_inner(), + dir.into_inner(), + up.into_inner(), + ) + .into(); + output + }, + ) + .register( + "look_at_lh", + | + eye: Val, + center: Val, + up: Val| + { + let output: Val = bevy::math::DAffine3::look_at_lh( + eye.into_inner(), + center.into_inner(), + up.into_inner(), + ) + .into(); + output + }, + ) + .register( + "look_at_rh", + | + eye: Val, + center: Val, + up: Val| + { + let output: Val = bevy::math::DAffine3::look_at_rh( + eye.into_inner(), + center.into_inner(), + up.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_point3", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::DAffine3::transform_point3( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "transform_vector3", + |_self: Ref, rhs: Val| { + let output: Val = bevy::math::DAffine3::transform_vector3( + &_self, + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Ref| { + let output: bool = bevy::math::DAffine3::is_finite(&_self).into(); + output + }, + ) + .register( + "is_nan", + |_self: Ref| { + let output: bool = bevy::math::DAffine3::is_nan(&_self).into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Ref, + rhs: Val, + max_abs_diff: f64| + { + let output: bool = bevy::math::DAffine3::abs_diff_eq( + &_self, + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .register( + "inverse", + |_self: Ref| { + let output: Val = bevy::math::DAffine3::inverse( + &_self, + ) + .into(); + output + }, + ) + .register( + "mul", + |_self: Val, rhs: Val| { + let output: Val = >::mul(_self.into_inner(), rhs.into_inner()) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::DQuat>::new(world) + .register( + "mul", + |_self: Val, rhs: f64| { + 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( + "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, + ) + .into(); + output + }, + ) + .register( + "div", + |_self: Val, rhs: f64| { + let output: Val = >::div(_self.into_inner(), rhs) + .into(); + output + }, + ) + .register( + "from_xyzw", + |x: f64, y: f64, z: f64, w: f64| { + let output: Val = bevy::math::DQuat::from_xyzw( + x, + y, + z, + w, + ) + .into(); + output + }, + ) + .register( + "from_array", + |a: [f64; 4]| { + let output: Val = bevy::math::DQuat::from_array(a) + .into(); + output + }, + ) + .register( + "from_vec4", + |v: Val| { + let output: Val = bevy::math::DQuat::from_vec4( + v.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_axis_angle", + |axis: Val, angle: f64| { + let output: Val = bevy::math::DQuat::from_axis_angle( + axis.into_inner(), + angle, + ) + .into(); + output + }, + ) + .register( + "from_scaled_axis", + |v: Val| { + let output: Val = bevy::math::DQuat::from_scaled_axis( + v.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_rotation_x", + |angle: f64| { + let output: Val = bevy::math::DQuat::from_rotation_x( + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_y", + |angle: f64| { + let output: Val = bevy::math::DQuat::from_rotation_y( + angle, + ) + .into(); + output + }, + ) + .register( + "from_rotation_z", + |angle: f64| { + let output: Val = bevy::math::DQuat::from_rotation_z( + angle, + ) + .into(); + output + }, + ) + .register( + "from_euler", + |euler: Val, a: f64, b: f64, c: f64| { + let output: Val = bevy::math::DQuat::from_euler( + euler.into_inner(), + a, + b, + c, + ) + .into(); + output + }, + ) + .register( + "from_mat3", + |mat: Ref| { + let output: Val = bevy::math::DQuat::from_mat3( + &mat, + ) + .into(); + output + }, + ) + .register( + "from_mat4", + |mat: Ref| { + let output: Val = bevy::math::DQuat::from_mat4( + &mat, + ) + .into(); + output + }, + ) + .register( + "from_rotation_arc", + |from: Val, to: Val| { + let output: Val = bevy::math::DQuat::from_rotation_arc( + from.into_inner(), + to.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_rotation_arc_colinear", + |from: Val, to: Val| { + let output: Val = bevy::math::DQuat::from_rotation_arc_colinear( + from.into_inner(), + to.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_rotation_arc_2d", + |from: Val, to: Val| { + let output: Val = bevy::math::DQuat::from_rotation_arc_2d( + from.into_inner(), + to.into_inner(), + ) + .into(); + output + }, + ) + .register( + "to_scaled_axis", + |_self: Val| { + let output: Val = bevy::math::DQuat::to_scaled_axis( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "to_euler", + |_self: Val, order: Val| { + let output: (f64, f64, f64) = bevy::math::DQuat::to_euler( + _self.into_inner(), + order.into_inner(), + ) + .into(); + output + }, + ) + .register( + "to_array", + |_self: Ref| { + let output: [f64; 4] = bevy::math::DQuat::to_array(&_self).into(); + output + }, + ) + .register( + "xyz", + |_self: Val| { + let output: Val = bevy::math::DQuat::xyz( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "conjugate", + |_self: Val| { + let output: Val = bevy::math::DQuat::conjugate( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "inverse", + |_self: Val| { + let output: Val = bevy::math::DQuat::inverse( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "dot", + |_self: Val, rhs: Val| { + let output: f64 = bevy::math::DQuat::dot( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length", + |_self: Val| { + let output: f64 = bevy::math::DQuat::length(_self.into_inner()) + .into(); + output + }, + ) + .register( + "length_squared", + |_self: Val| { + let output: f64 = bevy::math::DQuat::length_squared( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "length_recip", + |_self: Val| { + let output: f64 = bevy::math::DQuat::length_recip(_self.into_inner()) + .into(); + output + }, + ) + .register( + "normalize", + |_self: Val| { + let output: Val = bevy::math::DQuat::normalize( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Val| { + let output: bool = bevy::math::DQuat::is_finite(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_nan", + |_self: Val| { + let output: bool = bevy::math::DQuat::is_nan(_self.into_inner()) + .into(); + output + }, + ) + .register( + "is_normalized", + |_self: Val| { + let output: bool = bevy::math::DQuat::is_normalized( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_near_identity", + |_self: Val| { + let output: bool = bevy::math::DQuat::is_near_identity( + _self.into_inner(), + ) + .into(); + output + }, + ) + .register( + "angle_between", + |_self: Val, rhs: Val| { + let output: f64 = bevy::math::DQuat::angle_between( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "rotate_towards", + | + _self: Ref, + rhs: Val, + max_angle: f64| + { + let output: Val = bevy::math::DQuat::rotate_towards( + &_self, + rhs.into_inner(), + max_angle, + ) + .into(); + output + }, + ) + .register( + "abs_diff_eq", + | + _self: Val, + rhs: Val, + max_abs_diff: f64| + { + let output: bool = bevy::math::DQuat::abs_diff_eq( + _self.into_inner(), + rhs.into_inner(), + max_abs_diff, + ) + .into(); + output + }, + ) + .register( + "lerp", + |_self: Val, end: Val, s: f64| { + let output: Val = bevy::math::DQuat::lerp( + _self.into_inner(), + end.into_inner(), + s, + ) + .into(); + output + }, + ) + .register( + "slerp", + |_self: Val, end: Val, s: f64| { + let output: Val = bevy::math::DQuat::slerp( + _self.into_inner(), + end.into_inner(), + s, + ) + .into(); + output + }, + ) + .register( + "mul_vec3", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DQuat::mul_vec3( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul_quat", + |_self: Val, rhs: Val| { + let output: Val = bevy::math::DQuat::mul_quat( + _self.into_inner(), + rhs.into_inner(), + ) + .into(); + output + }, + ) + .register( + "from_affine3", + |a: Ref| { + let output: Val = bevy::math::DQuat::from_affine3( + &a, + ) + .into(); + output + }, + ) + .register( + "as_quat", + |_self: Val| { + let output: Val = bevy::math::DQuat::as_quat( + _self.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: 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::EulerRot>::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( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::math::BVec3A>::new(world) + .register( + "new", + |x: bool, y: bool, z: bool| { + let output: Val = bevy::math::BVec3A::new( + x, + y, + z, + ) + .into(); + output + }, + ) + .register( + "splat", + |v: bool| { + let output: Val = bevy::math::BVec3A::splat(v) + .into(); + output + }, + ) + .register( + "from_array", + |a: [bool; 3]| { + let output: Val = bevy::math::BVec3A::from_array( + a, + ) + .into(); + output + }, + ) + .register( + "bitmask", + |_self: Val| { + let output: u32 = bevy::math::BVec3A::bitmask(_self.into_inner()) + .into(); + output + }, + ) + .register( + "any", + |_self: Val| { + let output: bool = bevy::math::BVec3A::any(_self.into_inner()) + .into(); + output + }, + ) + .register( + "all", + |_self: Val| { + let output: bool = bevy::math::BVec3A::all(_self.into_inner()) + .into(); + output + }, + ) + .register( + "test", + |_self: Ref, index: usize| { + let output: bool = bevy::math::BVec3A::test(&_self, index).into(); + output + }, + ) + .register( + "set", + |mut _self: Mut, index: usize, value: bool| { + let output: () = bevy::math::BVec3A::set(&mut _self, index, value) + .into(); + output + }, + ) + .register( + "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::BVec4A>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ) + .register( + "new", + |x: bool, y: bool, z: bool, w: bool| { + let output: Val = bevy::math::BVec4A::new( + x, + y, + z, + w, + ) + .into(); + output + }, + ) + .register( + "splat", + |v: bool| { + let output: Val = bevy::math::BVec4A::splat(v) + .into(); + output + }, + ) + .register( + "from_array", + |a: [bool; 4]| { + let output: Val = bevy::math::BVec4A::from_array( + a, + ) + .into(); + output + }, + ) + .register( + "bitmask", + |_self: Val| { + let output: u32 = bevy::math::BVec4A::bitmask(_self.into_inner()) + .into(); + output + }, + ) + .register( + "any", + |_self: Val| { + let output: bool = bevy::math::BVec4A::any(_self.into_inner()) + .into(); + output + }, + ) + .register( + "all", + |_self: Val| { + let output: bool = bevy::math::BVec4A::all(_self.into_inner()) + .into(); + output + }, + ) + .register( + "test", + |_self: Ref, index: usize| { + let output: bool = bevy::math::BVec4A::test(&_self, index).into(); + output + }, + ) + .register( + "set", + |mut _self: Mut, index: usize, value: bool| { + let output: () = bevy::math::BVec4A::set(&mut _self, index, value) + .into(); + output + }, + ) + .register( + "eq", + |_self: Ref, rhs: Ref| { + let output: bool = >::eq(&_self, &rhs) + .into(); + output + }, + ); + NamespaceBuilder::<::smol_str::SmolStr>::new(world) + .register( + "to_string", + |_self: Ref| { + let output: std::string::String = smol_str::SmolStr::to_string( + &_self, + ) + .into(); + output + }, + ) + .register( + "len", + |_self: Ref| { + let output: usize = smol_str::SmolStr::len(&_self).into(); + output + }, + ) + .register( + "is_empty", + |_self: Ref| { + let output: bool = smol_str::SmolStr::is_empty(&_self).into(); + output + }, + ) + .register( + "is_heap_allocated", + |_self: Ref| { + let output: bool = smol_str::SmolStr::is_heap_allocated(&_self) + .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 + }, + ); + NamespaceBuilder::<::uuid::Uuid>::new(world) + .register( + "nil", + || { + let output: Val = uuid::Uuid::nil().into(); + output + }, + ) + .register( + "max", + || { + let output: Val = uuid::Uuid::max().into(); + output + }, + ) + .register( + "from_u128", + |v: u128| { + let output: Val = uuid::Uuid::from_u128(v).into(); + output + }, + ) + .register( + "from_u128_le", + |v: u128| { + let output: Val = uuid::Uuid::from_u128_le(v).into(); + output + }, + ) + .register( + "from_u64_pair", + |high_bits: u64, low_bits: u64| { + let output: Val = uuid::Uuid::from_u64_pair( + high_bits, + low_bits, + ) + .into(); + output + }, + ) + .register( + "from_bytes", + |bytes: [u8; 16]| { + let output: Val = uuid::Uuid::from_bytes(bytes).into(); + output + }, + ) + .register( + "from_bytes_le", + |b: [u8; 16]| { + let output: Val = uuid::Uuid::from_bytes_le(b).into(); + 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| { + let output: usize = uuid::Uuid::get_version_num(&_self).into(); + output + }, + ) + .register( + "as_u128", + |_self: Ref| { + let output: u128 = uuid::Uuid::as_u128(&_self).into(); + output + }, + ) + .register( + "to_u128_le", + |_self: Ref| { + let output: u128 = uuid::Uuid::to_u128_le(&_self).into(); + output + }, + ) + .register( + "as_u64_pair", + |_self: Ref| { + let output: (u64, u64) = uuid::Uuid::as_u64_pair(&_self).into(); + output + }, + ) + .register( + "into_bytes", + |_self: Val| { + let output: [u8; 16] = uuid::Uuid::into_bytes(_self.into_inner()) + .into(); + output + }, + ) + .register( + "to_bytes_le", + |_self: Ref| { + let output: [u8; 16] = uuid::Uuid::to_bytes_le(&_self).into(); + output + }, + ) + .register( + "is_nil", + |_self: Ref| { + let output: bool = uuid::Uuid::is_nil(&_self).into(); + output + }, + ) + .register( + "is_max", + |_self: Ref| { + let output: bool = uuid::Uuid::is_max(&_self).into(); + output + }, + ) + .register( + "encode_buffer", + || { + let output: [u8; 45] = uuid::Uuid::encode_buffer().into(); + output + }, + ) + .register( + "get_node_id", + |_self: Ref| { + let output: bevy::reflect::erased_serde::__private::serde::__private::Option< + [u8; 6], + > = uuid::Uuid::get_node_id(&_self).into(); + output + }, + ) + .register( + "eq", + |_self: Ref, other: Ref| { + let output: bool = >::eq(&_self, &other) + .into(); + output + }, + ) + .register( + "new_v4", + || { + let output: Val = uuid::Uuid::new_v4().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_time.rs b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_time.rs new file mode 100644 index 00000000..b3234e16 --- /dev/null +++ b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_time.rs @@ -0,0 +1,336 @@ +// @generated by cargo bevy-api-gen generate, modify the templates not this file +#![allow(clippy::all)] +#![allow(unused, deprecated, dead_code)] +#![cfg_attr(rustfmt, rustfmt_skip)] +use super::bevy_ecs::*; +use super::bevy_reflect::*; +use bevy_mod_scripting_core::{ + AddContextInitializer, StoreDocumentation, + bindings::{ReflectReference, function::from::{Ref, Mut, Val}}, +}; +use crate::*; +pub struct BevyTimeScriptingPlugin; +impl ::bevy::app::Plugin for BevyTimeScriptingPlugin { + fn build(&self, app: &mut ::bevy::prelude::App) { + let mut world = app.world_mut(); + NamespaceBuilder::<::bevy::time::prelude::Fixed>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::time::prelude::Real>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::time::prelude::Timer>::new(world) + .register( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .into(); + output + }, + ) + .register( + "from_seconds", + |duration: f32, mode: Val| { + let output: Val = bevy::time::prelude::Timer::from_seconds( + duration, + mode.into_inner(), + ) + .into(); + output + }, + ) + .register( + "finished", + |_self: Ref| { + let output: bool = bevy::time::prelude::Timer::finished(&_self) + .into(); + output + }, + ) + .register( + "just_finished", + |_self: Ref| { + let output: bool = bevy::time::prelude::Timer::just_finished(&_self) + .into(); + output + }, + ) + .register( + "elapsed_secs", + |_self: Ref| { + let output: f32 = bevy::time::prelude::Timer::elapsed_secs(&_self) + .into(); + output + }, + ) + .register( + "elapsed_secs_f64", + |_self: Ref| { + let output: f64 = bevy::time::prelude::Timer::elapsed_secs_f64( + &_self, + ) + .into(); + output + }, + ) + .register( + "mode", + |_self: Ref| { + let output: Val = bevy::time::prelude::Timer::mode( + &_self, + ) + .into(); + output + }, + ) + .register( + "set_mode", + | + mut _self: Mut, + mode: Val| + { + let output: () = bevy::time::prelude::Timer::set_mode( + &mut _self, + mode.into_inner(), + ) + .into(); + output + }, + ) + .register( + "pause", + |mut _self: Mut| { + let output: () = bevy::time::prelude::Timer::pause(&mut _self) + .into(); + output + }, + ) + .register( + "unpause", + |mut _self: Mut| { + let output: () = bevy::time::prelude::Timer::unpause(&mut _self) + .into(); + output + }, + ) + .register( + "paused", + |_self: Ref| { + let output: bool = bevy::time::prelude::Timer::paused(&_self).into(); + output + }, + ) + .register( + "reset", + |mut _self: Mut| { + let output: () = bevy::time::prelude::Timer::reset(&mut _self) + .into(); + output + }, + ) + .register( + "fraction", + |_self: Ref| { + let output: f32 = bevy::time::prelude::Timer::fraction(&_self) + .into(); + output + }, + ) + .register( + "fraction_remaining", + |_self: Ref| { + let output: f32 = bevy::time::prelude::Timer::fraction_remaining( + &_self, + ) + .into(); + output + }, + ) + .register( + "remaining_secs", + |_self: Ref| { + let output: f32 = bevy::time::prelude::Timer::remaining_secs(&_self) + .into(); + output + }, + ) + .register( + "times_finished_this_tick", + |_self: Ref| { + let output: u32 = bevy::time::prelude::Timer::times_finished_this_tick( + &_self, + ) + .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::time::prelude::TimerMode>::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( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::time::prelude::Virtual>::new(world) + .register( + "clone", + |_self: Ref| { + let output: Val = ::clone( + &_self, + ) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::time::Stopwatch>::new(world) + .register( + "assert_receiver_is_total_eq", + |_self: Ref| { + let output: () = ::assert_receiver_is_total_eq( + &_self, + ) + .into(); + output + }, + ) + .register( + "new", + || { + let output: Val = bevy::time::Stopwatch::new() + .into(); + output + }, + ) + .register( + "elapsed_secs", + |_self: Ref| { + let output: f32 = bevy::time::Stopwatch::elapsed_secs(&_self).into(); + output + }, + ) + .register( + "elapsed_secs_f64", + |_self: Ref| { + let output: f64 = bevy::time::Stopwatch::elapsed_secs_f64(&_self) + .into(); + output + }, + ) + .register( + "pause", + |mut _self: Mut| { + let output: () = bevy::time::Stopwatch::pause(&mut _self).into(); + output + }, + ) + .register( + "unpause", + |mut _self: Mut| { + let output: () = bevy::time::Stopwatch::unpause(&mut _self).into(); + output + }, + ) + .register( + "is_paused", + |_self: Ref| { + let output: bool = bevy::time::Stopwatch::is_paused(&_self).into(); + output + }, + ) + .register( + "reset", + |mut _self: Mut| { + let output: () = bevy::time::Stopwatch::reset(&mut _self).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 + }, + ); + } +} 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 new file mode 100644 index 00000000..5fc7357e --- /dev/null +++ b/crates/bevy_mod_scripting_functions/src/bevy_bindings/bevy_transform.rs @@ -0,0 +1,272 @@ +// @generated by cargo bevy-api-gen generate, modify the templates not this file +#![allow(clippy::all)] +#![allow(unused, deprecated, dead_code)] +#![cfg_attr(rustfmt, rustfmt_skip)] +use super::bevy_ecs::*; +use super::bevy_reflect::*; +use super::bevy_core::*; +use super::bevy_math::*; +use super::bevy_hierarchy::*; +use bevy_mod_scripting_core::{ + AddContextInitializer, StoreDocumentation, + bindings::{ReflectReference, function::from::{Ref, Mut, Val}}, +}; +use crate::*; +pub struct BevyTransformScriptingPlugin; +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| { + let output: Val = bevy::transform::components::GlobalTransform::from_xyz( + x, + y, + z, + ) + .into(); + output + }, + ) + .register( + "compute_transform", + |_self: Ref| { + let output: Val = bevy::transform::components::GlobalTransform::compute_transform( + &_self, + ) + .into(); + output + }, + ) + .register( + "reparented_to", + | + _self: Ref, + parent: Ref| + { + let output: Val = bevy::transform::components::GlobalTransform::reparented_to( + &_self, + &parent, + ) + .into(); + output + }, + ) + .register( + "mul_transform", + | + _self: Ref, + transform: Val| + { + let output: Val = bevy::transform::components::GlobalTransform::mul_transform( + &_self, + transform.into_inner(), + ) + .into(); + output + }, + ) + .register( + "mul", + | + _self: Val, + global_transform: Val| + { + let output: Val = >::mul(_self.into_inner(), global_transform.into_inner()) + .into(); + output + }, + ) + .register( + "mul", + | + _self: Val, + transform: Val| + { + let output: Val = >::mul(_self.into_inner(), transform.into_inner()) + .into(); + output + }, + ); + NamespaceBuilder::<::bevy::transform::components::Transform>::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( + "mul", + | + _self: Val, + global_transform: Val| + { + let output: Val = >::mul(_self.into_inner(), global_transform.into_inner()) + .into(); + output + }, + ) + .register( + "from_xyz", + |x: f32, y: f32, z: f32| { + let output: Val = bevy::transform::components::Transform::from_xyz( + x, + y, + z, + ) + .into(); + output + }, + ) + .register( + "rotate_x", + |mut _self: Mut, angle: f32| { + let output: () = bevy::transform::components::Transform::rotate_x( + &mut _self, + angle, + ) + .into(); + output + }, + ) + .register( + "rotate_y", + |mut _self: Mut, angle: f32| { + let output: () = bevy::transform::components::Transform::rotate_y( + &mut _self, + angle, + ) + .into(); + output + }, + ) + .register( + "rotate_z", + |mut _self: Mut, angle: f32| { + let output: () = bevy::transform::components::Transform::rotate_z( + &mut _self, + angle, + ) + .into(); + output + }, + ) + .register( + "rotate_local_x", + |mut _self: Mut, angle: f32| { + let output: () = bevy::transform::components::Transform::rotate_local_x( + &mut _self, + angle, + ) + .into(); + output + }, + ) + .register( + "rotate_local_y", + |mut _self: Mut, angle: f32| { + let output: () = bevy::transform::components::Transform::rotate_local_y( + &mut _self, + angle, + ) + .into(); + output + }, + ) + .register( + "rotate_local_z", + |mut _self: Mut, angle: f32| { + let output: () = bevy::transform::components::Transform::rotate_local_z( + &mut _self, + angle, + ) + .into(); + output + }, + ) + .register( + "mul_transform", + | + _self: Ref, + transform: Val| + { + let output: Val = bevy::transform::components::Transform::mul_transform( + &_self, + transform.into_inner(), + ) + .into(); + output + }, + ) + .register( + "is_finite", + |_self: Ref| { + let output: bool = bevy::transform::components::Transform::is_finite( + &_self, + ) + .into(); + output + }, + ) + .register( + "mul", + | + _self: Val, + transform: Val| + { + let output: Val = >::mul(_self.into_inner(), transform.into_inner()) + .into(); + output + }, + ); + } +} diff --git a/crates/bevy_mod_scripting_functions/src/bevy_bindings/mod.rs b/crates/bevy_mod_scripting_functions/src/bevy_bindings/mod.rs new file mode 100644 index 00000000..7aa09772 --- /dev/null +++ b/crates/bevy_mod_scripting_functions/src/bevy_bindings/mod.rs @@ -0,0 +1,25 @@ +// @generated by cargo bevy-api-gen collect, modify the templates not this file +#![allow(clippy::all)] +#![allow(unused, deprecated, dead_code)] +#![cfg_attr(rustfmt, rustfmt_skip)] +pub mod bevy_reflect; +pub mod bevy_math; +pub mod bevy_input; +pub mod bevy_transform; +pub mod bevy_core; +pub mod bevy_hierarchy; +pub mod bevy_ecs; +pub mod bevy_time; +pub struct LuaBevyScriptingPlugin; +impl ::bevy::app::Plugin for LuaBevyScriptingPlugin { + fn build(&self, app: &mut ::bevy::prelude::App) { + bevy_reflect::BevyReflectScriptingPlugin.build(app); + bevy_math::BevyMathScriptingPlugin.build(app); + bevy_input::BevyInputScriptingPlugin.build(app); + bevy_transform::BevyTransformScriptingPlugin.build(app); + bevy_core::BevyCoreScriptingPlugin.build(app); + bevy_hierarchy::BevyHierarchyScriptingPlugin.build(app); + bevy_ecs::BevyEcsScriptingPlugin.build(app); + bevy_time::BevyTimeScriptingPlugin.build(app); + } +} diff --git a/crates/bevy_mod_scripting_functions/src/core.rs b/crates/bevy_mod_scripting_functions/src/core.rs new file mode 100644 index 00000000..15b160cb --- /dev/null +++ b/crates/bevy_mod_scripting_functions/src/core.rs @@ -0,0 +1,430 @@ +//! Contains functions defined by the [`bevy_mod_scripting_core`] crate + +use crate::NamespaceBuilder; +use bevy::{ + prelude::*, + reflect::{func::FunctionRegistrationError, ParsedPath}, +}; +use bevy_mod_scripting_core::*; +use bindings::{ + access_map::ReflectAccessId, + function::{ + from::{Ref, Val}, + from_ref::FromScriptRef, + into_ref::IntoScriptRef, + script_function::{CallerContext, ScriptFunctionMut}, + }, + pretty_print::DisplayWithWorld, + script_value::ScriptValue, + ReflectReference, ReflectionPathExt, ScriptQueryBuilder, ScriptQueryResult, + ScriptTypeRegistration, WorldCallbackAccess, +}; +use error::InteropError; +use reflection_extensions::{PartialReflectExt, TypeIdExtensions}; + +pub fn register_bevy_bindings(app: &mut App) { + #[cfg(feature = "bevy_bindings")] + app.add_plugins(crate::bevy_bindings::LuaBevyScriptingPlugin); +} + +pub fn register_world_functions(reg: &mut World) -> Result<(), FunctionRegistrationError> { + NamespaceBuilder::::new_unregistered(reg) + .register( + "get_type_by_name", + |world: WorldCallbackAccess, type_name: String| { + let val = world.get_type_by_name(type_name)?; + Ok(val.map(Val)) + }, + ) + .register( + "get_component", + |world: WorldCallbackAccess, + entity: Val, + registration: Val| { + registration + .component_id() + .and_then(|id| world.get_component(*entity, id).transpose()) + .transpose() + }, + ) + .register( + "has_component", + |s: WorldCallbackAccess, + entity: Val, + registration: Val| { + match registration.component_id() { + Some(id) => s.has_component(*entity, id), + None => Ok(false), + } + }, + ) + .register( + "remove_component", + |s: WorldCallbackAccess, e: Val, r: Val| { + s.remove_component(*e, r.clone()) + }, + ) + .register( + "get_resource", + |world: WorldCallbackAccess, registration: Val| { + match registration.resource_id() { + Some(id) => Ok(world.get_resource(id)?), + None => Ok(None), + } + }, + ) + .register( + "has_resource", + |s: WorldCallbackAccess, registration: Val| match registration + .resource_id() + { + Some(id) => s.has_resource(id), + None => Ok(false), + }, + ) + .register( + "remove_resource", + |s: WorldCallbackAccess, r: Val| s.remove_resource(r.clone()), + ) + .register( + "add_default_component", + |w: WorldCallbackAccess, e: Val, r: Val| { + w.add_default_component(*e, r.clone()) + }, + ) + .register("spawn", |s: WorldCallbackAccess| Ok(Val(s.spawn()?))) + .register( + "insert_children", + |caller_context: CallerContext, + w: WorldCallbackAccess, + e: Val, + index: usize, + c: Vec>| { + let index = if caller_context.convert_to_0_indexed { + index - 1 + } else { + index + }; + w.insert_children(*e, index, &c.into_iter().map(|v| *v).collect::>()) + }, + ) + .register( + "push_children", + |w: WorldCallbackAccess, e: Val, c: Vec>| { + w.push_children(*e, &c.into_iter().map(|v| *v).collect::>()) + }, + ) + .register("get_children", |w: WorldCallbackAccess, e: Val| { + let children = w.get_children(*e)?; + Ok(children.into_iter().map(Val).collect::>()) + }) + .register("get_parent", |w: WorldCallbackAccess, e: Val| { + let parent = w.get_parent(*e)?; + Ok(parent.map(Val)) + }) + .register("despawn", |s: WorldCallbackAccess, e: Val| { + s.despawn(*e) + }) + .register( + "despawn_descendants", + |s: WorldCallbackAccess, e: Val| s.despawn_descendants(*e), + ) + .register( + "despawn_recursive", + |s: WorldCallbackAccess, e: Val| s.despawn_recursive(*e), + ) + .register("has_entity", |s: WorldCallbackAccess, e: Val| { + s.has_entity(*e) + }) + .register("query", || { + let query_builder = ScriptQueryBuilder::default(); + Ok(Val(query_builder)) + }) + .register("exit", |s: WorldCallbackAccess| s.exit()) + .register("log_all_allocations", |s: WorldCallbackAccess| { + let world = s.try_read().expect("stale world"); + let allocator = world.allocator(); + let allocator = allocator.read(); + for (id, _) in allocator.iter_allocations() { + let raid = ReflectAccessId::for_allocation(id.clone()); + if world.claim_read_access(raid) { + // Safety: ref released above + unsafe { world.release_access(raid) }; + } else { + panic!("Failed to claim read access for allocation id: {}", id.id()); + } + } + }); + Ok(()) +} + +pub fn register_reflect_reference_functions( + reg: &mut World, +) -> Result<(), FunctionRegistrationError> { + NamespaceBuilder::::new(reg) + .register( + "display_ref", + |w: WorldCallbackAccess, s: ReflectReference| { + let world = w.try_read().expect("Stale world"); + s.display_with_world(world) + }, + ) + .register("display_value", |w: WorldCallbackAccess, s: ReflectReference| { + let world = w.try_read().expect("Stale world"); + s.display_value_with_world(world) + }) + .register( + "get", + |caller_context: CallerContext, + world: WorldCallbackAccess, + mut self_: ReflectReference, + key: ScriptValue| { + let mut path: ParsedPath = key.try_into()?; + if caller_context.convert_to_0_indexed { + path.convert_to_0_indexed(); + } + self_.index_path(path); + let world = world.try_read().expect("Stale world"); + ReflectReference::into_script_ref(self_, world) + }, + ) + .register( + "set", + |caller_context: CallerContext, + world: WorldCallbackAccess, + self_: ScriptValue, + key: ScriptValue, + value: ScriptValue| { + if let ScriptValue::Reference(mut self_) = self_ { + let world = world.try_read().expect("stale world"); + let mut path: ParsedPath = key.try_into().unwrap(); + if caller_context.convert_to_0_indexed { + path.convert_to_0_indexed(); + } + self_.index_path(path); + let r: ScriptValue = self_ + .with_reflect_mut(world.clone(), |r| { + let target_type_id = r + .get_represented_type_info() + .map(|i| i.type_id()) + .or_fake_id(); + let other = >::from_script_ref( + target_type_id, + value, + world.clone(), + )?; + r.try_apply(other.as_partial_reflect()).unwrap(); + Ok::<_, InteropError>(()) + }) + .into(); + return r; + } + ScriptValue::Unit + }, + ) + .register( + "push", + |w: WorldCallbackAccess, s: ReflectReference, v: ScriptValue| { + let world = w.try_read().expect("stale world"); + let target_type_id = s.element_type_id(world.clone())?.ok_or_else(|| { + InteropError::unsupported_operation( + s.tail_type_id(world.clone()).unwrap_or_default(), + Some(Box::new(v.clone())), + "Could not get element type id. Are you trying to insert elements into a type that's not a list?".to_owned(), + ) + })?; + let other = >::from_script_ref(target_type_id, v, world.clone())?; + s.with_reflect_mut(world, |s| s.try_push_boxed(other))? + }, + ) + .register("pop", |w: WorldCallbackAccess, s: ReflectReference| { + let world = w.try_read().expect("stale world"); + let o = s.with_reflect_mut(world.clone(), |s| s.try_pop_boxed())??; + let reference = { + let allocator = world.allocator(); + let mut allocator = allocator.write(); + ReflectReference::new_allocated_boxed(o, &mut allocator) + }; + + ReflectReference::into_script_ref(reference, world) + }) + .register("insert", |caller_context: CallerContext, w: WorldCallbackAccess, s: ReflectReference, k: ScriptValue, v: ScriptValue| { + let world = w.try_read().expect("stale world"); + let key_type_id = s.key_type_id(world.clone())?.ok_or_else(|| { + InteropError::unsupported_operation( + s.tail_type_id(world.clone()).unwrap_or_default(), + Some(Box::new(k.clone())), + "Could not get key type id. Are you trying to insert elements into a type that's not a map?".to_owned(), + ) + })?; + + let mut key = >::from_script_ref(key_type_id, k, world.clone())?; + + if caller_context.convert_to_0_indexed { + key.convert_to_0_indexed_key(); + } + + let value_type_id = s.element_type_id(world.clone())?.ok_or_else(|| { + InteropError::unsupported_operation( + s.tail_type_id(world.clone()).unwrap_or_default(), + Some(Box::new(v.clone())), + "Could not get element type id. Are you trying to insert elements into a type that's not a map?".to_owned(), + ) + })?; + + let value = >::from_script_ref(value_type_id, v, world.clone())?; + + s.with_reflect_mut(world, |s| s.try_insert_boxed(key, value))? + }) + .register("clear", |w: WorldCallbackAccess, s: ReflectReference| { + let world = w.try_read().expect("stale world"); + s.with_reflect_mut(world, |s| s.try_clear())? + }) + .register("len", |w: WorldCallbackAccess, s: ReflectReference| { + let world = w.try_read().expect("stale world"); + s.len(world) + }) + .register("remove", |caller_context: CallerContext, w: WorldCallbackAccess, s: ReflectReference, k: ScriptValue| { + let world = w.try_read().expect("stale world"); + let key_type_id = s.key_type_id(world.clone())?.ok_or_else(|| { + InteropError::unsupported_operation( + s.tail_type_id(world.clone()).unwrap_or_default(), + Some(Box::new(k.clone())), + "Could not get key type id. Are you trying to remove elements from a type that's not a map?".to_owned(), + ) + })?; + + let mut key = >::from_script_ref(key_type_id, k, world.clone())?; + + if caller_context.convert_to_0_indexed { + key.convert_to_0_indexed_key(); + } + + let removed = s.with_reflect_mut(world.clone(), |s| s.try_remove_boxed(key))??; + + removed.map(|some| { + let reference = { + let allocator = world.allocator(); + let mut allocator = allocator.write(); + ReflectReference::new_allocated_boxed(some, &mut allocator) + }; + ReflectReference::into_script_ref(reference, world) + }).transpose() + }) + .register("iter", |w: WorldCallbackAccess, s: ReflectReference| { + let world = w.try_read().expect("stale world"); + let mut len = s.len(world.clone())?.unwrap_or_default(); + let mut infinite_iter = s.into_iter_infinite(); + let iter_function = move || { + if len == 0 { + return Ok(ScriptValue::Unit); + } + + let (next_ref, _) = infinite_iter.next_ref(); + + let converted = ReflectReference::into_script_ref(next_ref, world.clone()); + // println!("idx: {idx:?}, converted: {converted:?}"); + len -= 1; + // we stop once the reflection path is invalid + converted + }; + + Ok(iter_function.into_dynamic_script_function_mut()) + }); + + Ok(()) +} + +pub fn register_script_type_registration_functions( + registry: &mut World, +) -> Result<(), FunctionRegistrationError> { + NamespaceBuilder::::new(registry) + .register("type_name", |s: Ref| s.type_name()) + .register("short_name", |s: Ref| { + s.short_name() + }) + .register("is_resource", |s: Ref| { + s.resource_id().is_some() + }) + .register("is_component", |s: Ref| { + s.component_id().is_some() + }); + Ok(()) +} + +pub fn register_script_query_builder_functions( + registry: &mut World, +) -> Result<(), FunctionRegistrationError> { + NamespaceBuilder::::new(registry) + .register( + "component", + |s: Val, components: Val| { + let mut builder = s.into_inner(); + builder.component(components.into_inner()); + Val(builder) + }, + ) + .register( + "with", + |s: Val, with: Val| { + let mut builder = s.into_inner(); + builder.with_component(with.into_inner()); + Val(builder) + }, + ) + .register( + "without", + |s: Val, without: Val| { + let mut builder = s.into_inner(); + builder.without_component(without.into_inner()); + Val(builder) + }, + ) + .register( + "build", + |world: WorldCallbackAccess, s: Val| { + let builder = s.into_inner(); + let result = world.query(builder)?; + let result = result.into_iter().map(Val).collect::>(); + Ok(result) + }, + ); + Ok(()) +} + +pub fn register_script_query_result_functions( + world: &mut World, +) -> Result<(), FunctionRegistrationError> { + NamespaceBuilder::::new(world) + .register("entity", |s: Ref| Val::new(s.entity)) + .register("components", |s: Ref| { + s.components.to_vec() + }); + Ok(()) +} + +pub fn register_core_functions(app: &mut App) { + let world = app.world_mut(); + // we don't exclude from compilation here, + // since these are much smaller and still useful if not included initially + // perhaps people might want to include some but not all of these + + #[cfg(feature = "core_functions")] + register_world_functions(world).expect("Failed to register world functions"); + + #[cfg(feature = "core_functions")] + register_reflect_reference_functions(world) + .expect("Failed to register reflect reference functions"); + + #[cfg(feature = "core_functions")] + register_script_type_registration_functions(world) + .expect("Failed to register script type registration functions"); + + #[cfg(feature = "core_functions")] + register_script_query_builder_functions(world) + .expect("Failed to register script query builder functions"); + + #[cfg(feature = "core_functions")] + register_script_query_result_functions(world) + .expect("Failed to register script query result functions"); +} diff --git a/crates/bevy_mod_scripting_functions/src/lib.rs b/crates/bevy_mod_scripting_functions/src/lib.rs new file mode 100644 index 00000000..3a446b9e --- /dev/null +++ b/crates/bevy_mod_scripting_functions/src/lib.rs @@ -0,0 +1,18 @@ +use ::bevy::prelude::*; +#[cfg(feature = "bevy_bindings")] +pub mod bevy_bindings; +pub mod core; + +pub mod namespaced_register; + +pub use core::*; +pub use namespaced_register::*; + +pub struct ScriptFunctionsPlugin; + +impl Plugin for ScriptFunctionsPlugin { + fn build(&self, app: &mut App) { + register_bevy_bindings(app); + register_core_functions(app); + } +} diff --git a/crates/bevy_mod_scripting_functions/src/namespaced_register.rs b/crates/bevy_mod_scripting_functions/src/namespaced_register.rs new file mode 100644 index 00000000..6a8ee669 --- /dev/null +++ b/crates/bevy_mod_scripting_functions/src/namespaced_register.rs @@ -0,0 +1,192 @@ +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 { + fn register_namespaced_function(&mut self, name: N, function: F) + where + N: Into>, + S: IntoNamespace, + F: ScriptFunction<'static, M>; +} + +pub trait GetNamespacedFunction { + fn iter_overloads_namespaced( + &self, + name: N, + namespace: Namespace, + ) -> impl Iterator + where + N: Into>; + fn get_namespaced_function( + &self, + name: N, + namespace: Namespace, + ) -> Option<&DynamicScriptFunction> + where + N: Into>; + + fn get_namespaced_function_typed(&self, name: N) -> Option<&DynamicScriptFunction> + where + N: Into>, + NS: IntoNamespace, + { + Self::get_namespaced_function(self, name, NS::into_namespace()) + } + + fn has_namespaced_function(&self, name: N, namespace: Namespace) -> bool + where + N: Into>; + + fn has_namespaced_function_typed(&self, name: N) -> bool + where + N: Into>, + NS: IntoNamespace, + { + Self::has_namespaced_function(self, name, NS::into_namespace()) + } +} + +pub enum Namespace { + /// The function is registered in the global namespace, i.e. with no namespace + Global, + /// The function is registered in the namespace corresponding to the given type + OnType(TypeId), +} + +pub trait IntoNamespace { + fn into_namespace() -> Namespace; +} + +impl IntoNamespace for T { + fn into_namespace() -> Namespace { + Namespace::OnType(TypeId::of::()) + } +} + +impl Namespace { + pub fn prefix(self) -> Cow<'static, str> { + match self { + Namespace::Global => Cow::Borrowed(""), + Namespace::OnType(type_id) => Cow::Owned(format!("{:?}::", type_id)), + } + } + + /// Returns the fully qualified name of a function in this namespace + pub fn function_name(self, name: Cow<'static, str>) -> Cow<'static, str> { + match self { + Namespace::Global => name, + Namespace::OnType(type_id) => Cow::Owned(format!("{:?}::{}", type_id, name)), + } + } +} + +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) + } +} + +pub struct NamespaceBuilder<'a, N> { + namespace: PhantomData, + pub world: &'a mut World, +} + +impl<'a, S: IntoNamespace> NamespaceBuilder<'a, S> { + /// Creates a new `NamespaceBuilder` that will register functions in the namespace corresponding to the given type + /// It will also register the type itself in the type registry. + pub fn new(world: &'a mut World) -> Self + where + S: GetTypeRegistration, + { + { + let registry = world.get_resource_or_init::(); + let mut registry = registry.write(); + registry.register::(); + } + Self { + namespace: Default::default(), + world, + } + } + + /// Prefer using the `register` method on the `NamespaceBuilder` instead + pub fn new_unregistered(world: &'a mut World) -> Self { + Self { + namespace: Default::default(), + world, + } + } + + pub fn register(&mut self, name: N, function: F) -> &mut Self + where + N: Into>, + F: ScriptFunction<'static, M> + GetFunctionTypeDependencies, + { + { + { + let mut registry = self + .world + .get_resource_or_init::(); + let mut registry = registry.write(); + registry.register_namespaced_function::(name, function); + } + { + let type_registry = self.world.get_resource_or_init::(); + let mut type_registry = type_registry.write(); + F::register_type_dependencies(&mut type_registry); + } + } + self + } +} diff --git a/crates/bevy_script_api/CHANGELOG.md b/crates/bevy_script_api/CHANGELOG.md deleted file mode 100644 index c5726fa0..00000000 --- a/crates/bevy_script_api/CHANGELOG.md +++ /dev/null @@ -1,31 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -## [0.8.0-alpha.2](https://github.com/makspll/bevy_mod_scripting/compare/bevy_script_api-v0.8.0-alpha.1...bevy_script_api-v0.8.0-alpha.2) - 2024-12-03 - -### Other - -- Small fixes ([#155](https://github.com/makspll/bevy_mod_scripting/pull/155)) -- Luau support attempt ([#154](https://github.com/makspll/bevy_mod_scripting/pull/154)) -- Bump bevy & bevy console ([#153](https://github.com/makspll/bevy_mod_scripting/pull/153)) - -## [0.8.0-alpha.1](https://github.com/makspll/bevy_mod_scripting/compare/bevy_script_api-v0.8.0-alpha.0...bevy_script_api-v0.8.0-alpha.1) - 2024-11-10 - -### Other - -- Bump Bevy release candidate ([#143](https://github.com/makspll/bevy_mod_scripting/pull/143)) - -## [0.7.0](https://github.com/makspll/bevy_mod_scripting/compare/bevy_script_api-v0.6.0...bevy_script_api-v0.7.0) - 2024-11-03 - -### Other - -- Migrate to bevy 0.14 ([#127](https://github.com/makspll/bevy_mod_scripting/pull/127)) -- Dynamic Queries ([#118](https://github.com/makspll/bevy_mod_scripting/pull/118)) -- Make generated wrappers publically accessible ([#114](https://github.com/makspll/bevy_mod_scripting/pull/114)) -- update metadata diff --git a/crates/bevy_script_api/Cargo.toml b/crates/bevy_script_api/Cargo.toml deleted file mode 100644 index 63cea796..00000000 --- a/crates/bevy_script_api/Cargo.toml +++ /dev/null @@ -1,41 +0,0 @@ -[package] -name = "bevy_script_api" -version = "0.8.0" -authors = ["Maksymilian Mozolewski "] -edition = "2021" -license = "MIT OR Apache-2.0" -description = "Bevy API for multiple script languages, part of bevy_mod_scripting." -repository = "https://github.com/makspll/bevy_mod_scripting" -homepage = "https://github.com/makspll/bevy_mod_scripting" -keywords = ["bevy", "gamedev", "scripting", "lua", "rhai"] -categories = ["game-development"] -readme = "readme.md" - -[features] -lua = ["bevy_mod_scripting_lua", "bevy_mod_scripting_lua_derive"] -rhai = ["bevy_mod_scripting_rhai"] - -[dependencies] -bevy = { workspace = true, default-features = false, features = [ - "bevy_asset", - "bevy_animation", - "bevy_core_pipeline", - "bevy_ui", - "bevy_pbr", - "bevy_render", - "bevy_text", - "bevy_sprite", - "file_watcher", - "multi_threaded", -] } -uuid = "1.10" -bevy_mod_scripting_core = { workspace = true } -parking_lot = "0.12.1" -paste = "1.0.7" -thiserror = "1.0.32" -# lua -bevy_mod_scripting_lua = { path = "../languages/bevy_mod_scripting_lua", version = "0.8.0", optional = true } -bevy_mod_scripting_lua_derive = { path = "../languages/bevy_mod_scripting_lua_derive", version = "0.8.0", optional = true } -bevy_mod_scripting_rhai = { path = "../languages/bevy_mod_scripting_rhai", version = "0.8.0", optional = true } -smol_str = "0.2" -allocator-api2 = "0.2" diff --git a/crates/bevy_script_api/readme.md b/crates/bevy_script_api/readme.md deleted file mode 100644 index 2a766e09..00000000 --- a/crates/bevy_script_api/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -# bevy_script_api - -This crate is a part of the ["bevy_mod_scripting" workspace](https://github.com/makspll/bevy_mod_scripting). \ No newline at end of file diff --git a/crates/bevy_script_api/src/common/bevy/mod.rs b/crates/bevy_script_api/src/common/bevy/mod.rs deleted file mode 100644 index 6df4b72e..00000000 --- a/crates/bevy_script_api/src/common/bevy/mod.rs +++ /dev/null @@ -1,443 +0,0 @@ -use crate::ReflectReference; -/// Common functionality for all script hosts -use bevy::{ - ecs::{ - component::ComponentId, - query::QueryBuilder, - world::{Command, EntityRef, World}, - }, - prelude::{ - AppTypeRegistry, BuildChildren, Children, DespawnChildrenRecursive, DespawnRecursive, - Entity, Parent, ReflectComponent, ReflectDefault, ReflectResource, - }, - reflect::{ - DynamicArray, DynamicEnum, DynamicList, DynamicMap, DynamicSet, DynamicStruct, - DynamicTuple, DynamicTupleStruct, TypeRegistration, - }, -}; -use bevy_mod_scripting_core::{prelude::ScriptError, world::WorldPointer}; -use parking_lot::MappedRwLockWriteGuard; -use std::{ - any::Any, - ops::{Deref, DerefMut}, - sync::Arc, -}; - -/// Helper trait for retrieving a world pointer from a script context. -pub trait GetWorld { - type Error; - fn get_world(&self) -> Result; -} - -#[derive(Clone)] -pub struct ScriptTypeRegistration(pub(crate) Arc); - -impl ScriptTypeRegistration { - pub fn new(arc: Arc) -> Self { - Self(arc) - } - - #[inline(always)] - pub fn short_name(&self) -> &str { - self.0.type_info().type_path_table().short_path() - } - - #[inline(always)] - pub fn type_name(&self) -> &'static str { - self.0.type_info().type_path_table().path() - } -} - -impl std::fmt::Debug for ScriptTypeRegistration { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("ScriptTypeRegistration") - .field(&self.0.type_info().type_path()) - .finish() - } -} - -impl std::fmt::Display for ScriptTypeRegistration { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(self.0.type_info().type_path()) - } -} - -impl Deref for ScriptTypeRegistration { - type Target = TypeRegistration; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -#[derive(Clone)] -pub struct ScriptQueryBuilder { - world: ScriptWorld, - components: Vec, - with: Vec, - without: Vec, -} - -impl ScriptQueryBuilder { - pub fn new(world: ScriptWorld) -> Self { - Self { - world, - components: vec![], - with: vec![], - without: vec![], - } - } - - pub fn components(&mut self, components: Vec) -> &mut Self { - self.components.extend(components); - self - } - - pub fn with(&mut self, with: Vec) -> &mut Self { - self.with.extend(with); - self - } - - pub fn without(&mut self, without: Vec) -> &mut Self { - self.without.extend(without); - self - } - - pub fn build(&mut self) -> Result, ScriptError> { - self.world.query( - std::mem::take(&mut self.components), - std::mem::take(&mut self.with), - std::mem::take(&mut self.without), - ) - } -} - -#[derive(Clone)] -pub struct ScriptQueryResult(pub Entity, pub Vec); - -#[derive(Clone, Debug)] -pub struct ScriptWorld(WorldPointer); - -impl std::fmt::Display for ScriptWorld { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str("World") - } -} - -impl Deref for ScriptWorld { - type Target = WorldPointer; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for ScriptWorld { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl AsRef for ScriptWorld { - fn as_ref(&self) -> &WorldPointer { - &self.0 - } -} - -impl From for WorldPointer { - fn from(val: ScriptWorld) -> Self { - val.0 - } -} - -impl ScriptWorld { - pub fn new(ptr: WorldPointer) -> Self { - Self(ptr) - } - - pub fn get_children(&self, parent: Entity) -> Vec { - let w = self.read(); - w.get::(parent) - .map(|v| v.to_vec()) - .unwrap_or_default() - } - - pub fn get_parent(&self, entity: Entity) -> Option { - let w = self.read(); - w.get::(entity).map(|parent| parent.get()) - } - - pub fn push_child(&self, parent: Entity, child: Entity) { - let mut w = self.write(); - if let Ok(mut entity) = w.get_entity_mut(parent) { - entity.add_children(&[child]); - } - } - - pub fn remove_children(&self, parent: Entity, children: &[Entity]) { - let mut w = self.write(); - - if let Ok(mut entity) = w.get_entity_mut(parent) { - entity.remove_children(children); - } - } - - pub fn insert_children(&self, parent: Entity, index: usize, children: &[Entity]) { - let mut w = self.write(); - - if let Ok(mut entity) = w.get_entity_mut(parent) { - entity.insert_children(index, children); - } - } - - pub fn despawn_children_recursive(&self, entity: Entity) { - let mut w = self.write(); - DespawnChildrenRecursive { entity, warn: true }.apply(&mut w); - } - - pub fn despawn_recursive(&self, entity: Entity) { - let mut w = self.write(); - DespawnRecursive { entity, warn: true }.apply(&mut w); - } - - pub fn get_type_by_name(&self, type_name: &str) -> Option { - let w = self.read(); - - let registry: &AppTypeRegistry = w.get_resource().unwrap(); - - let registry = registry.read(); - - registry - .get_with_short_type_path(type_name) - .or_else(|| registry.get_with_type_path(type_name)) - .map(|registration| ScriptTypeRegistration::new(Arc::new(registration.clone()))) - } - - pub fn add_default_component( - &self, - entity: Entity, - comp_type: ScriptTypeRegistration, - ) -> Result { - let mut w = self.write(); - - // Remove: AppTypeRegistry - let registry: AppTypeRegistry = w.remove_resource().unwrap(); - - let mut entity_ref = w - .get_entity_mut(entity) - .map_err(|e| ScriptError::Other(format!("Entity is not valid {:#?}. {e}", entity)))?; - - let component_data = comp_type.data::().ok_or_else(|| { - ScriptError::Other(format!("Not a component {}", comp_type.short_name())) - })?; - - let registry_lock = registry.read(); - - // this is just a formality - // TODO: maybe get an add_default impl added to ReflectComponent - // this means that we don't require ReflectDefault for adding components! - match comp_type.0.type_info(){ - bevy::reflect::TypeInfo::Struct(_) => component_data.insert(&mut entity_ref, &DynamicStruct::default(), ®istry_lock), - bevy::reflect::TypeInfo::TupleStruct(_) => component_data.insert(&mut entity_ref, &DynamicTupleStruct::default(), ®istry_lock), - bevy::reflect::TypeInfo::Tuple(_) => component_data.insert(&mut entity_ref, &DynamicTuple::default(), ®istry_lock), - bevy::reflect::TypeInfo::List(_) => component_data.insert(&mut entity_ref, &DynamicList::default(), ®istry_lock), - bevy::reflect::TypeInfo::Array(_) => component_data.insert(&mut entity_ref, &DynamicArray::new(Box::new([])), ®istry_lock), - bevy::reflect::TypeInfo::Map(_) => component_data.insert(&mut entity_ref, &DynamicMap::default(), ®istry_lock), - bevy::reflect::TypeInfo::Set(_) => component_data.insert(&mut entity_ref, &DynamicSet::default(), ®istry_lock), - bevy::reflect::TypeInfo::Opaque(_) => component_data.insert(&mut entity_ref, - comp_type.data::().ok_or_else(|| - ScriptError::Other(format!("Component {} is a value or dynamic type with no `ReflectDefault` type_data, cannot instantiate sensible value",comp_type.short_name())))? - .default() - .as_partial_reflect(), - ®istry_lock), - bevy::reflect::TypeInfo::Enum(_) => component_data.insert(&mut entity_ref, &DynamicEnum::default(), ®istry_lock), - }; - // if we do not drop the lock here, line below will complain registry is still borrowed at drop - drop(registry_lock); - - // Insert: AppTypeRegistry - w.insert_resource(registry); - - Ok(ReflectReference::new_component_ref( - component_data.clone(), - entity, - self.clone().into(), - )) - } - - pub fn get_component( - &self, - entity: Entity, - comp_type: ScriptTypeRegistration, - ) -> Result, ScriptError> { - let w = self.read(); - - let entity_ref = w - .get_entity(entity) - .map_err(|e| ScriptError::Other(format!("Entity is not valid {:#?}. {e}", entity)))?; - - let component_data = comp_type.data::().ok_or_else(|| { - ScriptError::Other(format!("Not a component {}", comp_type.short_name())) - })?; - - Ok(component_data.reflect(entity_ref).map(|_component| { - ReflectReference::new_component_ref(component_data.clone(), entity, self.clone().into()) - })) - } - - pub fn has_component( - &self, - entity: Entity, - comp_type: ScriptTypeRegistration, - ) -> Result { - let w = self.read(); - let component_data = comp_type.data::().ok_or_else(|| { - ScriptError::Other(format!("Not a component {}", comp_type.short_name())) - })?; - - let entity_ref = w - .get_entity(entity) - .map_err(|e| ScriptError::Other(format!("Entity is not valid {:#?}. {e}", entity)))?; - - Ok(component_data.reflect(entity_ref).is_some()) - } - - pub fn remove_component( - &mut self, - entity: Entity, - comp_type: ScriptTypeRegistration, - ) -> Result<(), ScriptError> { - let mut w = self.write(); - - let mut entity_ref = w - .get_entity_mut(entity) - .map_err(|e| ScriptError::Other(format!("Entity is not valid {:#?}. {e}", entity)))?; - - let component_data = comp_type.data::().ok_or_else(|| { - ScriptError::Other(format!("Not a component {}", comp_type.short_name())) - })?; - component_data.remove(&mut entity_ref); - Ok(()) - } - - pub fn get_resource( - &self, - res_type: ScriptTypeRegistration, - ) -> Result, ScriptError> { - let w = self.read(); - - let resource_data = res_type.data::().ok_or_else(|| { - ScriptError::Other(format!("Not a resource {}", res_type.short_name())) - })?; - - Ok(resource_data.reflect(&w).map(|_res| { - ReflectReference::new_resource_ref(resource_data.clone(), self.clone().into()) - })) - } - - pub fn has_resource(&self, res_type: ScriptTypeRegistration) -> Result { - let w = self.read(); - - let resource_data = res_type.data::().ok_or_else(|| { - ScriptError::Other(format!("Not a resource {}", res_type.short_name())) - })?; - - Ok(resource_data.reflect(&w).is_some()) - } - - pub fn remove_resource(&mut self, res_type: ScriptTypeRegistration) -> Result<(), ScriptError> { - let mut w = self.write(); - - let resource_data = res_type.data::().ok_or_else(|| { - ScriptError::Other(format!("Not a resource {}", res_type.short_name())) - })?; - resource_data.remove(&mut w); - Ok(()) - } - - pub fn query( - &mut self, - components: Vec, - with: Vec, - without: Vec, - ) -> Result, ScriptError> { - let mut w = self.write(); - - let get_id = |component: &ScriptTypeRegistration, - w: &MappedRwLockWriteGuard| - -> Result { - w.components() - .get_id(component.type_info().type_id()) - .ok_or_else(|| { - ScriptError::Other(format!("Not a component {}", component.short_name())) - }) - }; - - let components: Vec<(ReflectComponent, ComponentId)> = components - .into_iter() - .map(|component| { - let reflect_component = component.data::().ok_or_else(|| { - ScriptError::Other(format!("Not a component {}", component.short_name())) - }); - - let component_id = get_id(&component, &w); - reflect_component.map(|v1| component_id.map(|v2| (v1.clone(), v2)))? - }) - .collect::, ScriptError>>()?; - - let with_ids: Vec = with - .iter() - .map(|component| get_id(component, &w)) - .collect::, ScriptError>>()?; - - let without_ids: Vec = without - .iter() - .map(|component| get_id(component, &w)) - .collect::, ScriptError>>()?; - - let mut q = QueryBuilder::::new(&mut w); - - for (_, id) in &components { - q.ref_id(*id); - } - - for with_id in with_ids { - q.with_id(with_id); - } - - for without_id in without_ids { - q.without_id(without_id); - } - - let query_result: Vec> = q.build().iter_mut(&mut w).collect(); - - query_result - .into_iter() - .map(|filtered_entity| { - components - .clone() - .into_iter() - .map(|(reflect_component, _)| { - let type_id = reflect_component.type_id(); - reflect_component - .reflect(filtered_entity) - .map(|_component| { - ReflectReference::new_component_ref( - reflect_component, - filtered_entity.id(), - self.clone().into(), - ) - }) - .ok_or_else(|| { - ScriptError::Other(format!( - "Failed to reflect component during query: {:?}", - type_id - )) - }) - }) - .collect::, ScriptError>>() - .map(|references| ScriptQueryResult(filtered_entity.id(), references)) - }) - .collect::, ScriptError>>() - } -} diff --git a/crates/bevy_script_api/src/common/mod.rs b/crates/bevy_script_api/src/common/mod.rs deleted file mode 100644 index 70b747d3..00000000 --- a/crates/bevy_script_api/src/common/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod bevy; -pub mod std; diff --git a/crates/bevy_script_api/src/common/std.rs b/crates/bevy_script_api/src/common/std.rs deleted file mode 100644 index f3da1234..00000000 --- a/crates/bevy_script_api/src/common/std.rs +++ /dev/null @@ -1,141 +0,0 @@ -use std::marker::PhantomData; - -use bevy::reflect::{FromReflect, GetTypeRegistration, TypePath, Typed}; - -use crate::{error::ReflectionError, ReflectReference, ValueIndex}; - -pub struct ScriptVec { - pub(crate) ref_: ReflectReference, - _ph: PhantomData, -} - -impl Clone for ScriptVec { - fn clone(&self) -> Self { - Self { - ref_: self.ref_.clone(), - _ph: PhantomData, - } - } -} - -impl std::fmt::Debug for ScriptVec { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("ScriptVec") - .field("ref_", &self.ref_) - .finish() - } -} - -impl std::fmt::Display - for ScriptVec -{ - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let str = self - .ref_ - .get_typed(|s: &Vec| s.iter().map(|v| format!("{v}")).collect::>()) - .map_err(|_| std::fmt::Error)? - .join(","); - f.write_str("[")?; - f.write_str(&str)?; - f.write_str("]") - } -} - -impl ScriptVec { - pub fn new_ref(ref_: ReflectReference) -> Self { - Self { - ref_, - _ph: PhantomData, - } - } - - pub fn is_empty(&self) -> Result { - Ok(self.len()? == 0) - } - - pub fn len(&self) -> Result { - self.ref_.get_typed(|s: &Vec| s.len()) - } - - pub fn push(&mut self, val: T) -> Result<(), ReflectionError> { - self.ref_.get_mut_typed(|s: &mut Vec| { - s.push(val); - Ok(()) - })? - } - - pub fn pop(&mut self) -> Result, ReflectionError> { - self.ref_.get_mut_typed(|s: &mut Vec| s.pop()) - } - - pub fn clear(&mut self) -> Result<(), ReflectionError> { - self.ref_.get_mut_typed(|s: &mut Vec| { - s.clear(); - Ok(()) - })? - } - - pub fn insert(&mut self, idx: usize, val: T) -> Result<(), ReflectionError> { - self.ref_.get_mut_typed(|s: &mut Vec| { - s.insert(idx, val); - Ok(()) - })? - } - - pub fn remove(&mut self, idx: usize) -> Result { - self.ref_ - .get_mut_typed(|s: &mut Vec| Ok(s.remove(idx)))? - } -} - -impl ValueIndex for ScriptVec { - type Output = ReflectReference; - - fn index(&self, index: usize) -> Self::Output { - self.ref_.index(index) - } -} - -impl From> for ReflectReference { - fn from(v: ScriptVec) -> Self { - v.ref_ - } -} - -pub struct ScriptVecIterator { - current: usize, - len: usize, - base: ScriptVec, -} - -impl Iterator for ScriptVecIterator { - type Item = ReflectReference; - - fn next(&mut self) -> Option { - let nxt = (self.current < self.len).then(|| self.base.index(self.current)); - self.current += 1; - nxt - } -} - -impl IntoIterator for ScriptVec { - type Item = ReflectReference; - - type IntoIter = ScriptVecIterator; - - /// Converts the vector into an iterator over references - /// - /// # Panics - /// will panic if the base reference is invalid or mutably locked - fn into_iter(self) -> Self::IntoIter { - ScriptVecIterator { - current: 0, - // TODO?: end used to be an Option, and this check moved into the next method but - // I am not sure if this will ever realistically fail, so if you do get this exception happening - // hit me with an issue - // if len > 0, subtract 1, otherwise set to 0 - len: self.len().expect("Failed to get length of ScriptVec"), - base: self, - } - } -} diff --git a/crates/bevy_script_api/src/core_providers.rs b/crates/bevy_script_api/src/core_providers.rs deleted file mode 100644 index 814a499c..00000000 --- a/crates/bevy_script_api/src/core_providers.rs +++ /dev/null @@ -1,115 +0,0 @@ -use crate::lua::RegisterForeignLuaType; - -pub struct LuaCoreBevyAPIProvider; - -#[derive(Default)] -pub(crate) struct CoreBevyGlobals; - -crate::impl_tealr_generic!(pub(crate) struct T); - -impl bevy_mod_scripting_lua::tealr::mlu::ExportInstances for CoreBevyGlobals { - fn add_instances<'lua, T: bevy_mod_scripting_lua::tealr::mlu::InstanceCollector<'lua>>( - self, - instances: &mut T, - ) -> bevy_mod_scripting_lua::tealr::mlu::mlua::Result<()> { - instances.add_instance( - "world", - crate::lua::util::DummyTypeName::::new, - )?; - instances.add_instance( - "script", - crate::lua::util::DummyTypeName::::new, - )?; - instances.add_instance( - "entity", - crate::lua::util::DummyTypeName::::new, - )?; - Ok(()) - } -} - -impl bevy_mod_scripting_core::hosts::APIProvider for LuaCoreBevyAPIProvider { - type APITarget = std::sync::Mutex; - type ScriptContext = std::sync::Mutex; - type DocTarget = bevy_mod_scripting_lua::docs::LuaDocFragment; - - fn attach_api( - &mut self, - ctx: &mut Self::APITarget, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - let ctx = ctx - .get_mut() - .expect("Unable to acquire lock on Lua context"); - bevy_mod_scripting_lua::tealr::mlu::set_global_env(CoreBevyGlobals, ctx) - .map_err(|e| bevy_mod_scripting_core::error::ScriptError::Other(e.to_string())) - } - - fn get_doc_fragment(&self) -> Option { - Some(bevy_mod_scripting_lua::docs::LuaDocFragment::new( - "CoreBevyAPI", - |tw| { - tw - .document_global_instance::().expect("Something went wrong documenting globals") - .process_type::() - .process_type::>() - .process_type::() - .process_type::>() - .process_type::() - .process_type::>() - .process_type::() - }, - )) - } - - fn setup_script( - &mut self, - script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - let ctx = ctx.get_mut().expect("Could not get context"); - let globals = ctx.globals(); - globals - .set( - "entity", - crate::providers::bevy_ecs::LuaEntity::new(script_data.entity), - ) - .map_err(bevy_mod_scripting_core::error::ScriptError::new_other)?; - globals - .set::<_, crate::lua::bevy::LuaScriptData>("script", script_data.into()) - .map_err(bevy_mod_scripting_core::error::ScriptError::new_other)?; - - Ok(()) - } - - fn setup_script_runtime( - &mut self, - world_ptr: bevy_mod_scripting_core::world::WorldPointer, - _script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - let ctx = ctx.get_mut().expect("Could not get context"); - let globals = ctx.globals(); - globals - .set("world", crate::lua::bevy::LuaWorld::new(world_ptr)) - .map_err(bevy_mod_scripting_core::error::ScriptError::new_other) - } - - fn register_with_app(&self, app: &mut bevy::app::App) { - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - } -} diff --git a/crates/bevy_script_api/src/error.rs b/crates/bevy_script_api/src/error.rs deleted file mode 100644 index aa2ae622..00000000 --- a/crates/bevy_script_api/src/error.rs +++ /dev/null @@ -1,37 +0,0 @@ -use std::borrow::Cow; -use thiserror::Error; - -#[derive(Error, Debug, Clone)] -pub enum ReflectionError { - #[error("Base reference `{base}` is invalid. {reason}")] - InvalidBaseReference { base: String, reason: String }, - #[error("Insuficient provenance error while accessing `{path}`. {msg}")] - InsufficientProvenance { path: String, msg: String }, - #[error("Invalid reflection path: `{path}`. {msg}")] - InvalidReflectionPath { path: String, msg: String }, - #[error("Cannot downcast from `{from}` to `{to}`")] - CannotDowncast { - from: Cow<'static, str>, - to: Cow<'static, str>, - }, - #[error("{0}")] - Other(String), -} - -#[cfg(feature = "lua")] -impl From for bevy_mod_scripting_lua::tealr::mlu::mlua::Error { - fn from(e: ReflectionError) -> Self { - bevy_mod_scripting_lua::tealr::mlu::mlua::Error::RuntimeError(e.to_string()) - } -} - -#[cfg(feature = "rhai")] -impl From for Box { - fn from(e: ReflectionError) -> Self { - bevy_mod_scripting_rhai::rhai::EvalAltResult::ErrorRuntime( - e.to_string().into(), - bevy_mod_scripting_rhai::rhai::Position::NONE, - ) - .into() - } -} diff --git a/crates/bevy_script_api/src/lib.rs b/crates/bevy_script_api/src/lib.rs deleted file mode 100644 index ca79c6d1..00000000 --- a/crates/bevy_script_api/src/lib.rs +++ /dev/null @@ -1,45 +0,0 @@ -extern crate bevy; - -pub mod error; -#[cfg(feature = "lua")] -pub mod lua; -#[cfg(feature = "rhai")] -pub mod rhai; - -pub mod common; - -#[cfg(feature = "lua")] -pub mod core_providers; -// for now providers do not support any other lang so just remove this whole module if they are not needed -#[cfg(feature = "lua")] -pub mod providers; - -pub mod script_ref; -pub mod sub_reflect; -pub mod wrappers; - -pub use {script_ref::*, sub_reflect::*}; - -pub mod prelude { - #[cfg(feature = "lua")] - pub use crate::{ - core_providers::LuaCoreBevyAPIProvider, - lua::{std::LuaVec, FromLuaProxy, IntoLuaProxy, LuaProxyable, ReflectLuaProxyable}, - providers::LuaBevyAPIProvider, - LuaProxy, - }; - - #[cfg(feature = "rhai")] - pub use crate::rhai::{ - bevy::RhaiBevyAPIProvider, - std::{RhaiCopy, RhaiVec}, - FromRhaiProxy, ReflectRhaiProxyable, RhaiProxyable, ToRhaiProxy, - }; - - pub use crate::{common::bevy::GetWorld, ValueIndex}; -} - -#[cfg(feature = "lua")] -pub use bevy_mod_scripting_lua_derive::LuaProxy; - -pub use parking_lot; diff --git a/crates/bevy_script_api/src/lua/bevy/mod.rs b/crates/bevy_script_api/src/lua/bevy/mod.rs deleted file mode 100644 index 54715102..00000000 --- a/crates/bevy_script_api/src/lua/bevy/mod.rs +++ /dev/null @@ -1,386 +0,0 @@ -use crate::common::bevy::{ - ScriptQueryBuilder, ScriptQueryResult, ScriptTypeRegistration, ScriptWorld, -}; -use crate::lua::{ - mlua::prelude::{IntoLuaMulti, LuaError, LuaMultiValue}, - tealr::{mlu::TypedFunction, ToTypename}, - util::{VariadicComponents, VariadicQueryResult}, - Lua, -}; -use crate::providers::bevy_ecs::LuaEntity; -use crate::{impl_from_lua_with_clone, impl_tealr_type}; -use bevy::hierarchy::BuildChildren; -use bevy::prelude::{AppTypeRegistry, ReflectResource}; -use bevy_mod_scripting_core::prelude::*; -use bevy_mod_scripting_lua::{prelude::IntoLua, tealr}; -use std::sync::Arc; - -use tealr::mlu::{ - mlua::{self}, - TealData, TealDataMethods, -}; - -use super::util::LuaIndex; - -pub type LuaTypeRegistration = ScriptTypeRegistration; -impl_tealr_type!(LuaTypeRegistration); -impl_from_lua_with_clone!(LuaTypeRegistration); - -impl TealData for LuaTypeRegistration { - fn add_methods<'lua, T: TealDataMethods<'lua, Self>>(methods: &mut T) { - methods.document_type("An object representing an existing and registered rust type."); - methods.document_type("Can be obtained via [`LuaWorld::get_type_by_name`]."); - } - - fn add_fields<'lua, F: tealr::mlu::TealDataFields<'lua, Self>>(fields: &mut F) { - fields.document("The [short name](https://docs.rs/bevy/latest/bevy/reflect/struct.TypeRegistration.html#method.get_short_name) of a type"); - fields.add_field_method_get("short_name", |_, s| Ok(s.short_name().to_string())); - - fields.document("The full name of the type"); - fields.add_field_method_get("type_name", |_, s| Ok(s.type_name())); - } -} - -#[derive(Debug)] -pub struct LuaScriptData { - sid: u32, -} - -impl From<&ScriptData<'_>> for LuaScriptData { - fn from(sd: &ScriptData) -> Self { - Self { sid: sd.sid } - } -} - -impl_tealr_type!(LuaScriptData); - -impl TealData for LuaScriptData { - fn add_fields<'lua, F: tealr::mlu::TealDataFields<'lua, Self>>(fields: &mut F) { - fields.document("The unique ID of this script"); - fields.add_field_method_get("sid", |_, s| Ok(s.sid)) - } - - fn add_methods<'lua, T: TealDataMethods<'lua, Self>>(methods: &mut T) { - methods.add_meta_method(tealr::mlu::mlua::MetaMethod::ToString, |_, s, ()| { - Ok(format!("{:?}", s)) - }); - } -} - -pub type LuaQueryResult = ScriptQueryResult; - -impl_from_lua_with_clone!(LuaQueryResult); - -impl IntoLuaMulti<'_> for LuaQueryResult { - fn into_lua_multi(self, lua: &Lua) -> Result, LuaError> { - let mut values = LuaMultiValue::from_vec( - self.1 - .into_iter() - .map(|v| v.into_lua(lua)) - .collect::, LuaError>>()?, - ); - values.push_front(LuaEntity::new(self.0).into_lua(lua)?); - Ok(values) - } -} - -impl ToTypename for LuaQueryResult { - fn to_typename() -> bevy_mod_scripting_lua::tealr::Type { - bevy_mod_scripting_lua::tealr::Type::new_single( - stringify!(QueryResult), - bevy_mod_scripting_lua::tealr::KindOfType::External, - ) - } -} - -pub type LuaQueryBuilder = ScriptQueryBuilder; - -impl_tealr_type!(LuaQueryBuilder); -impl_from_lua_with_clone!(LuaQueryBuilder); - -impl TealData for LuaQueryBuilder { - fn add_fields<'lua, F: tealr::mlu::TealDataFields<'lua, Self>>(fields: &mut F) { - fields.document("A Builder object which allows for filtering and iterating over components and entities in the world."); - } - - fn add_methods<'lua, T: TealDataMethods<'lua, Self>>(methods: &mut T) { - methods.document("Filters out entities without any of the components passed"); - methods.add_method_mut("with", |_, s, components: VariadicComponents| { - s.with(components.0); - Ok(s.clone()) - }); - - methods.document("Filters out entities with any components passed"); - methods.add_method_mut("without", |_, s, components: VariadicComponents| { - s.without(components.0); - Ok(s.clone()) - }); - - methods - .document("Queries the world and returns an iterator over the entity and components."); - methods.add_method_mut("iter", |ctx, s, _: ()| { - let query_result = s - .build() - .map_err(|e| mlua::Error::RuntimeError(e.to_string()))?; - - let len = query_result.len(); - let mut curr_idx = 0; - TypedFunction::from_rust_mut( - move |_, ()| { - let o = if curr_idx < len { - let query_result = query_result.get(curr_idx).unwrap(); - VariadicQueryResult::Some( - LuaEntity::new(query_result.0), - query_result.1.clone(), - ) - } else { - VariadicQueryResult::None - }; - curr_idx += 1; - Ok(o) - }, - ctx, - ) - }); - } -} - -pub type LuaWorld = ScriptWorld; - -impl_tealr_type!(LuaWorld); -impl_from_lua_with_clone!(LuaWorld); - -impl TealData for LuaWorld { - fn add_methods<'lua, T: TealDataMethods<'lua, Self>>(methods: &mut T) { - methods.document_type("Represents the bevy world all scripts live in."); - methods.document_type("Provides ways to interact with and modify the world."); - - methods.add_meta_method(tealr::mlu::mlua::MetaMethod::ToString, |_, s, ()| { - Ok(format!("{s:?}")) - }); - - methods.document("Retrieves type information given either a short (`MyType`) or fully qualified rust type name (`MyModule::MyType`)."); - methods.document( - "Returns `nil` if no such type exists or if one wasn't registered on the rust side.", - ); - methods.document("\n"); - methods.document("This is used extensively in [`LuaWorld`]"); - methods.add_method("get_type_by_name", |_, world, type_name: String| { - let w = world.read(); - - let registry: &AppTypeRegistry = w.get_resource().unwrap(); - - let registry = registry.read(); - - Ok(registry - .get_with_short_type_path(&type_name) - .or_else(|| registry.get_with_type_path(&type_name)) - .map(|registration| LuaTypeRegistration::new(Arc::new(registration.clone())))) - }); - - methods.document("Inserts a component of the given type to the given entity by instantiating a default version of it."); - methods.document("The component can then be modified using field access."); - methods.add_method( - "add_default_component", - |_, world, (entity, comp_type): (LuaEntity, LuaTypeRegistration)| { - world - .add_default_component(entity.inner()?, comp_type) - .map_err(|e| mlua::Error::RuntimeError(e.to_string())) - }, - ); - - methods.document("Retrieves a component of the given type from the given entity."); - methods.document("If such a component does not exist returns `nil`."); - methods.add_method( - "get_component", - |_, world, (entity, comp_type): (LuaEntity, LuaTypeRegistration)| { - world - .get_component(entity.inner()?, comp_type) - .map_err(|e| mlua::Error::RuntimeError(e.to_string())) - }, - ); - - methods.document("Creates a LuaQueryBuilder, querying for the passed components types."); - methods.document("Can be iterated over using `LuaQueryBuilder:iter()`"); - methods.add_method_mut("query", |_, world, components: VariadicComponents| { - Ok(LuaQueryBuilder::new(world.clone()) - .components(components.0) - .clone()) - }); - - methods - .document("Returns `true` if the given entity contains a component of the given type."); - methods.add_method( - "has_component", - |_, world, (entity, comp_type): (LuaEntity, LuaTypeRegistration)| { - world - .has_component(entity.inner()?, comp_type) - .map_err(|e| mlua::Error::RuntimeError(e.to_string())) - }, - ); - - methods.document("Removes the given component from the given entity, does nothing if it doesn't exist on the entity."); - methods.add_method_mut( - "remove_component", - |_, world, (entity, comp_type): (LuaEntity, LuaTypeRegistration)| { - world - .remove_component(entity.inner()?, comp_type) - .map_err(|e| mlua::Error::RuntimeError(e.to_string())) - }, - ); - - methods.document("Retrieves a resource of the given type from the world."); - methods.document("If such a resource does not exist returns `nil`."); - methods.add_method("get_resource", |_, world, res_type: LuaTypeRegistration| { - world - .get_resource(res_type) - .map_err(|e| mlua::Error::RuntimeError(e.to_string())) - }); - - methods.document( - "Removes the given resource from the world, if one doesn't exist it does nothing.", - ); - methods.add_method( - "remove_resource", - |_, world, res_type: LuaTypeRegistration| { - let mut w = world.write(); - - let resource_data = res_type.data::().ok_or_else(|| { - mlua::Error::RuntimeError(format!("Not a resource {}", res_type.short_name())) - })?; - resource_data.remove(&mut w); - Ok(()) - }, - ); - - methods.document("Returns `true` if the world contains a resource of the given type."); - methods.add_method("has_resource", |_, world, res_type: LuaTypeRegistration| { - let w = world.read(); - - let resource_data = res_type.data::().ok_or_else(|| { - mlua::Error::RuntimeError(format!("Not a resource {}", res_type.short_name())) - })?; - - Ok(resource_data.reflect(&w).is_some()) - }); - - methods.document("Retrieves children entities of the parent entity if it has any."); - methods.add_method("get_children", |_, world, parent: LuaEntity| { - Ok(world - .get_children(parent.inner()?) - .into_iter() - .map(LuaEntity::new) - .collect::>()) - }); - - methods.document("Retrieves the parent entity of the given entity if it has any."); - methods.add_method("get_parent", |_, world, parent: LuaEntity| { - Ok(world.get_parent(parent.inner()?).map(LuaEntity::new)) - }); - - methods.document("Attaches children entities to the given parent entity."); - methods.add_method( - "push_children", - |_, world, (parent, children): (LuaEntity, Vec)| { - let mut w = world.write(); - let children = children - .iter() - .map(|e| e.inner()) - .collect::, _>>()?; - - if let Ok(mut entity) = w.get_entity_mut(parent.inner()?) { - entity.add_children(&children); - } - - Ok(()) - }, - ); - - methods.document("Attaches child entity to the given parent entity."); - methods.add_method_mut( - "push_child", - |_, world, (parent, child): (LuaEntity, LuaEntity)| { - world.push_child(parent.inner()?, child.inner()?); - Ok(()) - }, - ); - - methods.document("Removes children entities from the given parent entity."); - methods.add_method( - "remove_children", - |_, world, (parent, children): (LuaEntity, Vec)| { - let children = children - .iter() - .map(|e| e.inner()) - .collect::, _>>()?; - - world.remove_children(parent.inner()?, &children); - Ok(()) - }, - ); - - methods.document("Removes child entity from the given parent entity."); - methods.add_method( - "remove_child", - |_, world, (parent, child): (LuaEntity, LuaEntity)| { - world.remove_children(parent.inner()?, &[child.inner()?]); - Ok(()) - }, - ); - - methods - .document("Inserts children entities to the given parent entity at the given index."); - methods.add_method( - "insert_children", - |_, world, (parent, index, children): (LuaEntity, LuaIndex, Vec)| { - let children = children - .iter() - .map(|e| e.inner()) - .collect::, _>>()?; - - world.insert_children(parent.inner()?, *index, &children); - Ok(()) - }, - ); - - methods.document("Inserts child entity to the given parent entity at the given index."); - methods.add_method( - "insert_child", - |_, world, (parent, index, child): (LuaEntity, LuaIndex, LuaEntity)| { - world.insert_children(parent.inner()?, *index, &[child.inner()?]); - Ok(()) - }, - ); - - methods.document("Despawns the given entity's children recursively"); - methods.add_method( - "despawn_children_recursive", - |_, world, entity: LuaEntity| { - world.despawn_children_recursive(entity.inner()?); - Ok(()) - }, - ); - - methods.document("Despawns the given entity and the entity's children recursively"); - methods.add_method("despawn_recursive", |_, world, entity: LuaEntity| { - world.despawn_recursive(entity.inner()?); - Ok(()) - }); - - methods.document("Spawns a new entity and returns its Entity ID"); - methods.add_method("spawn", |_, world, ()| { - let mut w = world.write(); - - Ok(LuaEntity::new(w.spawn(()).id())) - }); - - methods.document( - "Despawns the given entity if it exists, returns true if deletion was successfull", - ); - methods.add_method("despawn", |_, world, entity: LuaEntity| { - let mut w = world.write(); - - Ok(w.despawn(entity.inner()?)) - }); - } -} diff --git a/crates/bevy_script_api/src/lua/mod.rs b/crates/bevy_script_api/src/lua/mod.rs deleted file mode 100644 index 5338fb9c..00000000 --- a/crates/bevy_script_api/src/lua/mod.rs +++ /dev/null @@ -1,306 +0,0 @@ -use ::std::any::TypeId; -use ::std::borrow::Cow; - -use crate::common::bevy::GetWorld; -use crate::{impl_from_lua_with_clone, impl_tealr_type}; -use ::bevy::prelude::{App, AppTypeRegistry}; - -use ::bevy::reflect::{FromType, GetTypeRegistration, Reflect}; - -use bevy_mod_scripting_core::world::WorldPointer; -use bevy_mod_scripting_lua::tealr::{self, ToTypename}; - -use tealr::mlu::mlua::MetaMethod; -use tealr::mlu::{ - mlua::{self, FromLua, IntoLua, Lua, UserData, Value}, - TealData, TealDataMethods, -}; - -use crate::script_ref::{ReflectReference, ReflectedValue, ValueIndex}; - -use self::bevy::LuaWorld; -use self::util::to_host_idx; - -pub mod bevy; -pub mod std; -pub mod util; - -/// A trait allowing to register the [`LuaProxyable`] trait with the type registry for foreign types -/// -/// If you have access to the type you should prefer to use `#[reflect(LuaProxyable)]` instead. -/// This is exactly equivalent. -pub trait RegisterForeignLuaType { - /// Register an instance of `ReflecLuaProxyable` type data on this type's registration, - /// if a registration does not yet exist, creates one. - fn register_foreign_lua_type( - &mut self, - ) -> &mut Self; -} - -impl RegisterForeignLuaType for App { - fn register_foreign_lua_type( - &mut self, - ) -> &mut Self { - { - let registry = self.world_mut().resource_mut::(); - let mut registry = registry.write(); - - let user_data = >::from_type(); - - if let Some(registration) = registry.get_mut(TypeId::of::()) { - registration.insert(user_data) - } else { - let mut registration = T::get_type_registration(); - registration.insert(user_data); - registry.add_registration(registration); - } - } - - self - } -} - -impl ValueIndex> for ReflectReference { - type Output = Result; - - fn index(&self, index: Value<'_>) -> Self::Output { - match index { - Value::Integer(idx) => Ok(self.index(to_host_idx(idx as usize))), - Value::String(field) => { - let str_ = field.to_str()?.to_string(); - // TODO: hopefully possible to use a &'_ str here - // but this requires Reflect implementation for &str - Ok(>>::index( - self, - str_.into(), - )) - } - _ => Err(mlua::Error::RuntimeError(format!( - "Cannot index a rust object with {:?}", - index - ))), - } - } -} - -/// For internal use only. -/// -/// Mainly necessary for separation of concerns on the [`ReflectReference`] type, but might have other uses potentially. -/// -/// This is not the same as [`LuaProxyable`], internally this in fact will use [`LuaProxyable`] so treating it like so will cause inifnite loops. -pub(crate) trait ApplyLua { - /// set the proxied object with the given lua value - fn apply_lua<'lua>(&mut self, ctx: &'lua Lua, v: Value<'lua>) -> mlua::Result<()>; -} -impl ApplyLua for ReflectReference { - /// Applies the given lua value to the proxied reflect type. Semantically equivalent to `Reflect::apply` - fn apply_lua<'lua>(&mut self, ctx: &'lua Lua, v: Value<'lua>) -> Result<(), mlua::Error> { - let luaworld = ctx.globals().get::<_, LuaWorld>("world").unwrap(); - - // remove typedata from the world to be able to manipulate world - let proxyable = { - let world = luaworld.read(); - let type_registry = world.resource::().read(); - type_registry - .get_type_data::(self.get(|s| s.type_id())?) - .cloned() - }; - - if let Some(ud) = proxyable { - return ud.apply_lua(self, ctx, v); - } else if let Value::UserData(v) = &v { - if v.is::() { - let b = v.take::().unwrap(); - self.apply(&b.into())?; - return Ok(()); - } - } - - Err(mlua::Error::RuntimeError(self.get(|s| - format!("Attempted to assign `{}` = {v:?}. Did you forget to call `app.register_foreign_lua_type::<{}>`?", - self.path, - s.get_represented_type_info().unwrap().type_path() - ))?) - ) - } -} - -impl<'lua> IntoLua<'lua> for ReflectReference { - /// Converts the LuaRef to the most convenient representation - /// checking conversions in this order: - /// - A primitive or bevy type which has a reflect interface is converted to a custom UserData exposing its API to lua conveniently - /// - A type implementing CustomUserData is converted with its `ref_to_lua` method - /// - Finally the method is represented as a `ReflectedValue` which exposes the Reflect interface - fn into_lua(self, ctx: &'lua Lua) -> mlua::Result> { - let world = self.world_ptr.clone(); - let world = world.read(); - - let typedata = &world.resource::(); - let g = typedata.read(); - - let type_id = self.get(|s| s.type_id())?; - if let Some(v) = g.get_type_data::(type_id) { - v.ref_to_lua(self, ctx) - } else { - ReflectedValue { ref_: self }.into_lua(ctx) - } - } -} - -impl ToTypename for ReflectReference { - fn to_typename() -> tealr::Type { - tealr::Type::new_single("ReflectedValue", tealr::KindOfType::External) - } -} - -impl_tealr_type!(ReflectedValue); -impl_from_lua_with_clone!(ReflectedValue); -impl TealData for ReflectedValue { - fn add_methods<'lua, T: TealDataMethods<'lua, Self>>(methods: &mut T) { - methods.document_type("This type represents a generic reflected value."); - methods.document_type("If you know the reflected value converts to a LuaType (via LuaProxyable), use the `as` operator to convert to said type."); - - methods.add_meta_method(MetaMethod::ToString, |_, val, ()| { - val.ref_.get(|s| Ok(format!("{:?}", &s)))? - }); - - methods.add_meta_method_mut(MetaMethod::Index, |_, val, field: Value| { - let r = val.ref_.index(field)?; - Ok(r) - }); - - methods.add_meta_method_mut( - MetaMethod::NewIndex, - |ctx, val, (field, new_val): (Value, Value)| { - val.ref_.index(field)?.apply_lua(ctx, new_val)?; - Ok(()) - }, - ); - } -} -/// A higher level trait for allowing types to be interpreted as custom lua proxy types (or just normal types, this interface is flexible). -/// Types implementing this trait can have [`ReflectLuaProxyable`] type data registrations inserted into the reflection API. -/// -/// Types registered via the reflection API this way can be accessed from Lua via [`ReflectReference`] objects (via field access). -pub trait LuaProxyable { - /// a version of [`mlua::ToLua::to_lua`] which does not consume the object. - /// - /// Note: The self reference is sourced from the given ReflectReference, attempting to get another mutable reference from the ReflectReference might - /// cause a runtime error to prevent breaking of aliasing rules - fn ref_to_lua(self_: ReflectReference, lua: &Lua) -> mlua::Result; - - /// similar to [`Reflect::apply`] - /// - /// Note: - /// The self reference is sourced from the given ReflectReference, attempting to get another reference from the ReflectReference might - /// cause a runtime error to prevent breaking of aliasing rules - fn apply_lua<'lua>( - self_: &mut ReflectReference, - lua: &'lua Lua, - new_val: Value<'lua>, - ) -> mlua::Result<()>; -} - -/// Exactly alike to [`mlua::ToLua`] -pub trait FromLuaProxy<'lua>: Sized { - fn from_lua_proxy(new_val: Value<'lua>, lua: &'lua Lua) -> mlua::Result; -} - -/// Exactly alike to [`mlua::FromLua`] -pub trait IntoLuaProxy<'lua> { - fn to_lua_proxy(self, lua: &'lua Lua) -> mlua::Result>; -} - -/// A struct providing type data for the `LuaProxyable` trait. -/// -/// This allows casting static methods from the `LuaProxyable trait`. -#[derive(Clone)] -pub struct ReflectLuaProxyable { - ref_to_lua: for<'lua> fn(ref_: ReflectReference, lua: &'lua Lua) -> mlua::Result>, - apply_lua: for<'lua> fn( - ref_: &mut ReflectReference, - lua: &'lua Lua, - new_val: Value<'lua>, - ) -> mlua::Result<()>, -} - -impl ReflectLuaProxyable { - pub fn ref_to_lua<'lua>( - &self, - ref_: ReflectReference, - lua: &'lua Lua, - ) -> mlua::Result> { - (self.ref_to_lua)(ref_, lua) - } - - pub fn apply_lua<'lua>( - &self, - ref_: &mut ReflectReference, - lua: &'lua Lua, - new_val: Value<'lua>, - ) -> mlua::Result<()> { - (self.apply_lua)(ref_, lua, new_val) - } -} - -impl ::bevy::reflect::FromType - for ReflectLuaProxyable -{ - fn from_type() -> Self { - Self { - ref_to_lua: T::ref_to_lua, - apply_lua: T::apply_lua, - } - } -} - -/// A dummy trait used to combat rust's orphan rules -/// -/// In the future when trait specialization is a thing, this might be a companion trait -/// to `RefLuaType` which allows non Clone types to be used -pub trait ValueLuaType {} - -impl LuaProxyable for T { - fn ref_to_lua(self_: ReflectReference, lua: &Lua) -> mlua::Result { - self_.get_typed(|s: &Self| s.clone().into_lua(lua))? - } - - fn apply_lua<'lua>( - self_: &mut ReflectReference, - _: &'lua Lua, - new_val: Value<'lua>, - ) -> mlua::Result<()> { - if let Value::UserData(v) = new_val { - let o = v.borrow::()?; - - self_.get_mut_typed(|s| *s = o.clone())?; - - Ok(()) - } else { - Err(mlua::Error::RuntimeError( - "Error in assigning to custom user data".to_owned(), - )) - } - } -} - -impl<'lua, T: Clone + UserData + FromLua<'lua> + Send + ValueLuaType + Reflect + 'static> - FromLuaProxy<'lua> for T -{ - fn from_lua_proxy(new_val: Value<'lua>, lua: &'lua Lua) -> mlua::Result { - T::from_lua(new_val, lua) - } -} - -impl<'lua, T: Clone + UserData + Send + ValueLuaType + Reflect + 'static> IntoLuaProxy<'lua> for T { - fn to_lua_proxy(self, lua: &'lua Lua) -> mlua::Result> { - self.into_lua(lua) - } -} - -impl GetWorld for Lua { - type Error = mlua::Error; - fn get_world(&self) -> Result { - self.globals().get::<_, LuaWorld>("world").map(Into::into) - } -} diff --git a/crates/bevy_script_api/src/lua/std.rs b/crates/bevy_script_api/src/lua/std.rs deleted file mode 100644 index 945b4c16..00000000 --- a/crates/bevy_script_api/src/lua/std.rs +++ /dev/null @@ -1,492 +0,0 @@ -use std::sync::Arc; - -use bevy::reflect::FromReflect; -use bevy::reflect::Reflect; - -use bevy::reflect::{GetTypeRegistration, TypePath}; -use bevy_mod_scripting_lua::tealr; - -use bevy_mod_scripting_lua::tealr::ToTypename; -use tealr::mlu::mlua::MetaMethod; -use tealr::mlu::TypedFunction; -use tealr::mlu::{ - mlua::{self, FromLua, IntoLua, Lua, UserData, Value}, - TealData, TealDataMethods, -}; -use tealr::TypeBody; - -use paste::paste; - -use crate::common::std::ScriptVec; -use crate::{ - error::ReflectionError, - script_ref::{ReflectReference, ValueIndex}, - sub_reflect::ReflectionPathElement, -}; - -use super::util::to_lua_idx; -use super::util::LuaIndex; -use super::ApplyLua; -use super::FromLuaProxy; -use super::IntoLuaProxy; -use super::LuaProxyable; - -/// Implements custom user data for simple copy types which implement to and from lua -macro_rules! impl_proxyable_by_copy( - ( $($num_ty:ty),*) => { - paste! { - $( - impl $crate::lua::LuaProxyable for $num_ty { - fn ref_to_lua(self_: $crate::script_ref::ReflectReference,lua: & tealr::mlu::mlua::Lua) -> tealr::mlu::mlua::Result > { - self_.get_typed(|self_ : &Self| self_.into_lua(lua))? - } - - fn apply_lua< 'lua>(self_: &mut $crate::script_ref::ReflectReference,lua: & 'lua tealr::mlu::mlua::Lua,new_val:tealr::mlu::mlua::Value< 'lua>) -> tealr::mlu::mlua::Result<()> { - self_.set_val(Self::from_lua(new_val,lua)?)?; - Ok(()) - } - } - - impl <'lua>$crate::lua::FromLuaProxy<'lua> for $num_ty { - #[inline(always)] - fn from_lua_proxy(new_value: Value<'lua>, lua: &'lua Lua) -> tealr::mlu::mlua::Result { - Self::from_lua(new_value,lua) - } - } - - impl <'lua>$crate::lua::IntoLuaProxy<'lua> for $num_ty { - #[inline(always)] - fn to_lua_proxy(self, lua: &'lua Lua) -> tealr::mlu::mlua::Result> { - self.into_lua(lua) - } - } - )* - } - } -); - -impl_proxyable_by_copy!(bool); -impl_proxyable_by_copy!(f32, f64); -impl_proxyable_by_copy!(i8, i16, i32, i64, i128, isize); -impl_proxyable_by_copy!(u8, u16, u32, u64, u128, usize); - -impl LuaProxyable for String { - fn ref_to_lua(self_: ReflectReference, lua: &Lua) -> mlua::Result { - self_.get_typed(|self_: &String| self_.as_str().into_lua(lua))? - } - - fn apply_lua<'lua>( - self_: &mut ReflectReference, - lua: &'lua Lua, - new_val: Value<'lua>, - ) -> mlua::Result<()> { - self_.get_mut_typed(|self_| { - *self_ = Self::from_lua(new_val, lua)?; - Ok(()) - })? - } -} - -impl<'lua> FromLuaProxy<'lua> for String { - fn from_lua_proxy(new_val: Value<'lua>, lua: &'lua Lua) -> mlua::Result { - Self::from_lua(new_val, lua) - } -} - -impl<'lua> IntoLuaProxy<'lua> for String { - fn to_lua_proxy(self, lua: &'lua Lua) -> mlua::Result> { - self.into_lua(lua) - } -} - -impl< - T: LuaProxyable - + Reflect - + FromReflect - + GetTypeRegistration - + TypePath - + for<'a> FromLuaProxy<'a> - + Clone - + bevy::reflect::Typed, - > LuaProxyable for Option -{ - fn ref_to_lua(self_: ReflectReference, lua: &Lua) -> mlua::Result { - self_.get_typed(|s: &Option| match s { - Some(_) => T::ref_to_lua( - self_.sub_ref(ReflectionPathElement::SubReflection { - label: "as_ref", - get: Arc::new(|ref_| { - ref_.downcast_ref::>() - .ok_or_else(|| ReflectionError::CannotDowncast { - from: ref_.get_represented_type_info().unwrap().type_path().into(), - to: stringify!(Option).into(), - })? - .as_ref() - .map(|t| t as &dyn Reflect) - .ok_or_else(|| { - ReflectionError::Other( - "Stale reference to Option. Cannot sub reflect.".to_owned(), - ) - }) - }), - get_mut: Arc::new(|ref_| { - ref_.downcast_mut::>() - // TODO: there is some weird borrow checker fuckery going on here - // i tried having from: ref_.get_represented_type_info().unwrap().type_path().into() instead of "Reflect" - // and lying this out in an if let expression, but nothing will satisfy the borrow checker here, so leaving this for now - .ok_or_else(|| ReflectionError::CannotDowncast { - from: "Reflect".into(), - to: stringify!(Option).into(), - })? - .as_mut() - .map(|t| t as &mut dyn Reflect) - .ok_or_else(|| { - ReflectionError::Other( - "Stale reference to Option. Cannot sub reflect.".to_owned(), - ) - }) - }), - }), - lua, - ), - None => Ok(Value::Nil), - })? - } - - fn apply_lua<'lua>( - self_: &mut ReflectReference, - lua: &'lua Lua, - new_val: Value<'lua>, - ) -> mlua::Result<()> { - if let Value::Nil = new_val { - self_.get_mut_typed(|s: &mut Option| { - *s = None; - Ok(()) - })? - } else { - // we need to do this in two passes, first - // ensure that the target type is the 'some' variant to allow a sub reference - let is_none = self_.get_typed(|s: &Option| s.is_none())?; - - if is_none { - return self_.get_mut_typed(|s: &mut Option| { - *s = Some(T::from_lua_proxy(new_val, lua)?); - Ok::<_, mlua::Error>(()) - })?; - } - - T::apply_lua( - &mut self_.sub_ref(ReflectionPathElement::SubReflection { - label: "", - get: Arc::new(|ref_| { - ref_.downcast_ref::>() - .ok_or_else(|| ReflectionError::CannotDowncast { - from: ref_.get_represented_type_info().unwrap().type_path().into(), - to: stringify!(Option).into(), - })? - .as_ref() - .map(|t| t as &dyn Reflect) - .ok_or_else(|| { - ReflectionError::Other( - "Stale reference to Option. Cannot sub reflect.".to_owned(), - ) - }) - }), - get_mut: Arc::new(|ref_| { - if ref_.is::>() { - ref_.downcast_mut::>() - .unwrap() - .as_mut() - .map(|t| t as &mut dyn Reflect) - .ok_or_else(|| { - ReflectionError::Other( - "Stale reference to Option. Cannot sub reflect.".to_owned(), - ) - }) - } else { - Err(ReflectionError::CannotDowncast { - from: ref_.get_represented_type_info().unwrap().type_path().into(), - to: stringify!(Option).into(), - }) - } - }), - }), - lua, - new_val, - ) - } - } -} - -impl<'lua, T: for<'a> FromLuaProxy<'a>> FromLuaProxy<'lua> for Option { - fn from_lua_proxy(new_val: Value<'lua>, lua: &'lua Lua) -> mlua::Result { - if let Value::Nil = new_val { - Ok(None) - } else { - T::from_lua_proxy(new_val, lua).map(Option::Some) - } - } -} - -impl<'lua, T: for<'a> IntoLuaProxy<'a>> IntoLuaProxy<'lua> for Option { - fn to_lua_proxy(self, lua: &'lua Lua) -> mlua::Result> { - match self { - Some(v) => v.to_lua_proxy(lua), - None => Ok(Value::Nil), - } - } -} - -/// A reference to a rust vec (vec reference proxy), does not need an owned variant since -/// lua can natively represent lists of things -pub type LuaVec = ScriptVec; - -impl< - T: ToTypename - + FromReflect - + GetTypeRegistration - + TypePath - + LuaProxyable - + bevy::reflect::Typed - + for<'a> FromLuaProxy<'a> - + for<'a> IntoLuaProxy<'a> - + std::fmt::Debug, - > UserData for LuaVec -{ - fn add_methods<'lua, M: tealr::mlu::mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { - let mut x = tealr::mlu::UserDataWrapper::from_user_data_methods(methods); - ::add_methods(&mut x); - } - fn add_fields<'lua, F: tealr::mlu::mlua::UserDataFields<'lua, Self>>(fields: &mut F) { - let mut wrapper = tealr::mlu::UserDataWrapper::from_user_data_fields(fields); - ::add_fields(&mut wrapper) - } -} - -impl ToTypename for LuaVec { - /// Before tealr deprecated TypeName, this used to incorporate generics here, but right now I don't think they're supported anymore - fn to_typename() -> tealr::Type { - tealr::Type::new_single("LuaVec", tealr::KindOfType::External) - } -} - -impl< - T: ToTypename - + FromReflect - + GetTypeRegistration - + TypePath - + LuaProxyable - + bevy::reflect::Typed - + for<'a> FromLuaProxy<'a> - + for<'a> IntoLuaProxy<'a> - + std::fmt::Debug, - > TypeBody for LuaVec -{ - fn get_type_body() -> tealr::TypeGenerator { - let mut gen = tealr::RecordGenerator::new::(false); - gen.is_user_data = true; - ::add_fields(&mut gen); - ::add_methods(&mut gen); - gen.into() - } -} - -impl< - T: ToTypename - + FromReflect - + GetTypeRegistration - + TypePath - + LuaProxyable - + bevy::reflect::Typed - + for<'a> FromLuaProxy<'a> - + for<'a> IntoLuaProxy<'a>, - > TealData for LuaVec -{ - fn add_methods<'lua, M: TealDataMethods<'lua, Self>>(methods: &mut M) { - methods.document_type("A reference to the Vec Rust type."); - methods.document_type("All indexing begins at 1."); - - methods.add_meta_method(MetaMethod::ToString, |_, s, ()| { - Ok(s.ref_.get(|s| format!("{:?}", s))?) - }); - - methods.add_meta_method(MetaMethod::Index, |_, s, index: LuaIndex| { - Ok(s.index(*index)) - }); - - methods.add_meta_method_mut( - MetaMethod::NewIndex, - |ctx, s, (index, value): (LuaIndex, Value)| s.index(*index).apply_lua(ctx, value), - ); - - bevy_mod_scripting_lua::__cfg_feature_any_lua52_lua53_lua54_luajit52!( - methods.add_meta_method( - MetaMethod::Pairs, - |ctx, s, _: ()| { - let len = s.len()?; - let mut curr_idx = 0; - let ref_: ReflectReference = s.clone().into(); - TypedFunction::from_rust_mut( - move |ctx, ()| { - let o = if curr_idx < len { - ( - to_lua_idx(curr_idx).into_lua(ctx)?, - ref_.index(curr_idx).into_lua(ctx)?, - ) - } else { - (Value::Nil, Value::Nil) - }; - curr_idx += 1; - Ok(o) - }, - ctx, - ) - }, - ); - ); - methods.add_meta_method(MetaMethod::Len, |_, s, ()| Ok(s.len()?)); - - methods.add_method("to_table", |ctx, s, ()| { - let table = ctx.create_table()?; - let len = s.len()?; - - for i in 0..len { - table.raw_set(to_lua_idx(i), s.index(i).into_lua(ctx)?)?; - } - - Ok(table) - }); - - methods.add_method_mut("push", |ctx, s, v: Value| { - let new_val = T::from_lua_proxy(v, ctx)?; - s.push(new_val)?; - Ok(()) - }); - - methods.add_method_mut("pop", |ctx, s, ()| s.pop().map(|v| v.to_lua_proxy(ctx))?); - - methods.add_method_mut("clear", |_, s, ()| { - s.clear()?; - Ok(()) - }); - - methods.add_method_mut("insert", |ctx, s, (idx, v): (LuaIndex, Value<'lua>)| { - s.insert(*idx, T::from_lua_proxy(v, ctx)?)?; - Ok(()) - }); - - methods.add_method_mut("remove", |ctx, s, idx: LuaIndex| { - let removed = s.remove(*idx)?; - removed.to_lua_proxy(ctx) - }); - } -} - -impl< - T: ToTypename - + FromReflect - + GetTypeRegistration - + TypePath - + LuaProxyable - + bevy::reflect::Typed - + for<'a> FromLuaProxy<'a> - + for<'a> IntoLuaProxy<'a> - + std::fmt::Debug, - > LuaProxyable for Vec -{ - fn ref_to_lua(self_: ReflectReference, lua: &Lua) -> mlua::Result { - LuaVec::::new_ref(self_).into_lua(lua) - } - - fn apply_lua<'lua>( - self_: &mut ReflectReference, - lua: &'lua Lua, - new_val: Value<'lua>, - ) -> mlua::Result<()> { - match &new_val { - Value::UserData(ud) => { - let lua_vec = ud.borrow::>()?; - self_.apply(&lua_vec.ref_)?; - } - Value::Table(table) => { - let last_target_idx = self_.get_typed(|s: &Vec| s.len())? - 1; - // there is also another case to consider, Vec has a lua representation available as well (table) - // if we receive one of those, we should also apply it - for entry in table.clone().pairs::() { - let (lua_idx, v) = entry?; - let idx = lua_idx - 1; - if idx > last_target_idx { - // here we don't need to do anything special just use LuaProxyable impl - T::apply_lua(&mut self_.index(idx), lua, v)?; - } else { - // here we don't have anything to apply this to - // use FromLua impl - self_.get_mut_typed(|s: &mut Vec| { - s[idx] = T::from_lua_proxy(v, lua)?; - Ok::<_, mlua::Error>(()) - })??; - } - } - } - _ => { - return Err(mlua::Error::FromLuaConversionError { - from: new_val.type_name(), - to: "userdata or table", - message: Some("LuaVec can only be assigned with itself or a table".to_owned()), - }) - } - } - - Ok(()) - } -} - -impl< - 'lua, - T: ToTypename - + for<'a> FromLuaProxy<'a> - + for<'a> IntoLuaProxy<'a> - + Clone - + FromReflect - + GetTypeRegistration - + TypePath - + LuaProxyable - + bevy::reflect::Typed - + std::fmt::Debug, - > FromLuaProxy<'lua> for Vec -{ - fn from_lua_proxy(new_val: Value<'lua>, lua: &'lua Lua) -> mlua::Result { - match new_val { - Value::UserData(ud) => { - let lua_vec = ud.borrow::>()?; - lua_vec.ref_.get_typed(|s: &Vec| Ok(s.clone()))? - } - Value::Table(table) => { - // there is also another case to consider, Vec has a lua representation available as well (table) - // if we receive one of those, we should clone it one by one - table - .pairs::() - .map(|v| v.and_then(|(_, v)| T::from_lua_proxy(v, lua))) - .collect::, _>>() - } - _ => Err(mlua::Error::FromLuaConversionError { - from: new_val.type_name(), - to: "userdata or table", - message: Some("LuaVec can only be assigned with itself or a table".to_owned()), - }), - } - } -} - -impl<'lua, T: for<'a> IntoLuaProxy<'a> + Clone + FromReflect + LuaProxyable> IntoLuaProxy<'lua> - for Vec -{ - fn to_lua_proxy(self, lua: &'lua Lua) -> mlua::Result> { - let proxies = lua.create_table()?; - for (idx, elem) in self.into_iter().enumerate() { - proxies.raw_set(idx, elem.to_lua_proxy(lua)?)?; - } - - proxies.into_lua(lua) - } -} diff --git a/crates/bevy_script_api/src/lua/util.rs b/crates/bevy_script_api/src/lua/util.rs deleted file mode 100644 index 6c611e0b..00000000 --- a/crates/bevy_script_api/src/lua/util.rs +++ /dev/null @@ -1,427 +0,0 @@ -use crate::{lua::bevy::LuaTypeRegistration, providers::bevy_ecs::LuaEntity, ReflectReference}; -use bevy_mod_scripting_lua::{ - prelude::{ - FromLua, FromLuaMulti, IntoLua, IntoLuaMulti, Lua, LuaError, LuaMultiValue, LuaValue, - }, - tealr::{self, FunctionParam, KindOfType, Name, SingleType, TealMultiValue, ToTypename, Type}, -}; -use std::{ - marker::PhantomData, - ops::{Deref, DerefMut}, -}; - -/// Newtype abstraction of usize to represent a lua integer indexing things. -/// Lua is 1 based, host is 0 based, and this type performs this conversion automatically via ToLua and FromLua traits. -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct LuaIndex(usize); - -impl ToTypename for LuaIndex { - fn to_typename() -> tealr::Type { - ::to_typename() - } -} - -impl Deref for LuaIndex { - type Target = usize; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for LuaIndex { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl IntoLua<'_> for LuaIndex { - fn into_lua(self, lua: &Lua) -> Result { - to_lua_idx(self.0).into_lua(lua) - } -} - -impl FromLua<'_> for LuaIndex { - fn from_lua(value: LuaValue, lua: &Lua) -> Result { - Ok(LuaIndex(to_host_idx(usize::from_lua(value, lua)?))) - } -} - -/// Converts lua index to host index (Lua is 1 based, host is 0 based) -pub fn to_host_idx(lua_idx: usize) -> usize { - lua_idx - 1 -} - -/// Converts host index to lua index (Lua is 1 based, host is 0 based) -pub fn to_lua_idx(host_idx: usize) -> usize { - host_idx + 1 -} - -/// forwards the TypeName implementation of T, useful for internal 'fake' global instances -pub struct DummyTypeName { - _ph: PhantomData, -} - -impl DummyTypeName { - pub fn new( - _: &bevy_mod_scripting_lua::tealr::mlu::mlua::Lua, - ) -> bevy_mod_scripting_lua::tealr::mlu::mlua::Result { - Ok(Self { - _ph: PhantomData::, - }) - } -} - -impl<'lua, T> bevy_mod_scripting_lua::tealr::mlu::mlua::IntoLua<'lua> for DummyTypeName { - fn into_lua( - self, - _: &'lua bevy_mod_scripting_lua::tealr::mlu::mlua::Lua, - ) -> bevy_mod_scripting_lua::tealr::mlu::mlua::Result< - bevy_mod_scripting_lua::tealr::mlu::mlua::Value<'lua>, - > { - Ok(bevy_mod_scripting_lua::tealr::mlu::mlua::Value::Nil) - } -} - -impl ToTypename for DummyTypeName { - fn to_typename() -> bevy_mod_scripting_lua::tealr::Type { - T::to_typename() - } -} - -/// A utility type that allows us to accept any number of components as a parameter into a function. -#[derive(Clone)] -pub struct VariadicComponents(pub Vec); - -impl IntoLuaMulti<'_> for VariadicComponents { - fn into_lua_multi(self, lua: &Lua) -> Result, LuaError> { - let values = LuaMultiValue::from_vec( - self.0 - .into_iter() - .map(|v| v.into_lua(lua).unwrap()) - .collect(), - ); - - Ok(values) - } -} - -impl FromLuaMulti<'_> for VariadicComponents { - fn from_lua_multi(value: LuaMultiValue<'_>, lua: &Lua) -> Result { - Ok(VariadicComponents( - value - .into_vec() - .into_iter() - .map(|v| LuaTypeRegistration::from_lua(v, lua).unwrap()) - .collect(), - )) - } -} - -impl TealMultiValue for VariadicComponents { - fn get_types_as_params() -> Vec { - vec![FunctionParam { - // `...:T` will be a variadic type - param_name: Some(Name("...".into())), - ty: LuaTypeRegistration::to_typename(), - }] - } -} - -/// A utility enum that allows us to return an entity and any number of components from a function. -#[derive(Clone)] -pub enum VariadicQueryResult { - Some(LuaEntity, Vec), - None, -} - -impl IntoLuaMulti<'_> for VariadicQueryResult { - fn into_lua_multi(self, lua: &Lua) -> Result, LuaError> { - match self { - VariadicQueryResult::Some(entity, vec) => { - let mut values = LuaMultiValue::from_vec( - vec.into_iter() - .map(|v| v.into_lua(lua)) - .collect::, LuaError>>()?, - ); - - values.push_front(entity.into_lua(lua)?); - Ok(values) - } - VariadicQueryResult::None => Ok(().into_lua_multi(lua)?), - } - } -} - -impl TealMultiValue for VariadicQueryResult { - fn get_types_as_params() -> Vec { - vec![ - FunctionParam { - param_name: None, - ty: LuaEntity::to_typename(), - }, - FunctionParam { - param_name: None, - ty: Type::Single(SingleType { - kind: KindOfType::External, - // tealr doesn't have a way to add variadic return types, so it's inserted into the type name instead - name: Name(format!("{}...", stringify!(ReflectedValue)).into()), - }), - }, - ] - } -} - -#[macro_export] -macro_rules! impl_from_lua_with_clone { - ($v:ty) => { - impl<'lua> bevy_mod_scripting_lua::tealr::mlu::mlua::FromLua<'lua> for $v { - #[inline] - fn from_lua( - value: bevy_mod_scripting_lua::tealr::mlu::mlua::Value<'lua>, - _: &'lua bevy_mod_scripting_lua::tealr::mlu::mlua::Lua, - ) -> bevy_mod_scripting_lua::tealr::mlu::mlua::Result<$v> { - match value { - bevy_mod_scripting_lua::tealr::mlu::mlua::Value::UserData(ud) => { - Ok(ud.borrow::<$v>()?.clone()) - } - _ => Err( - bevy_mod_scripting_lua::tealr::mlu::mlua::Error::FromLuaConversionError { - from: value.type_name(), - to: "userdata", - message: None, - }, - ), - } - } - } - }; -} - -/// Implements :tealr::TypeName, tealr::TypeBody and mlua::Userdata based on non-generic single token type name implementing TealData -#[macro_export] -macro_rules! impl_tealr_type { - ($v:ty) => { - impl bevy_mod_scripting_lua::tealr::ToTypename for $v { - fn to_typename() -> bevy_mod_scripting_lua::tealr::Type { - bevy_mod_scripting_lua::tealr::Type::new_single(stringify!($v), bevy_mod_scripting_lua::tealr::KindOfType::External) - } - } - - impl bevy_mod_scripting_lua::tealr::mlu::mlua::UserData for $v { - fn add_fields<'lua, F: bevy_mod_scripting_lua::tealr::mlu::mlua::prelude::LuaUserDataFields<'lua, Self>>(fields: &mut F) { - let mut wrapper = ::bevy_mod_scripting_lua::tealr::mlu::UserDataWrapper::from_user_data_fields(fields); - ::add_fields(&mut wrapper) - } - - fn add_methods<'lua, M: bevy_mod_scripting_lua::tealr::mlu::mlua::prelude::LuaUserDataMethods<'lua, Self>>( - methods: &mut M, - ) { - let mut x = ::bevy_mod_scripting_lua::tealr::mlu::UserDataWrapper::from_user_data_methods(methods); - ::add_methods(&mut x); - } - } - - impl bevy_mod_scripting_lua::tealr::TypeBody for $v { - fn get_type_body() -> bevy_mod_scripting_lua::tealr::TypeGenerator { - let mut gen = ::bevy_mod_scripting_lua::tealr::RecordGenerator::new::(false); - gen.is_user_data = true; - ::add_fields(&mut gen); - ::add_methods(&mut gen); - <_ as ::std::convert::From<_>>::from(gen) - } - } - }; -} - -/// like create_bevy_mod_scripting_lua::tealr_union but translates to `any` in the lua declaration file, -/// a fill in to allow multiple userdata types -#[macro_export] -macro_rules! impl_tealr_any_union { - ($visibility:vis $(Derives($($derives:ident), +))? enum $type_name:ident = $($sub_types_ident:ident: $sub_types_type:ty) | +) => { - #[derive($($($derives ,)*)*)] - #[allow(non_camel_case_types)] - $visibility enum $type_name { - $($sub_types_ident($sub_types_type) ,)* - } - impl<'lua> ::bevy_mod_scripting_lua::tealr::mlu::mlua::IntoLua<'lua> for $type_name { - fn into_lua(self, lua: &'lua ::bevy_mod_scripting_lua::tealr::mlu::mlua::Lua) -> ::std::result::Result<::bevy_mod_scripting_lua::tealr::mlu::mlua::Value<'lua>, ::bevy_mod_scripting_lua::tealr::mlu::mlua::Error> { - match self { - $($type_name::$sub_types_ident(x) => x.into_lua(lua),)* - } - } - } - impl<'lua> ::bevy_mod_scripting_lua::tealr::mlu::mlua::FromLua<'lua> for $type_name { - fn from_lua(value: ::bevy_mod_scripting_lua::tealr::mlu::mlua::Value<'lua>, lua: &'lua ::bevy_mod_scripting_lua::tealr::mlu::mlua::Lua) -> ::std::result::Result { - $(match $sub_types_ident::from_lua(value.clone(),lua) { - Ok(x) => return Ok($type_name::$sub_types_ident(x)), - Err(::bevy_mod_scripting_lua::tealr::mlu::mlua::Error::FromLuaConversionError{from:_,to:_,message:_}) => {} - Err(x) => return Err(x) - };)* - Err(::bevy_mod_scripting_lua::tealr::mlu::mlua::Error::FromLuaConversionError{ - to: stringify!( $($sub_types_ident)|* ), - from: value.type_name(), - message: None - }) - } - } - impl ::bevy_mod_scripting_lua::tealr::ToTypename for $type_name { - fn to_typename() -> bevy_mod_scripting_lua::tealr::Type { - bevy_mod_scripting_lua::tealr::Type::new_single("any", bevy_mod_scripting_lua::tealr::KindOfType::Builtin) - } - } - }; -} - -#[macro_export] -macro_rules! impl_tealr_generic{ - { - $vis:vis struct $name:ident - } => { - #[derive(Default,Clone,Debug)] - $vis struct $name; - - impl $crate::lua::ValueLuaType for $name {} - - impl ::bevy_mod_scripting_lua::tealr::mlu::TealData for $name { - - } - - impl ::bevy::reflect::Typed for $name { - fn type_info() -> &'static ::bevy::reflect::TypeInfo { - panic!("This should never be called, I am a dummy implementation") - } - } - - impl ::bevy::reflect::TypePath for $name { - fn short_type_path() -> &'static str{ - panic!("This should never be called, I am a dummy implementation") - } - - fn type_path() -> &'static str{ - panic!("This should never be called, I am a dummy implementation") - } - } - - - impl ::bevy::reflect::PartialReflect for $name { - fn get_represented_type_info(&self) -> std::option::Option<&'static bevy::reflect::TypeInfo> { - panic!("This should never be called, I am a dummy implementation"); - } - - fn into_partial_reflect(self: Box) -> Box { - panic!("This should never be called, I am a dummy implementation"); - } - - fn as_partial_reflect(&self) -> &dyn ::bevy::reflect::PartialReflect { - panic!("This should never be called, I am a dummy implementation"); - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn ::bevy::reflect::PartialReflect { - panic!("This should never be called, I am a dummy implementation"); - } - - fn try_into_reflect(self: Box) -> std::result::Result, std::boxed::Box<(dyn bevy::prelude::PartialReflect + 'static)>> { - panic!("This should never be called, I am a dummy implementation"); - } - - fn try_as_reflect(&self) -> std::option::Option<&(dyn bevy::prelude::Reflect + 'static)> { - panic!("This should never be called, I am a dummy implementation"); - } - - fn try_as_reflect_mut(&mut self) -> std::option::Option<&mut (dyn bevy::prelude::Reflect + 'static)> { - panic!("This should never be called, I am a dummy implementation"); - } - - fn try_apply(&mut self, _value: &dyn ::bevy::prelude::PartialReflect) -> std::result::Result<(), ::bevy::reflect::ApplyError> { - panic!("This should never be called, I am a dummy implementation"); - } - - fn reflect_ref(&self) -> ::bevy::reflect::ReflectRef { - panic!("This should never be called, I am a dummy implementation"); - } - - fn reflect_mut(&mut self) -> ::bevy::reflect::ReflectMut { - panic!("This should never be called, I am a dummy implementation"); - } - - fn reflect_owned(self: Box) -> ::bevy::reflect::ReflectOwned { - panic!("This should never be called, I am a dummy implementation"); - } - - fn clone_value(&self) -> Box { - panic!("This should never be called, I am a dummy implementation"); - } - } - - - impl ::bevy::reflect::Reflect for $name { - - fn into_any(self: Box) -> Box { - panic!("This should never be called, I am a dummy implementation"); - } - - fn as_any(&self) -> &dyn std::any::Any { - panic!("This should never be called, I am a dummy implementation"); - } - - fn as_any_mut(&mut self) -> &mut dyn std::any::Any { - panic!("This should never be called, I am a dummy implementation"); - } - - fn as_reflect(&self) -> &dyn ::bevy::reflect::Reflect { - panic!("This should never be called, I am a dummy implementation"); - } - - fn as_reflect_mut(&mut self) -> &mut dyn ::bevy::reflect::Reflect { - panic!("This should never be called, I am a dummy implementation"); - } - - fn set(&mut self, _: Box) -> Result<(), Box> { - panic!("This should never be called, I am a dummy implementation"); - } - - fn into_reflect(self: Box) -> Box { - panic!("This should never be called, I am a dummy implementation"); - } - } - - impl ::bevy::reflect::FromReflect for $name { - fn from_reflect(_: &(dyn bevy::prelude::PartialReflect + 'static)) -> std::option::Option { - panic!("This should never be called, I am a dummy implementation"); - } - - } - - impl ::bevy::reflect::GetTypeRegistration for $name { - fn get_type_registration() -> bevy::reflect::TypeRegistration { - panic!("This should never be called, I am a dummy implementation"); - } - } - - $crate::impl_tealr_type!($name); - $crate::impl_from_lua_with_clone!($name); - } -} - -// /// Implements UserData for type which implements TealData, can handle generics after the type name: -// /// ```rust,ignore -// /// impl_user_data!(MyType<'a,T : Debug>); -// /// ``` -// macro_rules! impl_user_data { -// ($v:ident $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt $(<'a>)? )* )? ),+ >)? ) => { -// impl $(< $( $lt $( : $clt $(+ $dlt $(<'a>)?)* )? ),+ >)? ::bevy_mod_scripting_lua::tealr::mlu::mlua::UserData for $v $(< $( $lt ),+ >)? { -// fn add_methods<'lua, M: ::bevy_mod_scripting_lua::tealr::mlu::mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { -// let mut x = ::bevy_mod_scripting_lua::tealr::mlu::UserDataWrapper::from_user_data_methods(methods); -// ::add_methods(&mut x); -// } -// fn add_fields<'lua, F: ::bevy_mod_scripting_lua::tealr::mlu::mlua::UserDataFields<'lua, Self>>(fields: &mut F) { -// let mut wrapper = ::bevy_mod_scripting_lua::tealr::mlu::UserDataWrapper::from_user_data_fields(fields); -// ::add_fields(&mut wrapper) -// } -// } - -// } -// } - -// pub(crate) use impl_user_data; diff --git a/crates/bevy_script_api/src/providers/bevy_core.rs b/crates/bevy_script_api/src/providers/bevy_core.rs deleted file mode 100644 index 762e6fb7..00000000 --- a/crates/bevy_script_api/src/providers/bevy_core.rs +++ /dev/null @@ -1,95 +0,0 @@ -// @generated by cargo bevy-api-gen generate, modify the templates not this file -#![allow(clippy::all)] -#![allow(unused, deprecated, dead_code)] -#![cfg_attr(rustfmt, rustfmt_skip)] -use super::bevy_ecs::*; -use super::bevy_reflect::*; -extern crate self as bevy_script_api; -use bevy_script_api::{ - lua::RegisterForeignLuaType, ReflectedValue, common::bevy::GetWorld, -}; -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::core::prelude::Name", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &name::Name) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::core::prelude::Name; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{}", _self) -} -"#] -)] -struct Name {} -#[derive(Default)] -pub(crate) struct Globals; -impl bevy_mod_scripting_lua::tealr::mlu::ExportInstances for Globals { - fn add_instances< - 'lua, - T: bevy_mod_scripting_lua::tealr::mlu::InstanceCollector<'lua>, - >(self, instances: &mut T) -> bevy_mod_scripting_lua::tealr::mlu::mlua::Result<()> { - Ok(()) - } -} -pub struct BevyCoreAPIProvider; -impl bevy_mod_scripting_core::hosts::APIProvider for BevyCoreAPIProvider { - type APITarget = std::sync::Mutex; - type ScriptContext = std::sync::Mutex; - type DocTarget = bevy_mod_scripting_lua::docs::LuaDocFragment; - fn attach_api( - &mut self, - ctx: &mut Self::APITarget, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - let ctx = ctx.get_mut().expect("Unable to acquire lock on Lua context"); - bevy_mod_scripting_lua::tealr::mlu::set_global_env(Globals, ctx) - .map_err(|e| bevy_mod_scripting_core::error::ScriptError::Other( - e.to_string(), - )) - } - fn get_doc_fragment(&self) -> Option { - Some( - bevy_mod_scripting_lua::docs::LuaDocFragment::new( - "BevyCoreAPI", - |tw| { - tw.document_global_instance::() - .expect("Something went wrong documenting globals") - .process_type::() - }, - ), - ) - } - fn setup_script( - &mut self, - script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - fn setup_script_runtime( - &mut self, - world_ptr: bevy_mod_scripting_core::world::WorldPointer, - _script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - fn register_with_app(&self, app: &mut bevy::app::App) { - app.register_foreign_lua_type::(); - } -} diff --git a/crates/bevy_script_api/src/providers/bevy_ecs.rs b/crates/bevy_script_api/src/providers/bevy_ecs.rs deleted file mode 100644 index a790dbc9..00000000 --- a/crates/bevy_script_api/src/providers/bevy_ecs.rs +++ /dev/null @@ -1,560 +0,0 @@ -// @generated by cargo bevy-api-gen generate, modify the templates not this file -#![allow(clippy::all)] -#![allow(unused, deprecated, dead_code)] -#![cfg_attr(rustfmt, rustfmt_skip)] -use super::bevy_reflect::*; -extern crate self as bevy_script_api; -use bevy_script_api::{ - lua::RegisterForeignLuaType, ReflectedValue, common::bevy::GetWorld, -}; -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::ecs::entity::Entity", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &entity::Entity) -> bool; - -"#, - r#" -/// Creates a new entity ID with the specified `index` and a generation of 1. -/// # Note -/// Spawning a specific `entity` value is __rarely the right choice__. Most apps should favor -/// [`Commands::spawn`](crate::system::Commands::spawn). This method should generally -/// only be used for sharing entities across apps, and only when they have a scheme -/// worked out to share an index space (which doesn't happen by default). -/// In general, one should not try to synchronize the ECS by attempting to ensure that -/// `Entity` lines up between instances, but instead insert a secondary identifier as -/// a component. - - #[lua(kind = "Function", output(proxy))] - fn from_raw(index: u32) -> bevy::ecs::entity::Entity; - -"#, - r#" -/// Convert to a form convenient for passing outside of rust. -/// Only useful for identifying entities within the same instance of an application. Do not use -/// for serialization between runs. -/// No particular structure is guaranteed for the returned bits. - - #[lua(kind = "Method")] - fn to_bits(self) -> u64; - -"#, - r#" -/// Reconstruct an `Entity` previously destructured with [`Entity::to_bits`]. -/// Only useful when applied to results from `to_bits` in the same instance of an application. -/// # Panics -/// This method will likely panic if given `u64` values that did not come from [`Entity::to_bits`]. - - #[lua(kind = "Function", output(proxy))] - fn from_bits(bits: u64) -> bevy::ecs::entity::Entity; - -"#, - r#" -/// Return a transiently unique identifier. -/// No two simultaneously-live entities share the same index, but dead entities' indices may collide -/// with both live and dead entities. Useful for compactly representing entities within a -/// specific snapshot of the world, such as when serializing. - - #[lua(kind = "Method")] - fn index(self) -> u32; - -"#, - r#" -/// Returns the generation of this Entity's index. The generation is incremented each time an -/// entity with a given index is despawned. This serves as a "count" of the number of times a -/// given index has been reused (index, generation) pairs uniquely identify a given Entity. - - #[lua(kind = "Method")] - fn generation(self) -> u32; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::ecs::entity::Entity; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Entity {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(), - remote = "bevy::ecs::world::OnAdd", - functions[r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct OnAdd {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(), - remote = "bevy::ecs::world::OnInsert", - functions[r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct OnInsert {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(), - remote = "bevy::ecs::world::OnRemove", - functions[r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct OnRemove {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(), - remote = "bevy::ecs::world::OnReplace", - functions[r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct OnReplace {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::ecs::component::ComponentId", - functions[r#" -/// Creates a new [`ComponentId`]. -/// The `index` is a unique value associated with each type of component in a given world. -/// Usually, this value is taken from a counter incremented for each type of component registered with the world. - - #[lua(kind = "Function", output(proxy))] - fn new(index: usize) -> bevy::ecs::component::ComponentId; - -"#, - r#" -/// Returns the index of the current component. - - #[lua(kind = "Method")] - fn index(self) -> usize; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::ecs::component::ComponentId; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &component::ComponentId) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct ComponentId(); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::ecs::component::Tick", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::ecs::component::Tick; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &component::Tick) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" -/// Creates a new [`Tick`] wrapping the given value. - - #[lua(kind = "Function", output(proxy))] - fn new(tick: u32) -> bevy::ecs::component::Tick; - -"#, - r#" -/// Gets the value of this change tick. - - #[lua(kind = "Method")] - fn get(self) -> u32; - -"#, - r#" -/// Sets the value of this change tick. - - #[lua(kind = "MutatingMethod")] - fn set(&mut self, tick: u32) -> (); - -"#, - r#" -/// Returns `true` if this `Tick` occurred since the system's `last_run`. -/// `this_run` is the current tick of the system, used as a reference to help deal with wraparound. - - #[lua(kind = "Method")] - fn is_newer_than( - self, - #[proxy] - last_run: bevy::ecs::component::Tick, - #[proxy] - this_run: bevy::ecs::component::Tick, - ) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Tick {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::ecs::component::ComponentTicks", - functions[r#" -/// Returns `true` if the component or resource was added after the system last ran -/// (or the system is running for the first time). - - #[lua(kind = "Method")] - fn is_added( - &self, - #[proxy] - last_run: bevy::ecs::component::Tick, - #[proxy] - this_run: bevy::ecs::component::Tick, - ) -> bool; - -"#, - r#" -/// Returns `true` if the component or resource was added or mutably dereferenced after the system last ran -/// (or the system is running for the first time). - - #[lua(kind = "Method")] - fn is_changed( - &self, - #[proxy] - last_run: bevy::ecs::component::Tick, - #[proxy] - this_run: bevy::ecs::component::Tick, - ) -> bool; - -"#, - r#" -/// Creates a new instance with the same change tick for `added` and `changed`. - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - change_tick: bevy::ecs::component::Tick, - ) -> bevy::ecs::component::ComponentTicks; - -"#, - r#" -/// Manually sets the change tick. -/// This is normally done automatically via the [`DerefMut`](std::ops::DerefMut) implementation -/// on [`Mut`](crate::change_detection::Mut), [`ResMut`](crate::change_detection::ResMut), etc. -/// However, components and resources that make use of interior mutability might require manual updates. -/// # Example -/// ```no_run -/// # use bevy_ecs::{world::World, component::ComponentTicks}; -/// let world: World = unimplemented!(); -/// let component_ticks: ComponentTicks = unimplemented!(); -/// component_ticks.set_changed(world.read_change_tick()); -/// ``` - - #[lua(kind = "MutatingMethod")] - fn set_changed(&mut self, #[proxy] change_tick: bevy::ecs::component::Tick) -> (); - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::ecs::component::ComponentTicks; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct ComponentTicks { - #[lua(output(proxy))] - added: bevy::ecs::component::Tick, - #[lua(output(proxy))] - changed: bevy::ecs::component::Tick, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::ecs::identifier::Identifier", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &identifier::Identifier) -> bool; - -"#, - r#" -/// Returns the value of the low segment of the [`Identifier`]. - - #[lua(kind = "Method")] - fn low(self) -> u32; - -"#, - r#" -/// Returns the masked value of the high segment of the [`Identifier`]. -/// Does not include the flag bits. - - #[lua(kind = "Method")] - fn masked_high(self) -> u32; - -"#, - r#" -/// Convert the [`Identifier`] into a `u64`. - - #[lua(kind = "Method")] - fn to_bits(self) -> u64; - -"#, - r#" -/// Convert a `u64` into an [`Identifier`]. -/// # Panics -/// This method will likely panic if given `u64` values that did not come from [`Identifier::to_bits`]. - - #[lua(kind = "Function", output(proxy))] - fn from_bits(value: u64) -> bevy::ecs::identifier::Identifier; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::ecs::identifier::Identifier; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Identifier {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::ecs::entity::EntityHash", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::ecs::entity::EntityHash; - -"#] -)] -struct EntityHash {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::ecs::removal_detection::RemovedComponentEntity", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::ecs::removal_detection::RemovedComponentEntity; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct RemovedComponentEntity(); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy(derive(), remote = "bevy::ecs::system::SystemIdMarker", functions[])] -struct SystemIdMarker {} -#[derive(Default)] -pub(crate) struct Globals; -impl bevy_mod_scripting_lua::tealr::mlu::ExportInstances for Globals { - fn add_instances< - 'lua, - T: bevy_mod_scripting_lua::tealr::mlu::InstanceCollector<'lua>, - >(self, instances: &mut T) -> bevy_mod_scripting_lua::tealr::mlu::mlua::Result<()> { - instances - .add_instance( - "Entity", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "ComponentId", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Tick", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "ComponentTicks", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::< - LuaComponentTicks, - >::new, - )?; - instances - .add_instance( - "Identifier", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - Ok(()) - } -} -pub struct BevyEcsAPIProvider; -impl bevy_mod_scripting_core::hosts::APIProvider for BevyEcsAPIProvider { - type APITarget = std::sync::Mutex; - type ScriptContext = std::sync::Mutex; - type DocTarget = bevy_mod_scripting_lua::docs::LuaDocFragment; - fn attach_api( - &mut self, - ctx: &mut Self::APITarget, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - let ctx = ctx.get_mut().expect("Unable to acquire lock on Lua context"); - bevy_mod_scripting_lua::tealr::mlu::set_global_env(Globals, ctx) - .map_err(|e| bevy_mod_scripting_core::error::ScriptError::Other( - e.to_string(), - )) - } - fn get_doc_fragment(&self) -> Option { - Some( - bevy_mod_scripting_lua::docs::LuaDocFragment::new( - "BevyEcsAPI", - |tw| { - tw.document_global_instance::() - .expect("Something went wrong documenting globals") - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaComponentId, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaComponentTicks, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaIdentifier, - >, - >() - .process_type::() - .process_type::() - .process_type::() - }, - ), - ) - } - fn setup_script( - &mut self, - script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - fn setup_script_runtime( - &mut self, - world_ptr: bevy_mod_scripting_core::world::WorldPointer, - _script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - fn register_with_app(&self, app: &mut bevy::app::App) { - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::< - bevy::ecs::removal_detection::RemovedComponentEntity, - >(); - app.register_foreign_lua_type::(); - } -} diff --git a/crates/bevy_script_api/src/providers/bevy_hierarchy.rs b/crates/bevy_script_api/src/providers/bevy_hierarchy.rs deleted file mode 100644 index 23708e43..00000000 --- a/crates/bevy_script_api/src/providers/bevy_hierarchy.rs +++ /dev/null @@ -1,161 +0,0 @@ -// @generated by cargo bevy-api-gen generate, modify the templates not this file -#![allow(clippy::all)] -#![allow(unused, deprecated, dead_code)] -#![cfg_attr(rustfmt, rustfmt_skip)] -use super::bevy_ecs::*; -use super::bevy_reflect::*; -use super::bevy_core::*; -extern crate self as bevy_script_api; -use bevy_script_api::{ - lua::RegisterForeignLuaType, ReflectedValue, common::bevy::GetWorld, -}; -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(), - remote = "bevy::hierarchy::prelude::Children", - functions[r#" -/// Swaps the child at `a_index` with the child at `b_index`. - - #[lua(kind = "MutatingMethod")] - fn swap(&mut self, a_index: usize, b_index: usize) -> (); - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Children(); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(), - remote = "bevy::hierarchy::prelude::Parent", - functions[r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &components::parent::Parent) -> bool; - -"#, - r#" -/// Gets the [`Entity`] ID of the parent. - - #[lua(kind = "Method", output(proxy))] - fn get(&self) -> bevy::ecs::entity::Entity; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Parent(); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::hierarchy::HierarchyEvent", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::hierarchy::HierarchyEvent; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &events::HierarchyEvent) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct HierarchyEvent {} -#[derive(Default)] -pub(crate) struct Globals; -impl bevy_mod_scripting_lua::tealr::mlu::ExportInstances for Globals { - fn add_instances< - 'lua, - T: bevy_mod_scripting_lua::tealr::mlu::InstanceCollector<'lua>, - >(self, instances: &mut T) -> bevy_mod_scripting_lua::tealr::mlu::mlua::Result<()> { - Ok(()) - } -} -pub struct BevyHierarchyAPIProvider; -impl bevy_mod_scripting_core::hosts::APIProvider for BevyHierarchyAPIProvider { - type APITarget = std::sync::Mutex; - type ScriptContext = std::sync::Mutex; - type DocTarget = bevy_mod_scripting_lua::docs::LuaDocFragment; - fn attach_api( - &mut self, - ctx: &mut Self::APITarget, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - let ctx = ctx.get_mut().expect("Unable to acquire lock on Lua context"); - bevy_mod_scripting_lua::tealr::mlu::set_global_env(Globals, ctx) - .map_err(|e| bevy_mod_scripting_core::error::ScriptError::Other( - e.to_string(), - )) - } - fn get_doc_fragment(&self) -> Option { - Some( - bevy_mod_scripting_lua::docs::LuaDocFragment::new( - "BevyHierarchyAPI", - |tw| { - tw.document_global_instance::() - .expect("Something went wrong documenting globals") - .process_type::() - .process_type::() - .process_type::() - }, - ), - ) - } - fn setup_script( - &mut self, - script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - fn setup_script_runtime( - &mut self, - world_ptr: bevy_mod_scripting_core::world::WorldPointer, - _script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - fn register_with_app(&self, app: &mut bevy::app::App) { - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - } -} diff --git a/crates/bevy_script_api/src/providers/bevy_input.rs b/crates/bevy_script_api/src/providers/bevy_input.rs deleted file mode 100644 index 852d5a90..00000000 --- a/crates/bevy_script_api/src/providers/bevy_input.rs +++ /dev/null @@ -1,1887 +0,0 @@ -// @generated by cargo bevy-api-gen generate, modify the templates not this file -#![allow(clippy::all)] -#![allow(unused, deprecated, dead_code)] -#![cfg_attr(rustfmt, rustfmt_skip)] -use super::bevy_ecs::*; -use super::bevy_reflect::*; -use super::bevy_core::*; -use super::bevy_math::*; -extern crate self as bevy_script_api; -use bevy_script_api::{ - lua::RegisterForeignLuaType, ReflectedValue, common::bevy::GetWorld, -}; -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(), - remote = "bevy::input::gamepad::Gamepad", - functions[r#" -/// Returns the USB vendor ID as assigned by the USB-IF, if available. - - #[lua(kind = "Method")] - fn vendor_id(&self) -> std::option::Option; - -"#, - r#" -/// Returns the USB product ID as assigned by the [vendor], if available. -/// [vendor]: Self::vendor_id - - #[lua(kind = "Method")] - fn product_id(&self) -> std::option::Option; - -"#, - r#" -/// Returns the left stick as a [`Vec2`] - - #[lua(kind = "Method", output(proxy))] - fn left_stick(&self) -> bevy::math::Vec2; - -"#, - r#" -/// Returns the right stick as a [`Vec2`] - - #[lua(kind = "Method", output(proxy))] - fn right_stick(&self) -> bevy::math::Vec2; - -"#, - r#" -/// Returns the directional pad as a [`Vec2`] - - #[lua(kind = "Method", output(proxy))] - fn dpad(&self) -> bevy::math::Vec2; - -"#, - r#" -/// Returns `true` if the [`GamepadButton`] has been pressed. - - #[lua(kind = "Method")] - fn pressed(&self, #[proxy] button_type: bevy::input::gamepad::GamepadButton) -> bool; - -"#, - r#" -/// Returns `true` if the [`GamepadButton`] has been pressed during the current frame. -/// Note: This function does not imply information regarding the current state of [`ButtonInput::pressed`] or [`ButtonInput::just_released`]. - - #[lua(kind = "Method")] - fn just_pressed( - &self, - #[proxy] - button_type: bevy::input::gamepad::GamepadButton, - ) -> bool; - -"#, - r#" -/// Returns `true` if the [`GamepadButton`] has been released during the current frame. -/// Note: This function does not imply information regarding the current state of [`ButtonInput::pressed`] or [`ButtonInput::just_pressed`]. - - #[lua(kind = "Method")] - fn just_released( - &self, - #[proxy] - button_type: bevy::input::gamepad::GamepadButton, - ) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Gamepad {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gamepad::GamepadAxis", - functions[r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gamepad::GamepadAxis; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gamepad::GamepadAxis) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct GamepadAxis {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gamepad::GamepadButton", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gamepad::GamepadButton) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gamepad::GamepadButton; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct GamepadButton {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gamepad::GamepadSettings", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gamepad::GamepadSettings; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct GamepadSettings { - #[lua(output(proxy))] - default_button_settings: bevy::input::gamepad::ButtonSettings, - #[lua(output(proxy))] - default_axis_settings: bevy::input::gamepad::AxisSettings, - #[lua(output(proxy))] - default_button_axis_settings: bevy::input::gamepad::ButtonAxisSettings, - button_settings: ReflectedValue, - axis_settings: ReflectedValue, - button_axis_settings: ReflectedValue, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::keyboard::KeyCode", - functions[r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::keyboard::KeyCode; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &keyboard::KeyCode) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct KeyCode {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::mouse::MouseButton", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &mouse::MouseButton) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::mouse::MouseButton; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct MouseButton {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::touch::TouchInput", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::touch::TouchInput; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &touch::TouchInput) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct TouchInput { - #[lua(output(proxy))] - phase: bevy::input::touch::TouchPhase, - #[lua(output(proxy))] - position: bevy::math::Vec2, - #[lua(output(proxy))] - window: bevy::ecs::entity::Entity, - force: ReflectedValue, - id: u64, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::keyboard::KeyboardFocusLost", - functions[r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &keyboard::KeyboardFocusLost) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::keyboard::KeyboardFocusLost; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct KeyboardFocusLost {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::keyboard::KeyboardInput", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &keyboard::KeyboardInput) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::keyboard::KeyboardInput; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct KeyboardInput { - #[lua(output(proxy))] - key_code: bevy::input::keyboard::KeyCode, - #[lua(output(proxy))] - logical_key: bevy::input::keyboard::Key, - #[lua(output(proxy))] - state: bevy::input::ButtonState, - repeat: bool, - #[lua(output(proxy))] - window: bevy::ecs::entity::Entity, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::mouse::AccumulatedMouseMotion", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &mouse::AccumulatedMouseMotion) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::mouse::AccumulatedMouseMotion; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct AccumulatedMouseMotion { - #[lua(output(proxy))] - delta: bevy::math::Vec2, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::mouse::AccumulatedMouseScroll", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &mouse::AccumulatedMouseScroll) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::mouse::AccumulatedMouseScroll; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct AccumulatedMouseScroll { - #[lua(output(proxy))] - unit: bevy::input::mouse::MouseScrollUnit, - #[lua(output(proxy))] - delta: bevy::math::Vec2, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::mouse::MouseButtonInput", - functions[r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::mouse::MouseButtonInput; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &mouse::MouseButtonInput) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct MouseButtonInput { - #[lua(output(proxy))] - button: bevy::input::mouse::MouseButton, - #[lua(output(proxy))] - state: bevy::input::ButtonState, - #[lua(output(proxy))] - window: bevy::ecs::entity::Entity, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::mouse::MouseMotion", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &mouse::MouseMotion) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::mouse::MouseMotion; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct MouseMotion { - #[lua(output(proxy))] - delta: bevy::math::Vec2, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::mouse::MouseWheel", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::mouse::MouseWheel; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &mouse::MouseWheel) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct MouseWheel { - #[lua(output(proxy))] - unit: bevy::input::mouse::MouseScrollUnit, - x: f32, - y: f32, - #[lua(output(proxy))] - window: bevy::ecs::entity::Entity, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gamepad::GamepadAxisChangedEvent", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gamepad::GamepadAxisChangedEvent; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gamepad::GamepadAxisChangedEvent) -> bool; - -"#, - r#" -/// Creates a new [`GamepadAxisChangedEvent`] - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - entity: bevy::ecs::entity::Entity, - #[proxy] - axis: bevy::input::gamepad::GamepadAxis, - value: f32, - ) -> bevy::input::gamepad::GamepadAxisChangedEvent; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct GamepadAxisChangedEvent { - #[lua(output(proxy))] - entity: bevy::ecs::entity::Entity, - #[lua(output(proxy))] - axis: bevy::input::gamepad::GamepadAxis, - value: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gamepad::GamepadButtonChangedEvent", - functions[r#" -/// Creates a new [`GamepadButtonChangedEvent`] - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - entity: bevy::ecs::entity::Entity, - #[proxy] - button: bevy::input::gamepad::GamepadButton, - #[proxy] - state: bevy::input::ButtonState, - value: f32, - ) -> bevy::input::gamepad::GamepadButtonChangedEvent; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gamepad::GamepadButtonChangedEvent; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gamepad::GamepadButtonChangedEvent) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct GamepadButtonChangedEvent { - #[lua(output(proxy))] - entity: bevy::ecs::entity::Entity, - #[lua(output(proxy))] - button: bevy::input::gamepad::GamepadButton, - #[lua(output(proxy))] - state: bevy::input::ButtonState, - value: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gamepad::GamepadButtonStateChangedEvent", - functions[r#" -/// Creates a new [`GamepadButtonStateChangedEvent`] - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - entity: bevy::ecs::entity::Entity, - #[proxy] - button: bevy::input::gamepad::GamepadButton, - #[proxy] - state: bevy::input::ButtonState, - ) -> bevy::input::gamepad::GamepadButtonStateChangedEvent; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gamepad::GamepadButtonStateChangedEvent) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gamepad::GamepadButtonStateChangedEvent; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct GamepadButtonStateChangedEvent { - #[lua(output(proxy))] - entity: bevy::ecs::entity::Entity, - #[lua(output(proxy))] - button: bevy::input::gamepad::GamepadButton, - #[lua(output(proxy))] - state: bevy::input::ButtonState, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gamepad::GamepadConnection", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gamepad::GamepadConnection) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gamepad::GamepadConnection; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct GamepadConnection {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gamepad::GamepadConnectionEvent", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gamepad::GamepadConnectionEvent) -> bool; - -"#, - r#" -/// Creates a [`GamepadConnectionEvent`]. - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - gamepad: bevy::ecs::entity::Entity, - #[proxy] - connection: bevy::input::gamepad::GamepadConnection, - ) -> bevy::input::gamepad::GamepadConnectionEvent; - -"#, - r#" -/// Is the gamepad connected? - - #[lua(kind = "Method")] - fn connected(&self) -> bool; - -"#, - r#" -/// Is the gamepad disconnected? - - #[lua(kind = "Method")] - fn disconnected(&self) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gamepad::GamepadConnectionEvent; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct GamepadConnectionEvent { - #[lua(output(proxy))] - gamepad: bevy::ecs::entity::Entity, - #[lua(output(proxy))] - connection: bevy::input::gamepad::GamepadConnection, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gamepad::GamepadEvent", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gamepad::GamepadEvent) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gamepad::GamepadEvent; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct GamepadEvent {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gamepad::GamepadInput", - functions[r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gamepad::GamepadInput) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gamepad::GamepadInput; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct GamepadInput {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gamepad::GamepadRumbleRequest", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gamepad::GamepadRumbleRequest; - -"#, - r#" -/// Get the [`Entity`] associated with this request. - - #[lua(kind = "Method", output(proxy))] - fn gamepad(&self) -> bevy::ecs::entity::Entity; - -"#] -)] -struct GamepadRumbleRequest {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gamepad::RawGamepadAxisChangedEvent", - functions[r#" -/// Creates a [`RawGamepadAxisChangedEvent`]. - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - gamepad: bevy::ecs::entity::Entity, - #[proxy] - axis_type: bevy::input::gamepad::GamepadAxis, - value: f32, - ) -> bevy::input::gamepad::RawGamepadAxisChangedEvent; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gamepad::RawGamepadAxisChangedEvent) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gamepad::RawGamepadAxisChangedEvent; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct RawGamepadAxisChangedEvent { - #[lua(output(proxy))] - gamepad: bevy::ecs::entity::Entity, - #[lua(output(proxy))] - axis: bevy::input::gamepad::GamepadAxis, - value: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gamepad::RawGamepadButtonChangedEvent", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gamepad::RawGamepadButtonChangedEvent) -> bool; - -"#, - r#" -/// Creates a [`RawGamepadButtonChangedEvent`]. - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - gamepad: bevy::ecs::entity::Entity, - #[proxy] - button_type: bevy::input::gamepad::GamepadButton, - value: f32, - ) -> bevy::input::gamepad::RawGamepadButtonChangedEvent; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gamepad::RawGamepadButtonChangedEvent; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct RawGamepadButtonChangedEvent { - #[lua(output(proxy))] - gamepad: bevy::ecs::entity::Entity, - #[lua(output(proxy))] - button: bevy::input::gamepad::GamepadButton, - value: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gamepad::RawGamepadEvent", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gamepad::RawGamepadEvent) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gamepad::RawGamepadEvent; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct RawGamepadEvent {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gestures::PinchGesture", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gestures::PinchGesture) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gestures::PinchGesture; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct PinchGesture(f32); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gestures::RotationGesture", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gestures::RotationGesture; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gestures::RotationGesture) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct RotationGesture(f32); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gestures::DoubleTapGesture", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gestures::DoubleTapGesture) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gestures::DoubleTapGesture; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct DoubleTapGesture {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gestures::PanGesture", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gestures::PanGesture) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gestures::PanGesture; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct PanGesture(#[lua(output(proxy))] bevy::math::Vec2); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::ButtonState", - functions[r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &ButtonState) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::ButtonState; - -"#, - r#" -/// Is this button pressed? - - #[lua(kind = "Method")] - fn is_pressed(&self) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct ButtonState {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gamepad::ButtonSettings", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gamepad::ButtonSettings) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gamepad::ButtonSettings; - -"#, - r#" -/// Returns `true` if the button is pressed. -/// A button is considered pressed if the `value` passed is greater than or equal to the press threshold. - - #[lua(kind = "Method")] - fn is_pressed(&self, value: f32) -> bool; - -"#, - r#" -/// Returns `true` if the button is released. -/// A button is considered released if the `value` passed is lower than or equal to the release threshold. - - #[lua(kind = "Method")] - fn is_released(&self, value: f32) -> bool; - -"#, - r#" -/// Get the button input threshold above which the button is considered pressed. - - #[lua(kind = "Method")] - fn press_threshold(&self) -> f32; - -"#, - r#" -/// Try to set the button input threshold above which the button is considered pressed. -/// If the value passed is outside the range [release threshold..=1.0], the value will not be changed. -/// Returns the new value of the press threshold. - - #[lua(kind = "MutatingMethod")] - fn set_press_threshold(&mut self, value: f32) -> f32; - -"#, - r#" -/// Get the button input threshold below which the button is considered released. - - #[lua(kind = "Method")] - fn release_threshold(&self) -> f32; - -"#, - r#" -/// Try to set the button input threshold below which the button is considered released. If the -/// value passed is outside the range [0.0..=press threshold], the value will not be changed. -/// Returns the new value of the release threshold. - - #[lua(kind = "MutatingMethod")] - fn set_release_threshold(&mut self, value: f32) -> f32; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct ButtonSettings {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gamepad::AxisSettings", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gamepad::AxisSettings) -> bool; - -"#, - r#" -/// Get the value above which inputs will be rounded up to 1.0. - - #[lua(kind = "Method")] - fn livezone_upperbound(&self) -> f32; - -"#, - r#" -/// Try to set the value above which inputs will be rounded up to 1.0. -/// If the value passed is negative or less than `deadzone_upperbound`, -/// the value will not be changed. -/// Returns the new value of `livezone_upperbound`. - - #[lua(kind = "MutatingMethod")] - fn set_livezone_upperbound(&mut self, value: f32) -> f32; - -"#, - r#" -/// Get the value below which positive inputs will be rounded down to 0.0. - - #[lua(kind = "Method")] - fn deadzone_upperbound(&self) -> f32; - -"#, - r#" -/// Try to set the value below which positive inputs will be rounded down to 0.0. -/// If the value passed is negative or greater than `livezone_upperbound`, -/// the value will not be changed. -/// Returns the new value of `deadzone_upperbound`. - - #[lua(kind = "MutatingMethod")] - fn set_deadzone_upperbound(&mut self, value: f32) -> f32; - -"#, - r#" -/// Get the value below which negative inputs will be rounded down to -1.0. - - #[lua(kind = "Method")] - fn livezone_lowerbound(&self) -> f32; - -"#, - r#" -/// Try to set the value below which negative inputs will be rounded down to -1.0. -/// If the value passed is positive or greater than `deadzone_lowerbound`, -/// the value will not be changed. -/// Returns the new value of `livezone_lowerbound`. - - #[lua(kind = "MutatingMethod")] - fn set_livezone_lowerbound(&mut self, value: f32) -> f32; - -"#, - r#" -/// Get the value above which inputs will be rounded up to 0.0. - - #[lua(kind = "Method")] - fn deadzone_lowerbound(&self) -> f32; - -"#, - r#" -/// Try to set the value above which inputs will be rounded up to 0.0. -/// If the value passed is less than -1.0 or less than `livezone_lowerbound`, -/// the value will not be changed. -/// Returns the new value of `deadzone_lowerbound`. - - #[lua(kind = "MutatingMethod")] - fn set_deadzone_lowerbound(&mut self, value: f32) -> f32; - -"#, - r#" -/// Get the minimum value by which input must change before the change is registered. - - #[lua(kind = "Method")] - fn threshold(&self) -> f32; - -"#, - r#" -/// Try to set the minimum value by which input must change before the changes will be applied. -/// If the value passed is not within [0.0..=2.0], the value will not be changed. -/// Returns the new value of threshold. - - #[lua(kind = "MutatingMethod")] - fn set_threshold(&mut self, value: f32) -> f32; - -"#, - r#" -/// Clamps the `raw_value` according to the `AxisSettings`. - - #[lua(kind = "Method")] - fn clamp(&self, new_value: f32) -> f32; - -"#, - r#" -/// Filters the `new_value` based on the `old_value`, according to the [`AxisSettings`]. -/// Returns the clamped `new_value` if the change exceeds the settings threshold, -/// and `None` otherwise. - - #[lua(kind = "Method")] - fn filter( - &self, - new_value: f32, - old_value: std::option::Option, - ) -> std::option::Option; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gamepad::AxisSettings; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct AxisSettings {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gamepad::ButtonAxisSettings", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gamepad::ButtonAxisSettings; - -"#, - r#" -/// Filters the `new_value` based on the `old_value`, according to the [`ButtonAxisSettings`]. -/// Returns the clamped `new_value`, according to the [`ButtonAxisSettings`], if the change -/// exceeds the settings threshold, and `None` otherwise. - - #[lua(kind = "Method")] - fn filter( - &self, - new_value: f32, - old_value: std::option::Option, - ) -> std::option::Option; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct ButtonAxisSettings { - high: f32, - low: f32, - threshold: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::gamepad::GamepadRumbleIntensity", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &gamepad::GamepadRumbleIntensity) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::gamepad::GamepadRumbleIntensity; - -"#, - r#" -/// Creates a new rumble intensity with weak motor intensity set to the given value. -/// Clamped within the `0.0` to `1.0` range. - - #[lua(kind = "Function", output(proxy))] - fn weak_motor(intensity: f32) -> bevy::input::gamepad::GamepadRumbleIntensity; - -"#, - r#" -/// Creates a new rumble intensity with strong motor intensity set to the given value. -/// Clamped within the `0.0` to `1.0` range. - - #[lua(kind = "Function", output(proxy))] - fn strong_motor(intensity: f32) -> bevy::input::gamepad::GamepadRumbleIntensity; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct GamepadRumbleIntensity { - strong_motor: f32, - weak_motor: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::keyboard::Key", - functions[r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &keyboard::Key) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::keyboard::Key; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Key {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::keyboard::NativeKeyCode", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &keyboard::NativeKeyCode) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::keyboard::NativeKeyCode; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct NativeKeyCode {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::keyboard::NativeKey", - functions[r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::keyboard::NativeKey; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &keyboard::NativeKey) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct NativeKey {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::mouse::MouseScrollUnit", - functions[r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::mouse::MouseScrollUnit; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &mouse::MouseScrollUnit) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct MouseScrollUnit {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::touch::TouchPhase", - functions[r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::touch::TouchPhase; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &touch::TouchPhase) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct TouchPhase {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::input::touch::ForceTouch", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::input::touch::ForceTouch; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &touch::ForceTouch) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct ForceTouch {} -#[derive(Default)] -pub(crate) struct Globals; -impl bevy_mod_scripting_lua::tealr::mlu::ExportInstances for Globals { - fn add_instances< - 'lua, - T: bevy_mod_scripting_lua::tealr::mlu::InstanceCollector<'lua>, - >(self, instances: &mut T) -> bevy_mod_scripting_lua::tealr::mlu::mlua::Result<()> { - instances - .add_instance( - "GamepadAxisChangedEvent", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::< - LuaGamepadAxisChangedEvent, - >::new, - )?; - instances - .add_instance( - "GamepadButtonChangedEvent", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::< - LuaGamepadButtonChangedEvent, - >::new, - )?; - instances - .add_instance( - "GamepadButtonStateChangedEvent", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::< - LuaGamepadButtonStateChangedEvent, - >::new, - )?; - instances - .add_instance( - "GamepadConnectionEvent", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::< - LuaGamepadConnectionEvent, - >::new, - )?; - instances - .add_instance( - "RawGamepadAxisChangedEvent", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::< - LuaRawGamepadAxisChangedEvent, - >::new, - )?; - instances - .add_instance( - "RawGamepadButtonChangedEvent", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::< - LuaRawGamepadButtonChangedEvent, - >::new, - )?; - instances - .add_instance( - "GamepadRumbleIntensity", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::< - LuaGamepadRumbleIntensity, - >::new, - )?; - Ok(()) - } -} -pub struct BevyInputAPIProvider; -impl bevy_mod_scripting_core::hosts::APIProvider for BevyInputAPIProvider { - type APITarget = std::sync::Mutex; - type ScriptContext = std::sync::Mutex; - type DocTarget = bevy_mod_scripting_lua::docs::LuaDocFragment; - fn attach_api( - &mut self, - ctx: &mut Self::APITarget, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - let ctx = ctx.get_mut().expect("Unable to acquire lock on Lua context"); - bevy_mod_scripting_lua::tealr::mlu::set_global_env(Globals, ctx) - .map_err(|e| bevy_mod_scripting_core::error::ScriptError::Other( - e.to_string(), - )) - } - fn get_doc_fragment(&self) -> Option { - Some( - bevy_mod_scripting_lua::docs::LuaDocFragment::new( - "BevyInputAPI", - |tw| { - tw.document_global_instance::() - .expect("Something went wrong documenting globals") - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaGamepadAxisChangedEvent, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaGamepadButtonChangedEvent, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaGamepadButtonStateChangedEvent, - >, - >() - .process_type::() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaGamepadConnectionEvent, - >, - >() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaRawGamepadAxisChangedEvent, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaRawGamepadButtonChangedEvent, - >, - >() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaGamepadRumbleIntensity, - >, - >() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - }, - ), - ) - } - fn setup_script( - &mut self, - script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - fn setup_script_runtime( - &mut self, - world_ptr: bevy_mod_scripting_core::world::WorldPointer, - _script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - fn register_with_app(&self, app: &mut bevy::app::App) { - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::< - bevy::input::gamepad::GamepadButtonChangedEvent, - >(); - app.register_foreign_lua_type::< - bevy::input::gamepad::GamepadButtonStateChangedEvent, - >(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::< - bevy::input::gamepad::RawGamepadAxisChangedEvent, - >(); - app.register_foreign_lua_type::< - bevy::input::gamepad::RawGamepadButtonChangedEvent, - >(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - } -} diff --git a/crates/bevy_script_api/src/providers/bevy_math.rs b/crates/bevy_script_api/src/providers/bevy_math.rs deleted file mode 100644 index 57cd3657..00000000 --- a/crates/bevy_script_api/src/providers/bevy_math.rs +++ /dev/null @@ -1,5539 +0,0 @@ -// @generated by cargo bevy-api-gen generate, modify the templates not this file -#![allow(clippy::all)] -#![allow(unused, deprecated, dead_code)] -#![cfg_attr(rustfmt, rustfmt_skip)] -use super::bevy_reflect::*; -extern crate self as bevy_script_api; -use bevy_script_api::{ - lua::RegisterForeignLuaType, ReflectedValue, common::bevy::GetWorld, -}; -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::AspectRatio", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::AspectRatio; - -"#, - r#" -/// Returns the aspect ratio as a f32 value. - - #[lua(kind = "Method")] - fn ratio(&self) -> f32; - -"#, - r#" -/// Returns the inverse of this aspect ratio (height/width). - - #[lua(kind = "Method", output(proxy))] - fn inverse(&self) -> bevy::math::AspectRatio; - -"#, - r#" -/// Returns true if the aspect ratio represents a landscape orientation. - - #[lua(kind = "Method")] - fn is_landscape(&self) -> bool; - -"#, - r#" -/// Returns true if the aspect ratio represents a portrait orientation. - - #[lua(kind = "Method")] - fn is_portrait(&self) -> bool; - -"#, - r#" -/// Returns true if the aspect ratio is exactly square. - - #[lua(kind = "Method")] - fn is_square(&self) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &aspect_ratio::AspectRatio) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct AspectRatio(); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::CompassOctant", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::CompassOctant; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &compass::CompassOctant) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct CompassOctant {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::CompassQuadrant", - functions[r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &compass::CompassQuadrant) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::CompassQuadrant; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct CompassQuadrant {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::Isometry2d", - functions[r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::prelude::Dir2) -> bevy::math::prelude::Dir2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::prelude::Vec2) -> bevy::math::prelude::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Isometry2d) -> bevy::math::Isometry2d; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &isometry::Isometry2d) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::Isometry2d; - -"#, - r#" -/// Create a two-dimensional isometry from a rotation and a translation. - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - translation: bevy::math::prelude::Vec2, - #[proxy] - rotation: bevy::math::Rot2, - ) -> bevy::math::Isometry2d; - -"#, - r#" -/// Create a two-dimensional isometry from a rotation. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation(#[proxy] rotation: bevy::math::Rot2) -> bevy::math::Isometry2d; - -"#, - r#" -/// Create a two-dimensional isometry from a translation. - - #[lua(kind = "Function", output(proxy))] - fn from_translation( - #[proxy] - translation: bevy::math::prelude::Vec2, - ) -> bevy::math::Isometry2d; - -"#, - r#" -/// Create a two-dimensional isometry from a translation with the given `x` and `y` components. - - #[lua(kind = "Function", output(proxy))] - fn from_xy(x: f32, y: f32) -> bevy::math::Isometry2d; - -"#, - r#" -/// The inverse isometry that undoes this one. - - #[lua(kind = "Method", output(proxy))] - fn inverse(&self) -> bevy::math::Isometry2d; - -"#, - r#" -/// Compute `iso1.inverse() * iso2` in a more efficient way for one-shot cases. -/// If the same isometry is used multiple times, it is more efficient to instead compute -/// the inverse once and use that for each transformation. - - #[lua(kind = "Method", output(proxy))] - fn inverse_mul( - &self, - #[proxy] - rhs: bevy::math::Isometry2d, - ) -> bevy::math::Isometry2d; - -"#, - r#" -/// Transform a point by rotating and translating it using this isometry. - - #[lua(kind = "Method", output(proxy))] - fn transform_point( - &self, - #[proxy] - point: bevy::math::prelude::Vec2, - ) -> bevy::math::prelude::Vec2; - -"#, - r#" -/// Transform a point by rotating and translating it using the inverse of this isometry. -/// This is more efficient than `iso.inverse().transform_point(point)` for one-shot cases. -/// If the same isometry is used multiple times, it is more efficient to instead compute -/// the inverse once and use that for each transformation. - - #[lua(kind = "Method", output(proxy))] - fn inverse_transform_point( - &self, - #[proxy] - point: bevy::math::prelude::Vec2, - ) -> bevy::math::prelude::Vec2; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Isometry2d { - #[lua(output(proxy))] - rotation: bevy::math::Rot2, - #[lua(output(proxy))] - translation: bevy::math::prelude::Vec2, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::Isometry3d", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::Isometry3d; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Create a three-dimensional isometry from a rotation. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation( - #[proxy] - rotation: bevy::math::prelude::Quat, - ) -> bevy::math::Isometry3d; - -"#, - r#" -/// Create a three-dimensional isometry from a translation with the given `x`, `y`, and `z` components. - - #[lua(kind = "Function", output(proxy))] - fn from_xyz(x: f32, y: f32, z: f32) -> bevy::math::Isometry3d; - -"#, - r#" -/// The inverse isometry that undoes this one. - - #[lua(kind = "Method", output(proxy))] - fn inverse(&self) -> bevy::math::Isometry3d; - -"#, - r#" -/// Compute `iso1.inverse() * iso2` in a more efficient way for one-shot cases. -/// If the same isometry is used multiple times, it is more efficient to instead compute -/// the inverse once and use that for each transformation. - - #[lua(kind = "Method", output(proxy))] - fn inverse_mul( - &self, - #[proxy] - rhs: bevy::math::Isometry3d, - ) -> bevy::math::Isometry3d; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Isometry3d) -> bevy::math::Isometry3d; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &isometry::Isometry3d) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::prelude::Vec3) -> bevy::math::prelude::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::prelude::Dir3) -> bevy::math::prelude::Dir3; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Isometry3d { - #[lua(output(proxy))] - rotation: bevy::math::prelude::Quat, - #[lua(output(proxy))] - translation: bevy::math::Vec3A, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::Ray2d", - functions[r#" -/// Create a new `Ray2d` from a given origin and direction - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - origin: bevy::math::prelude::Vec2, - #[proxy] - direction: bevy::math::prelude::Dir2, - ) -> bevy::math::Ray2d; - -"#, - r#" -/// Get a point at a given distance along the ray - - #[lua(kind = "Method", output(proxy))] - fn get_point(&self, distance: f32) -> bevy::math::prelude::Vec2; - -"#, - r#" -/// Get the distance to a plane if the ray intersects it - - #[lua(kind = "Method")] - fn intersect_plane( - &self, - #[proxy] - plane_origin: bevy::math::prelude::Vec2, - #[proxy] - plane: bevy::math::primitives::Plane2d, - ) -> std::option::Option; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &ray::Ray2d) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::Ray2d; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Ray2d { - #[lua(output(proxy))] - origin: bevy::math::prelude::Vec2, - #[lua(output(proxy))] - direction: bevy::math::prelude::Dir2, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::Ray3d", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &ray::Ray3d) -> bool; - -"#, - r#" -/// Create a new `Ray3d` from a given origin and direction - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - origin: bevy::math::prelude::Vec3, - #[proxy] - direction: bevy::math::prelude::Dir3, - ) -> bevy::math::Ray3d; - -"#, - r#" -/// Get a point at a given distance along the ray - - #[lua(kind = "Method", output(proxy))] - fn get_point(&self, distance: f32) -> bevy::math::prelude::Vec3; - -"#, - r#" -/// Get the distance to a plane if the ray intersects it - - #[lua(kind = "Method")] - fn intersect_plane( - &self, - #[proxy] - plane_origin: bevy::math::prelude::Vec3, - #[proxy] - plane: bevy::math::primitives::InfinitePlane3d, - ) -> std::option::Option; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::Ray3d; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Ray3d { - #[lua(output(proxy))] - origin: bevy::math::prelude::Vec3, - #[lua(output(proxy))] - direction: bevy::math::prelude::Dir3, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::Rot2", - functions[r#" -/// Rotates the [`Dir2`] using a [`Rot2`]. - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul( - self, - #[proxy] - direction: bevy::math::prelude::Dir2, - ) -> bevy::math::prelude::Dir2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Rot2) -> bevy::math::Rot2; - -"#, - r#" -/// Creates a [`Rot2`] from a counterclockwise angle in radians. -/// # Note -/// The input rotation will always be clamped to the range `(-π, π]` by design. -/// # Example -/// ``` -/// # use bevy_math::Rot2; -/// # use approx::assert_relative_eq; -/// # use std::f32::consts::{FRAC_PI_2, PI}; -/// let rot1 = Rot2::radians(3.0 * FRAC_PI_2); -/// let rot2 = Rot2::radians(-FRAC_PI_2); -/// assert_relative_eq!(rot1, rot2); -/// let rot3 = Rot2::radians(PI); -/// assert_relative_eq!(rot1 * rot1, rot3); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn radians(radians: f32) -> bevy::math::Rot2; - -"#, - r#" -/// Creates a [`Rot2`] from a counterclockwise angle in degrees. -/// # Note -/// The input rotation will always be clamped to the range `(-180°, 180°]` by design. -/// # Example -/// ``` -/// # use bevy_math::Rot2; -/// # use approx::assert_relative_eq; -/// let rot1 = Rot2::degrees(270.0); -/// let rot2 = Rot2::degrees(-90.0); -/// assert_relative_eq!(rot1, rot2); -/// let rot3 = Rot2::degrees(180.0); -/// assert_relative_eq!(rot1 * rot1, rot3); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn degrees(degrees: f32) -> bevy::math::Rot2; - -"#, - r#" -/// Creates a [`Rot2`] from a counterclockwise fraction of a full turn of 360 degrees. -/// # Note -/// The input rotation will always be clamped to the range `(-50%, 50%]` by design. -/// # Example -/// ``` -/// # use bevy_math::Rot2; -/// # use approx::assert_relative_eq; -/// let rot1 = Rot2::turn_fraction(0.75); -/// let rot2 = Rot2::turn_fraction(-0.25); -/// assert_relative_eq!(rot1, rot2); -/// let rot3 = Rot2::turn_fraction(0.5); -/// assert_relative_eq!(rot1 * rot1, rot3); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn turn_fraction(fraction: f32) -> bevy::math::Rot2; - -"#, - r#" -/// Creates a [`Rot2`] from the sine and cosine of an angle in radians. -/// The rotation is only valid if `sin * sin + cos * cos == 1.0`. -/// # Panics -/// Panics if `sin * sin + cos * cos != 1.0` when the `glam_assert` feature is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_sin_cos(sin: f32, cos: f32) -> bevy::math::Rot2; - -"#, - r#" -/// Returns the rotation in radians in the `(-pi, pi]` range. - - #[lua(kind = "Method")] - fn as_radians(self) -> f32; - -"#, - r#" -/// Returns the rotation in degrees in the `(-180, 180]` range. - - #[lua(kind = "Method")] - fn as_degrees(self) -> f32; - -"#, - r#" -/// Returns the rotation as a fraction of a full 360 degree turn. - - #[lua(kind = "Method")] - fn as_turn_fraction(self) -> f32; - -"#, - r#" -/// Returns the sine and cosine of the rotation angle in radians. - - #[lua(kind = "Method")] - fn sin_cos(self) -> (f32, f32); - -"#, - r#" -/// Computes the length or norm of the complex number used to represent the rotation. -/// The length is typically expected to be `1.0`. Unexpectedly denormalized rotations -/// can be a result of incorrect construction or floating point error caused by -/// successive operations. - - #[lua(kind = "Method")] - fn length(self) -> f32; - -"#, - r#" -/// Computes the squared length or norm of the complex number used to represent the rotation. -/// This is generally faster than [`Rot2::length()`], as it avoids a square -/// root operation. -/// The length is typically expected to be `1.0`. Unexpectedly denormalized rotations -/// can be a result of incorrect construction or floating point error caused by -/// successive operations. - - #[lua(kind = "Method")] - fn length_squared(self) -> f32; - -"#, - r#" -/// Computes `1.0 / self.length()`. -/// For valid results, `self` must _not_ have a length of zero. - - #[lua(kind = "Method")] - fn length_recip(self) -> f32; - -"#, - r#" -/// Returns `self` with a length of `1.0`. -/// Note that [`Rot2`] should typically already be normalized by design. -/// Manual normalization is only needed when successive operations result in -/// accumulated floating point error, or if the rotation was constructed -/// with invalid values. -/// # Panics -/// Panics if `self` has a length of zero, NaN, or infinity when debug assertions are enabled. - - #[lua(kind = "Method", output(proxy))] - fn normalize(self) -> bevy::math::Rot2; - -"#, - r#" -/// Returns `self` after an approximate normalization, assuming the value is already nearly normalized. -/// Useful for preventing numerical error accumulation. -/// See [`Dir3::fast_renormalize`](crate::Dir3::fast_renormalize) for an example of when such error accumulation might occur. - - #[lua(kind = "Method", output(proxy))] - fn fast_renormalize(self) -> bevy::math::Rot2; - -"#, - r#" -/// Returns `true` if the rotation is neither infinite nor NaN. - - #[lua(kind = "Method")] - fn is_finite(self) -> bool; - -"#, - r#" -/// Returns `true` if the rotation is NaN. - - #[lua(kind = "Method")] - fn is_nan(self) -> bool; - -"#, - r#" -/// Returns whether `self` has a length of `1.0` or not. -/// Uses a precision threshold of approximately `1e-4`. - - #[lua(kind = "Method")] - fn is_normalized(self) -> bool; - -"#, - r#" -/// Returns `true` if the rotation is near [`Rot2::IDENTITY`]. - - #[lua(kind = "Method")] - fn is_near_identity(self) -> bool; - -"#, - r#" -/// Returns the angle in radians needed to make `self` and `other` coincide. - - #[lua(kind = "Method")] - fn angle_between(self, #[proxy] other: bevy::math::Rot2) -> f32; - -"#, - r#" -/// Returns the angle in radians needed to make `self` and `other` coincide. - - #[lua(kind = "Method")] - fn angle_to(self, #[proxy] other: bevy::math::Rot2) -> f32; - -"#, - r#" -/// Returns the inverse of the rotation. This is also the conjugate -/// of the unit complex number representing the rotation. - - #[lua(kind = "Method", output(proxy))] - fn inverse(self) -> bevy::math::Rot2; - -"#, - r#" -/// Performs a linear interpolation between `self` and `rhs` based on -/// the value `s`, and normalizes the rotation afterwards. -/// When `s == 0.0`, the result will be equal to `self`. -/// When `s == 1.0`, the result will be equal to `rhs`. -/// This is slightly more efficient than [`slerp`](Self::slerp), and produces a similar result -/// when the difference between the two rotations is small. At larger differences, -/// the result resembles a kind of ease-in-out effect. -/// If you would like the angular velocity to remain constant, consider using [`slerp`](Self::slerp) instead. -/// # Details -/// `nlerp` corresponds to computing an angle for a point at position `s` on a line drawn -/// between the endpoints of the arc formed by `self` and `rhs` on a unit circle, -/// and normalizing the result afterwards. -/// Note that if the angles are opposite like 0 and π, the line will pass through the origin, -/// and the resulting angle will always be either `self` or `rhs` depending on `s`. -/// If `s` happens to be `0.5` in this case, a valid rotation cannot be computed, and `self` -/// will be returned as a fallback. -/// # Example -/// ``` -/// # use bevy_math::Rot2; -/// # -/// let rot1 = Rot2::IDENTITY; -/// let rot2 = Rot2::degrees(135.0); -/// let result1 = rot1.nlerp(rot2, 1.0 / 3.0); -/// assert_eq!(result1.as_degrees(), 28.675055); -/// let result2 = rot1.nlerp(rot2, 0.5); -/// assert_eq!(result2.as_degrees(), 67.5); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn nlerp(self, #[proxy] end: bevy::math::Rot2, s: f32) -> bevy::math::Rot2; - -"#, - r#" -/// Performs a spherical linear interpolation between `self` and `end` -/// based on the value `s`. -/// This corresponds to interpolating between the two angles at a constant angular velocity. -/// When `s == 0.0`, the result will be equal to `self`. -/// When `s == 1.0`, the result will be equal to `rhs`. -/// If you would like the rotation to have a kind of ease-in-out effect, consider -/// using the slightly more efficient [`nlerp`](Self::nlerp) instead. -/// # Example -/// ``` -/// # use bevy_math::Rot2; -/// # -/// let rot1 = Rot2::IDENTITY; -/// let rot2 = Rot2::degrees(135.0); -/// let result1 = rot1.slerp(rot2, 1.0 / 3.0); -/// assert_eq!(result1.as_degrees(), 45.0); -/// let result2 = rot1.slerp(rot2, 0.5); -/// assert_eq!(result2.as_degrees(), 67.5); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn slerp(self, #[proxy] end: bevy::math::Rot2, s: f32) -> bevy::math::Rot2; - -"#, - r#" -/// Rotates a [`Vec2`] by a [`Rot2`]. - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::prelude::Vec2) -> bevy::math::prelude::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &rotation2d::Rot2) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::Rot2; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Rot2 { - cos: f32, - sin: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::prelude::Dir2", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &direction::Dir2) -> bool; - -"#, - r#" -/// Create a [`Dir2`] from a [`Vec2`] that is already normalized. -/// # Warning -/// `value` must be normalized, i.e its length must be `1.0`. - - #[lua(kind = "Function", output(proxy))] - fn new_unchecked( - #[proxy] - value: bevy::math::prelude::Vec2, - ) -> bevy::math::prelude::Dir2; - -"#, - r#" -/// Create a direction from its `x` and `y` components, assuming the resulting vector is normalized. -/// # Warning -/// The vector produced from `x` and `y` must be normalized, i.e its length must be `1.0`. - - #[lua(kind = "Function", output(proxy))] - fn from_xy_unchecked(x: f32, y: f32) -> bevy::math::prelude::Dir2; - -"#, - r#" -/// Returns the inner [`Vec2`] - - #[lua(kind = "Method", output(proxy))] - fn as_vec2(&self) -> bevy::math::prelude::Vec2; - -"#, - r#" -/// Performs a spherical linear interpolation between `self` and `rhs` -/// based on the value `s`. -/// This corresponds to interpolating between the two directions at a constant angular velocity. -/// When `s == 0.0`, the result will be equal to `self`. -/// When `s == 1.0`, the result will be equal to `rhs`. -/// # Example -/// ``` -/// # use bevy_math::Dir2; -/// # use approx::{assert_relative_eq, RelativeEq}; -/// # -/// let dir1 = Dir2::X; -/// let dir2 = Dir2::Y; -/// let result1 = dir1.slerp(dir2, 1.0 / 3.0); -/// assert_relative_eq!(result1, Dir2::from_xy(0.75_f32.sqrt(), 0.5).unwrap()); -/// let result2 = dir1.slerp(dir2, 0.5); -/// assert_relative_eq!(result2, Dir2::from_xy(0.5_f32.sqrt(), 0.5_f32.sqrt()).unwrap()); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn slerp( - self, - #[proxy] - rhs: bevy::math::prelude::Dir2, - s: f32, - ) -> bevy::math::prelude::Dir2; - -"#, - r#" -/// Get the rotation that rotates this direction to `other`. - - #[lua(kind = "Method", output(proxy))] - fn rotation_to(self, #[proxy] other: bevy::math::prelude::Dir2) -> bevy::math::Rot2; - -"#, - r#" -/// Get the rotation that rotates `other` to this direction. - - #[lua(kind = "Method", output(proxy))] - fn rotation_from( - self, - #[proxy] - other: bevy::math::prelude::Dir2, - ) -> bevy::math::Rot2; - -"#, - r#" -/// Get the rotation that rotates the X-axis to this direction. - - #[lua(kind = "Method", output(proxy))] - fn rotation_from_x(self) -> bevy::math::Rot2; - -"#, - r#" -/// Get the rotation that rotates this direction to the X-axis. - - #[lua(kind = "Method", output(proxy))] - fn rotation_to_x(self) -> bevy::math::Rot2; - -"#, - r#" -/// Get the rotation that rotates the Y-axis to this direction. - - #[lua(kind = "Method", output(proxy))] - fn rotation_from_y(self) -> bevy::math::Rot2; - -"#, - r#" -/// Get the rotation that rotates this direction to the Y-axis. - - #[lua(kind = "Method", output(proxy))] - fn rotation_to_y(self) -> bevy::math::Rot2; - -"#, - r#" -/// Returns `self` after an approximate normalization, assuming the value is already nearly normalized. -/// Useful for preventing numerical error accumulation. -/// See [`Dir3::fast_renormalize`] for an example of when such error accumulation might occur. - - #[lua(kind = "Method", output(proxy))] - fn fast_renormalize(self) -> bevy::math::prelude::Dir2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::prelude::Dir2; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::prelude::Dir2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f32) -> bevy::math::prelude::Vec2; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Dir2(); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::prelude::Dir3", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::prelude::Dir3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f32) -> bevy::math::prelude::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::prelude::Dir3; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &direction::Dir3) -> bool; - -"#, - r#" -/// Create a [`Dir3`] from a [`Vec3`] that is already normalized. -/// # Warning -/// `value` must be normalized, i.e its length must be `1.0`. - - #[lua(kind = "Function", output(proxy))] - fn new_unchecked( - #[proxy] - value: bevy::math::prelude::Vec3, - ) -> bevy::math::prelude::Dir3; - -"#, - r#" -/// Create a direction from its `x`, `y`, and `z` components, assuming the resulting vector is normalized. -/// # Warning -/// The vector produced from `x`, `y`, and `z` must be normalized, i.e its length must be `1.0`. - - #[lua(kind = "Function", output(proxy))] - fn from_xyz_unchecked(x: f32, y: f32, z: f32) -> bevy::math::prelude::Dir3; - -"#, - r#" -/// Returns the inner [`Vec3`] - - #[lua(kind = "Method", output(proxy))] - fn as_vec3(&self) -> bevy::math::prelude::Vec3; - -"#, - r#" -/// Performs a spherical linear interpolation between `self` and `rhs` -/// based on the value `s`. -/// This corresponds to interpolating between the two directions at a constant angular velocity. -/// When `s == 0.0`, the result will be equal to `self`. -/// When `s == 1.0`, the result will be equal to `rhs`. -/// # Example -/// ``` -/// # use bevy_math::Dir3; -/// # use approx::{assert_relative_eq, RelativeEq}; -/// # -/// let dir1 = Dir3::X; -/// let dir2 = Dir3::Y; -/// let result1 = dir1.slerp(dir2, 1.0 / 3.0); -/// assert_relative_eq!( -/// result1, -/// Dir3::from_xyz(0.75_f32.sqrt(), 0.5, 0.0).unwrap(), -/// epsilon = 0.000001 -/// ); -/// let result2 = dir1.slerp(dir2, 0.5); -/// assert_relative_eq!(result2, Dir3::from_xyz(0.5_f32.sqrt(), 0.5_f32.sqrt(), 0.0).unwrap()); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn slerp( - self, - #[proxy] - rhs: bevy::math::prelude::Dir3, - s: f32, - ) -> bevy::math::prelude::Dir3; - -"#, - r#" -/// Returns `self` after an approximate normalization, assuming the value is already nearly normalized. -/// Useful for preventing numerical error accumulation. -/// # Example -/// The following seemingly benign code would start accumulating errors over time, -/// leading to `dir` eventually not being normalized anymore. -/// ``` -/// # use bevy_math::prelude::*; -/// # let N: usize = 200; -/// let mut dir = Dir3::X; -/// let quaternion = Quat::from_euler(EulerRot::XYZ, 1.0, 2.0, 3.0); -/// for i in 0..N { -/// dir = quaternion * dir; -/// } -/// ``` -/// Instead, do the following. -/// ``` -/// # use bevy_math::prelude::*; -/// # let N: usize = 200; -/// let mut dir = Dir3::X; -/// let quaternion = Quat::from_euler(EulerRot::XYZ, 1.0, 2.0, 3.0); -/// for i in 0..N { -/// dir = quaternion * dir; -/// dir = dir.fast_renormalize(); -/// } -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn fast_renormalize(self) -> bevy::math::prelude::Dir3; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Dir3(); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::prelude::Dir3A", - functions[r#" -/// Create a [`Dir3A`] from a [`Vec3A`] that is already normalized. -/// # Warning -/// `value` must be normalized, i.e its length must be `1.0`. - - #[lua(kind = "Function", output(proxy))] - fn new_unchecked(#[proxy] value: bevy::math::Vec3A) -> bevy::math::prelude::Dir3A; - -"#, - r#" -/// Create a direction from its `x`, `y`, and `z` components, assuming the resulting vector is normalized. -/// # Warning -/// The vector produced from `x`, `y`, and `z` must be normalized, i.e its length must be `1.0`. - - #[lua(kind = "Function", output(proxy))] - fn from_xyz_unchecked(x: f32, y: f32, z: f32) -> bevy::math::prelude::Dir3A; - -"#, - r#" -/// Returns the inner [`Vec3A`] - - #[lua(kind = "Method", output(proxy))] - fn as_vec3a(&self) -> bevy::math::Vec3A; - -"#, - r#" -/// Performs a spherical linear interpolation between `self` and `rhs` -/// based on the value `s`. -/// This corresponds to interpolating between the two directions at a constant angular velocity. -/// When `s == 0.0`, the result will be equal to `self`. -/// When `s == 1.0`, the result will be equal to `rhs`. -/// # Example -/// ``` -/// # use bevy_math::Dir3A; -/// # use approx::{assert_relative_eq, RelativeEq}; -/// # -/// let dir1 = Dir3A::X; -/// let dir2 = Dir3A::Y; -/// let result1 = dir1.slerp(dir2, 1.0 / 3.0); -/// assert_relative_eq!( -/// result1, -/// Dir3A::from_xyz(0.75_f32.sqrt(), 0.5, 0.0).unwrap(), -/// epsilon = 0.000001 -/// ); -/// let result2 = dir1.slerp(dir2, 0.5); -/// assert_relative_eq!(result2, Dir3A::from_xyz(0.5_f32.sqrt(), 0.5_f32.sqrt(), 0.0).unwrap()); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn slerp( - self, - #[proxy] - rhs: bevy::math::prelude::Dir3A, - s: f32, - ) -> bevy::math::prelude::Dir3A; - -"#, - r#" -/// Returns `self` after an approximate normalization, assuming the value is already nearly normalized. -/// Useful for preventing numerical error accumulation. -/// See [`Dir3::fast_renormalize`] for an example of when such error accumulation might occur. - - #[lua(kind = "Method", output(proxy))] - fn fast_renormalize(self) -> bevy::math::prelude::Dir3A; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &direction::Dir3A) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f32) -> bevy::math::Vec3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::prelude::Dir3A; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::prelude::Dir3A; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Dir3A(); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::prelude::IRect", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &rects::irect::IRect) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::prelude::IRect; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" -/// Create a new rectangle from two corner points. -/// The two points do not need to be the minimum and/or maximum corners. -/// They only need to be two opposite corners. -/// # Examples -/// ``` -/// # use bevy_math::IRect; -/// let r = IRect::new(0, 4, 10, 6); // w=10 h=2 -/// let r = IRect::new(2, 3, 5, -1); // w=3 h=4 -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn new(x0: i32, y0: i32, x1: i32, y1: i32) -> bevy::math::prelude::IRect; - -"#, - r#" -/// Create a new rectangle from two corner points. -/// The two points do not need to be the minimum and/or maximum corners. -/// They only need to be two opposite corners. -/// # Examples -/// ``` -/// # use bevy_math::{IRect, IVec2}; -/// // Unit rect from [0,0] to [1,1] -/// let r = IRect::from_corners(IVec2::ZERO, IVec2::ONE); // w=1 h=1 -/// // Same; the points do not need to be ordered -/// let r = IRect::from_corners(IVec2::ONE, IVec2::ZERO); // w=1 h=1 -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_corners( - #[proxy] - p0: bevy::math::prelude::IVec2, - #[proxy] - p1: bevy::math::prelude::IVec2, - ) -> bevy::math::prelude::IRect; - -"#, - r#" -/// Create a new rectangle from its center and size. -/// # Rounding Behavior -/// If the size contains odd numbers they will be rounded down to the nearest whole number. -/// # Panics -/// This method panics if any of the components of the size is negative. -/// # Examples -/// ``` -/// # use bevy_math::{IRect, IVec2}; -/// let r = IRect::from_center_size(IVec2::ZERO, IVec2::new(3, 2)); // w=2 h=2 -/// assert_eq!(r.min, IVec2::splat(-1)); -/// assert_eq!(r.max, IVec2::splat(1)); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_center_size( - #[proxy] - origin: bevy::math::prelude::IVec2, - #[proxy] - size: bevy::math::prelude::IVec2, - ) -> bevy::math::prelude::IRect; - -"#, - r#" -/// Create a new rectangle from its center and half-size. -/// # Panics -/// This method panics if any of the components of the half-size is negative. -/// # Examples -/// ``` -/// # use bevy_math::{IRect, IVec2}; -/// let r = IRect::from_center_half_size(IVec2::ZERO, IVec2::ONE); // w=2 h=2 -/// assert_eq!(r.min, IVec2::splat(-1)); -/// assert_eq!(r.max, IVec2::splat(1)); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_center_half_size( - #[proxy] - origin: bevy::math::prelude::IVec2, - #[proxy] - half_size: bevy::math::prelude::IVec2, - ) -> bevy::math::prelude::IRect; - -"#, - r#" -/// Check if the rectangle is empty. -/// # Examples -/// ``` -/// # use bevy_math::{IRect, IVec2}; -/// let r = IRect::from_corners(IVec2::ZERO, IVec2::new(0, 1)); // w=0 h=1 -/// assert!(r.is_empty()); -/// ``` - - #[lua(kind = "Method")] - fn is_empty(&self) -> bool; - -"#, - r#" -/// Rectangle width (max.x - min.x). -/// # Examples -/// ``` -/// # use bevy_math::IRect; -/// let r = IRect::new(0, 0, 5, 1); // w=5 h=1 -/// assert_eq!(r.width(), 5); -/// ``` - - #[lua(kind = "Method")] - fn width(&self) -> i32; - -"#, - r#" -/// Rectangle height (max.y - min.y). -/// # Examples -/// ``` -/// # use bevy_math::IRect; -/// let r = IRect::new(0, 0, 5, 1); // w=5 h=1 -/// assert_eq!(r.height(), 1); -/// ``` - - #[lua(kind = "Method")] - fn height(&self) -> i32; - -"#, - r#" -/// Rectangle size. -/// # Examples -/// ``` -/// # use bevy_math::{IRect, IVec2}; -/// let r = IRect::new(0, 0, 5, 1); // w=5 h=1 -/// assert_eq!(r.size(), IVec2::new(5, 1)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn size(&self) -> bevy::math::prelude::IVec2; - -"#, - r#" -/// Rectangle half-size. -/// # Rounding Behavior -/// If the full size contains odd numbers they will be rounded down to the nearest whole number when calculating the half size. -/// # Examples -/// ``` -/// # use bevy_math::{IRect, IVec2}; -/// let r = IRect::new(0, 0, 4, 3); // w=4 h=3 -/// assert_eq!(r.half_size(), IVec2::new(2, 1)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn half_size(&self) -> bevy::math::prelude::IVec2; - -"#, - r#" -/// The center point of the rectangle. -/// # Rounding Behavior -/// If the (min + max) contains odd numbers they will be rounded down to the nearest whole number when calculating the center. -/// # Examples -/// ``` -/// # use bevy_math::{IRect, IVec2}; -/// let r = IRect::new(0, 0, 5, 2); // w=5 h=2 -/// assert_eq!(r.center(), IVec2::new(2, 1)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn center(&self) -> bevy::math::prelude::IVec2; - -"#, - r#" -/// Check if a point lies within this rectangle, inclusive of its edges. -/// # Examples -/// ``` -/// # use bevy_math::IRect; -/// let r = IRect::new(0, 0, 5, 1); // w=5 h=1 -/// assert!(r.contains(r.center())); -/// assert!(r.contains(r.min)); -/// assert!(r.contains(r.max)); -/// ``` - - #[lua(kind = "Method")] - fn contains(&self, #[proxy] point: bevy::math::prelude::IVec2) -> bool; - -"#, - r#" -/// Build a new rectangle formed of the union of this rectangle and another rectangle. -/// The union is the smallest rectangle enclosing both rectangles. -/// # Examples -/// ``` -/// # use bevy_math::{IRect, IVec2}; -/// let r1 = IRect::new(0, 0, 5, 1); // w=5 h=1 -/// let r2 = IRect::new(1, -1, 3, 3); // w=2 h=4 -/// let r = r1.union(r2); -/// assert_eq!(r.min, IVec2::new(0, -1)); -/// assert_eq!(r.max, IVec2::new(5, 3)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn union( - &self, - #[proxy] - other: bevy::math::prelude::IRect, - ) -> bevy::math::prelude::IRect; - -"#, - r#" -/// Build a new rectangle formed of the union of this rectangle and a point. -/// The union is the smallest rectangle enclosing both the rectangle and the point. If the -/// point is already inside the rectangle, this method returns a copy of the rectangle. -/// # Examples -/// ``` -/// # use bevy_math::{IRect, IVec2}; -/// let r = IRect::new(0, 0, 5, 1); // w=5 h=1 -/// let u = r.union_point(IVec2::new(3, 6)); -/// assert_eq!(u.min, IVec2::ZERO); -/// assert_eq!(u.max, IVec2::new(5, 6)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn union_point( - &self, - #[proxy] - other: bevy::math::prelude::IVec2, - ) -> bevy::math::prelude::IRect; - -"#, - r#" -/// Build a new rectangle formed of the intersection of this rectangle and another rectangle. -/// The intersection is the largest rectangle enclosed in both rectangles. If the intersection -/// is empty, this method returns an empty rectangle ([`IRect::is_empty()`] returns `true`), but -/// the actual values of [`IRect::min`] and [`IRect::max`] are implementation-dependent. -/// # Examples -/// ``` -/// # use bevy_math::{IRect, IVec2}; -/// let r1 = IRect::new(0, 0, 5, 1); // w=5 h=1 -/// let r2 = IRect::new(1, -1, 3, 3); // w=2 h=4 -/// let r = r1.intersect(r2); -/// assert_eq!(r.min, IVec2::new(1, 0)); -/// assert_eq!(r.max, IVec2::new(3, 1)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn intersect( - &self, - #[proxy] - other: bevy::math::prelude::IRect, - ) -> bevy::math::prelude::IRect; - -"#, - r#" -/// Create a new rectangle by expanding it evenly on all sides. -/// A positive expansion value produces a larger rectangle, -/// while a negative expansion value produces a smaller rectangle. -/// If this would result in zero or negative width or height, [`IRect::EMPTY`] is returned instead. -/// # Examples -/// ``` -/// # use bevy_math::{IRect, IVec2}; -/// let r = IRect::new(0, 0, 5, 1); // w=5 h=1 -/// let r2 = r.inflate(3); // w=11 h=7 -/// assert_eq!(r2.min, IVec2::splat(-3)); -/// assert_eq!(r2.max, IVec2::new(8, 4)); -/// let r = IRect::new(0, -1, 4, 3); // w=4 h=4 -/// let r2 = r.inflate(-1); // w=2 h=2 -/// assert_eq!(r2.min, IVec2::new(1, 0)); -/// assert_eq!(r2.max, IVec2::new(3, 2)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn inflate(&self, expansion: i32) -> bevy::math::prelude::IRect; - -"#, - r#" -/// Returns self as [`Rect`] (f32) - - #[lua(kind = "Method", output(proxy))] - fn as_rect(&self) -> bevy::math::prelude::Rect; - -"#, - r#" -/// Returns self as [`URect`] (u32) - - #[lua(kind = "Method", output(proxy))] - fn as_urect(&self) -> bevy::math::prelude::URect; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct IRect { - #[lua(output(proxy))] - min: bevy::math::prelude::IVec2, - #[lua(output(proxy))] - max: bevy::math::prelude::IVec2, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::prelude::Rect", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::prelude::Rect; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &rects::rect::Rect) -> bool; - -"#, - r#" -/// Create a new rectangle from two corner points. -/// The two points do not need to be the minimum and/or maximum corners. -/// They only need to be two opposite corners. -/// # Examples -/// ``` -/// # use bevy_math::Rect; -/// let r = Rect::new(0., 4., 10., 6.); // w=10 h=2 -/// let r = Rect::new(2., 3., 5., -1.); // w=3 h=4 -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn new(x0: f32, y0: f32, x1: f32, y1: f32) -> bevy::math::prelude::Rect; - -"#, - r#" -/// Create a new rectangle from two corner points. -/// The two points do not need to be the minimum and/or maximum corners. -/// They only need to be two opposite corners. -/// # Examples -/// ``` -/// # use bevy_math::{Rect, Vec2}; -/// // Unit rect from [0,0] to [1,1] -/// let r = Rect::from_corners(Vec2::ZERO, Vec2::ONE); // w=1 h=1 -/// // Same; the points do not need to be ordered -/// let r = Rect::from_corners(Vec2::ONE, Vec2::ZERO); // w=1 h=1 -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_corners( - #[proxy] - p0: bevy::math::prelude::Vec2, - #[proxy] - p1: bevy::math::prelude::Vec2, - ) -> bevy::math::prelude::Rect; - -"#, - r#" -/// Create a new rectangle from its center and size. -/// # Panics -/// This method panics if any of the components of the size is negative. -/// # Examples -/// ``` -/// # use bevy_math::{Rect, Vec2}; -/// let r = Rect::from_center_size(Vec2::ZERO, Vec2::ONE); // w=1 h=1 -/// assert!(r.min.abs_diff_eq(Vec2::splat(-0.5), 1e-5)); -/// assert!(r.max.abs_diff_eq(Vec2::splat(0.5), 1e-5)); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_center_size( - #[proxy] - origin: bevy::math::prelude::Vec2, - #[proxy] - size: bevy::math::prelude::Vec2, - ) -> bevy::math::prelude::Rect; - -"#, - r#" -/// Create a new rectangle from its center and half-size. -/// # Panics -/// This method panics if any of the components of the half-size is negative. -/// # Examples -/// ``` -/// # use bevy_math::{Rect, Vec2}; -/// let r = Rect::from_center_half_size(Vec2::ZERO, Vec2::ONE); // w=2 h=2 -/// assert!(r.min.abs_diff_eq(Vec2::splat(-1.), 1e-5)); -/// assert!(r.max.abs_diff_eq(Vec2::splat(1.), 1e-5)); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_center_half_size( - #[proxy] - origin: bevy::math::prelude::Vec2, - #[proxy] - half_size: bevy::math::prelude::Vec2, - ) -> bevy::math::prelude::Rect; - -"#, - r#" -/// Check if the rectangle is empty. -/// # Examples -/// ``` -/// # use bevy_math::{Rect, Vec2}; -/// let r = Rect::from_corners(Vec2::ZERO, Vec2::new(0., 1.)); // w=0 h=1 -/// assert!(r.is_empty()); -/// ``` - - #[lua(kind = "Method")] - fn is_empty(&self) -> bool; - -"#, - r#" -/// Rectangle width (max.x - min.x). -/// # Examples -/// ``` -/// # use bevy_math::Rect; -/// let r = Rect::new(0., 0., 5., 1.); // w=5 h=1 -/// assert!((r.width() - 5.).abs() <= 1e-5); -/// ``` - - #[lua(kind = "Method")] - fn width(&self) -> f32; - -"#, - r#" -/// Rectangle height (max.y - min.y). -/// # Examples -/// ``` -/// # use bevy_math::Rect; -/// let r = Rect::new(0., 0., 5., 1.); // w=5 h=1 -/// assert!((r.height() - 1.).abs() <= 1e-5); -/// ``` - - #[lua(kind = "Method")] - fn height(&self) -> f32; - -"#, - r#" -/// Rectangle size. -/// # Examples -/// ``` -/// # use bevy_math::{Rect, Vec2}; -/// let r = Rect::new(0., 0., 5., 1.); // w=5 h=1 -/// assert!(r.size().abs_diff_eq(Vec2::new(5., 1.), 1e-5)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn size(&self) -> bevy::math::prelude::Vec2; - -"#, - r#" -/// Rectangle half-size. -/// # Examples -/// ``` -/// # use bevy_math::{Rect, Vec2}; -/// let r = Rect::new(0., 0., 5., 1.); // w=5 h=1 -/// assert!(r.half_size().abs_diff_eq(Vec2::new(2.5, 0.5), 1e-5)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn half_size(&self) -> bevy::math::prelude::Vec2; - -"#, - r#" -/// The center point of the rectangle. -/// # Examples -/// ``` -/// # use bevy_math::{Rect, Vec2}; -/// let r = Rect::new(0., 0., 5., 1.); // w=5 h=1 -/// assert!(r.center().abs_diff_eq(Vec2::new(2.5, 0.5), 1e-5)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn center(&self) -> bevy::math::prelude::Vec2; - -"#, - r#" -/// Check if a point lies within this rectangle, inclusive of its edges. -/// # Examples -/// ``` -/// # use bevy_math::Rect; -/// let r = Rect::new(0., 0., 5., 1.); // w=5 h=1 -/// assert!(r.contains(r.center())); -/// assert!(r.contains(r.min)); -/// assert!(r.contains(r.max)); -/// ``` - - #[lua(kind = "Method")] - fn contains(&self, #[proxy] point: bevy::math::prelude::Vec2) -> bool; - -"#, - r#" -/// Build a new rectangle formed of the union of this rectangle and another rectangle. -/// The union is the smallest rectangle enclosing both rectangles. -/// # Examples -/// ``` -/// # use bevy_math::{Rect, Vec2}; -/// let r1 = Rect::new(0., 0., 5., 1.); // w=5 h=1 -/// let r2 = Rect::new(1., -1., 3., 3.); // w=2 h=4 -/// let r = r1.union(r2); -/// assert!(r.min.abs_diff_eq(Vec2::new(0., -1.), 1e-5)); -/// assert!(r.max.abs_diff_eq(Vec2::new(5., 3.), 1e-5)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn union( - &self, - #[proxy] - other: bevy::math::prelude::Rect, - ) -> bevy::math::prelude::Rect; - -"#, - r#" -/// Build a new rectangle formed of the union of this rectangle and a point. -/// The union is the smallest rectangle enclosing both the rectangle and the point. If the -/// point is already inside the rectangle, this method returns a copy of the rectangle. -/// # Examples -/// ``` -/// # use bevy_math::{Rect, Vec2}; -/// let r = Rect::new(0., 0., 5., 1.); // w=5 h=1 -/// let u = r.union_point(Vec2::new(3., 6.)); -/// assert!(u.min.abs_diff_eq(Vec2::ZERO, 1e-5)); -/// assert!(u.max.abs_diff_eq(Vec2::new(5., 6.), 1e-5)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn union_point( - &self, - #[proxy] - other: bevy::math::prelude::Vec2, - ) -> bevy::math::prelude::Rect; - -"#, - r#" -/// Build a new rectangle formed of the intersection of this rectangle and another rectangle. -/// The intersection is the largest rectangle enclosed in both rectangles. If the intersection -/// is empty, this method returns an empty rectangle ([`Rect::is_empty()`] returns `true`), but -/// the actual values of [`Rect::min`] and [`Rect::max`] are implementation-dependent. -/// # Examples -/// ``` -/// # use bevy_math::{Rect, Vec2}; -/// let r1 = Rect::new(0., 0., 5., 1.); // w=5 h=1 -/// let r2 = Rect::new(1., -1., 3., 3.); // w=2 h=4 -/// let r = r1.intersect(r2); -/// assert!(r.min.abs_diff_eq(Vec2::new(1., 0.), 1e-5)); -/// assert!(r.max.abs_diff_eq(Vec2::new(3., 1.), 1e-5)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn intersect( - &self, - #[proxy] - other: bevy::math::prelude::Rect, - ) -> bevy::math::prelude::Rect; - -"#, - r#" -/// Create a new rectangle by expanding it evenly on all sides. -/// A positive expansion value produces a larger rectangle, -/// while a negative expansion value produces a smaller rectangle. -/// If this would result in zero or negative width or height, [`Rect::EMPTY`] is returned instead. -/// # Examples -/// ``` -/// # use bevy_math::{Rect, Vec2}; -/// let r = Rect::new(0., 0., 5., 1.); // w=5 h=1 -/// let r2 = r.inflate(3.); // w=11 h=7 -/// assert!(r2.min.abs_diff_eq(Vec2::splat(-3.), 1e-5)); -/// assert!(r2.max.abs_diff_eq(Vec2::new(8., 4.), 1e-5)); -/// let r = Rect::new(0., -1., 6., 7.); // w=6 h=8 -/// let r2 = r.inflate(-2.); // w=11 h=7 -/// assert!(r2.min.abs_diff_eq(Vec2::new(2., 1.), 1e-5)); -/// assert!(r2.max.abs_diff_eq(Vec2::new(4., 5.), 1e-5)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn inflate(&self, expansion: f32) -> bevy::math::prelude::Rect; - -"#, - r#" -/// Build a new rectangle from this one with its coordinates expressed -/// relative to `other` in a normalized ([0..1] x [0..1]) coordinate system. -/// # Examples -/// ``` -/// # use bevy_math::{Rect, Vec2}; -/// let r = Rect::new(2., 3., 4., 6.); -/// let s = Rect::new(0., 0., 10., 10.); -/// let n = r.normalize(s); -/// assert_eq!(n.min.x, 0.2); -/// assert_eq!(n.min.y, 0.3); -/// assert_eq!(n.max.x, 0.4); -/// assert_eq!(n.max.y, 0.6); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn normalize( - &self, - #[proxy] - other: bevy::math::prelude::Rect, - ) -> bevy::math::prelude::Rect; - -"#, - r#" -/// Returns self as [`IRect`] (i32) - - #[lua(kind = "Method", output(proxy))] - fn as_irect(&self) -> bevy::math::prelude::IRect; - -"#, - r#" -/// Returns self as [`URect`] (u32) - - #[lua(kind = "Method", output(proxy))] - fn as_urect(&self) -> bevy::math::prelude::URect; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Rect { - #[lua(output(proxy))] - min: bevy::math::prelude::Vec2, - #[lua(output(proxy))] - max: bevy::math::prelude::Vec2, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::prelude::URect", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::prelude::URect; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &rects::urect::URect) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" -/// Create a new rectangle from two corner points. -/// The two points do not need to be the minimum and/or maximum corners. -/// They only need to be two opposite corners. -/// # Examples -/// ``` -/// # use bevy_math::URect; -/// let r = URect::new(0, 4, 10, 6); // w=10 h=2 -/// let r = URect::new(2, 4, 5, 0); // w=3 h=4 -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn new(x0: u32, y0: u32, x1: u32, y1: u32) -> bevy::math::prelude::URect; - -"#, - r#" -/// Create a new rectangle from two corner points. -/// The two points do not need to be the minimum and/or maximum corners. -/// They only need to be two opposite corners. -/// # Examples -/// ``` -/// # use bevy_math::{URect, UVec2}; -/// // Unit rect from [0,0] to [1,1] -/// let r = URect::from_corners(UVec2::ZERO, UVec2::ONE); // w=1 h=1 -/// // Same; the points do not need to be ordered -/// let r = URect::from_corners(UVec2::ONE, UVec2::ZERO); // w=1 h=1 -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_corners( - #[proxy] - p0: bevy::math::prelude::UVec2, - #[proxy] - p1: bevy::math::prelude::UVec2, - ) -> bevy::math::prelude::URect; - -"#, - r#" -/// Create a new rectangle from its center and size. -/// # Rounding Behavior -/// If the size contains odd numbers they will be rounded down to the nearest whole number. -/// # Panics -/// This method panics if any of the components of the size is negative or if `origin - (size / 2)` results in any negatives. -/// # Examples -/// ``` -/// # use bevy_math::{URect, UVec2}; -/// let r = URect::from_center_size(UVec2::ONE, UVec2::splat(2)); // w=2 h=2 -/// assert_eq!(r.min, UVec2::splat(0)); -/// assert_eq!(r.max, UVec2::splat(2)); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_center_size( - #[proxy] - origin: bevy::math::prelude::UVec2, - #[proxy] - size: bevy::math::prelude::UVec2, - ) -> bevy::math::prelude::URect; - -"#, - r#" -/// Create a new rectangle from its center and half-size. -/// # Panics -/// This method panics if any of the components of the half-size is negative or if `origin - half_size` results in any negatives. -/// # Examples -/// ``` -/// # use bevy_math::{URect, UVec2}; -/// let r = URect::from_center_half_size(UVec2::ONE, UVec2::ONE); // w=2 h=2 -/// assert_eq!(r.min, UVec2::splat(0)); -/// assert_eq!(r.max, UVec2::splat(2)); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_center_half_size( - #[proxy] - origin: bevy::math::prelude::UVec2, - #[proxy] - half_size: bevy::math::prelude::UVec2, - ) -> bevy::math::prelude::URect; - -"#, - r#" -/// Check if the rectangle is empty. -/// # Examples -/// ``` -/// # use bevy_math::{URect, UVec2}; -/// let r = URect::from_corners(UVec2::ZERO, UVec2::new(0, 1)); // w=0 h=1 -/// assert!(r.is_empty()); -/// ``` - - #[lua(kind = "Method")] - fn is_empty(&self) -> bool; - -"#, - r#" -/// Rectangle width (max.x - min.x). -/// # Examples -/// ``` -/// # use bevy_math::URect; -/// let r = URect::new(0, 0, 5, 1); // w=5 h=1 -/// assert_eq!(r.width(), 5); -/// ``` - - #[lua(kind = "Method")] - fn width(&self) -> u32; - -"#, - r#" -/// Rectangle height (max.y - min.y). -/// # Examples -/// ``` -/// # use bevy_math::URect; -/// let r = URect::new(0, 0, 5, 1); // w=5 h=1 -/// assert_eq!(r.height(), 1); -/// ``` - - #[lua(kind = "Method")] - fn height(&self) -> u32; - -"#, - r#" -/// Rectangle size. -/// # Examples -/// ``` -/// # use bevy_math::{URect, UVec2}; -/// let r = URect::new(0, 0, 5, 1); // w=5 h=1 -/// assert_eq!(r.size(), UVec2::new(5, 1)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn size(&self) -> bevy::math::prelude::UVec2; - -"#, - r#" -/// Rectangle half-size. -/// # Rounding Behavior -/// If the full size contains odd numbers they will be rounded down to the nearest whole number when calculating the half size. -/// # Examples -/// ``` -/// # use bevy_math::{URect, UVec2}; -/// let r = URect::new(0, 0, 4, 2); // w=4 h=2 -/// assert_eq!(r.half_size(), UVec2::new(2, 1)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn half_size(&self) -> bevy::math::prelude::UVec2; - -"#, - r#" -/// The center point of the rectangle. -/// # Rounding Behavior -/// If the (min + max) contains odd numbers they will be rounded down to the nearest whole number when calculating the center. -/// # Examples -/// ``` -/// # use bevy_math::{URect, UVec2}; -/// let r = URect::new(0, 0, 4, 2); // w=4 h=2 -/// assert_eq!(r.center(), UVec2::new(2, 1)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn center(&self) -> bevy::math::prelude::UVec2; - -"#, - r#" -/// Check if a point lies within this rectangle, inclusive of its edges. -/// # Examples -/// ``` -/// # use bevy_math::URect; -/// let r = URect::new(0, 0, 5, 1); // w=5 h=1 -/// assert!(r.contains(r.center())); -/// assert!(r.contains(r.min)); -/// assert!(r.contains(r.max)); -/// ``` - - #[lua(kind = "Method")] - fn contains(&self, #[proxy] point: bevy::math::prelude::UVec2) -> bool; - -"#, - r#" -/// Build a new rectangle formed of the union of this rectangle and another rectangle. -/// The union is the smallest rectangle enclosing both rectangles. -/// # Examples -/// ``` -/// # use bevy_math::{URect, UVec2}; -/// let r1 = URect::new(0, 0, 5, 1); // w=5 h=1 -/// let r2 = URect::new(1, 0, 3, 8); // w=2 h=4 -/// let r = r1.union(r2); -/// assert_eq!(r.min, UVec2::new(0, 0)); -/// assert_eq!(r.max, UVec2::new(5, 8)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn union( - &self, - #[proxy] - other: bevy::math::prelude::URect, - ) -> bevy::math::prelude::URect; - -"#, - r#" -/// Build a new rectangle formed of the union of this rectangle and a point. -/// The union is the smallest rectangle enclosing both the rectangle and the point. If the -/// point is already inside the rectangle, this method returns a copy of the rectangle. -/// # Examples -/// ``` -/// # use bevy_math::{URect, UVec2}; -/// let r = URect::new(0, 0, 5, 1); // w=5 h=1 -/// let u = r.union_point(UVec2::new(3, 6)); -/// assert_eq!(u.min, UVec2::ZERO); -/// assert_eq!(u.max, UVec2::new(5, 6)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn union_point( - &self, - #[proxy] - other: bevy::math::prelude::UVec2, - ) -> bevy::math::prelude::URect; - -"#, - r#" -/// Build a new rectangle formed of the intersection of this rectangle and another rectangle. -/// The intersection is the largest rectangle enclosed in both rectangles. If the intersection -/// is empty, this method returns an empty rectangle ([`URect::is_empty()`] returns `true`), but -/// the actual values of [`URect::min`] and [`URect::max`] are implementation-dependent. -/// # Examples -/// ``` -/// # use bevy_math::{URect, UVec2}; -/// let r1 = URect::new(0, 0, 2, 2); // w=2 h=2 -/// let r2 = URect::new(1, 1, 3, 3); // w=2 h=2 -/// let r = r1.intersect(r2); -/// assert_eq!(r.min, UVec2::new(1, 1)); -/// assert_eq!(r.max, UVec2::new(2, 2)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn intersect( - &self, - #[proxy] - other: bevy::math::prelude::URect, - ) -> bevy::math::prelude::URect; - -"#, - r#" -/// Create a new rectangle by expanding it evenly on all sides. -/// A positive expansion value produces a larger rectangle, -/// while a negative expansion value produces a smaller rectangle. -/// If this would result in zero width or height, [`URect::EMPTY`] is returned instead. -/// # Examples -/// ``` -/// # use bevy_math::{URect, UVec2}; -/// let r = URect::new(4, 4, 6, 6); // w=2 h=2 -/// let r2 = r.inflate(1); // w=4 h=4 -/// assert_eq!(r2.min, UVec2::splat(3)); -/// assert_eq!(r2.max, UVec2::splat(7)); -/// let r = URect::new(4, 4, 8, 8); // w=4 h=4 -/// let r2 = r.inflate(-1); // w=2 h=2 -/// assert_eq!(r2.min, UVec2::splat(5)); -/// assert_eq!(r2.max, UVec2::splat(7)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn inflate(&self, expansion: i32) -> bevy::math::prelude::URect; - -"#, - r#" -/// Returns self as [`Rect`] (f32) - - #[lua(kind = "Method", output(proxy))] - fn as_rect(&self) -> bevy::math::prelude::Rect; - -"#, - r#" -/// Returns self as [`IRect`] (i32) - - #[lua(kind = "Method", output(proxy))] - fn as_irect(&self) -> bevy::math::prelude::IRect; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct URect { - #[lua(output(proxy))] - min: bevy::math::prelude::UVec2, - #[lua(output(proxy))] - max: bevy::math::prelude::UVec2, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy(derive(), remote = "bevy::math::Affine3", functions[])] -struct Affine3 { - #[lua(output(proxy))] - matrix3: bevy::math::prelude::Mat3, - #[lua(output(proxy))] - translation: bevy::math::prelude::Vec3, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::bounding::Aabb2d", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::bounding::Aabb2d; - -"#, - r#" -/// Constructs an AABB from its center and half-size. - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - center: bevy::math::prelude::Vec2, - #[proxy] - half_size: bevy::math::prelude::Vec2, - ) -> bevy::math::bounding::Aabb2d; - -"#, - r#" -/// Computes the smallest [`BoundingCircle`] containing this [`Aabb2d`]. - - #[lua(kind = "Method", output(proxy))] - fn bounding_circle(&self) -> bevy::math::bounding::BoundingCircle; - -"#, - r#" -/// Finds the point on the AABB that is closest to the given `point`. -/// If the point is outside the AABB, the returned point will be on the perimeter of the AABB. -/// Otherwise, it will be inside the AABB and returned as is. - - #[lua(kind = "Method", output(proxy))] - fn closest_point( - &self, - #[proxy] - point: bevy::math::prelude::Vec2, - ) -> bevy::math::prelude::Vec2; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Aabb2d { - #[lua(output(proxy))] - min: bevy::math::prelude::Vec2, - #[lua(output(proxy))] - max: bevy::math::prelude::Vec2, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::bounding::BoundingCircle", - functions[r#" -/// Constructs a bounding circle from its center and radius. - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - center: bevy::math::prelude::Vec2, - radius: f32, - ) -> bevy::math::bounding::BoundingCircle; - -"#, - r#" -/// Get the radius of the bounding circle - - #[lua(kind = "Method")] - fn radius(&self) -> f32; - -"#, - r#" -/// Computes the smallest [`Aabb2d`] containing this [`BoundingCircle`]. - - #[lua(kind = "Method", output(proxy))] - fn aabb_2d(&self) -> bevy::math::bounding::Aabb2d; - -"#, - r#" -/// Finds the point on the bounding circle that is closest to the given `point`. -/// If the point is outside the circle, the returned point will be on the perimeter of the circle. -/// Otherwise, it will be inside the circle and returned as is. - - #[lua(kind = "Method", output(proxy))] - fn closest_point( - &self, - #[proxy] - point: bevy::math::prelude::Vec2, - ) -> bevy::math::prelude::Vec2; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::bounding::BoundingCircle; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct BoundingCircle { - #[lua(output(proxy))] - center: bevy::math::prelude::Vec2, - #[lua(output(proxy))] - circle: bevy::math::primitives::Circle, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Circle", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Circle; - -"#, - r#" -/// Create a new [`Circle`] from a `radius` - - #[lua(kind = "Function", output(proxy))] - fn new(radius: f32) -> bevy::math::primitives::Circle; - -"#, - r#" -/// Get the diameter of the circle - - #[lua(kind = "Method")] - fn diameter(&self) -> f32; - -"#, - r#" -/// Finds the point on the circle that is closest to the given `point`. -/// If the point is outside the circle, the returned point will be on the perimeter of the circle. -/// Otherwise, it will be inside the circle and returned as is. - - #[lua(kind = "Method", output(proxy))] - fn closest_point( - &self, - #[proxy] - point: bevy::math::prelude::Vec2, - ) -> bevy::math::prelude::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim2::Circle) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Circle { - radius: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Annulus", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim2::Annulus) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Annulus; - -"#, - r#" -/// Create a new [`Annulus`] from the radii of the inner and outer circle - - #[lua(kind = "Function", output(proxy))] - fn new(inner_radius: f32, outer_radius: f32) -> bevy::math::primitives::Annulus; - -"#, - r#" -/// Get the diameter of the annulus - - #[lua(kind = "Method")] - fn diameter(&self) -> f32; - -"#, - r#" -/// Get the thickness of the annulus - - #[lua(kind = "Method")] - fn thickness(&self) -> f32; - -"#, - r#" -/// Finds the point on the annulus that is closest to the given `point`: -/// - If the point is outside of the annulus completely, the returned point will be on the outer perimeter. -/// - If the point is inside of the inner circle (hole) of the annulus, the returned point will be on the inner perimeter. -/// - Otherwise, the returned point is overlapping the annulus and returned as is. - - #[lua(kind = "Method", output(proxy))] - fn closest_point( - &self, - #[proxy] - point: bevy::math::prelude::Vec2, - ) -> bevy::math::prelude::Vec2; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Annulus { - #[lua(output(proxy))] - inner_circle: bevy::math::primitives::Circle, - #[lua(output(proxy))] - outer_circle: bevy::math::primitives::Circle, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Arc2d", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Arc2d; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim2::Arc2d) -> bool; - -"#, - r#" -/// Create a new [`Arc2d`] from a `radius` and a `half_angle` - - #[lua(kind = "Function", output(proxy))] - fn new(radius: f32, half_angle: f32) -> bevy::math::primitives::Arc2d; - -"#, - r#" -/// Create a new [`Arc2d`] from a `radius` and an `angle` in radians - - #[lua(kind = "Function", output(proxy))] - fn from_radians(radius: f32, angle: f32) -> bevy::math::primitives::Arc2d; - -"#, - r#" -/// Create a new [`Arc2d`] from a `radius` and an `angle` in degrees. - - #[lua(kind = "Function", output(proxy))] - fn from_degrees(radius: f32, angle: f32) -> bevy::math::primitives::Arc2d; - -"#, - r#" -/// Create a new [`Arc2d`] from a `radius` and a `fraction` of a single turn. -/// For instance, `0.5` turns is a semicircle. - - #[lua(kind = "Function", output(proxy))] - fn from_turns(radius: f32, fraction: f32) -> bevy::math::primitives::Arc2d; - -"#, - r#" -/// Get the angle of the arc - - #[lua(kind = "Method")] - fn angle(&self) -> f32; - -"#, - r#" -/// Get the length of the arc - - #[lua(kind = "Method")] - fn length(&self) -> f32; - -"#, - r#" -/// Get the right-hand end point of the arc - - #[lua(kind = "Method", output(proxy))] - fn right_endpoint(&self) -> bevy::math::prelude::Vec2; - -"#, - r#" -/// Get the left-hand end point of the arc - - #[lua(kind = "Method", output(proxy))] - fn left_endpoint(&self) -> bevy::math::prelude::Vec2; - -"#, - r#" -/// Get the midpoint of the arc - - #[lua(kind = "Method", output(proxy))] - fn midpoint(&self) -> bevy::math::prelude::Vec2; - -"#, - r#" -/// Get half the distance between the endpoints (half the length of the chord) - - #[lua(kind = "Method")] - fn half_chord_length(&self) -> f32; - -"#, - r#" -/// Get the distance between the endpoints (the length of the chord) - - #[lua(kind = "Method")] - fn chord_length(&self) -> f32; - -"#, - r#" -/// Get the midpoint of the two endpoints (the midpoint of the chord) - - #[lua(kind = "Method", output(proxy))] - fn chord_midpoint(&self) -> bevy::math::prelude::Vec2; - -"#, - r#" -/// Get the length of the apothem of this arc, that is, -/// the distance from the center of the circle to the midpoint of the chord, in the direction of the midpoint of the arc. -/// Equivalently, the [`radius`](Self::radius) minus the [`sagitta`](Self::sagitta). -/// Note that for a [`major`](Self::is_major) arc, the apothem will be negative. - - #[lua(kind = "Method")] - fn apothem(&self) -> f32; - -"#, - r#" -/// Get the length of the sagitta of this arc, that is, -/// the length of the line between the midpoints of the arc and its chord. -/// Equivalently, the height of the triangle whose base is the chord and whose apex is the midpoint of the arc. -/// The sagitta is also the sum of the [`radius`](Self::radius) and the [`apothem`](Self::apothem). - - #[lua(kind = "Method")] - fn sagitta(&self) -> f32; - -"#, - r#" -/// Produces true if the arc is at most half a circle. -/// **Note:** This is not the negation of [`is_major`](Self::is_major): an exact semicircle is both major and minor. - - #[lua(kind = "Method")] - fn is_minor(&self) -> bool; - -"#, - r#" -/// Produces true if the arc is at least half a circle. -/// **Note:** This is not the negation of [`is_minor`](Self::is_minor): an exact semicircle is both major and minor. - - #[lua(kind = "Method")] - fn is_major(&self) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Arc2d { - radius: f32, - half_angle: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Capsule2d", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim2::Capsule2d) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Capsule2d; - -"#, - r#" -/// Create a new `Capsule2d` from a radius and length - - #[lua(kind = "Function", output(proxy))] - fn new(radius: f32, length: f32) -> bevy::math::primitives::Capsule2d; - -"#, - r#" -/// Get the part connecting the semicircular ends of the capsule as a [`Rectangle`] - - #[lua(kind = "Method", output(proxy))] - fn to_inner_rectangle(&self) -> bevy::math::primitives::Rectangle; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Capsule2d { - radius: f32, - half_length: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::CircularSector", - functions[r#" -/// Create a new [`CircularSector`] from a `radius` and an `angle` - - #[lua(kind = "Function", output(proxy))] - fn new(radius: f32, angle: f32) -> bevy::math::primitives::CircularSector; - -"#, - r#" -/// Create a new [`CircularSector`] from a `radius` and an `angle` in radians. - - #[lua(kind = "Function", output(proxy))] - fn from_radians(radius: f32, angle: f32) -> bevy::math::primitives::CircularSector; - -"#, - r#" -/// Create a new [`CircularSector`] from a `radius` and an `angle` in degrees. - - #[lua(kind = "Function", output(proxy))] - fn from_degrees(radius: f32, angle: f32) -> bevy::math::primitives::CircularSector; - -"#, - r#" -/// Create a new [`CircularSector`] from a `radius` and a number of `turns` of a circle. -/// For instance, `0.5` turns is a semicircle. - - #[lua(kind = "Function", output(proxy))] - fn from_turns(radius: f32, fraction: f32) -> bevy::math::primitives::CircularSector; - -"#, - r#" -/// Get half the angle of the sector - - #[lua(kind = "Method")] - fn half_angle(&self) -> f32; - -"#, - r#" -/// Get the angle of the sector - - #[lua(kind = "Method")] - fn angle(&self) -> f32; - -"#, - r#" -/// Get the radius of the sector - - #[lua(kind = "Method")] - fn radius(&self) -> f32; - -"#, - r#" -/// Get the length of the arc defining the sector - - #[lua(kind = "Method")] - fn arc_length(&self) -> f32; - -"#, - r#" -/// Get half the length of the chord defined by the sector -/// See [`Arc2d::half_chord_length`] - - #[lua(kind = "Method")] - fn half_chord_length(&self) -> f32; - -"#, - r#" -/// Get the length of the chord defined by the sector -/// See [`Arc2d::chord_length`] - - #[lua(kind = "Method")] - fn chord_length(&self) -> f32; - -"#, - r#" -/// Get the midpoint of the chord defined by the sector -/// See [`Arc2d::chord_midpoint`] - - #[lua(kind = "Method", output(proxy))] - fn chord_midpoint(&self) -> bevy::math::prelude::Vec2; - -"#, - r#" -/// Get the length of the apothem of this sector -/// See [`Arc2d::apothem`] - - #[lua(kind = "Method")] - fn apothem(&self) -> f32; - -"#, - r#" -/// Get the length of the sagitta of this sector -/// See [`Arc2d::sagitta`] - - #[lua(kind = "Method")] - fn sagitta(&self) -> f32; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::CircularSector; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim2::CircularSector) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct CircularSector { - #[lua(output(proxy))] - arc: bevy::math::primitives::Arc2d, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::CircularSegment", - functions[r#" -/// Create a new [`CircularSegment`] from a `radius`, and an `angle` - - #[lua(kind = "Function", output(proxy))] - fn new(radius: f32, angle: f32) -> bevy::math::primitives::CircularSegment; - -"#, - r#" -/// Create a new [`CircularSegment`] from a `radius` and an `angle` in radians. - - #[lua(kind = "Function", output(proxy))] - fn from_radians(radius: f32, angle: f32) -> bevy::math::primitives::CircularSegment; - -"#, - r#" -/// Create a new [`CircularSegment`] from a `radius` and an `angle` in degrees. - - #[lua(kind = "Function", output(proxy))] - fn from_degrees(radius: f32, angle: f32) -> bevy::math::primitives::CircularSegment; - -"#, - r#" -/// Create a new [`CircularSegment`] from a `radius` and a number of `turns` of a circle. -/// For instance, `0.5` turns is a semicircle. - - #[lua(kind = "Function", output(proxy))] - fn from_turns(radius: f32, fraction: f32) -> bevy::math::primitives::CircularSegment; - -"#, - r#" -/// Get the half-angle of the segment - - #[lua(kind = "Method")] - fn half_angle(&self) -> f32; - -"#, - r#" -/// Get the angle of the segment - - #[lua(kind = "Method")] - fn angle(&self) -> f32; - -"#, - r#" -/// Get the radius of the segment - - #[lua(kind = "Method")] - fn radius(&self) -> f32; - -"#, - r#" -/// Get the length of the arc defining the segment - - #[lua(kind = "Method")] - fn arc_length(&self) -> f32; - -"#, - r#" -/// Get half the length of the segment's base, also known as its chord - - #[lua(kind = "Method")] - fn half_chord_length(&self) -> f32; - -"#, - r#" -/// Get the length of the segment's base, also known as its chord - - #[lua(kind = "Method")] - fn chord_length(&self) -> f32; - -"#, - r#" -/// Get the midpoint of the segment's base, also known as its chord - - #[lua(kind = "Method", output(proxy))] - fn chord_midpoint(&self) -> bevy::math::prelude::Vec2; - -"#, - r#" -/// Get the length of the apothem of this segment, -/// which is the signed distance between the segment and the center of its circle -/// See [`Arc2d::apothem`] - - #[lua(kind = "Method")] - fn apothem(&self) -> f32; - -"#, - r#" -/// Get the length of the sagitta of this segment, also known as its height -/// See [`Arc2d::sagitta`] - - #[lua(kind = "Method")] - fn sagitta(&self) -> f32; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim2::CircularSegment) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::CircularSegment; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct CircularSegment { - #[lua(output(proxy))] - arc: bevy::math::primitives::Arc2d, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Ellipse", - functions[r#" -/// Create a new `Ellipse` from half of its width and height. -/// This corresponds to the two perpendicular radii defining the ellipse. - - #[lua(kind = "Function", output(proxy))] - fn new(half_width: f32, half_height: f32) -> bevy::math::primitives::Ellipse; - -"#, - r#" -/// Create a new `Ellipse` from a given full size. -/// `size.x` is the diameter along the X axis, and `size.y` is the diameter along the Y axis. - - #[lua(kind = "Function", output(proxy))] - fn from_size( - #[proxy] - size: bevy::math::prelude::Vec2, - ) -> bevy::math::primitives::Ellipse; - -"#, - r#" -/// Returns the [eccentricity](https://en.wikipedia.org/wiki/Eccentricity_(mathematics)) of the ellipse. -/// It can be thought of as a measure of how "stretched" or elongated the ellipse is. -/// The value should be in the range [0, 1), where 0 represents a circle, and 1 represents a parabola. - - #[lua(kind = "Method")] - fn eccentricity(&self) -> f32; - -"#, - r#" -/// Get the focal length of the ellipse. This corresponds to the distance between one of the foci and the center of the ellipse. -/// The focal length of an ellipse is related to its eccentricity by `eccentricity = focal_length / semi_major` - - #[lua(kind = "Method")] - fn focal_length(&self) -> f32; - -"#, - r#" -/// Returns the length of the semi-major axis. This corresponds to the longest radius of the ellipse. - - #[lua(kind = "Method")] - fn semi_major(&self) -> f32; - -"#, - r#" -/// Returns the length of the semi-minor axis. This corresponds to the shortest radius of the ellipse. - - #[lua(kind = "Method")] - fn semi_minor(&self) -> f32; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Ellipse; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim2::Ellipse) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Ellipse { - #[lua(output(proxy))] - half_size: bevy::math::prelude::Vec2, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Line2d", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim2::Line2d) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Line2d; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Line2d { - #[lua(output(proxy))] - direction: bevy::math::prelude::Dir2, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Plane2d", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim2::Plane2d) -> bool; - -"#, - r#" -/// Create a new `Plane2d` from a normal -/// # Panics -/// Panics if the given `normal` is zero (or very close to zero), or non-finite. - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - normal: bevy::math::prelude::Vec2, - ) -> bevy::math::primitives::Plane2d; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Plane2d; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Plane2d { - #[lua(output(proxy))] - normal: bevy::math::prelude::Dir2, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Rectangle", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim2::Rectangle) -> bool; - -"#, - r#" -/// Create a new `Rectangle` from a full width and height - - #[lua(kind = "Function", output(proxy))] - fn new(width: f32, height: f32) -> bevy::math::primitives::Rectangle; - -"#, - r#" -/// Create a new `Rectangle` from a given full size - - #[lua(kind = "Function", output(proxy))] - fn from_size( - #[proxy] - size: bevy::math::prelude::Vec2, - ) -> bevy::math::primitives::Rectangle; - -"#, - r#" -/// Create a new `Rectangle` from two corner points - - #[lua(kind = "Function", output(proxy))] - fn from_corners( - #[proxy] - point1: bevy::math::prelude::Vec2, - #[proxy] - point2: bevy::math::prelude::Vec2, - ) -> bevy::math::primitives::Rectangle; - -"#, - r#" -/// Create a `Rectangle` from a single length. -/// The resulting `Rectangle` will be the same size in every direction. - - #[lua(kind = "Function", output(proxy))] - fn from_length(length: f32) -> bevy::math::primitives::Rectangle; - -"#, - r#" -/// Get the size of the rectangle - - #[lua(kind = "Method", output(proxy))] - fn size(&self) -> bevy::math::prelude::Vec2; - -"#, - r#" -/// Finds the point on the rectangle that is closest to the given `point`. -/// If the point is outside the rectangle, the returned point will be on the perimeter of the rectangle. -/// Otherwise, it will be inside the rectangle and returned as is. - - #[lua(kind = "Method", output(proxy))] - fn closest_point( - &self, - #[proxy] - point: bevy::math::prelude::Vec2, - ) -> bevy::math::prelude::Vec2; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Rectangle; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Rectangle { - #[lua(output(proxy))] - half_size: bevy::math::prelude::Vec2, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::RegularPolygon", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::RegularPolygon; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim2::RegularPolygon) -> bool; - -"#, - r#" -/// Create a new `RegularPolygon` -/// from the radius of the circumcircle and a number of sides -/// # Panics -/// Panics if `circumradius` is negative - - #[lua(kind = "Function", output(proxy))] - fn new(circumradius: f32, sides: u32) -> bevy::math::primitives::RegularPolygon; - -"#, - r#" -/// Get the radius of the circumcircle on which all vertices -/// of the regular polygon lie - - #[lua(kind = "Method")] - fn circumradius(&self) -> f32; - -"#, - r#" -/// Get the inradius or apothem of the regular polygon. -/// This is the radius of the largest circle that can -/// be drawn within the polygon - - #[lua(kind = "Method")] - fn inradius(&self) -> f32; - -"#, - r#" -/// Get the length of one side of the regular polygon - - #[lua(kind = "Method")] - fn side_length(&self) -> f32; - -"#, - r#" -/// Get the internal angle of the regular polygon in degrees. -/// This is the angle formed by two adjacent sides with points -/// within the angle being in the interior of the polygon - - #[lua(kind = "Method")] - fn internal_angle_degrees(&self) -> f32; - -"#, - r#" -/// Get the internal angle of the regular polygon in radians. -/// This is the angle formed by two adjacent sides with points -/// within the angle being in the interior of the polygon - - #[lua(kind = "Method")] - fn internal_angle_radians(&self) -> f32; - -"#, - r#" -/// Get the external angle of the regular polygon in degrees. -/// This is the angle formed by two adjacent sides with points -/// within the angle being in the exterior of the polygon - - #[lua(kind = "Method")] - fn external_angle_degrees(&self) -> f32; - -"#, - r#" -/// Get the external angle of the regular polygon in radians. -/// This is the angle formed by two adjacent sides with points -/// within the angle being in the exterior of the polygon - - #[lua(kind = "Method")] - fn external_angle_radians(&self) -> f32; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct RegularPolygon { - #[lua(output(proxy))] - circumcircle: bevy::math::primitives::Circle, - sides: u32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Rhombus", - functions[r#" -/// Create a new `Rhombus` from a vertical and horizontal diagonal sizes. - - #[lua(kind = "Function", output(proxy))] - fn new( - horizontal_diagonal: f32, - vertical_diagonal: f32, - ) -> bevy::math::primitives::Rhombus; - -"#, - r#" -/// Create a new `Rhombus` from a side length with all inner angles equal. - - #[lua(kind = "Function", output(proxy))] - fn from_side(side: f32) -> bevy::math::primitives::Rhombus; - -"#, - r#" -/// Create a new `Rhombus` from a given inradius with all inner angles equal. - - #[lua(kind = "Function", output(proxy))] - fn from_inradius(inradius: f32) -> bevy::math::primitives::Rhombus; - -"#, - r#" -/// Get the length of each side of the rhombus - - #[lua(kind = "Method")] - fn side(&self) -> f32; - -"#, - r#" -/// Get the radius of the circumcircle on which all vertices -/// of the rhombus lie - - #[lua(kind = "Method")] - fn circumradius(&self) -> f32; - -"#, - r#" -/// Get the radius of the largest circle that can -/// be drawn within the rhombus - - #[lua(kind = "Method")] - fn inradius(&self) -> f32; - -"#, - r#" -/// Finds the point on the rhombus that is closest to the given `point`. -/// If the point is outside the rhombus, the returned point will be on the perimeter of the rhombus. -/// Otherwise, it will be inside the rhombus and returned as is. - - #[lua(kind = "Method", output(proxy))] - fn closest_point( - &self, - #[proxy] - point: bevy::math::prelude::Vec2, - ) -> bevy::math::prelude::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim2::Rhombus) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Rhombus; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Rhombus { - #[lua(output(proxy))] - half_diagonals: bevy::math::prelude::Vec2, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Segment2d", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim2::Segment2d) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Segment2d; - -"#, - r#" -/// Create a new `Segment2d` from a direction and full length of the segment - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - direction: bevy::math::prelude::Dir2, - length: f32, - ) -> bevy::math::primitives::Segment2d; - -"#, - r#" -/// Get the position of the first point on the line segment - - #[lua(kind = "Method", output(proxy))] - fn point1(&self) -> bevy::math::prelude::Vec2; - -"#, - r#" -/// Get the position of the second point on the line segment - - #[lua(kind = "Method", output(proxy))] - fn point2(&self) -> bevy::math::prelude::Vec2; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Segment2d { - #[lua(output(proxy))] - direction: bevy::math::prelude::Dir2, - half_length: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Triangle2d", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim2::Triangle2d) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Triangle2d; - -"#, - r#" -/// Create a new `Triangle2d` from points `a`, `b`, and `c` - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - a: bevy::math::prelude::Vec2, - #[proxy] - b: bevy::math::prelude::Vec2, - #[proxy] - c: bevy::math::prelude::Vec2, - ) -> bevy::math::primitives::Triangle2d; - -"#, - r#" -/// Checks if the triangle is degenerate, meaning it has zero area. -/// A triangle is degenerate if the cross product of the vectors `ab` and `ac` has a length less than `10e-7`. -/// This indicates that the three vertices are collinear or nearly collinear. - - #[lua(kind = "Method")] - fn is_degenerate(&self) -> bool; - -"#, - r#" -/// Checks if the triangle is acute, meaning all angles are less than 90 degrees - - #[lua(kind = "Method")] - fn is_acute(&self) -> bool; - -"#, - r#" -/// Checks if the triangle is obtuse, meaning one angle is greater than 90 degrees - - #[lua(kind = "Method")] - fn is_obtuse(&self) -> bool; - -"#, - r#" -/// Reverse the [`WindingOrder`] of the triangle -/// by swapping the first and last vertices. - - #[lua(kind = "MutatingMethod")] - fn reverse(&mut self) -> (); - -"#, - r#" -/// This triangle but reversed. - - #[lua(kind = "Method", output(proxy))] - fn reversed(self) -> bevy::math::primitives::Triangle2d; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Triangle2d { - vertices: ReflectedValue, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::bounding::Aabb3d", - functions[r#" -/// Computes the smallest [`BoundingSphere`] containing this [`Aabb3d`]. - - #[lua(kind = "Method", output(proxy))] - fn bounding_sphere(&self) -> bevy::math::bounding::BoundingSphere; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::bounding::Aabb3d; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Aabb3d { - #[lua(output(proxy))] - min: bevy::math::Vec3A, - #[lua(output(proxy))] - max: bevy::math::Vec3A, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::bounding::BoundingSphere", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::bounding::BoundingSphere; - -"#, - r#" -/// Get the radius of the bounding sphere - - #[lua(kind = "Method")] - fn radius(&self) -> f32; - -"#, - r#" -/// Computes the smallest [`Aabb3d`] containing this [`BoundingSphere`]. - - #[lua(kind = "Method", output(proxy))] - fn aabb_3d(&self) -> bevy::math::bounding::Aabb3d; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct BoundingSphere { - #[lua(output(proxy))] - center: bevy::math::Vec3A, - #[lua(output(proxy))] - sphere: bevy::math::primitives::Sphere, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Sphere", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim3::Sphere) -> bool; - -"#, - r#" -/// Create a new [`Sphere`] from a `radius` - - #[lua(kind = "Function", output(proxy))] - fn new(radius: f32) -> bevy::math::primitives::Sphere; - -"#, - r#" -/// Get the diameter of the sphere - - #[lua(kind = "Method")] - fn diameter(&self) -> f32; - -"#, - r#" -/// Finds the point on the sphere that is closest to the given `point`. -/// If the point is outside the sphere, the returned point will be on the surface of the sphere. -/// Otherwise, it will be inside the sphere and returned as is. - - #[lua(kind = "Method", output(proxy))] - fn closest_point( - &self, - #[proxy] - point: bevy::math::prelude::Vec3, - ) -> bevy::math::prelude::Vec3; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Sphere; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Sphere { - radius: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Cuboid", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Cuboid; - -"#, - r#" -/// Create a new `Cuboid` from a full x, y, and z length - - #[lua(kind = "Function", output(proxy))] - fn new( - x_length: f32, - y_length: f32, - z_length: f32, - ) -> bevy::math::primitives::Cuboid; - -"#, - r#" -/// Create a new `Cuboid` from a given full size - - #[lua(kind = "Function", output(proxy))] - fn from_size( - #[proxy] - size: bevy::math::prelude::Vec3, - ) -> bevy::math::primitives::Cuboid; - -"#, - r#" -/// Create a new `Cuboid` from two corner points - - #[lua(kind = "Function", output(proxy))] - fn from_corners( - #[proxy] - point1: bevy::math::prelude::Vec3, - #[proxy] - point2: bevy::math::prelude::Vec3, - ) -> bevy::math::primitives::Cuboid; - -"#, - r#" -/// Create a `Cuboid` from a single length. -/// The resulting `Cuboid` will be the same size in every direction. - - #[lua(kind = "Function", output(proxy))] - fn from_length(length: f32) -> bevy::math::primitives::Cuboid; - -"#, - r#" -/// Get the size of the cuboid - - #[lua(kind = "Method", output(proxy))] - fn size(&self) -> bevy::math::prelude::Vec3; - -"#, - r#" -/// Finds the point on the cuboid that is closest to the given `point`. -/// If the point is outside the cuboid, the returned point will be on the surface of the cuboid. -/// Otherwise, it will be inside the cuboid and returned as is. - - #[lua(kind = "Method", output(proxy))] - fn closest_point( - &self, - #[proxy] - point: bevy::math::prelude::Vec3, - ) -> bevy::math::prelude::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim3::Cuboid) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Cuboid { - #[lua(output(proxy))] - half_size: bevy::math::prelude::Vec3, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Cylinder", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim3::Cylinder) -> bool; - -"#, - r#" -/// Create a new `Cylinder` from a radius and full height - - #[lua(kind = "Function", output(proxy))] - fn new(radius: f32, height: f32) -> bevy::math::primitives::Cylinder; - -"#, - r#" -/// Get the base of the cylinder as a [`Circle`] - - #[lua(kind = "Method", output(proxy))] - fn base(&self) -> bevy::math::primitives::Circle; - -"#, - r#" -/// Get the surface area of the side of the cylinder, -/// also known as the lateral area - - #[lua(kind = "Method")] - fn lateral_area(&self) -> f32; - -"#, - r#" -/// Get the surface area of one base of the cylinder - - #[lua(kind = "Method")] - fn base_area(&self) -> f32; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Cylinder; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Cylinder { - radius: f32, - half_height: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Capsule3d", - functions[r#" -/// Create a new `Capsule3d` from a radius and length - - #[lua(kind = "Function", output(proxy))] - fn new(radius: f32, length: f32) -> bevy::math::primitives::Capsule3d; - -"#, - r#" -/// Get the part connecting the hemispherical ends -/// of the capsule as a [`Cylinder`] - - #[lua(kind = "Method", output(proxy))] - fn to_cylinder(&self) -> bevy::math::primitives::Cylinder; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Capsule3d; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim3::Capsule3d) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Capsule3d { - radius: f32, - half_length: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Cone", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim3::Cone) -> bool; - -"#, - r#" -/// Create a new [`Cone`] from a radius and height. - - #[lua(kind = "Function", output(proxy))] - fn new(radius: f32, height: f32) -> bevy::math::primitives::Cone; - -"#, - r#" -/// Get the base of the cone as a [`Circle`] - - #[lua(kind = "Method", output(proxy))] - fn base(&self) -> bevy::math::primitives::Circle; - -"#, - r#" -/// Get the slant height of the cone, the length of the line segment -/// connecting a point on the base to the apex - - #[lua(kind = "Method")] - fn slant_height(&self) -> f32; - -"#, - r#" -/// Get the surface area of the side of the cone, -/// also known as the lateral area - - #[lua(kind = "Method")] - fn lateral_area(&self) -> f32; - -"#, - r#" -/// Get the surface area of the base of the cone - - #[lua(kind = "Method")] - fn base_area(&self) -> f32; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Cone; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Cone { - radius: f32, - height: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::ConicalFrustum", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::ConicalFrustum; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim3::ConicalFrustum) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct ConicalFrustum { - radius_top: f32, - radius_bottom: f32, - height: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::InfinitePlane3d", - functions[r#" -/// Computes an [`Isometry3d`] which transforms points from the plane in 3D space with the given -/// `origin` to the XY-plane. -/// ## Guarantees -/// * the transformation is a [congruence] meaning it will preserve all distances and angles of -/// the transformed geometry -/// * uses the least rotation possible to transform the geometry -/// * if two geometries are transformed with the same isometry, then the relations between -/// them, like distances, are also preserved -/// * compared to projections, the transformation is lossless (up to floating point errors) -/// reversible -/// ## Non-Guarantees -/// * the rotation used is generally not unique -/// * the orientation of the transformed geometry in the XY plane might be arbitrary, to -/// enforce some kind of alignment the user has to use an extra transformation ontop of this -/// one -/// See [`isometries_xy`] for example usescases. -/// [congruence]: https://en.wikipedia.org/wiki/Congruence_(geometry) -/// [`isometries_xy`]: `InfinitePlane3d::isometries_xy` - - #[lua(kind = "Method", output(proxy))] - fn isometry_into_xy( - &self, - #[proxy] - origin: bevy::math::prelude::Vec3, - ) -> bevy::math::Isometry3d; - -"#, - r#" -/// Computes an [`Isometry3d`] which transforms points from the XY-plane to this plane with the -/// given `origin`. -/// ## Guarantees -/// * the transformation is a [congruence] meaning it will preserve all distances and angles of -/// the transformed geometry -/// * uses the least rotation possible to transform the geometry -/// * if two geometries are transformed with the same isometry, then the relations between -/// them, like distances, are also preserved -/// * compared to projections, the transformation is lossless (up to floating point errors) -/// reversible -/// ## Non-Guarantees -/// * the rotation used is generally not unique -/// * the orientation of the transformed geometry in the XY plane might be arbitrary, to -/// enforce some kind of alignment the user has to use an extra transformation ontop of this -/// one -/// See [`isometries_xy`] for example usescases. -/// [congruence]: https://en.wikipedia.org/wiki/Congruence_(geometry) -/// [`isometries_xy`]: `InfinitePlane3d::isometries_xy` - - #[lua(kind = "Method", output(proxy))] - fn isometry_from_xy( - &self, - #[proxy] - origin: bevy::math::prelude::Vec3, - ) -> bevy::math::Isometry3d; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::InfinitePlane3d; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim3::InfinitePlane3d) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct InfinitePlane3d { - #[lua(output(proxy))] - normal: bevy::math::prelude::Dir3, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Line3d", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Line3d; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim3::Line3d) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Line3d { - #[lua(output(proxy))] - direction: bevy::math::prelude::Dir3, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Segment3d", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Segment3d; - -"#, - r#" -/// Create a new `Segment3d` from a direction and full length of the segment - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - direction: bevy::math::prelude::Dir3, - length: f32, - ) -> bevy::math::primitives::Segment3d; - -"#, - r#" -/// Get the position of the first point on the line segment - - #[lua(kind = "Method", output(proxy))] - fn point1(&self) -> bevy::math::prelude::Vec3; - -"#, - r#" -/// Get the position of the second point on the line segment - - #[lua(kind = "Method", output(proxy))] - fn point2(&self) -> bevy::math::prelude::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim3::Segment3d) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Segment3d { - #[lua(output(proxy))] - direction: bevy::math::prelude::Dir3, - half_length: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Torus", - functions[r#" -/// Create a new `Torus` from an inner and outer radius. -/// The inner radius is the radius of the hole, and the outer radius -/// is the radius of the entire object - - #[lua(kind = "Function", output(proxy))] - fn new(inner_radius: f32, outer_radius: f32) -> bevy::math::primitives::Torus; - -"#, - r#" -/// Get the inner radius of the torus. -/// For a ring torus, this corresponds to the radius of the hole, -/// or `major_radius - minor_radius` - - #[lua(kind = "Method")] - fn inner_radius(&self) -> f32; - -"#, - r#" -/// Get the outer radius of the torus. -/// This corresponds to the overall radius of the entire object, -/// or `major_radius + minor_radius` - - #[lua(kind = "Method")] - fn outer_radius(&self) -> f32; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim3::Torus) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Torus; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Torus { - minor_radius: f32, - major_radius: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Triangle3d", - functions[r#" -/// Create a new [`Triangle3d`] from points `a`, `b`, and `c`. - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - a: bevy::math::prelude::Vec3, - #[proxy] - b: bevy::math::prelude::Vec3, - #[proxy] - c: bevy::math::prelude::Vec3, - ) -> bevy::math::primitives::Triangle3d; - -"#, - r#" -/// Checks if the triangle is degenerate, meaning it has zero area. -/// A triangle is degenerate if the cross product of the vectors `ab` and `ac` has a length less than `10e-7`. -/// This indicates that the three vertices are collinear or nearly collinear. - - #[lua(kind = "Method")] - fn is_degenerate(&self) -> bool; - -"#, - r#" -/// Checks if the triangle is acute, meaning all angles are less than 90 degrees - - #[lua(kind = "Method")] - fn is_acute(&self) -> bool; - -"#, - r#" -/// Checks if the triangle is obtuse, meaning one angle is greater than 90 degrees - - #[lua(kind = "Method")] - fn is_obtuse(&self) -> bool; - -"#, - r#" -/// Reverse the triangle by swapping the first and last vertices. - - #[lua(kind = "MutatingMethod")] - fn reverse(&mut self) -> (); - -"#, - r#" -/// This triangle but reversed. - - #[lua(kind = "Method", output(proxy))] - fn reversed(self) -> bevy::math::primitives::Triangle3d; - -"#, - r#" -/// Get the centroid of the triangle. -/// This function finds the geometric center of the triangle by averaging the vertices: -/// `centroid = (a + b + c) / 3`. - - #[lua(kind = "Method", output(proxy))] - fn centroid(&self) -> bevy::math::prelude::Vec3; - -"#, - r#" -/// Get the circumcenter of the triangle. - - #[lua(kind = "Method", output(proxy))] - fn circumcenter(&self) -> bevy::math::prelude::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim3::Triangle3d) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Triangle3d; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Triangle3d { - vertices: ReflectedValue, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::bounding::RayCast2d", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::bounding::RayCast2d; - -"#, - r#" -/// Construct a [`RayCast2d`] from an origin, [`Dir2`], and max distance. - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - origin: bevy::math::prelude::Vec2, - #[proxy] - direction: bevy::math::prelude::Dir2, - max: f32, - ) -> bevy::math::bounding::RayCast2d; - -"#, - r#" -/// Construct a [`RayCast2d`] from a [`Ray2d`] and max distance. - - #[lua(kind = "Function", output(proxy))] - fn from_ray( - #[proxy] - ray: bevy::math::Ray2d, - max: f32, - ) -> bevy::math::bounding::RayCast2d; - -"#, - r#" -/// Get the cached multiplicative inverse of the direction of the ray. - - #[lua(kind = "Method", output(proxy))] - fn direction_recip(&self) -> bevy::math::prelude::Vec2; - -"#, - r#" -/// Get the distance of an intersection with an [`Aabb2d`], if any. - - #[lua(kind = "Method")] - fn aabb_intersection_at( - &self, - #[proxy] - aabb: &bounding::bounded2d::Aabb2d, - ) -> std::option::Option; - -"#, - r#" -/// Get the distance of an intersection with a [`BoundingCircle`], if any. - - #[lua(kind = "Method")] - fn circle_intersection_at( - &self, - #[proxy] - circle: &bounding::bounded2d::BoundingCircle, - ) -> std::option::Option; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct RayCast2d { - #[lua(output(proxy))] - ray: bevy::math::Ray2d, - max: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::bounding::AabbCast2d", - functions[r#" -/// Construct an [`AabbCast2d`] from an [`Aabb2d`], origin, [`Dir2`], and max distance. - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - aabb: bevy::math::bounding::Aabb2d, - #[proxy] - origin: bevy::math::prelude::Vec2, - #[proxy] - direction: bevy::math::prelude::Dir2, - max: f32, - ) -> bevy::math::bounding::AabbCast2d; - -"#, - r#" -/// Construct an [`AabbCast2d`] from an [`Aabb2d`], [`Ray2d`], and max distance. - - #[lua(kind = "Function", output(proxy))] - fn from_ray( - #[proxy] - aabb: bevy::math::bounding::Aabb2d, - #[proxy] - ray: bevy::math::Ray2d, - max: f32, - ) -> bevy::math::bounding::AabbCast2d; - -"#, - r#" -/// Get the distance at which the [`Aabb2d`]s collide, if at all. - - #[lua(kind = "Method")] - fn aabb_collision_at( - &self, - #[proxy] - aabb: bevy::math::bounding::Aabb2d, - ) -> std::option::Option; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::bounding::AabbCast2d; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct AabbCast2d { - #[lua(output(proxy))] - ray: bevy::math::bounding::RayCast2d, - #[lua(output(proxy))] - aabb: bevy::math::bounding::Aabb2d, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::bounding::BoundingCircleCast", - functions[r#" -/// Construct a [`BoundingCircleCast`] from a [`BoundingCircle`], origin, [`Dir2`], and max distance. - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - circle: bevy::math::bounding::BoundingCircle, - #[proxy] - origin: bevy::math::prelude::Vec2, - #[proxy] - direction: bevy::math::prelude::Dir2, - max: f32, - ) -> bevy::math::bounding::BoundingCircleCast; - -"#, - r#" -/// Construct a [`BoundingCircleCast`] from a [`BoundingCircle`], [`Ray2d`], and max distance. - - #[lua(kind = "Function", output(proxy))] - fn from_ray( - #[proxy] - circle: bevy::math::bounding::BoundingCircle, - #[proxy] - ray: bevy::math::Ray2d, - max: f32, - ) -> bevy::math::bounding::BoundingCircleCast; - -"#, - r#" -/// Get the distance at which the [`BoundingCircle`]s collide, if at all. - - #[lua(kind = "Method")] - fn circle_collision_at( - &self, - #[proxy] - circle: bevy::math::bounding::BoundingCircle, - ) -> std::option::Option; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::bounding::BoundingCircleCast; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct BoundingCircleCast { - #[lua(output(proxy))] - ray: bevy::math::bounding::RayCast2d, - #[lua(output(proxy))] - circle: bevy::math::bounding::BoundingCircle, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::bounding::RayCast3d", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::bounding::RayCast3d; - -"#, - r#" -/// Construct a [`RayCast3d`] from a [`Ray3d`] and max distance. - - #[lua(kind = "Function", output(proxy))] - fn from_ray( - #[proxy] - ray: bevy::math::Ray3d, - max: f32, - ) -> bevy::math::bounding::RayCast3d; - -"#, - r#" -/// Get the cached multiplicative inverse of the direction of the ray. - - #[lua(kind = "Method", output(proxy))] - fn direction_recip(&self) -> bevy::math::Vec3A; - -"#, - r#" -/// Get the distance of an intersection with an [`Aabb3d`], if any. - - #[lua(kind = "Method")] - fn aabb_intersection_at( - &self, - #[proxy] - aabb: &bounding::bounded3d::Aabb3d, - ) -> std::option::Option; - -"#, - r#" -/// Get the distance of an intersection with a [`BoundingSphere`], if any. - - #[lua(kind = "Method")] - fn sphere_intersection_at( - &self, - #[proxy] - sphere: &bounding::bounded3d::BoundingSphere, - ) -> std::option::Option; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct RayCast3d { - #[lua(output(proxy))] - origin: bevy::math::Vec3A, - #[lua(output(proxy))] - direction: bevy::math::prelude::Dir3A, - max: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::bounding::AabbCast3d", - functions[r#" -/// Construct an [`AabbCast3d`] from an [`Aabb3d`], [`Ray3d`], and max distance. - - #[lua(kind = "Function", output(proxy))] - fn from_ray( - #[proxy] - aabb: bevy::math::bounding::Aabb3d, - #[proxy] - ray: bevy::math::Ray3d, - max: f32, - ) -> bevy::math::bounding::AabbCast3d; - -"#, - r#" -/// Get the distance at which the [`Aabb3d`]s collide, if at all. - - #[lua(kind = "Method")] - fn aabb_collision_at( - &self, - #[proxy] - aabb: bevy::math::bounding::Aabb3d, - ) -> std::option::Option; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::bounding::AabbCast3d; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct AabbCast3d { - #[lua(output(proxy))] - ray: bevy::math::bounding::RayCast3d, - #[lua(output(proxy))] - aabb: bevy::math::bounding::Aabb3d, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::bounding::BoundingSphereCast", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::bounding::BoundingSphereCast; - -"#, - r#" -/// Construct a [`BoundingSphereCast`] from a [`BoundingSphere`], [`Ray3d`], and max distance. - - #[lua(kind = "Function", output(proxy))] - fn from_ray( - #[proxy] - sphere: bevy::math::bounding::BoundingSphere, - #[proxy] - ray: bevy::math::Ray3d, - max: f32, - ) -> bevy::math::bounding::BoundingSphereCast; - -"#, - r#" -/// Get the distance at which the [`BoundingSphere`]s collide, if at all. - - #[lua(kind = "Method")] - fn sphere_collision_at( - &self, - #[proxy] - sphere: bevy::math::bounding::BoundingSphere, - ) -> std::option::Option; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct BoundingSphereCast { - #[lua(output(proxy))] - ray: bevy::math::bounding::RayCast3d, - #[lua(output(proxy))] - sphere: bevy::math::bounding::BoundingSphere, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::curve::interval::Interval", - functions[r#" -/// Get the start of this interval. - - #[lua(kind = "Method")] - fn start(self) -> f32; - -"#, - r#" -/// Get the end of this interval. - - #[lua(kind = "Method")] - fn end(self) -> f32; - -"#, - r#" -/// Get the length of this interval. Note that the result may be infinite (`f32::INFINITY`). - - #[lua(kind = "Method")] - fn length(self) -> f32; - -"#, - r#" -/// Returns `true` if this interval is bounded — that is, if both its start and end are finite. -/// Equivalently, an interval is bounded if its length is finite. - - #[lua(kind = "Method")] - fn is_bounded(self) -> bool; - -"#, - r#" -/// Returns `true` if this interval has a finite start. - - #[lua(kind = "Method")] - fn has_finite_start(self) -> bool; - -"#, - r#" -/// Returns `true` if this interval has a finite end. - - #[lua(kind = "Method")] - fn has_finite_end(self) -> bool; - -"#, - r#" -/// Returns `true` if `item` is contained in this interval. - - #[lua(kind = "Method")] - fn contains(self, item: f32) -> bool; - -"#, - r#" -/// Returns `true` if the other interval is contained in this interval. -/// This is non-strict: each interval will contain itself. - - #[lua(kind = "Method")] - fn contains_interval( - self, - #[proxy] - other: bevy::math::curve::interval::Interval, - ) -> bool; - -"#, - r#" -/// Clamp the given `value` to lie within this interval. - - #[lua(kind = "Method")] - fn clamp(self, value: f32) -> f32; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::curve::interval::Interval; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &curve::interval::Interval) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Interval {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::FloatOrd", - functions[r#" - - #[lua(as_trait = "std::cmp::PartialOrd", kind = "Method")] - fn lt(&self, #[proxy] other: &float_ord::FloatOrd) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::cmp::PartialOrd", kind = "Method")] - fn le(&self, #[proxy] other: &float_ord::FloatOrd) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::cmp::PartialOrd", kind = "Method")] - fn gt(&self, #[proxy] other: &float_ord::FloatOrd) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::cmp::PartialOrd", kind = "Method")] - fn ge(&self, #[proxy] other: &float_ord::FloatOrd) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::FloatOrd; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &float_ord::FloatOrd) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::FloatOrd; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct FloatOrd(f32); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Plane3d", - functions[r#" -/// Create a new `Plane3d` from a normal and a half size -/// # Panics -/// Panics if the given `normal` is zero (or very close to zero), or non-finite. - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - normal: bevy::math::prelude::Vec3, - #[proxy] - half_size: bevy::math::prelude::Vec2, - ) -> bevy::math::primitives::Plane3d; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Plane3d; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim3::Plane3d) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Plane3d { - #[lua(output(proxy))] - normal: bevy::math::prelude::Dir3, - #[lua(output(proxy))] - half_size: bevy::math::prelude::Vec2, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::primitives::Tetrahedron", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::primitives::Tetrahedron; - -"#, - r#" -/// Create a new [`Tetrahedron`] from points `a`, `b`, `c` and `d`. - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - a: bevy::math::prelude::Vec3, - #[proxy] - b: bevy::math::prelude::Vec3, - #[proxy] - c: bevy::math::prelude::Vec3, - #[proxy] - d: bevy::math::prelude::Vec3, - ) -> bevy::math::primitives::Tetrahedron; - -"#, - r#" -/// Get the signed volume of the tetrahedron. -/// If it's negative, the normal vector of the face defined by -/// the first three points using the right-hand rule points -/// away from the fourth vertex. - - #[lua(kind = "Method")] - fn signed_volume(&self) -> f32; - -"#, - r#" -/// Get the centroid of the tetrahedron. -/// This function finds the geometric center of the tetrahedron -/// by averaging the vertices: `centroid = (a + b + c + d) / 4`. - - #[lua(kind = "Method", output(proxy))] - fn centroid(&self) -> bevy::math::prelude::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &primitives::dim3::Tetrahedron) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Tetrahedron { - vertices: ReflectedValue, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::curve::easing::EaseFunction", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::math::curve::easing::EaseFunction; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &curve::easing::EaseFunction) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct EaseFunction {} -#[derive(Default)] -pub(crate) struct Globals; -impl bevy_mod_scripting_lua::tealr::mlu::ExportInstances for Globals { - fn add_instances< - 'lua, - T: bevy_mod_scripting_lua::tealr::mlu::InstanceCollector<'lua>, - >(self, instances: &mut T) -> bevy_mod_scripting_lua::tealr::mlu::mlua::Result<()> { - instances - .add_instance( - "Isometry2d", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Isometry3d", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Ray2d", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Ray3d", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Rot2", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Dir2", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Dir3", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Dir3A", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "IRect", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Rect", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "URect", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Aabb2d", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "BoundingCircle", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::< - LuaBoundingCircle, - >::new, - )?; - instances - .add_instance( - "Circle", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Annulus", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Arc2d", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Capsule2d", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "CircularSector", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::< - LuaCircularSector, - >::new, - )?; - instances - .add_instance( - "CircularSegment", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::< - LuaCircularSegment, - >::new, - )?; - instances - .add_instance( - "Ellipse", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Plane2d", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Rectangle", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "RegularPolygon", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::< - LuaRegularPolygon, - >::new, - )?; - instances - .add_instance( - "Rhombus", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Segment2d", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Triangle2d", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Sphere", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Cuboid", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Cylinder", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Capsule3d", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Cone", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Segment3d", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Torus", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Triangle3d", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "RayCast2d", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "AabbCast2d", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "BoundingCircleCast", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::< - LuaBoundingCircleCast, - >::new, - )?; - instances - .add_instance( - "RayCast3d", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "AabbCast3d", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "BoundingSphereCast", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::< - LuaBoundingSphereCast, - >::new, - )?; - instances - .add_instance( - "Plane3d", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Tetrahedron", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - Ok(()) - } -} -pub struct BevyMathAPIProvider; -impl bevy_mod_scripting_core::hosts::APIProvider for BevyMathAPIProvider { - type APITarget = std::sync::Mutex; - type ScriptContext = std::sync::Mutex; - type DocTarget = bevy_mod_scripting_lua::docs::LuaDocFragment; - fn attach_api( - &mut self, - ctx: &mut Self::APITarget, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - let ctx = ctx.get_mut().expect("Unable to acquire lock on Lua context"); - bevy_mod_scripting_lua::tealr::mlu::set_global_env(Globals, ctx) - .map_err(|e| bevy_mod_scripting_core::error::ScriptError::Other( - e.to_string(), - )) - } - fn get_doc_fragment(&self) -> Option { - Some( - bevy_mod_scripting_lua::docs::LuaDocFragment::new( - "BevyMathAPI", - |tw| { - tw.document_global_instance::() - .expect("Something went wrong documenting globals") - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaIsometry2d, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaIsometry3d, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaBoundingCircle, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaCapsule2d, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaCircularSector, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaCircularSegment, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaRectangle, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaRegularPolygon, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaSegment2d, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaTriangle2d, - >, - >() - .process_type::() - .process_type::() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaCylinder, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaCapsule3d, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::() - .process_type::() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaSegment3d, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaTriangle3d, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaRayCast2d, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaAabbCast2d, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaBoundingCircleCast, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaRayCast3d, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaAabbCast3d, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaBoundingSphereCast, - >, - >() - .process_type::() - .process_type::() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaTetrahedron, - >, - >() - .process_type::() - }, - ), - ) - } - fn setup_script( - &mut self, - script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - fn setup_script_runtime( - &mut self, - world_ptr: bevy_mod_scripting_core::world::WorldPointer, - _script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - fn register_with_app(&self, app: &mut bevy::app::App) { - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - } -} diff --git a/crates/bevy_script_api/src/providers/bevy_reflect.rs b/crates/bevy_script_api/src/providers/bevy_reflect.rs deleted file mode 100644 index 45daa85d..00000000 --- a/crates/bevy_script_api/src/providers/bevy_reflect.rs +++ /dev/null @@ -1,22578 +0,0 @@ -// @generated by cargo bevy-api-gen generate, modify the templates not this file -#![allow(clippy::all)] -#![allow(unused, deprecated, dead_code)] -#![cfg_attr(rustfmt, rustfmt_skip)] -extern crate self as bevy_script_api; -use bevy_script_api::{ - lua::RegisterForeignLuaType, ReflectedValue, common::bevy::GetWorld, -}; -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(), - remote = "std::sync::atomic::AtomicBool", - functions[r#" -/// Creates a new `AtomicBool`. -/// # Examples -/// ``` -/// use std::sync::atomic::AtomicBool; -/// let atomic_true = AtomicBool::new(true); -/// let atomic_false = AtomicBool::new(false); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn new(v: bool) -> std::sync::atomic::AtomicBool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct AtomicBool {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(), - remote = "std::sync::atomic::AtomicI16", - functions[r#" -/// Creates a new atomic integer. -/// # Examples -/// ``` -///use std::sync::atomic::AtomicI16; -///let atomic_forty_two = AtomicI16::new(42); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn new(v: i16) -> std::sync::atomic::AtomicI16; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct AtomicI16 {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(), - remote = "std::sync::atomic::AtomicI32", - functions[r#" -/// Creates a new atomic integer. -/// # Examples -/// ``` -///use std::sync::atomic::AtomicI32; -///let atomic_forty_two = AtomicI32::new(42); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn new(v: i32) -> std::sync::atomic::AtomicI32; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct AtomicI32 {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(), - remote = "std::sync::atomic::AtomicI64", - functions[r#" -/// Creates a new atomic integer. -/// # Examples -/// ``` -///use std::sync::atomic::AtomicI64; -///let atomic_forty_two = AtomicI64::new(42); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn new(v: i64) -> std::sync::atomic::AtomicI64; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct AtomicI64 {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(), - remote = "std::sync::atomic::AtomicI8", - functions[r#" -/// Creates a new atomic integer. -/// # Examples -/// ``` -///use std::sync::atomic::AtomicI8; -///let atomic_forty_two = AtomicI8::new(42); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn new(v: i8) -> std::sync::atomic::AtomicI8; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct AtomicI8 {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(), - remote = "std::sync::atomic::AtomicIsize", - functions[r#" -/// Creates a new atomic integer. -/// # Examples -/// ``` -///use std::sync::atomic::AtomicIsize; -///let atomic_forty_two = AtomicIsize::new(42); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn new(v: isize) -> std::sync::atomic::AtomicIsize; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct AtomicIsize {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(), - remote = "std::sync::atomic::AtomicU16", - functions[r#" -/// Creates a new atomic integer. -/// # Examples -/// ``` -///use std::sync::atomic::AtomicU16; -///let atomic_forty_two = AtomicU16::new(42); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn new(v: u16) -> std::sync::atomic::AtomicU16; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct AtomicU16 {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(), - remote = "std::sync::atomic::AtomicU32", - functions[r#" -/// Creates a new atomic integer. -/// # Examples -/// ``` -///use std::sync::atomic::AtomicU32; -///let atomic_forty_two = AtomicU32::new(42); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn new(v: u32) -> std::sync::atomic::AtomicU32; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct AtomicU32 {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(), - remote = "std::sync::atomic::AtomicU64", - functions[r#" -/// Creates a new atomic integer. -/// # Examples -/// ``` -///use std::sync::atomic::AtomicU64; -///let atomic_forty_two = AtomicU64::new(42); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn new(v: u64) -> std::sync::atomic::AtomicU64; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct AtomicU64 {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(), - remote = "std::sync::atomic::AtomicU8", - functions[r#" -/// Creates a new atomic integer. -/// # Examples -/// ``` -///use std::sync::atomic::AtomicU8; -///let atomic_forty_two = AtomicU8::new(42); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn new(v: u8) -> std::sync::atomic::AtomicU8; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct AtomicU8 {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(), - remote = "std::sync::atomic::AtomicUsize", - functions[r#" -/// Creates a new atomic integer. -/// # Examples -/// ``` -///use std::sync::atomic::AtomicUsize; -///let atomic_forty_two = AtomicUsize::new(42); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn new(v: usize) -> std::sync::atomic::AtomicUsize; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct AtomicUsize {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::utils::Duration", - functions[r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: u32) -> bevy::utils::Duration; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::utils::Duration; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::utils::Duration) -> bevy::utils::Duration; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &bevy_utils::Duration) -> bool; - -"#, - r#" -/// Creates a new `Duration` from the specified number of whole seconds and -/// additional nanoseconds. -/// If the number of nanoseconds is greater than 1 billion (the number of -/// nanoseconds in a second), then it will carry over into the seconds provided. -/// # Panics -/// This constructor will panic if the carry from the nanoseconds overflows -/// the seconds counter. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let five_seconds = Duration::new(5, 0); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn new(secs: u64, nanos: u32) -> bevy::utils::Duration; - -"#, - r#" -/// Creates a new `Duration` from the specified number of whole seconds. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let duration = Duration::from_secs(5); -/// assert_eq!(5, duration.as_secs()); -/// assert_eq!(0, duration.subsec_nanos()); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_secs(secs: u64) -> bevy::utils::Duration; - -"#, - r#" -/// Creates a new `Duration` from the specified number of milliseconds. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let duration = Duration::from_millis(2_569); -/// assert_eq!(2, duration.as_secs()); -/// assert_eq!(569_000_000, duration.subsec_nanos()); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_millis(millis: u64) -> bevy::utils::Duration; - -"#, - r#" -/// Creates a new `Duration` from the specified number of microseconds. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let duration = Duration::from_micros(1_000_002); -/// assert_eq!(1, duration.as_secs()); -/// assert_eq!(2_000, duration.subsec_nanos()); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_micros(micros: u64) -> bevy::utils::Duration; - -"#, - r#" -/// Creates a new `Duration` from the specified number of nanoseconds. -/// Note: Using this on the return value of `as_nanos()` might cause unexpected behavior: -/// `as_nanos()` returns a u128, and can return values that do not fit in u64, e.g. 585 years. -/// Instead, consider using the pattern `Duration::new(d.as_secs(), d.subsec_nanos())` -/// if you cannot copy/clone the Duration directly. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let duration = Duration::from_nanos(1_000_000_123); -/// assert_eq!(1, duration.as_secs()); -/// assert_eq!(123, duration.subsec_nanos()); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_nanos(nanos: u64) -> bevy::utils::Duration; - -"#, - r#" -/// Returns true if this `Duration` spans no time. -/// # Examples -/// ``` -/// use std::time::Duration; -/// assert!(Duration::ZERO.is_zero()); -/// assert!(Duration::new(0, 0).is_zero()); -/// assert!(Duration::from_nanos(0).is_zero()); -/// assert!(Duration::from_secs(0).is_zero()); -/// assert!(!Duration::new(1, 1).is_zero()); -/// assert!(!Duration::from_nanos(1).is_zero()); -/// assert!(!Duration::from_secs(1).is_zero()); -/// ``` - - #[lua(kind = "Method")] - fn is_zero(&self) -> bool; - -"#, - r#" -/// Returns the number of _whole_ seconds contained by this `Duration`. -/// The returned value does not include the fractional (nanosecond) part of the -/// duration, which can be obtained using [`subsec_nanos`]. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let duration = Duration::new(5, 730_023_852); -/// assert_eq!(duration.as_secs(), 5); -/// ``` -/// To determine the total number of seconds represented by the `Duration` -/// including the fractional part, use [`as_secs_f64`] or [`as_secs_f32`] -/// [`as_secs_f64`]: Duration::as_secs_f64 -/// [`as_secs_f32`]: Duration::as_secs_f32 -/// [`subsec_nanos`]: Duration::subsec_nanos - - #[lua(kind = "Method")] - fn as_secs(&self) -> u64; - -"#, - r#" -/// Returns the fractional part of this `Duration`, in whole milliseconds. -/// This method does **not** return the length of the duration when -/// represented by milliseconds. The returned number always represents a -/// fractional portion of a second (i.e., it is less than one thousand). -/// # Examples -/// ``` -/// use std::time::Duration; -/// let duration = Duration::from_millis(5_432); -/// assert_eq!(duration.as_secs(), 5); -/// assert_eq!(duration.subsec_millis(), 432); -/// ``` - - #[lua(kind = "Method")] - fn subsec_millis(&self) -> u32; - -"#, - r#" -/// Returns the fractional part of this `Duration`, in whole microseconds. -/// This method does **not** return the length of the duration when -/// represented by microseconds. The returned number always represents a -/// fractional portion of a second (i.e., it is less than one million). -/// # Examples -/// ``` -/// use std::time::Duration; -/// let duration = Duration::from_micros(1_234_567); -/// assert_eq!(duration.as_secs(), 1); -/// assert_eq!(duration.subsec_micros(), 234_567); -/// ``` - - #[lua(kind = "Method")] - fn subsec_micros(&self) -> u32; - -"#, - r#" -/// Returns the fractional part of this `Duration`, in nanoseconds. -/// This method does **not** return the length of the duration when -/// represented by nanoseconds. The returned number always represents a -/// fractional portion of a second (i.e., it is less than one billion). -/// # Examples -/// ``` -/// use std::time::Duration; -/// let duration = Duration::from_millis(5_010); -/// assert_eq!(duration.as_secs(), 5); -/// assert_eq!(duration.subsec_nanos(), 10_000_000); -/// ``` - - #[lua(kind = "Method")] - fn subsec_nanos(&self) -> u32; - -"#, - r#" -/// Returns the total number of whole milliseconds contained by this `Duration`. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let duration = Duration::new(5, 730_023_852); -/// assert_eq!(duration.as_millis(), 5_730); -/// ``` - - #[lua(kind = "Method")] - fn as_millis(&self) -> u128; - -"#, - r#" -/// Returns the total number of whole microseconds contained by this `Duration`. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let duration = Duration::new(5, 730_023_852); -/// assert_eq!(duration.as_micros(), 5_730_023); -/// ``` - - #[lua(kind = "Method")] - fn as_micros(&self) -> u128; - -"#, - r#" -/// Returns the total number of nanoseconds contained by this `Duration`. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let duration = Duration::new(5, 730_023_852); -/// assert_eq!(duration.as_nanos(), 5_730_023_852); -/// ``` - - #[lua(kind = "Method")] - fn as_nanos(&self) -> u128; - -"#, - r#" -/// Computes the absolute difference between `self` and `other`. -/// # Examples -/// ``` -/// use std::time::Duration; -/// assert_eq!(Duration::new(100, 0).abs_diff(Duration::new(80, 0)), Duration::new(20, 0)); -/// assert_eq!(Duration::new(100, 400_000_000).abs_diff(Duration::new(110, 0)), Duration::new(9, 600_000_000)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn abs_diff(self, #[proxy] other: bevy::utils::Duration) -> bevy::utils::Duration; - -"#, - r#" -/// Saturating `Duration` addition. Computes `self + other`, returning [`Duration::MAX`] -/// if overflow occurred. -/// # Examples -/// ``` -/// #![feature(duration_constants)] -/// use std::time::Duration; -/// assert_eq!(Duration::new(0, 0).saturating_add(Duration::new(0, 1)), Duration::new(0, 1)); -/// assert_eq!(Duration::new(1, 0).saturating_add(Duration::new(u64::MAX, 0)), Duration::MAX); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn saturating_add( - self, - #[proxy] - rhs: bevy::utils::Duration, - ) -> bevy::utils::Duration; - -"#, - r#" -/// Saturating `Duration` subtraction. Computes `self - other`, returning [`Duration::ZERO`] -/// if the result would be negative or if overflow occurred. -/// # Examples -/// ``` -/// use std::time::Duration; -/// assert_eq!(Duration::new(0, 1).saturating_sub(Duration::new(0, 0)), Duration::new(0, 1)); -/// assert_eq!(Duration::new(0, 0).saturating_sub(Duration::new(0, 1)), Duration::ZERO); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub( - self, - #[proxy] - rhs: bevy::utils::Duration, - ) -> bevy::utils::Duration; - -"#, - r#" -/// Saturating `Duration` multiplication. Computes `self * other`, returning -/// [`Duration::MAX`] if overflow occurred. -/// # Examples -/// ``` -/// #![feature(duration_constants)] -/// use std::time::Duration; -/// assert_eq!(Duration::new(0, 500_000_001).saturating_mul(2), Duration::new(1, 2)); -/// assert_eq!(Duration::new(u64::MAX - 1, 0).saturating_mul(2), Duration::MAX); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn saturating_mul(self, rhs: u32) -> bevy::utils::Duration; - -"#, - r#" -/// Returns the number of seconds contained by this `Duration` as `f64`. -/// The returned value includes the fractional (nanosecond) part of the duration. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let dur = Duration::new(2, 700_000_000); -/// assert_eq!(dur.as_secs_f64(), 2.7); -/// ``` - - #[lua(kind = "Method")] - fn as_secs_f64(&self) -> f64; - -"#, - r#" -/// Returns the number of seconds contained by this `Duration` as `f32`. -/// The returned value includes the fractional (nanosecond) part of the duration. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let dur = Duration::new(2, 700_000_000); -/// assert_eq!(dur.as_secs_f32(), 2.7); -/// ``` - - #[lua(kind = "Method")] - fn as_secs_f32(&self) -> f32; - -"#, - r#" -/// Creates a new `Duration` from the specified number of seconds represented -/// as `f64`. -/// # Panics -/// This constructor will panic if `secs` is negative, overflows `Duration` or not finite. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let res = Duration::from_secs_f64(0.0); -/// assert_eq!(res, Duration::new(0, 0)); -/// let res = Duration::from_secs_f64(1e-20); -/// assert_eq!(res, Duration::new(0, 0)); -/// let res = Duration::from_secs_f64(4.2e-7); -/// assert_eq!(res, Duration::new(0, 420)); -/// let res = Duration::from_secs_f64(2.7); -/// assert_eq!(res, Duration::new(2, 700_000_000)); -/// let res = Duration::from_secs_f64(3e10); -/// assert_eq!(res, Duration::new(30_000_000_000, 0)); -/// // subnormal float -/// let res = Duration::from_secs_f64(f64::from_bits(1)); -/// assert_eq!(res, Duration::new(0, 0)); -/// // conversion uses rounding -/// let res = Duration::from_secs_f64(0.999e-9); -/// assert_eq!(res, Duration::new(0, 1)); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_secs_f64(secs: f64) -> bevy::utils::Duration; - -"#, - r#" -/// Creates a new `Duration` from the specified number of seconds represented -/// as `f32`. -/// # Panics -/// This constructor will panic if `secs` is negative, overflows `Duration` or not finite. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let res = Duration::from_secs_f32(0.0); -/// assert_eq!(res, Duration::new(0, 0)); -/// let res = Duration::from_secs_f32(1e-20); -/// assert_eq!(res, Duration::new(0, 0)); -/// let res = Duration::from_secs_f32(4.2e-7); -/// assert_eq!(res, Duration::new(0, 420)); -/// let res = Duration::from_secs_f32(2.7); -/// assert_eq!(res, Duration::new(2, 700_000_048)); -/// let res = Duration::from_secs_f32(3e10); -/// assert_eq!(res, Duration::new(30_000_001_024, 0)); -/// // subnormal float -/// let res = Duration::from_secs_f32(f32::from_bits(1)); -/// assert_eq!(res, Duration::new(0, 0)); -/// // conversion uses rounding -/// let res = Duration::from_secs_f32(0.999e-9); -/// assert_eq!(res, Duration::new(0, 1)); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_secs_f32(secs: f32) -> bevy::utils::Duration; - -"#, - r#" -/// Multiplies `Duration` by `f64`. -/// # Panics -/// This method will panic if result is negative, overflows `Duration` or not finite. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let dur = Duration::new(2, 700_000_000); -/// assert_eq!(dur.mul_f64(3.14), Duration::new(8, 478_000_000)); -/// assert_eq!(dur.mul_f64(3.14e5), Duration::new(847_800, 0)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn mul_f64(self, rhs: f64) -> bevy::utils::Duration; - -"#, - r#" -/// Multiplies `Duration` by `f32`. -/// # Panics -/// This method will panic if result is negative, overflows `Duration` or not finite. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let dur = Duration::new(2, 700_000_000); -/// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_641)); -/// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847_800, 0)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn mul_f32(self, rhs: f32) -> bevy::utils::Duration; - -"#, - r#" -/// Divides `Duration` by `f64`. -/// # Panics -/// This method will panic if result is negative, overflows `Duration` or not finite. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let dur = Duration::new(2, 700_000_000); -/// assert_eq!(dur.div_f64(3.14), Duration::new(0, 859_872_611)); -/// assert_eq!(dur.div_f64(3.14e5), Duration::new(0, 8_599)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn div_f64(self, rhs: f64) -> bevy::utils::Duration; - -"#, - r#" -/// Divides `Duration` by `f32`. -/// # Panics -/// This method will panic if result is negative, overflows `Duration` or not finite. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let dur = Duration::new(2, 700_000_000); -/// // note that due to rounding errors result is slightly -/// // different from 0.859_872_611 -/// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_580)); -/// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_599)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn div_f32(self, rhs: f32) -> bevy::utils::Duration; - -"#, - r#" -/// Divides `Duration` by `Duration` and returns `f64`. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let dur1 = Duration::new(2, 700_000_000); -/// let dur2 = Duration::new(5, 400_000_000); -/// assert_eq!(dur1.div_duration_f64(dur2), 0.5); -/// ``` - - #[lua(kind = "Method")] - fn div_duration_f64(self, #[proxy] rhs: bevy::utils::Duration) -> f64; - -"#, - r#" -/// Divides `Duration` by `Duration` and returns `f32`. -/// # Examples -/// ``` -/// use std::time::Duration; -/// let dur1 = Duration::new(2, 700_000_000); -/// let dur2 = Duration::new(5, 400_000_000); -/// assert_eq!(dur1.div_duration_f32(dur2), 0.5); -/// ``` - - #[lua(kind = "Method")] - fn div_duration_f32(self, #[proxy] rhs: bevy::utils::Duration) -> f32; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::utils::Duration) -> bevy::utils::Duration; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: u32) -> bevy::utils::Duration; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Duration {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::utils::Instant", - functions[r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &bevy_utils::Instant) -> bool; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::utils::Instant; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] other: bevy::utils::Duration) -> bevy::utils::Instant; - -"#, - r#" -/// Returns the amount of time elapsed from another instant to this one, -/// or zero duration if that instant is later than this one. -/// # Panics -/// Previous Rust versions panicked when `other` was later than `self`. Currently this -/// method saturates. Future versions may reintroduce the panic in some circumstances. -/// See [Monotonicity]. -/// [Monotonicity]: Instant#monotonicity - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] other: bevy::utils::Instant) -> bevy::utils::Duration; - -"#, - r#" -/// Returns an instant corresponding to "now". -/// # Examples -/// ``` -/// use std::time::Instant; -/// let now = Instant::now(); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn now() -> bevy::utils::Instant; - -"#, - r#" -/// Returns the amount of time elapsed from another instant to this one, -/// or zero duration if that instant is later than this one. -/// # Panics -/// Previous Rust versions panicked when `earlier` was later than `self`. Currently this -/// method saturates. Future versions may reintroduce the panic in some circumstances. -/// See [Monotonicity]. -/// [Monotonicity]: Instant#monotonicity -/// # Examples -/// ```no_run -/// use std::time::{Duration, Instant}; -/// use std::thread::sleep; -/// let now = Instant::now(); -/// sleep(Duration::new(1, 0)); -/// let new_now = Instant::now(); -/// println!("{:?}", new_now.duration_since(now)); -/// println!("{:?}", now.duration_since(new_now)); // 0ns -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn duration_since( - &self, - #[proxy] - earlier: bevy::utils::Instant, - ) -> bevy::utils::Duration; - -"#, - r#" -/// Returns the amount of time elapsed from another instant to this one, -/// or zero duration if that instant is later than this one. -/// # Examples -/// ```no_run -/// use std::time::{Duration, Instant}; -/// use std::thread::sleep; -/// let now = Instant::now(); -/// sleep(Duration::new(1, 0)); -/// let new_now = Instant::now(); -/// println!("{:?}", new_now.saturating_duration_since(now)); -/// println!("{:?}", now.saturating_duration_since(new_now)); // 0ns -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn saturating_duration_since( - &self, - #[proxy] - earlier: bevy::utils::Instant, - ) -> bevy::utils::Duration; - -"#, - r#" -/// Returns the amount of time elapsed since this instant. -/// # Panics -/// Previous Rust versions panicked when the current time was earlier than self. Currently this -/// method returns a Duration of zero in that case. Future versions may reintroduce the panic. -/// See [Monotonicity]. -/// [Monotonicity]: Instant#monotonicity -/// # Examples -/// ```no_run -/// use std::thread::sleep; -/// use std::time::{Duration, Instant}; -/// let instant = Instant::now(); -/// let three_secs = Duration::from_secs(3); -/// sleep(three_secs); -/// assert!(instant.elapsed() >= three_secs); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn elapsed(&self) -> bevy::utils::Duration; - -"#, - r#" -/// # Panics -/// This function may panic if the resulting point in time cannot be represented by the -/// underlying data structure. See [`Instant::checked_add`] for a version without panic. - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] other: bevy::utils::Duration) -> bevy::utils::Instant; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Instant(); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "std::path::PathBuf", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &std::path::PathBuf) -> bool; - -"#, - r#" -/// Allocates an empty `PathBuf`. -/// # Examples -/// ``` -/// use std::path::PathBuf; -/// let path = PathBuf::new(); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn new() -> std::path::PathBuf; - -"#, - r#" -/// Creates a new `PathBuf` with a given capacity used to create the -/// internal [`OsString`]. See [`with_capacity`] defined on [`OsString`]. -/// # Examples -/// ``` -/// use std::path::PathBuf; -/// let mut path = PathBuf::with_capacity(10); -/// let capacity = path.capacity(); -/// // This push is done without reallocating -/// path.push(r"C:\"); -/// assert_eq!(capacity, path.capacity()); -/// ``` -/// [`with_capacity`]: OsString::with_capacity - - #[lua(kind = "Function", output(proxy))] - fn with_capacity(capacity: usize) -> std::path::PathBuf; - -"#, - r#" -/// Truncates `self` to [`self.parent`]. -/// Returns `false` and does nothing if [`self.parent`] is [`None`]. -/// Otherwise, returns `true`. -/// [`self.parent`]: Path::parent -/// # Examples -/// ``` -/// use std::path::{Path, PathBuf}; -/// let mut p = PathBuf::from("/spirited/away.rs"); -/// p.pop(); -/// assert_eq!(Path::new("/spirited"), p); -/// p.pop(); -/// assert_eq!(Path::new("/"), p); -/// ``` - - #[lua(kind = "MutatingMethod")] - fn pop(&mut self) -> bool; - -"#, - r#" -/// Invokes [`capacity`] on the underlying instance of [`OsString`]. -/// [`capacity`]: OsString::capacity - - #[lua(kind = "Method")] - fn capacity(&self) -> usize; - -"#, - r#" -/// Invokes [`clear`] on the underlying instance of [`OsString`]. -/// [`clear`]: OsString::clear - - #[lua(kind = "MutatingMethod")] - fn clear(&mut self) -> (); - -"#, - r#" -/// Invokes [`reserve`] on the underlying instance of [`OsString`]. -/// [`reserve`]: OsString::reserve - - #[lua(kind = "MutatingMethod")] - fn reserve(&mut self, additional: usize) -> (); - -"#, - r#" -/// Invokes [`reserve_exact`] on the underlying instance of [`OsString`]. -/// [`reserve_exact`]: OsString::reserve_exact - - #[lua(kind = "MutatingMethod")] - fn reserve_exact(&mut self, additional: usize) -> (); - -"#, - r#" -/// Invokes [`shrink_to_fit`] on the underlying instance of [`OsString`]. -/// [`shrink_to_fit`]: OsString::shrink_to_fit - - #[lua(kind = "MutatingMethod")] - fn shrink_to_fit(&mut self) -> (); - -"#, - r#" -/// Invokes [`shrink_to`] on the underlying instance of [`OsString`]. -/// [`shrink_to`]: OsString::shrink_to - - #[lua(kind = "MutatingMethod")] - fn shrink_to(&mut self, min_capacity: usize) -> (); - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> std::path::PathBuf; - -"#, - r#" -/// Clones the contents of `source` into `self`. -/// This method is preferred over simply assigning `source.clone()` to `self`, -/// as it avoids reallocation if possible. - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "MutatingMethod", - )] - fn clone_from(&mut self, #[proxy] source: &std::path::PathBuf) -> (); - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct PathBuf {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "std::ops::RangeFull", - functions[r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> std::ops::RangeFull; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &std::ops::RangeFull) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct RangeFull {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::Quat", - functions[r#" -/// Subtracts the `rhs` quaternion from `self`. -/// The difference is not guaranteed to be normalized. - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::Quat) -> bevy::math::Quat; - -"#, - r#" -/// Multiplies a quaternion by a scalar value. -/// The product is not guaranteed to be normalized. - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f32) -> bevy::math::Quat; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::Quat; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::Quat; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Multiplies a quaternion and a 3D vector, returning the rotated vector. -/// # Panics -/// Will panic if `self` is not normalized when `glam_assert` is enabled. - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Adds two quaternions. -/// The sum is not guaranteed to be normalized. -/// Note that addition is not the same as combining the rotations represented by the -/// two quaternions! That corresponds to multiplication. - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::Quat) -> bevy::math::Quat; - -"#, - r#" -/// Divides a quaternion by a scalar value. -/// The quotient is not guaranteed to be normalized. - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: f32) -> bevy::math::Quat; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] rhs: &glam::Quat) -> bool; - -"#, - r#" -/// Creates a new rotation quaternion. -/// This should generally not be called manually unless you know what you are doing. -/// Use one of the other constructors instead such as `identity` or `from_axis_angle`. -/// `from_xyzw` is mostly used by unit tests and `serde` deserialization. -/// # Preconditions -/// This function does not check if the input is normalized, it is up to the user to -/// provide normalized input or to normalized the resulting quaternion. - - #[lua(kind = "Function", output(proxy))] - fn from_xyzw(x: f32, y: f32, z: f32, w: f32) -> bevy::math::Quat; - -"#, - r#" -/// Creates a rotation quaternion from an array. -/// # Preconditions -/// This function does not check if the input is normalized, it is up to the user to -/// provide normalized input or to normalized the resulting quaternion. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [f32; 4]) -> bevy::math::Quat; - -"#, - r#" -/// Creates a new rotation quaternion from a 4D vector. -/// # Preconditions -/// This function does not check if the input is normalized, it is up to the user to -/// provide normalized input or to normalized the resulting quaternion. - - #[lua(kind = "Function", output(proxy))] - fn from_vec4(#[proxy] v: bevy::math::Vec4) -> bevy::math::Quat; - -"#, - r#" -/// Create a quaternion for a normalized rotation `axis` and `angle` (in radians). -/// The axis must be a unit vector. -/// # Panics -/// Will panic if `axis` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_axis_angle(#[proxy] axis: bevy::math::Vec3, angle: f32) -> bevy::math::Quat; - -"#, - r#" -/// Create a quaternion that rotates `v.length()` radians around `v.normalize()`. -/// `from_scaled_axis(Vec3::ZERO)` results in the identity quaternion. - - #[lua(kind = "Function", output(proxy))] - fn from_scaled_axis(#[proxy] v: bevy::math::Vec3) -> bevy::math::Quat; - -"#, - r#" -/// Creates a quaternion from the `angle` (in radians) around the x axis. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_x(angle: f32) -> bevy::math::Quat; - -"#, - r#" -/// Creates a quaternion from the `angle` (in radians) around the y axis. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_y(angle: f32) -> bevy::math::Quat; - -"#, - r#" -/// Creates a quaternion from the `angle` (in radians) around the z axis. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_z(angle: f32) -> bevy::math::Quat; - -"#, - r#" -/// Creates a quaternion from the given Euler rotation sequence and the angles (in radians). - - #[lua(kind = "Function", output(proxy))] - fn from_euler( - #[proxy] - euler: bevy::math::EulerRot, - a: f32, - b: f32, - c: f32, - ) -> bevy::math::Quat; - -"#, - r#" -/// Creates a quaternion from a 3x3 rotation matrix. -/// Note if the input matrix contain scales, shears, or other non-rotation transformations then -/// the resulting quaternion will be ill-defined. -/// # Panics -/// Will panic if any input matrix column is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_mat3(#[proxy] mat: &glam::Mat3) -> bevy::math::Quat; - -"#, - r#" -/// Creates a quaternion from a 3x3 SIMD aligned rotation matrix. -/// Note if the input matrix contain scales, shears, or other non-rotation transformations then -/// the resulting quaternion will be ill-defined. -/// # Panics -/// Will panic if any input matrix column is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_mat3a(#[proxy] mat: &glam::Mat3A) -> bevy::math::Quat; - -"#, - r#" -/// Creates a quaternion from the upper 3x3 rotation matrix inside a homogeneous 4x4 matrix. -/// Note if the upper 3x3 matrix contain scales, shears, or other non-rotation transformations -/// then the resulting quaternion will be ill-defined. -/// # Panics -/// Will panic if any column of the upper 3x3 rotation matrix is not normalized when -/// `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_mat4(#[proxy] mat: &glam::Mat4) -> bevy::math::Quat; - -"#, - r#" -/// Gets the minimal rotation for transforming `from` to `to`. The rotation is in the -/// plane spanned by the two vectors. Will rotate at most 180 degrees. -/// The inputs must be unit vectors. -/// `from_rotation_arc(from, to) * from ≈ to`. -/// For near-singular cases (from≈to and from≈-to) the current implementation -/// is only accurate to about 0.001 (for `f32`). -/// # Panics -/// Will panic if `from` or `to` are not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_arc( - #[proxy] - from: bevy::math::Vec3, - #[proxy] - to: bevy::math::Vec3, - ) -> bevy::math::Quat; - -"#, - r#" -/// Gets the minimal rotation for transforming `from` to either `to` or `-to`. This means -/// that the resulting quaternion will rotate `from` so that it is colinear with `to`. -/// The rotation is in the plane spanned by the two vectors. Will rotate at most 90 -/// degrees. -/// The inputs must be unit vectors. -/// `to.dot(from_rotation_arc_colinear(from, to) * from).abs() ≈ 1`. -/// # Panics -/// Will panic if `from` or `to` are not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_arc_colinear( - #[proxy] - from: bevy::math::Vec3, - #[proxy] - to: bevy::math::Vec3, - ) -> bevy::math::Quat; - -"#, - r#" -/// Gets the minimal rotation for transforming `from` to `to`. The resulting rotation is -/// around the z axis. Will rotate at most 180 degrees. -/// The inputs must be unit vectors. -/// `from_rotation_arc_2d(from, to) * from ≈ to`. -/// For near-singular cases (from≈to and from≈-to) the current implementation -/// is only accurate to about 0.001 (for `f32`). -/// # Panics -/// Will panic if `from` or `to` are not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_arc_2d( - #[proxy] - from: bevy::math::Vec2, - #[proxy] - to: bevy::math::Vec2, - ) -> bevy::math::Quat; - -"#, - r#" -/// Returns the rotation axis scaled by the rotation in radians. - - #[lua(kind = "Method", output(proxy))] - fn to_scaled_axis(self) -> bevy::math::Vec3; - -"#, - r#" -/// Returns the rotation angles for the given euler rotation sequence. - - #[lua(kind = "Method")] - fn to_euler(self, #[proxy] order: bevy::math::EulerRot) -> (f32, f32, f32); - -"#, - r#" -/// `[x, y, z, w]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [f32; 4]; - -"#, - r#" -/// Returns the vector part of the quaternion. - - #[lua(kind = "Method", output(proxy))] - fn xyz(self) -> bevy::math::Vec3; - -"#, - r#" -/// Returns the quaternion conjugate of `self`. For a unit quaternion the -/// conjugate is also the inverse. - - #[lua(kind = "Method", output(proxy))] - fn conjugate(self) -> bevy::math::Quat; - -"#, - r#" -/// Returns the inverse of a normalized quaternion. -/// Typically quaternion inverse returns the conjugate of a normalized quaternion. -/// Because `self` is assumed to already be unit length this method *does not* normalize -/// before returning the conjugate. -/// # Panics -/// Will panic if `self` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn inverse(self) -> bevy::math::Quat; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. The dot product is -/// equal to the cosine of the angle between two quaternion rotations. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::Quat) -> f32; - -"#, - r#" -/// Computes the length of `self`. - - #[lua(kind = "Method")] - fn length(self) -> f32; - -"#, - r#" -/// Computes the squared length of `self`. -/// This is generally faster than `length()` as it avoids a square -/// root operation. - - #[lua(kind = "Method")] - fn length_squared(self) -> f32; - -"#, - r#" -/// Computes `1.0 / length()`. -/// For valid results, `self` must _not_ be of length zero. - - #[lua(kind = "Method")] - fn length_recip(self) -> f32; - -"#, - r#" -/// Returns `self` normalized to length 1.0. -/// For valid results, `self` must _not_ be of length zero. -/// Panics -/// Will panic if `self` is zero length when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn normalize(self) -> bevy::math::Quat; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. -/// If any element is either `NaN`, positive or negative infinity, this will return `false`. - - #[lua(kind = "Method")] - fn is_finite(self) -> bool; - -"#, - r#" -/// Returns `true` if any elements are `NAN`. - - #[lua(kind = "Method")] - fn is_nan(self) -> bool; - -"#, - r#" -/// Returns whether `self` of length `1.0` or not. -/// Uses a precision threshold of `1e-6`. - - #[lua(kind = "Method")] - fn is_normalized(self) -> bool; - -"#, - r#" - - #[lua(kind = "Method")] - fn is_near_identity(self) -> bool; - -"#, - r#" -/// Returns the angle (in radians) for the minimal rotation -/// for transforming this quaternion into another. -/// Both quaternions must be normalized. -/// # Panics -/// Will panic if `self` or `rhs` are not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method")] - fn angle_between(self, #[proxy] rhs: bevy::math::Quat) -> f32; - -"#, - r#" -/// Rotates towards `rhs` up to `max_angle` (in radians). -/// When `max_angle` is `0.0`, the result will be equal to `self`. When `max_angle` is equal to -/// `self.angle_between(rhs)`, the result will be equal to `rhs`. If `max_angle` is negative, -/// rotates towards the exact opposite of `rhs`. Will not go past the target. -/// Both quaternions must be normalized. -/// # Panics -/// Will panic if `self` or `rhs` are not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn rotate_towards( - &self, - #[proxy] - rhs: bevy::math::Quat, - max_angle: f32, - ) -> bevy::math::Quat; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` -/// is less than or equal to `max_abs_diff`. -/// This can be used to compare if two quaternions contain similar elements. It works -/// best when comparing with a known value. The `max_abs_diff` that should be used used -/// depends on the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(self, #[proxy] rhs: bevy::math::Quat, max_abs_diff: f32) -> bool; - -"#, - r#" -/// Performs a linear interpolation between `self` and `rhs` based on -/// the value `s`. -/// When `s` is `0.0`, the result will be equal to `self`. When `s` -/// is `1.0`, the result will be equal to `rhs`. -/// # Panics -/// Will panic if `self` or `end` are not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn lerp(self, #[proxy] end: bevy::math::Quat, s: f32) -> bevy::math::Quat; - -"#, - r#" -/// Performs a spherical linear interpolation between `self` and `end` -/// based on the value `s`. -/// When `s` is `0.0`, the result will be equal to `self`. When `s` -/// is `1.0`, the result will be equal to `end`. -/// # Panics -/// Will panic if `self` or `end` are not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn slerp(self, #[proxy] end: bevy::math::Quat, s: f32) -> bevy::math::Quat; - -"#, - r#" -/// Multiplies a quaternion and a 3D vector, returning the rotated vector. -/// # Panics -/// Will panic if `self` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn mul_vec3(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Multiplies two quaternions. If they each represent a rotation, the result will -/// represent the combined rotation. -/// Note that due to floating point rounding the result may not be perfectly normalized. -/// # Panics -/// Will panic if `self` or `rhs` are not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn mul_quat(self, #[proxy] rhs: bevy::math::Quat) -> bevy::math::Quat; - -"#, - r#" -/// Creates a quaternion from a 3x3 rotation matrix inside a 3D affine transform. -/// Note if the input affine matrix contain scales, shears, or other non-rotation -/// transformations then the resulting quaternion will be ill-defined. -/// # Panics -/// Will panic if any input affine matrix column is not normalized when `glam_assert` is -/// enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_affine3(#[proxy] a: &glam::Affine3A) -> bevy::math::Quat; - -"#, - r#" -/// Multiplies a quaternion and a 3D vector, returning the rotated vector. - - #[lua(kind = "Method", output(proxy))] - fn mul_vec3a(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" - - #[lua(kind = "Method", output(proxy))] - fn as_dquat(self) -> bevy::math::DQuat; - -"#, - r#" -/// Multiplies two quaternions. If they each represent a rotation, the result will -/// represent the combined rotation. -/// Note that due to floating point rounding the result may not be perfectly -/// normalized. -/// # Panics -/// Will panic if `self` or `rhs` are not normalized when `glam_assert` is enabled. - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Quat) -> bevy::math::Quat; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Quat(); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::Vec3", - functions[r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f32) -> bevy::math::Vec3; - -"#, - r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: f32, y: f32, z: f32) -> bevy::math::Vec3; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: f32) -> bevy::math::Vec3; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec3, - #[proxy] - if_true: bevy::math::Vec3, - #[proxy] - if_false: bevy::math::Vec3, - ) -> bevy::math::Vec3; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [f32; 3]) -> bevy::math::Vec3; - -"#, - r#" -/// `[x, y, z]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [f32; 3]; - -"#, - r#" -/// Creates a 4D vector from `self` and the given `w` value. - - #[lua(kind = "Method", output(proxy))] - fn extend(self, w: f32) -> bevy::math::Vec4; - -"#, - r#" -/// Creates a 2D vector from the `x` and `y` elements of `self`, discarding `z`. -/// Truncation may also be performed by using [`self.xy()`][crate::swizzles::Vec3Swizzles::xy()]. - - #[lua(kind = "Method", output(proxy))] - fn truncate(self) -> bevy::math::Vec2; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: f32) -> bevy::math::Vec3; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: f32) -> bevy::math::Vec3; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `z`. - - #[lua(kind = "Method", output(proxy))] - fn with_z(self, z: f32) -> bevy::math::Vec3; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::Vec3) -> f32; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Computes the cross product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn cross(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Component-wise clamping of values, similar to [`f32::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::Vec3, - #[proxy] - max: bevy::math::Vec3, - ) -> bevy::math::Vec3; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> f32; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> f32; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> f32; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> f32; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector containing the absolute value of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn abs(self) -> bevy::math::Vec3; - -"#, - r#" -/// Returns a vector with elements representing the sign of `self`. -/// - `1.0` if the number is positive, `+0.0` or `INFINITY` -/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` -/// - `NAN` if the number is `NAN` - - #[lua(kind = "Method", output(proxy))] - fn signum(self) -> bevy::math::Vec3; - -"#, - r#" -/// Returns a vector with signs of `rhs` and the magnitudes of `self`. - - #[lua(kind = "Method", output(proxy))] - fn copysign(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Returns a bitmask with the lowest 3 bits set to the sign bits from the elements of `self`. -/// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes -/// into the first lowest bit, element `y` into the second, etc. - - #[lua(kind = "Method")] - fn is_negative_bitmask(self) -> u32; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. If any element is either -/// `NaN`, positive or negative infinity, this will return `false`. - - #[lua(kind = "Method")] - fn is_finite(self) -> bool; - -"#, - r#" -/// Performs `is_finite` on each element of self, returning a vector mask of the results. -/// In other words, this computes `[x.is_finite(), y.is_finite(), ...]`. - - #[lua(kind = "Method", output(proxy))] - fn is_finite_mask(self) -> bevy::math::BVec3; - -"#, - r#" -/// Returns `true` if any elements are `NaN`. - - #[lua(kind = "Method")] - fn is_nan(self) -> bool; - -"#, - r#" -/// Performs `is_nan` on each element of self, returning a vector mask of the results. -/// In other words, this computes `[x.is_nan(), y.is_nan(), ...]`. - - #[lua(kind = "Method", output(proxy))] - fn is_nan_mask(self) -> bevy::math::BVec3; - -"#, - r#" -/// Computes the length of `self`. - - #[lua(kind = "Method")] - fn length(self) -> f32; - -"#, - r#" -/// Computes the squared length of `self`. -/// This is faster than `length()` as it avoids a square root operation. - - #[lua(kind = "Method")] - fn length_squared(self) -> f32; - -"#, - r#" -/// Computes `1.0 / length()`. -/// For valid results, `self` must _not_ be of length zero. - - #[lua(kind = "Method")] - fn length_recip(self) -> f32; - -"#, - r#" -/// Computes the Euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance(self, #[proxy] rhs: bevy::math::Vec3) -> f32; - -"#, - r#" -/// Compute the squared euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance_squared(self, #[proxy] rhs: bevy::math::Vec3) -> f32; - -"#, - r#" -/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn div_euclid(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. -/// [Euclidean division]: f32::rem_euclid - - #[lua(kind = "Method", output(proxy))] - fn rem_euclid(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Returns `self` normalized to length 1.0. -/// For valid results, `self` must be finite and _not_ of length zero, nor very close to zero. -/// See also [`Self::try_normalize()`] and [`Self::normalize_or_zero()`]. -/// Panics -/// Will panic if the resulting normalized vector is not finite when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn normalize(self) -> bevy::math::Vec3; - -"#, - r#" -/// Returns `self` normalized to length 1.0 if possible, else returns a -/// fallback value. -/// In particular, if the input is zero (or very close to zero), or non-finite, -/// the result of this operation will be the fallback value. -/// See also [`Self::try_normalize()`]. - - #[lua(kind = "Method", output(proxy))] - fn normalize_or(self, #[proxy] fallback: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Returns `self` normalized to length 1.0 if possible, else returns zero. -/// In particular, if the input is zero (or very close to zero), or non-finite, -/// the result of this operation will be zero. -/// See also [`Self::try_normalize()`]. - - #[lua(kind = "Method", output(proxy))] - fn normalize_or_zero(self) -> bevy::math::Vec3; - -"#, - r#" -/// Returns whether `self` is length `1.0` or not. -/// Uses a precision threshold of approximately `1e-4`. - - #[lua(kind = "Method")] - fn is_normalized(self) -> bool; - -"#, - r#" -/// Returns the vector projection of `self` onto `rhs`. -/// `rhs` must be of non-zero length. -/// # Panics -/// Will panic if `rhs` is zero length when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn project_onto(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Returns the vector rejection of `self` from `rhs`. -/// The vector rejection is the vector perpendicular to the projection of `self` onto -/// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`. -/// `rhs` must be of non-zero length. -/// # Panics -/// Will panic if `rhs` has a length of zero when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reject_from(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Returns the vector projection of `self` onto `rhs`. -/// `rhs` must be normalized. -/// # Panics -/// Will panic if `rhs` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn project_onto_normalized(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Returns the vector rejection of `self` from `rhs`. -/// The vector rejection is the vector perpendicular to the projection of `self` onto -/// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`. -/// `rhs` must be normalized. -/// # Panics -/// Will panic if `rhs` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reject_from_normalized(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Returns a vector containing the nearest integer to a number for each element of `self`. -/// Round half-way cases away from 0.0. - - #[lua(kind = "Method", output(proxy))] - fn round(self) -> bevy::math::Vec3; - -"#, - r#" -/// Returns a vector containing the largest integer less than or equal to a number for each -/// element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn floor(self) -> bevy::math::Vec3; - -"#, - r#" -/// Returns a vector containing the smallest integer greater than or equal to a number for -/// each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn ceil(self) -> bevy::math::Vec3; - -"#, - r#" -/// Returns a vector containing the integer part each element of `self`. This means numbers are -/// always truncated towards zero. - - #[lua(kind = "Method", output(proxy))] - fn trunc(self) -> bevy::math::Vec3; - -"#, - r#" -/// Returns a vector containing the fractional part of the vector as `self - self.trunc()`. -/// Note that this differs from the GLSL implementation of `fract` which returns -/// `self - self.floor()`. -/// Note that this is fast but not precise for large numbers. - - #[lua(kind = "Method", output(proxy))] - fn fract(self) -> bevy::math::Vec3; - -"#, - r#" -/// Returns a vector containing the fractional part of the vector as `self - self.floor()`. -/// Note that this differs from the Rust implementation of `fract` which returns -/// `self - self.trunc()`. -/// Note that this is fast but not precise for large numbers. - - #[lua(kind = "Method", output(proxy))] - fn fract_gl(self) -> bevy::math::Vec3; - -"#, - r#" -/// Returns a vector containing `e^self` (the exponential function) for each element of -/// `self`. - - #[lua(kind = "Method", output(proxy))] - fn exp(self) -> bevy::math::Vec3; - -"#, - r#" -/// Returns a vector containing each element of `self` raised to the power of `n`. - - #[lua(kind = "Method", output(proxy))] - fn powf(self, n: f32) -> bevy::math::Vec3; - -"#, - r#" -/// Returns a vector containing the reciprocal `1.0/n` of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn recip(self) -> bevy::math::Vec3; - -"#, - r#" -/// Performs a linear interpolation between `self` and `rhs` based on the value `s`. -/// When `s` is `0.0`, the result will be equal to `self`. When `s` is `1.0`, the result -/// will be equal to `rhs`. When `s` is outside of range `[0, 1]`, the result is linearly -/// extrapolated. - - #[lua(kind = "Method", output(proxy))] - fn lerp(self, #[proxy] rhs: bevy::math::Vec3, s: f32) -> bevy::math::Vec3; - -"#, - r#" -/// Moves towards `rhs` based on the value `d`. -/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to -/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn move_towards(&self, #[proxy] rhs: bevy::math::Vec3, d: f32) -> bevy::math::Vec3; - -"#, - r#" -/// Calculates the midpoint between `self` and `rhs`. -/// The midpoint is the average of, or halfway point between, two vectors. -/// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)` -/// while being slightly cheaper to compute. - - #[lua(kind = "Method", output(proxy))] - fn midpoint(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` is -/// less than or equal to `max_abs_diff`. -/// This can be used to compare if two vectors contain similar elements. It works best when -/// comparing with a known value. The `max_abs_diff` that should be used used depends on -/// the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(self, #[proxy] rhs: bevy::math::Vec3, max_abs_diff: f32) -> bool; - -"#, - r#" -/// Returns a vector with a length no less than `min` and no more than `max`. -/// # Panics -/// Will panic if `min` is greater than `max`, or if either `min` or `max` is negative, when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length(self, min: f32, max: f32) -> bevy::math::Vec3; - -"#, - r#" -/// Returns a vector with a length no more than `max`. -/// # Panics -/// Will panic if `max` is negative when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length_max(self, max: f32) -> bevy::math::Vec3; - -"#, - r#" -/// Returns a vector with a length no less than `min`. -/// # Panics -/// Will panic if `min` is negative when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length_min(self, min: f32) -> bevy::math::Vec3; - -"#, - r#" -/// Fused multiply-add. Computes `(self * a) + b` element-wise with only one rounding -/// error, yielding a more accurate result than an unfused multiply-add. -/// Using `mul_add` *may* be more performant than an unfused multiply-add if the target -/// architecture has a dedicated fma CPU instruction. However, this is not always true, -/// and will be heavily dependant on designing algorithms with specific target hardware in -/// mind. - - #[lua(kind = "Method", output(proxy))] - fn mul_add( - self, - #[proxy] - a: bevy::math::Vec3, - #[proxy] - b: bevy::math::Vec3, - ) -> bevy::math::Vec3; - -"#, - r#" -/// Returns the reflection vector for a given incident vector `self` and surface normal -/// `normal`. -/// `normal` must be normalized. -/// # Panics -/// Will panic if `normal` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reflect(self, #[proxy] normal: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Returns the refraction direction for a given incident vector `self`, surface normal -/// `normal` and ratio of indices of refraction, `eta`. When total internal reflection occurs, -/// a zero vector will be returned. -/// `self` and `normal` must be normalized. -/// # Panics -/// Will panic if `self` or `normal` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn refract(self, #[proxy] normal: bevy::math::Vec3, eta: f32) -> bevy::math::Vec3; - -"#, - r#" -/// Returns the angle (in radians) between two vectors in the range `[0, +π]`. -/// The inputs do not need to be unit vectors however they must be non-zero. - - #[lua(kind = "Method")] - fn angle_between(self, #[proxy] rhs: bevy::math::Vec3) -> f32; - -"#, - r#" -/// Returns some vector that is orthogonal to the given one. -/// The input vector must be finite and non-zero. -/// The output vector is not necessarily unit length. For that use -/// [`Self::any_orthonormal_vector()`] instead. - - #[lua(kind = "Method", output(proxy))] - fn any_orthogonal_vector(&self) -> bevy::math::Vec3; - -"#, - r#" -/// Returns any unit vector that is orthogonal to the given one. -/// The input vector must be unit length. -/// # Panics -/// Will panic if `self` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn any_orthonormal_vector(&self) -> bevy::math::Vec3; - -"#, - r#" -/// Casts all elements of `self` to `f64`. - - #[lua(kind = "Method", output(proxy))] - fn as_dvec3(&self) -> bevy::math::DVec3; - -"#, - r#" -/// Casts all elements of `self` to `i32`. - - #[lua(kind = "Method", output(proxy))] - fn as_ivec3(&self) -> bevy::math::IVec3; - -"#, - r#" -/// Casts all elements of `self` to `u32`. - - #[lua(kind = "Method", output(proxy))] - fn as_uvec3(&self) -> bevy::math::UVec3; - -"#, - r#" -/// Casts all elements of `self` to `i64`. - - #[lua(kind = "Method", output(proxy))] - fn as_i64vec3(&self) -> bevy::math::I64Vec3; - -"#, - r#" -/// Casts all elements of `self` to `u64`. - - #[lua(kind = "Method", output(proxy))] - fn as_u64vec3(&self) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: f32) -> bevy::math::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: f32) -> bevy::math::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: f32) -> bevy::math::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: f32) -> bevy::math::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::Vec3) -> bevy::math::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::Vec3) -> bevy::math::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::Vec3) -> bevy::math::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::Vec3) -> bevy::math::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::Vec3) -> bevy::math::Vec3; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::Vec3) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind="MetaMethod", raw , metamethod="Index")] -fn index(&self, lua: &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(self.inner()?[*idx]) -} -"#, - r#" -#[lua(kind="MutatingMetaMethod", raw, metamethod="NewIndex")] -fn index(&mut self, lua: &Lua, idx: crate::lua::util::LuaIndex, val: f32) -> Result<(),_> { - self.val_mut(|s| Ok(s[*idx] = val))? -} -"#] -)] -struct Vec3 { - x: f32, - y: f32, - z: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::IVec2", - functions[r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::IVec2) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::IVec2) -> bevy::math::IVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: i32) -> bevy::math::IVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::IVec2) -> bevy::math::IVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: i32) -> bevy::math::IVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::IVec2) -> bevy::math::IVec2; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::IVec2; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: i32) -> bevy::math::IVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: i32) -> bevy::math::IVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::IVec2) -> bevy::math::IVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: i32) -> bevy::math::IVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::IVec2; - -"#, - r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: i32, y: i32) -> bevy::math::IVec2; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: i32) -> bevy::math::IVec2; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec2, - #[proxy] - if_true: bevy::math::IVec2, - #[proxy] - if_false: bevy::math::IVec2, - ) -> bevy::math::IVec2; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [i32; 2]) -> bevy::math::IVec2; - -"#, - r#" -/// `[x, y]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [i32; 2]; - -"#, - r#" -/// Creates a 3D vector from `self` and the given `z` value. - - #[lua(kind = "Method", output(proxy))] - fn extend(self, z: i32) -> bevy::math::IVec3; - -"#, - r#" -/// Creates a 2D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: i32) -> bevy::math::IVec2; - -"#, - r#" -/// Creates a 2D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: i32) -> bevy::math::IVec2; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::IVec2) -> i32; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" -/// Component-wise clamping of values, similar to [`i32::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::IVec2, - #[proxy] - max: bevy::math::IVec2, - ) -> bevy::math::IVec2; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> i32; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> i32; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> i32; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> i32; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector containing the absolute value of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn abs(self) -> bevy::math::IVec2; - -"#, - r#" -/// Returns a vector with elements representing the sign of `self`. -/// - `0` if the number is zero -/// - `1` if the number is positive -/// - `-1` if the number is negative - - #[lua(kind = "Method", output(proxy))] - fn signum(self) -> bevy::math::IVec2; - -"#, - r#" -/// Returns a bitmask with the lowest 2 bits set to the sign bits from the elements of `self`. -/// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes -/// into the first lowest bit, element `y` into the second, etc. - - #[lua(kind = "Method")] - fn is_negative_bitmask(self) -> u32; - -"#, - r#" -/// Computes the squared length of `self`. - - #[lua(kind = "Method")] - fn length_squared(self) -> i32; - -"#, - r#" -/// Compute the squared euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance_squared(self, #[proxy] rhs: bevy::math::IVec2) -> i32; - -"#, - r#" -/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. -/// # Panics -/// This function will panic if any `rhs` element is 0 or the division results in overflow. - - #[lua(kind = "Method", output(proxy))] - fn div_euclid(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" -/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. -/// # Panics -/// This function will panic if any `rhs` element is 0 or the division results in overflow. -/// [Euclidean division]: i32::rem_euclid - - #[lua(kind = "Method", output(proxy))] - fn rem_euclid(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" -/// Returns a vector that is equal to `self` rotated by 90 degrees. - - #[lua(kind = "Method", output(proxy))] - fn perp(self) -> bevy::math::IVec2; - -"#, - r#" -/// The perpendicular dot product of `self` and `rhs`. -/// Also known as the wedge product, 2D cross product, and determinant. - - #[lua(kind = "Method")] - fn perp_dot(self, #[proxy] rhs: bevy::math::IVec2) -> i32; - -"#, - r#" -/// Returns `rhs` rotated by the angle of `self`. If `self` is normalized, -/// then this just rotation. This is what you usually want. Otherwise, -/// it will be like a rotation with a multiplication by `self`'s length. - - #[lua(kind = "Method", output(proxy))] - fn rotate(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec2(&self) -> bevy::math::Vec2; - -"#, - r#" -/// Casts all elements of `self` to `f64`. - - #[lua(kind = "Method", output(proxy))] - fn as_dvec2(&self) -> bevy::math::DVec2; - -"#, - r#" -/// Casts all elements of `self` to `u32`. - - #[lua(kind = "Method", output(proxy))] - fn as_uvec2(&self) -> bevy::math::UVec2; - -"#, - r#" -/// Casts all elements of `self` to `i64`. - - #[lua(kind = "Method", output(proxy))] - fn as_i64vec2(&self) -> bevy::math::I64Vec2; - -"#, - r#" -/// Casts all elements of `self` to `u64`. - - #[lua(kind = "Method", output(proxy))] - fn as_u64vec2(&self) -> bevy::math::U64Vec2; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_add(rhs.x), self.y.wrapping_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" -/// Returns a vector containing the wrapping subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_sub(rhs.x), self.y.wrapping_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_sub(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" -/// Returns a vector containing the wrapping multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_mul(rhs.x), self.y.wrapping_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_mul(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" -/// Returns a vector containing the wrapping division of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_div(rhs.x), self.y.wrapping_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_div(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" -/// Returns a vector containing the saturating addition of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_add(rhs.x), self.y.saturating_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" -/// Returns a vector containing the saturating subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_sub(rhs.x), self.y.saturating_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" -/// Returns a vector containing the saturating multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_mul(rhs.x), self.y.saturating_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_mul(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" -/// Returns a vector containing the saturating division of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_div(rhs.x), self.y.saturating_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_div(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::IVec2; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and unsigned vector `rhs`. -/// In other words this computes `[self.x.wrapping_add_unsigned(rhs.x), self.y.wrapping_add_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add_unsigned(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::IVec2; - -"#, - r#" -/// Returns a vector containing the wrapping subtraction of `self` and unsigned vector `rhs`. -/// In other words this computes `[self.x.wrapping_sub_unsigned(rhs.x), self.y.wrapping_sub_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_sub_unsigned(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::IVec2; - -"#, - r#" -/// In other words this computes `[self.x.saturating_add_unsigned(rhs.x), self.y.saturating_add_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add_unsigned( - self, - #[proxy] - rhs: bevy::math::UVec2, - ) -> bevy::math::IVec2; - -"#, - r#" -/// Returns a vector containing the saturating subtraction of `self` and unsigned vector `rhs`. -/// In other words this computes `[self.x.saturating_sub_unsigned(rhs.x), self.y.saturating_sub_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub_unsigned( - self, - #[proxy] - rhs: bevy::math::UVec2, - ) -> bevy::math::IVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::IVec2) -> bevy::math::IVec2; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind="MetaMethod", raw , metamethod="Index")] -fn index(&self, lua: &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(self.inner()?[*idx]) -} -"#, - r#" -#[lua(kind="MutatingMetaMethod", raw, metamethod="NewIndex")] -fn index(&mut self, lua: &Lua, idx: crate::lua::util::LuaIndex, val: i32) -> Result<(),_> { - self.val_mut(|s| Ok(s[*idx] = val))? -} -"#] -)] -struct IVec2 { - x: i32, - y: i32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::IVec3", - functions[r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: i32) -> bevy::math::IVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::IVec3) -> bevy::math::IVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: i32) -> bevy::math::IVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::IVec3) -> bevy::math::IVec3; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::IVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::IVec3) -> bevy::math::IVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::IVec3) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::IVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: i32) -> bevy::math::IVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: i32) -> bevy::math::IVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::IVec3) -> bevy::math::IVec3; - -"#, - r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: i32, y: i32, z: i32) -> bevy::math::IVec3; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: i32) -> bevy::math::IVec3; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec3, - #[proxy] - if_true: bevy::math::IVec3, - #[proxy] - if_false: bevy::math::IVec3, - ) -> bevy::math::IVec3; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [i32; 3]) -> bevy::math::IVec3; - -"#, - r#" -/// `[x, y, z]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [i32; 3]; - -"#, - r#" -/// Creates a 4D vector from `self` and the given `w` value. - - #[lua(kind = "Method", output(proxy))] - fn extend(self, w: i32) -> bevy::math::IVec4; - -"#, - r#" -/// Creates a 2D vector from the `x` and `y` elements of `self`, discarding `z`. -/// Truncation may also be performed by using [`self.xy()`][crate::swizzles::Vec3Swizzles::xy()]. - - #[lua(kind = "Method", output(proxy))] - fn truncate(self) -> bevy::math::IVec2; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: i32) -> bevy::math::IVec3; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: i32) -> bevy::math::IVec3; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `z`. - - #[lua(kind = "Method", output(proxy))] - fn with_z(self, z: i32) -> bevy::math::IVec3; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::IVec3) -> i32; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" -/// Computes the cross product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn cross(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" -/// Component-wise clamping of values, similar to [`i32::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::IVec3, - #[proxy] - max: bevy::math::IVec3, - ) -> bevy::math::IVec3; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> i32; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> i32; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> i32; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> i32; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector containing the absolute value of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn abs(self) -> bevy::math::IVec3; - -"#, - r#" -/// Returns a vector with elements representing the sign of `self`. -/// - `0` if the number is zero -/// - `1` if the number is positive -/// - `-1` if the number is negative - - #[lua(kind = "Method", output(proxy))] - fn signum(self) -> bevy::math::IVec3; - -"#, - r#" -/// Returns a bitmask with the lowest 3 bits set to the sign bits from the elements of `self`. -/// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes -/// into the first lowest bit, element `y` into the second, etc. - - #[lua(kind = "Method")] - fn is_negative_bitmask(self) -> u32; - -"#, - r#" -/// Computes the squared length of `self`. - - #[lua(kind = "Method")] - fn length_squared(self) -> i32; - -"#, - r#" -/// Compute the squared euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance_squared(self, #[proxy] rhs: bevy::math::IVec3) -> i32; - -"#, - r#" -/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. -/// # Panics -/// This function will panic if any `rhs` element is 0 or the division results in overflow. - - #[lua(kind = "Method", output(proxy))] - fn div_euclid(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" -/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. -/// # Panics -/// This function will panic if any `rhs` element is 0 or the division results in overflow. -/// [Euclidean division]: i32::rem_euclid - - #[lua(kind = "Method", output(proxy))] - fn rem_euclid(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec3(&self) -> bevy::math::Vec3; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec3a(&self) -> bevy::math::Vec3A; - -"#, - r#" -/// Casts all elements of `self` to `f64`. - - #[lua(kind = "Method", output(proxy))] - fn as_dvec3(&self) -> bevy::math::DVec3; - -"#, - r#" -/// Casts all elements of `self` to `u32`. - - #[lua(kind = "Method", output(proxy))] - fn as_uvec3(&self) -> bevy::math::UVec3; - -"#, - r#" -/// Casts all elements of `self` to `i64`. - - #[lua(kind = "Method", output(proxy))] - fn as_i64vec3(&self) -> bevy::math::I64Vec3; - -"#, - r#" -/// Casts all elements of `self` to `u64`. - - #[lua(kind = "Method", output(proxy))] - fn as_u64vec3(&self) -> bevy::math::U64Vec3; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_add(rhs.x), self.y.wrapping_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" -/// Returns a vector containing the wrapping subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_sub(rhs.x), self.y.wrapping_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_sub(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" -/// Returns a vector containing the wrapping multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_mul(rhs.x), self.y.wrapping_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_mul(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" -/// Returns a vector containing the wrapping division of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_div(rhs.x), self.y.wrapping_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_div(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" -/// Returns a vector containing the saturating addition of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_add(rhs.x), self.y.saturating_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" -/// Returns a vector containing the saturating subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_sub(rhs.x), self.y.saturating_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" -/// Returns a vector containing the saturating multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_mul(rhs.x), self.y.saturating_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_mul(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" -/// Returns a vector containing the saturating division of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_div(rhs.x), self.y.saturating_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_div(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::IVec3; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and unsigned vector `rhs`. -/// In other words this computes `[self.x.wrapping_add_unsigned(rhs.x), self.y.wrapping_add_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add_unsigned(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::IVec3; - -"#, - r#" -/// Returns a vector containing the wrapping subtraction of `self` and unsigned vector `rhs`. -/// In other words this computes `[self.x.wrapping_sub_unsigned(rhs.x), self.y.wrapping_sub_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_sub_unsigned(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::IVec3; - -"#, - r#" -/// In other words this computes `[self.x.saturating_add_unsigned(rhs.x), self.y.saturating_add_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add_unsigned( - self, - #[proxy] - rhs: bevy::math::UVec3, - ) -> bevy::math::IVec3; - -"#, - r#" -/// Returns a vector containing the saturating subtraction of `self` and unsigned vector `rhs`. -/// In other words this computes `[self.x.saturating_sub_unsigned(rhs.x), self.y.saturating_sub_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub_unsigned( - self, - #[proxy] - rhs: bevy::math::UVec3, - ) -> bevy::math::IVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::IVec3) -> bevy::math::IVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: i32) -> bevy::math::IVec3; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind="MetaMethod", raw , metamethod="Index")] -fn index(&self, lua: &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(self.inner()?[*idx]) -} -"#, - r#" -#[lua(kind="MutatingMetaMethod", raw, metamethod="NewIndex")] -fn index(&mut self, lua: &Lua, idx: crate::lua::util::LuaIndex, val: i32) -> Result<(),_> { - self.val_mut(|s| Ok(s[*idx] = val))? -} -"#] -)] -struct IVec3 { - x: i32, - y: i32, - z: i32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::IVec4", - functions[r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::IVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::IVec4) -> bevy::math::IVec4; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::IVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: i32) -> bevy::math::IVec4; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::IVec4) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: i32) -> bevy::math::IVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::IVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::IVec4) -> bevy::math::IVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::IVec4) -> bevy::math::IVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::IVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::IVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::IVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: i32) -> bevy::math::IVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: i32) -> bevy::math::IVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: i32) -> bevy::math::IVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::IVec4) -> bevy::math::IVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::IVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::IVec4) -> bevy::math::IVec4; - -"#, - r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: i32, y: i32, z: i32, w: i32) -> bevy::math::IVec4; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: i32) -> bevy::math::IVec4; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec4, - #[proxy] - if_true: bevy::math::IVec4, - #[proxy] - if_false: bevy::math::IVec4, - ) -> bevy::math::IVec4; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [i32; 4]) -> bevy::math::IVec4; - -"#, - r#" -/// `[x, y, z, w]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [i32; 4]; - -"#, - r#" -/// Creates a 3D vector from the `x`, `y` and `z` elements of `self`, discarding `w`. -/// Truncation to [`IVec3`] may also be performed by using [`self.xyz()`][crate::swizzles::Vec4Swizzles::xyz()]. - - #[lua(kind = "Method", output(proxy))] - fn truncate(self) -> bevy::math::IVec3; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: i32) -> bevy::math::IVec4; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: i32) -> bevy::math::IVec4; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `z`. - - #[lua(kind = "Method", output(proxy))] - fn with_z(self, z: i32) -> bevy::math::IVec4; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `w`. - - #[lua(kind = "Method", output(proxy))] - fn with_w(self, w: i32) -> bevy::math::IVec4; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::IVec4) -> i32; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::IVec4; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::IVec4; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::IVec4; - -"#, - r#" -/// Component-wise clamping of values, similar to [`i32::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::IVec4, - #[proxy] - max: bevy::math::IVec4, - ) -> bevy::math::IVec4; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> i32; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> i32; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> i32; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> i32; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector containing the absolute value of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn abs(self) -> bevy::math::IVec4; - -"#, - r#" -/// Returns a vector with elements representing the sign of `self`. -/// - `0` if the number is zero -/// - `1` if the number is positive -/// - `-1` if the number is negative - - #[lua(kind = "Method", output(proxy))] - fn signum(self) -> bevy::math::IVec4; - -"#, - r#" -/// Returns a bitmask with the lowest 4 bits set to the sign bits from the elements of `self`. -/// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes -/// into the first lowest bit, element `y` into the second, etc. - - #[lua(kind = "Method")] - fn is_negative_bitmask(self) -> u32; - -"#, - r#" -/// Computes the squared length of `self`. - - #[lua(kind = "Method")] - fn length_squared(self) -> i32; - -"#, - r#" -/// Compute the squared euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance_squared(self, #[proxy] rhs: bevy::math::IVec4) -> i32; - -"#, - r#" -/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. -/// # Panics -/// This function will panic if any `rhs` element is 0 or the division results in overflow. - - #[lua(kind = "Method", output(proxy))] - fn div_euclid(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::IVec4; - -"#, - r#" -/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. -/// # Panics -/// This function will panic if any `rhs` element is 0 or the division results in overflow. -/// [Euclidean division]: i32::rem_euclid - - #[lua(kind = "Method", output(proxy))] - fn rem_euclid(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::IVec4; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec4(&self) -> bevy::math::Vec4; - -"#, - r#" -/// Casts all elements of `self` to `f64`. - - #[lua(kind = "Method", output(proxy))] - fn as_dvec4(&self) -> bevy::math::DVec4; - -"#, - r#" -/// Casts all elements of `self` to `u32`. - - #[lua(kind = "Method", output(proxy))] - fn as_uvec4(&self) -> bevy::math::UVec4; - -"#, - r#" -/// Casts all elements of `self` to `i64`. - - #[lua(kind = "Method", output(proxy))] - fn as_i64vec4(&self) -> bevy::math::I64Vec4; - -"#, - r#" -/// Casts all elements of `self` to `u64`. - - #[lua(kind = "Method", output(proxy))] - fn as_u64vec4(&self) -> bevy::math::U64Vec4; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_add(rhs.x), self.y.wrapping_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::IVec4; - -"#, - r#" -/// Returns a vector containing the wrapping subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_sub(rhs.x), self.y.wrapping_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_sub(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::IVec4; - -"#, - r#" -/// Returns a vector containing the wrapping multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_mul(rhs.x), self.y.wrapping_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_mul(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::IVec4; - -"#, - r#" -/// Returns a vector containing the wrapping division of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_div(rhs.x), self.y.wrapping_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_div(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::IVec4; - -"#, - r#" -/// Returns a vector containing the saturating addition of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_add(rhs.x), self.y.saturating_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::IVec4; - -"#, - r#" -/// Returns a vector containing the saturating subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_sub(rhs.x), self.y.saturating_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::IVec4; - -"#, - r#" -/// Returns a vector containing the saturating multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_mul(rhs.x), self.y.saturating_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_mul(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::IVec4; - -"#, - r#" -/// Returns a vector containing the saturating division of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_div(rhs.x), self.y.saturating_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_div(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::IVec4; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and unsigned vector `rhs`. -/// In other words this computes `[self.x.wrapping_add_unsigned(rhs.x), self.y.wrapping_add_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add_unsigned(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::IVec4; - -"#, - r#" -/// Returns a vector containing the wrapping subtraction of `self` and unsigned vector `rhs`. -/// In other words this computes `[self.x.wrapping_sub_unsigned(rhs.x), self.y.wrapping_sub_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_sub_unsigned(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::IVec4; - -"#, - r#" -/// In other words this computes `[self.x.saturating_add_unsigned(rhs.x), self.y.saturating_add_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add_unsigned( - self, - #[proxy] - rhs: bevy::math::UVec4, - ) -> bevy::math::IVec4; - -"#, - r#" -/// Returns a vector containing the saturating subtraction of `self` and unsigned vector `rhs`. -/// In other words this computes `[self.x.saturating_sub_unsigned(rhs.x), self.y.saturating_sub_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub_unsigned( - self, - #[proxy] - rhs: bevy::math::UVec4, - ) -> bevy::math::IVec4; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind="MetaMethod", raw , metamethod="Index")] -fn index(&self, lua: &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(self.inner()?[*idx]) -} -"#, - r#" -#[lua(kind="MutatingMetaMethod", raw, metamethod="NewIndex")] -fn index(&mut self, lua: &Lua, idx: crate::lua::util::LuaIndex, val: i32) -> Result<(),_> { - self.val_mut(|s| Ok(s[*idx] = val))? -} -"#] -)] -struct IVec4 { - x: i32, - y: i32, - z: i32, - w: i32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::I64Vec2", - functions[r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: i64) -> bevy::math::I64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: i64) -> bevy::math::I64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: i64) -> bevy::math::I64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: i64) -> bevy::math::I64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: i64, y: i64) -> bevy::math::I64Vec2; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: i64) -> bevy::math::I64Vec2; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec2, - #[proxy] - if_true: bevy::math::I64Vec2, - #[proxy] - if_false: bevy::math::I64Vec2, - ) -> bevy::math::I64Vec2; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [i64; 2]) -> bevy::math::I64Vec2; - -"#, - r#" -/// `[x, y]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [i64; 2]; - -"#, - r#" -/// Creates a 3D vector from `self` and the given `z` value. - - #[lua(kind = "Method", output(proxy))] - fn extend(self, z: i64) -> bevy::math::I64Vec3; - -"#, - r#" -/// Creates a 2D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: i64) -> bevy::math::I64Vec2; - -"#, - r#" -/// Creates a 2D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: i64) -> bevy::math::I64Vec2; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::I64Vec2) -> i64; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" -/// Component-wise clamping of values, similar to [`i64::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::I64Vec2, - #[proxy] - max: bevy::math::I64Vec2, - ) -> bevy::math::I64Vec2; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> i64; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> i64; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> i64; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> i64; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector containing the absolute value of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn abs(self) -> bevy::math::I64Vec2; - -"#, - r#" -/// Returns a vector with elements representing the sign of `self`. -/// - `0` if the number is zero -/// - `1` if the number is positive -/// - `-1` if the number is negative - - #[lua(kind = "Method", output(proxy))] - fn signum(self) -> bevy::math::I64Vec2; - -"#, - r#" -/// Returns a bitmask with the lowest 2 bits set to the sign bits from the elements of `self`. -/// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes -/// into the first lowest bit, element `y` into the second, etc. - - #[lua(kind = "Method")] - fn is_negative_bitmask(self) -> u32; - -"#, - r#" -/// Computes the squared length of `self`. - - #[lua(kind = "Method")] - fn length_squared(self) -> i64; - -"#, - r#" -/// Compute the squared euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance_squared(self, #[proxy] rhs: bevy::math::I64Vec2) -> i64; - -"#, - r#" -/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. -/// # Panics -/// This function will panic if any `rhs` element is 0 or the division results in overflow. - - #[lua(kind = "Method", output(proxy))] - fn div_euclid(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" -/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. -/// # Panics -/// This function will panic if any `rhs` element is 0 or the division results in overflow. -/// [Euclidean division]: i64::rem_euclid - - #[lua(kind = "Method", output(proxy))] - fn rem_euclid(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" -/// Returns a vector that is equal to `self` rotated by 90 degrees. - - #[lua(kind = "Method", output(proxy))] - fn perp(self) -> bevy::math::I64Vec2; - -"#, - r#" -/// The perpendicular dot product of `self` and `rhs`. -/// Also known as the wedge product, 2D cross product, and determinant. - - #[lua(kind = "Method")] - fn perp_dot(self, #[proxy] rhs: bevy::math::I64Vec2) -> i64; - -"#, - r#" -/// Returns `rhs` rotated by the angle of `self`. If `self` is normalized, -/// then this just rotation. This is what you usually want. Otherwise, -/// it will be like a rotation with a multiplication by `self`'s length. - - #[lua(kind = "Method", output(proxy))] - fn rotate(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec2(&self) -> bevy::math::Vec2; - -"#, - r#" -/// Casts all elements of `self` to `f64`. - - #[lua(kind = "Method", output(proxy))] - fn as_dvec2(&self) -> bevy::math::DVec2; - -"#, - r#" -/// Casts all elements of `self` to `i32`. - - #[lua(kind = "Method", output(proxy))] - fn as_ivec2(&self) -> bevy::math::IVec2; - -"#, - r#" -/// Casts all elements of `self` to `u32`. - - #[lua(kind = "Method", output(proxy))] - fn as_uvec2(&self) -> bevy::math::UVec2; - -"#, - r#" -/// Casts all elements of `self` to `u64`. - - #[lua(kind = "Method", output(proxy))] - fn as_u64vec2(&self) -> bevy::math::U64Vec2; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_add(rhs.x), self.y.wrapping_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" -/// Returns a vector containing the wrapping subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_sub(rhs.x), self.y.wrapping_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_sub(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" -/// Returns a vector containing the wrapping multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_mul(rhs.x), self.y.wrapping_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_mul(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" -/// Returns a vector containing the wrapping division of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_div(rhs.x), self.y.wrapping_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_div(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" -/// Returns a vector containing the saturating addition of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_add(rhs.x), self.y.saturating_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" -/// Returns a vector containing the saturating subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_sub(rhs.x), self.y.saturating_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" -/// Returns a vector containing the saturating multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_mul(rhs.x), self.y.saturating_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_mul(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" -/// Returns a vector containing the saturating division of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_div(rhs.x), self.y.saturating_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_div(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and unsigned vector `rhs`. -/// In other words this computes `[self.x.wrapping_add_unsigned(rhs.x), self.y.wrapping_add_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add_unsigned( - self, - #[proxy] - rhs: bevy::math::U64Vec2, - ) -> bevy::math::I64Vec2; - -"#, - r#" -/// Returns a vector containing the wrapping subtraction of `self` and unsigned vector `rhs`. -/// In other words this computes `[self.x.wrapping_sub_unsigned(rhs.x), self.y.wrapping_sub_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_sub_unsigned( - self, - #[proxy] - rhs: bevy::math::U64Vec2, - ) -> bevy::math::I64Vec2; - -"#, - r#" -/// In other words this computes `[self.x.saturating_add_unsigned(rhs.x), self.y.saturating_add_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add_unsigned( - self, - #[proxy] - rhs: bevy::math::U64Vec2, - ) -> bevy::math::I64Vec2; - -"#, - r#" -/// Returns a vector containing the saturating subtraction of `self` and unsigned vector `rhs`. -/// In other words this computes `[self.x.saturating_sub_unsigned(rhs.x), self.y.saturating_sub_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub_unsigned( - self, - #[proxy] - rhs: bevy::math::U64Vec2, - ) -> bevy::math::I64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::I64Vec2) -> bool; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::I64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: i64) -> bevy::math::I64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::I64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::I64Vec2) -> bevy::math::I64Vec2; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct I64Vec2 { - x: i64, - y: i64, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::I64Vec3", - functions[r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::I64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: i64) -> bevy::math::I64Vec3; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::I64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: i64) -> bevy::math::I64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: i64) -> bevy::math::I64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: i64) -> bevy::math::I64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::I64Vec3) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: i64) -> bevy::math::I64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: i64, y: i64, z: i64) -> bevy::math::I64Vec3; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: i64) -> bevy::math::I64Vec3; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec3, - #[proxy] - if_true: bevy::math::I64Vec3, - #[proxy] - if_false: bevy::math::I64Vec3, - ) -> bevy::math::I64Vec3; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [i64; 3]) -> bevy::math::I64Vec3; - -"#, - r#" -/// `[x, y, z]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [i64; 3]; - -"#, - r#" -/// Creates a 4D vector from `self` and the given `w` value. - - #[lua(kind = "Method", output(proxy))] - fn extend(self, w: i64) -> bevy::math::I64Vec4; - -"#, - r#" -/// Creates a 2D vector from the `x` and `y` elements of `self`, discarding `z`. -/// Truncation may also be performed by using [`self.xy()`][crate::swizzles::Vec3Swizzles::xy()]. - - #[lua(kind = "Method", output(proxy))] - fn truncate(self) -> bevy::math::I64Vec2; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: i64) -> bevy::math::I64Vec3; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: i64) -> bevy::math::I64Vec3; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `z`. - - #[lua(kind = "Method", output(proxy))] - fn with_z(self, z: i64) -> bevy::math::I64Vec3; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::I64Vec3) -> i64; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" -/// Computes the cross product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn cross(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" -/// Component-wise clamping of values, similar to [`i64::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::I64Vec3, - #[proxy] - max: bevy::math::I64Vec3, - ) -> bevy::math::I64Vec3; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> i64; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> i64; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> i64; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> i64; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector containing the absolute value of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn abs(self) -> bevy::math::I64Vec3; - -"#, - r#" -/// Returns a vector with elements representing the sign of `self`. -/// - `0` if the number is zero -/// - `1` if the number is positive -/// - `-1` if the number is negative - - #[lua(kind = "Method", output(proxy))] - fn signum(self) -> bevy::math::I64Vec3; - -"#, - r#" -/// Returns a bitmask with the lowest 3 bits set to the sign bits from the elements of `self`. -/// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes -/// into the first lowest bit, element `y` into the second, etc. - - #[lua(kind = "Method")] - fn is_negative_bitmask(self) -> u32; - -"#, - r#" -/// Computes the squared length of `self`. - - #[lua(kind = "Method")] - fn length_squared(self) -> i64; - -"#, - r#" -/// Compute the squared euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance_squared(self, #[proxy] rhs: bevy::math::I64Vec3) -> i64; - -"#, - r#" -/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. -/// # Panics -/// This function will panic if any `rhs` element is 0 or the division results in overflow. - - #[lua(kind = "Method", output(proxy))] - fn div_euclid(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" -/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. -/// # Panics -/// This function will panic if any `rhs` element is 0 or the division results in overflow. -/// [Euclidean division]: i64::rem_euclid - - #[lua(kind = "Method", output(proxy))] - fn rem_euclid(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec3(&self) -> bevy::math::Vec3; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec3a(&self) -> bevy::math::Vec3A; - -"#, - r#" -/// Casts all elements of `self` to `f64`. - - #[lua(kind = "Method", output(proxy))] - fn as_dvec3(&self) -> bevy::math::DVec3; - -"#, - r#" -/// Casts all elements of `self` to `i32`. - - #[lua(kind = "Method", output(proxy))] - fn as_ivec3(&self) -> bevy::math::IVec3; - -"#, - r#" -/// Casts all elements of `self` to `u32`. - - #[lua(kind = "Method", output(proxy))] - fn as_uvec3(&self) -> bevy::math::UVec3; - -"#, - r#" -/// Casts all elements of `self` to `u64`. - - #[lua(kind = "Method", output(proxy))] - fn as_u64vec3(&self) -> bevy::math::U64Vec3; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_add(rhs.x), self.y.wrapping_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" -/// Returns a vector containing the wrapping subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_sub(rhs.x), self.y.wrapping_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_sub(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" -/// Returns a vector containing the wrapping multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_mul(rhs.x), self.y.wrapping_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_mul(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" -/// Returns a vector containing the wrapping division of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_div(rhs.x), self.y.wrapping_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_div(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" -/// Returns a vector containing the saturating addition of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_add(rhs.x), self.y.saturating_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" -/// Returns a vector containing the saturating subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_sub(rhs.x), self.y.saturating_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" -/// Returns a vector containing the saturating multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_mul(rhs.x), self.y.saturating_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_mul(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" -/// Returns a vector containing the saturating division of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_div(rhs.x), self.y.saturating_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_div(self, #[proxy] rhs: bevy::math::I64Vec3) -> bevy::math::I64Vec3; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and unsigned vector `rhs`. -/// In other words this computes `[self.x.wrapping_add_unsigned(rhs.x), self.y.wrapping_add_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add_unsigned( - self, - #[proxy] - rhs: bevy::math::U64Vec3, - ) -> bevy::math::I64Vec3; - -"#, - r#" -/// Returns a vector containing the wrapping subtraction of `self` and unsigned vector `rhs`. -/// In other words this computes `[self.x.wrapping_sub_unsigned(rhs.x), self.y.wrapping_sub_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_sub_unsigned( - self, - #[proxy] - rhs: bevy::math::U64Vec3, - ) -> bevy::math::I64Vec3; - -"#, - r#" -/// In other words this computes `[self.x.saturating_add_unsigned(rhs.x), self.y.saturating_add_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add_unsigned( - self, - #[proxy] - rhs: bevy::math::U64Vec3, - ) -> bevy::math::I64Vec3; - -"#, - r#" -/// Returns a vector containing the saturating subtraction of `self` and unsigned vector `rhs`. -/// In other words this computes `[self.x.saturating_sub_unsigned(rhs.x), self.y.saturating_sub_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub_unsigned( - self, - #[proxy] - rhs: bevy::math::U64Vec3, - ) -> bevy::math::I64Vec3; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct I64Vec3 { - x: i64, - y: i64, - z: i64, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::I64Vec4", - functions[r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: i64) -> bevy::math::I64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: i64) -> bevy::math::I64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: i64) -> bevy::math::I64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: i64) -> bevy::math::I64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: i64) -> bevy::math::I64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::I64Vec4) -> bool; - -"#, - r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: i64, y: i64, z: i64, w: i64) -> bevy::math::I64Vec4; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: i64) -> bevy::math::I64Vec4; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec4, - #[proxy] - if_true: bevy::math::I64Vec4, - #[proxy] - if_false: bevy::math::I64Vec4, - ) -> bevy::math::I64Vec4; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [i64; 4]) -> bevy::math::I64Vec4; - -"#, - r#" -/// `[x, y, z, w]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [i64; 4]; - -"#, - r#" -/// Creates a 3D vector from the `x`, `y` and `z` elements of `self`, discarding `w`. -/// Truncation to [`I64Vec3`] may also be performed by using [`self.xyz()`][crate::swizzles::Vec4Swizzles::xyz()]. - - #[lua(kind = "Method", output(proxy))] - fn truncate(self) -> bevy::math::I64Vec3; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: i64) -> bevy::math::I64Vec4; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: i64) -> bevy::math::I64Vec4; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `z`. - - #[lua(kind = "Method", output(proxy))] - fn with_z(self, z: i64) -> bevy::math::I64Vec4; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `w`. - - #[lua(kind = "Method", output(proxy))] - fn with_w(self, w: i64) -> bevy::math::I64Vec4; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::I64Vec4) -> i64; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" -/// Component-wise clamping of values, similar to [`i64::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::I64Vec4, - #[proxy] - max: bevy::math::I64Vec4, - ) -> bevy::math::I64Vec4; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> i64; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> i64; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> i64; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> i64; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector containing the absolute value of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn abs(self) -> bevy::math::I64Vec4; - -"#, - r#" -/// Returns a vector with elements representing the sign of `self`. -/// - `0` if the number is zero -/// - `1` if the number is positive -/// - `-1` if the number is negative - - #[lua(kind = "Method", output(proxy))] - fn signum(self) -> bevy::math::I64Vec4; - -"#, - r#" -/// Returns a bitmask with the lowest 4 bits set to the sign bits from the elements of `self`. -/// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes -/// into the first lowest bit, element `y` into the second, etc. - - #[lua(kind = "Method")] - fn is_negative_bitmask(self) -> u32; - -"#, - r#" -/// Computes the squared length of `self`. - - #[lua(kind = "Method")] - fn length_squared(self) -> i64; - -"#, - r#" -/// Compute the squared euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance_squared(self, #[proxy] rhs: bevy::math::I64Vec4) -> i64; - -"#, - r#" -/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. -/// # Panics -/// This function will panic if any `rhs` element is 0 or the division results in overflow. - - #[lua(kind = "Method", output(proxy))] - fn div_euclid(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" -/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. -/// # Panics -/// This function will panic if any `rhs` element is 0 or the division results in overflow. -/// [Euclidean division]: i64::rem_euclid - - #[lua(kind = "Method", output(proxy))] - fn rem_euclid(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec4(&self) -> bevy::math::Vec4; - -"#, - r#" -/// Casts all elements of `self` to `f64`. - - #[lua(kind = "Method", output(proxy))] - fn as_dvec4(&self) -> bevy::math::DVec4; - -"#, - r#" -/// Casts all elements of `self` to `i32`. - - #[lua(kind = "Method", output(proxy))] - fn as_ivec4(&self) -> bevy::math::IVec4; - -"#, - r#" -/// Casts all elements of `self` to `u32`. - - #[lua(kind = "Method", output(proxy))] - fn as_uvec4(&self) -> bevy::math::UVec4; - -"#, - r#" -/// Casts all elements of `self` to `u64`. - - #[lua(kind = "Method", output(proxy))] - fn as_u64vec4(&self) -> bevy::math::U64Vec4; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_add(rhs.x), self.y.wrapping_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" -/// Returns a vector containing the wrapping subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_sub(rhs.x), self.y.wrapping_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_sub(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" -/// Returns a vector containing the wrapping multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_mul(rhs.x), self.y.wrapping_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_mul(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" -/// Returns a vector containing the wrapping division of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_div(rhs.x), self.y.wrapping_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_div(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" -/// Returns a vector containing the saturating addition of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_add(rhs.x), self.y.saturating_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" -/// Returns a vector containing the saturating subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_sub(rhs.x), self.y.saturating_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" -/// Returns a vector containing the saturating multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_mul(rhs.x), self.y.saturating_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_mul(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" -/// Returns a vector containing the saturating division of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_div(rhs.x), self.y.saturating_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_div(self, #[proxy] rhs: bevy::math::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and unsigned vector `rhs`. -/// In other words this computes `[self.x.wrapping_add_unsigned(rhs.x), self.y.wrapping_add_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add_unsigned( - self, - #[proxy] - rhs: bevy::math::U64Vec4, - ) -> bevy::math::I64Vec4; - -"#, - r#" -/// Returns a vector containing the wrapping subtraction of `self` and unsigned vector `rhs`. -/// In other words this computes `[self.x.wrapping_sub_unsigned(rhs.x), self.y.wrapping_sub_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_sub_unsigned( - self, - #[proxy] - rhs: bevy::math::U64Vec4, - ) -> bevy::math::I64Vec4; - -"#, - r#" -/// In other words this computes `[self.x.saturating_add_unsigned(rhs.x), self.y.saturating_add_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add_unsigned( - self, - #[proxy] - rhs: bevy::math::U64Vec4, - ) -> bevy::math::I64Vec4; - -"#, - r#" -/// Returns a vector containing the saturating subtraction of `self` and unsigned vector `rhs`. -/// In other words this computes `[self.x.saturating_sub_unsigned(rhs.x), self.y.saturating_sub_unsigned(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub_unsigned( - self, - #[proxy] - rhs: bevy::math::U64Vec4, - ) -> bevy::math::I64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::I64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::I64Vec4) -> bevy::math::I64Vec4; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::I64Vec4; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct I64Vec4 { - x: i64, - y: i64, - z: i64, - w: i64, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::UVec2", - functions[r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: u32) -> bevy::math::UVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::UVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::UVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::UVec2; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::UVec2) -> bool; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::UVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::UVec2) -> bevy::math::UVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::UVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::UVec2) -> bevy::math::UVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: u32) -> bevy::math::UVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::UVec2) -> bevy::math::UVec2; - -"#, - r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: u32, y: u32) -> bevy::math::UVec2; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: u32) -> bevy::math::UVec2; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec2, - #[proxy] - if_true: bevy::math::UVec2, - #[proxy] - if_false: bevy::math::UVec2, - ) -> bevy::math::UVec2; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [u32; 2]) -> bevy::math::UVec2; - -"#, - r#" -/// `[x, y]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [u32; 2]; - -"#, - r#" -/// Creates a 3D vector from `self` and the given `z` value. - - #[lua(kind = "Method", output(proxy))] - fn extend(self, z: u32) -> bevy::math::UVec3; - -"#, - r#" -/// Creates a 2D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: u32) -> bevy::math::UVec2; - -"#, - r#" -/// Creates a 2D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: u32) -> bevy::math::UVec2; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::UVec2) -> u32; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::UVec2; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::UVec2; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::UVec2; - -"#, - r#" -/// Component-wise clamping of values, similar to [`u32::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::UVec2, - #[proxy] - max: bevy::math::UVec2, - ) -> bevy::math::UVec2; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> u32; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> u32; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> u32; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> u32; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::BVec2; - -"#, - r#" -/// Computes the squared length of `self`. - - #[lua(kind = "Method")] - fn length_squared(self) -> u32; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec2(&self) -> bevy::math::Vec2; - -"#, - r#" -/// Casts all elements of `self` to `f64`. - - #[lua(kind = "Method", output(proxy))] - fn as_dvec2(&self) -> bevy::math::DVec2; - -"#, - r#" -/// Casts all elements of `self` to `i32`. - - #[lua(kind = "Method", output(proxy))] - fn as_ivec2(&self) -> bevy::math::IVec2; - -"#, - r#" -/// Casts all elements of `self` to `i64`. - - #[lua(kind = "Method", output(proxy))] - fn as_i64vec2(&self) -> bevy::math::I64Vec2; - -"#, - r#" -/// Casts all elements of `self` to `u64`. - - #[lua(kind = "Method", output(proxy))] - fn as_u64vec2(&self) -> bevy::math::U64Vec2; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_add(rhs.x), self.y.wrapping_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::UVec2; - -"#, - r#" -/// Returns a vector containing the wrapping subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_sub(rhs.x), self.y.wrapping_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_sub(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::UVec2; - -"#, - r#" -/// Returns a vector containing the wrapping multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_mul(rhs.x), self.y.wrapping_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_mul(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::UVec2; - -"#, - r#" -/// Returns a vector containing the wrapping division of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_div(rhs.x), self.y.wrapping_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_div(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::UVec2; - -"#, - r#" -/// Returns a vector containing the saturating addition of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_add(rhs.x), self.y.saturating_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::UVec2; - -"#, - r#" -/// Returns a vector containing the saturating subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_sub(rhs.x), self.y.saturating_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::UVec2; - -"#, - r#" -/// Returns a vector containing the saturating multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_mul(rhs.x), self.y.saturating_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_mul(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::UVec2; - -"#, - r#" -/// Returns a vector containing the saturating division of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_div(rhs.x), self.y.saturating_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_div(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::UVec2; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and signed vector `rhs`. -/// In other words this computes `[self.x.wrapping_add_signed(rhs.x), self.y.wrapping_add_signed(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add_signed(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::UVec2; - -"#, - r#" -/// Returns a vector containing the saturating addition of `self` and signed vector `rhs`. -/// In other words this computes `[self.x.saturating_add_signed(rhs.x), self.y.saturating_add_signed(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add_signed(self, #[proxy] rhs: bevy::math::IVec2) -> bevy::math::UVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::UVec2) -> bevy::math::UVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::UVec2) -> bevy::math::UVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: u32) -> bevy::math::UVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: u32) -> bevy::math::UVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::UVec2) -> bevy::math::UVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: u32) -> bevy::math::UVec2; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind="MetaMethod", raw , metamethod="Index")] -fn index(&self, lua: &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(self.inner()?[*idx]) -} -"#, - r#" -#[lua(kind="MutatingMetaMethod", raw, metamethod="NewIndex")] -fn index(&mut self, lua: &Lua, idx: crate::lua::util::LuaIndex, val: u32) -> Result<(),_> { - self.val_mut(|s| Ok(s[*idx] = val))? -} -"#] -)] -struct UVec2 { - x: u32, - y: u32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::UVec3", - functions[r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::UVec3) -> bevy::math::UVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::UVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::UVec3) -> bevy::math::UVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::UVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: u32) -> bevy::math::UVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::UVec3) -> bevy::math::UVec3; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::UVec3) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::UVec3) -> bevy::math::UVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: u32) -> bevy::math::UVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: u32) -> bevy::math::UVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::UVec3; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::UVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::UVec3) -> bevy::math::UVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::UVec3; - -"#, - r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: u32, y: u32, z: u32) -> bevy::math::UVec3; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: u32) -> bevy::math::UVec3; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec3, - #[proxy] - if_true: bevy::math::UVec3, - #[proxy] - if_false: bevy::math::UVec3, - ) -> bevy::math::UVec3; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [u32; 3]) -> bevy::math::UVec3; - -"#, - r#" -/// `[x, y, z]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [u32; 3]; - -"#, - r#" -/// Creates a 4D vector from `self` and the given `w` value. - - #[lua(kind = "Method", output(proxy))] - fn extend(self, w: u32) -> bevy::math::UVec4; - -"#, - r#" -/// Creates a 2D vector from the `x` and `y` elements of `self`, discarding `z`. -/// Truncation may also be performed by using [`self.xy()`][crate::swizzles::Vec3Swizzles::xy()]. - - #[lua(kind = "Method", output(proxy))] - fn truncate(self) -> bevy::math::UVec2; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: u32) -> bevy::math::UVec3; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: u32) -> bevy::math::UVec3; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `z`. - - #[lua(kind = "Method", output(proxy))] - fn with_z(self, z: u32) -> bevy::math::UVec3; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::UVec3) -> u32; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::UVec3; - -"#, - r#" -/// Computes the cross product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn cross(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::UVec3; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::UVec3; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::UVec3; - -"#, - r#" -/// Component-wise clamping of values, similar to [`u32::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::UVec3, - #[proxy] - max: bevy::math::UVec3, - ) -> bevy::math::UVec3; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> u32; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> u32; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> u32; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> u32; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::BVec3; - -"#, - r#" -/// Computes the squared length of `self`. - - #[lua(kind = "Method")] - fn length_squared(self) -> u32; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec3(&self) -> bevy::math::Vec3; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec3a(&self) -> bevy::math::Vec3A; - -"#, - r#" -/// Casts all elements of `self` to `f64`. - - #[lua(kind = "Method", output(proxy))] - fn as_dvec3(&self) -> bevy::math::DVec3; - -"#, - r#" -/// Casts all elements of `self` to `i32`. - - #[lua(kind = "Method", output(proxy))] - fn as_ivec3(&self) -> bevy::math::IVec3; - -"#, - r#" -/// Casts all elements of `self` to `i64`. - - #[lua(kind = "Method", output(proxy))] - fn as_i64vec3(&self) -> bevy::math::I64Vec3; - -"#, - r#" -/// Casts all elements of `self` to `u64`. - - #[lua(kind = "Method", output(proxy))] - fn as_u64vec3(&self) -> bevy::math::U64Vec3; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_add(rhs.x), self.y.wrapping_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::UVec3; - -"#, - r#" -/// Returns a vector containing the wrapping subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_sub(rhs.x), self.y.wrapping_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_sub(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::UVec3; - -"#, - r#" -/// Returns a vector containing the wrapping multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_mul(rhs.x), self.y.wrapping_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_mul(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::UVec3; - -"#, - r#" -/// Returns a vector containing the wrapping division of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_div(rhs.x), self.y.wrapping_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_div(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::UVec3; - -"#, - r#" -/// Returns a vector containing the saturating addition of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_add(rhs.x), self.y.saturating_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::UVec3; - -"#, - r#" -/// Returns a vector containing the saturating subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_sub(rhs.x), self.y.saturating_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::UVec3; - -"#, - r#" -/// Returns a vector containing the saturating multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_mul(rhs.x), self.y.saturating_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_mul(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::UVec3; - -"#, - r#" -/// Returns a vector containing the saturating division of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_div(rhs.x), self.y.saturating_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_div(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::UVec3; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and signed vector `rhs`. -/// In other words this computes `[self.x.wrapping_add_signed(rhs.x), self.y.wrapping_add_signed(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add_signed(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::UVec3; - -"#, - r#" -/// Returns a vector containing the saturating addition of `self` and signed vector `rhs`. -/// In other words this computes `[self.x.saturating_add_signed(rhs.x), self.y.saturating_add_signed(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add_signed(self, #[proxy] rhs: bevy::math::IVec3) -> bevy::math::UVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: u32) -> bevy::math::UVec3; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: u32) -> bevy::math::UVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::UVec3) -> bevy::math::UVec3; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind="MetaMethod", raw , metamethod="Index")] -fn index(&self, lua: &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(self.inner()?[*idx]) -} -"#, - r#" -#[lua(kind="MutatingMetaMethod", raw, metamethod="NewIndex")] -fn index(&mut self, lua: &Lua, idx: crate::lua::util::LuaIndex, val: u32) -> Result<(),_> { - self.val_mut(|s| Ok(s[*idx] = val))? -} -"#] -)] -struct UVec3 { - x: u32, - y: u32, - z: u32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::UVec4", - functions[r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::UVec4) -> bevy::math::UVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: u32) -> bevy::math::UVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::UVec4; - -"#, - r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: u32, y: u32, z: u32, w: u32) -> bevy::math::UVec4; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: u32) -> bevy::math::UVec4; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec4, - #[proxy] - if_true: bevy::math::UVec4, - #[proxy] - if_false: bevy::math::UVec4, - ) -> bevy::math::UVec4; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [u32; 4]) -> bevy::math::UVec4; - -"#, - r#" -/// `[x, y, z, w]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [u32; 4]; - -"#, - r#" -/// Creates a 3D vector from the `x`, `y` and `z` elements of `self`, discarding `w`. -/// Truncation to [`UVec3`] may also be performed by using [`self.xyz()`][crate::swizzles::Vec4Swizzles::xyz()]. - - #[lua(kind = "Method", output(proxy))] - fn truncate(self) -> bevy::math::UVec3; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: u32) -> bevy::math::UVec4; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: u32) -> bevy::math::UVec4; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `z`. - - #[lua(kind = "Method", output(proxy))] - fn with_z(self, z: u32) -> bevy::math::UVec4; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `w`. - - #[lua(kind = "Method", output(proxy))] - fn with_w(self, w: u32) -> bevy::math::UVec4; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::UVec4) -> u32; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::UVec4; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::UVec4; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::UVec4; - -"#, - r#" -/// Component-wise clamping of values, similar to [`u32::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::UVec4, - #[proxy] - max: bevy::math::UVec4, - ) -> bevy::math::UVec4; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> u32; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> u32; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> u32; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> u32; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::BVec4; - -"#, - r#" -/// Computes the squared length of `self`. - - #[lua(kind = "Method")] - fn length_squared(self) -> u32; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec4(&self) -> bevy::math::Vec4; - -"#, - r#" -/// Casts all elements of `self` to `f64`. - - #[lua(kind = "Method", output(proxy))] - fn as_dvec4(&self) -> bevy::math::DVec4; - -"#, - r#" -/// Casts all elements of `self` to `i32`. - - #[lua(kind = "Method", output(proxy))] - fn as_ivec4(&self) -> bevy::math::IVec4; - -"#, - r#" -/// Casts all elements of `self` to `i64`. - - #[lua(kind = "Method", output(proxy))] - fn as_i64vec4(&self) -> bevy::math::I64Vec4; - -"#, - r#" -/// Casts all elements of `self` to `u64`. - - #[lua(kind = "Method", output(proxy))] - fn as_u64vec4(&self) -> bevy::math::U64Vec4; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_add(rhs.x), self.y.wrapping_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::UVec4; - -"#, - r#" -/// Returns a vector containing the wrapping subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_sub(rhs.x), self.y.wrapping_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_sub(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::UVec4; - -"#, - r#" -/// Returns a vector containing the wrapping multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_mul(rhs.x), self.y.wrapping_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_mul(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::UVec4; - -"#, - r#" -/// Returns a vector containing the wrapping division of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_div(rhs.x), self.y.wrapping_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_div(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::UVec4; - -"#, - r#" -/// Returns a vector containing the saturating addition of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_add(rhs.x), self.y.saturating_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::UVec4; - -"#, - r#" -/// Returns a vector containing the saturating subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_sub(rhs.x), self.y.saturating_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::UVec4; - -"#, - r#" -/// Returns a vector containing the saturating multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_mul(rhs.x), self.y.saturating_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_mul(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::UVec4; - -"#, - r#" -/// Returns a vector containing the saturating division of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_div(rhs.x), self.y.saturating_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_div(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::UVec4; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and signed vector `rhs`. -/// In other words this computes `[self.x.wrapping_add_signed(rhs.x), self.y.wrapping_add_signed(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add_signed(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::UVec4; - -"#, - r#" -/// Returns a vector containing the saturating addition of `self` and signed vector `rhs`. -/// In other words this computes `[self.x.saturating_add_signed(rhs.x), self.y.saturating_add_signed(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add_signed(self, #[proxy] rhs: bevy::math::IVec4) -> bevy::math::UVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::UVec4) -> bevy::math::UVec4; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::UVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::UVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::UVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::UVec4; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::UVec4) -> bevy::math::UVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::UVec4) -> bevy::math::UVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: u32) -> bevy::math::UVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: u32) -> bevy::math::UVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::UVec4) -> bevy::math::UVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::UVec4) -> bevy::math::UVec4; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::UVec4) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: u32) -> bevy::math::UVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: u32) -> bevy::math::UVec4; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind="MetaMethod", raw , metamethod="Index")] -fn index(&self, lua: &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(self.inner()?[*idx]) -} -"#, - r#" -#[lua(kind="MutatingMetaMethod", raw, metamethod="NewIndex")] -fn index(&mut self, lua: &Lua, idx: crate::lua::util::LuaIndex, val: u32) -> Result<(),_> { - self.val_mut(|s| Ok(s[*idx] = val))? -} -"#] -)] -struct UVec4 { - x: u32, - y: u32, - z: u32, - w: u32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::U64Vec2", - functions[r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: u64) -> bevy::math::U64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: u64) -> bevy::math::U64Vec2; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::U64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: u64) -> bevy::math::U64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: u64) -> bevy::math::U64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: u64) -> bevy::math::U64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::U64Vec2) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: u64, y: u64) -> bevy::math::U64Vec2; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: u64) -> bevy::math::U64Vec2; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec2, - #[proxy] - if_true: bevy::math::U64Vec2, - #[proxy] - if_false: bevy::math::U64Vec2, - ) -> bevy::math::U64Vec2; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [u64; 2]) -> bevy::math::U64Vec2; - -"#, - r#" -/// `[x, y]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [u64; 2]; - -"#, - r#" -/// Creates a 3D vector from `self` and the given `z` value. - - #[lua(kind = "Method", output(proxy))] - fn extend(self, z: u64) -> bevy::math::U64Vec3; - -"#, - r#" -/// Creates a 2D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: u64) -> bevy::math::U64Vec2; - -"#, - r#" -/// Creates a 2D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: u64) -> bevy::math::U64Vec2; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::U64Vec2) -> u64; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" -/// Component-wise clamping of values, similar to [`u64::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::U64Vec2, - #[proxy] - max: bevy::math::U64Vec2, - ) -> bevy::math::U64Vec2; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> u64; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> u64; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> u64; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> u64; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::BVec2; - -"#, - r#" -/// Computes the squared length of `self`. - - #[lua(kind = "Method")] - fn length_squared(self) -> u64; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec2(&self) -> bevy::math::Vec2; - -"#, - r#" -/// Casts all elements of `self` to `f64`. - - #[lua(kind = "Method", output(proxy))] - fn as_dvec2(&self) -> bevy::math::DVec2; - -"#, - r#" -/// Casts all elements of `self` to `i32`. - - #[lua(kind = "Method", output(proxy))] - fn as_ivec2(&self) -> bevy::math::IVec2; - -"#, - r#" -/// Casts all elements of `self` to `u32`. - - #[lua(kind = "Method", output(proxy))] - fn as_uvec2(&self) -> bevy::math::UVec2; - -"#, - r#" -/// Casts all elements of `self` to `i64`. - - #[lua(kind = "Method", output(proxy))] - fn as_i64vec2(&self) -> bevy::math::I64Vec2; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_add(rhs.x), self.y.wrapping_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" -/// Returns a vector containing the wrapping subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_sub(rhs.x), self.y.wrapping_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_sub(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" -/// Returns a vector containing the wrapping multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_mul(rhs.x), self.y.wrapping_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_mul(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" -/// Returns a vector containing the wrapping division of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_div(rhs.x), self.y.wrapping_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_div(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" -/// Returns a vector containing the saturating addition of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_add(rhs.x), self.y.saturating_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" -/// Returns a vector containing the saturating subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_sub(rhs.x), self.y.saturating_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" -/// Returns a vector containing the saturating multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_mul(rhs.x), self.y.saturating_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_mul(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" -/// Returns a vector containing the saturating division of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_div(rhs.x), self.y.saturating_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_div(self, #[proxy] rhs: bevy::math::U64Vec2) -> bevy::math::U64Vec2; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and signed vector `rhs`. -/// In other words this computes `[self.x.wrapping_add_signed(rhs.x), self.y.wrapping_add_signed(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add_signed( - self, - #[proxy] - rhs: bevy::math::I64Vec2, - ) -> bevy::math::U64Vec2; - -"#, - r#" -/// Returns a vector containing the saturating addition of `self` and signed vector `rhs`. -/// In other words this computes `[self.x.saturating_add_signed(rhs.x), self.y.saturating_add_signed(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add_signed( - self, - #[proxy] - rhs: bevy::math::I64Vec2, - ) -> bevy::math::U64Vec2; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct U64Vec2 { - x: u64, - y: u64, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::U64Vec3", - functions[r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: u64, y: u64, z: u64) -> bevy::math::U64Vec3; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: u64) -> bevy::math::U64Vec3; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec3, - #[proxy] - if_true: bevy::math::U64Vec3, - #[proxy] - if_false: bevy::math::U64Vec3, - ) -> bevy::math::U64Vec3; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [u64; 3]) -> bevy::math::U64Vec3; - -"#, - r#" -/// `[x, y, z]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [u64; 3]; - -"#, - r#" -/// Creates a 4D vector from `self` and the given `w` value. - - #[lua(kind = "Method", output(proxy))] - fn extend(self, w: u64) -> bevy::math::U64Vec4; - -"#, - r#" -/// Creates a 2D vector from the `x` and `y` elements of `self`, discarding `z`. -/// Truncation may also be performed by using [`self.xy()`][crate::swizzles::Vec3Swizzles::xy()]. - - #[lua(kind = "Method", output(proxy))] - fn truncate(self) -> bevy::math::U64Vec2; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: u64) -> bevy::math::U64Vec3; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: u64) -> bevy::math::U64Vec3; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `z`. - - #[lua(kind = "Method", output(proxy))] - fn with_z(self, z: u64) -> bevy::math::U64Vec3; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::U64Vec3) -> u64; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" -/// Computes the cross product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn cross(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" -/// Component-wise clamping of values, similar to [`u64::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::U64Vec3, - #[proxy] - max: bevy::math::U64Vec3, - ) -> bevy::math::U64Vec3; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> u64; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> u64; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> u64; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> u64; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::BVec3; - -"#, - r#" -/// Computes the squared length of `self`. - - #[lua(kind = "Method")] - fn length_squared(self) -> u64; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec3(&self) -> bevy::math::Vec3; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec3a(&self) -> bevy::math::Vec3A; - -"#, - r#" -/// Casts all elements of `self` to `f64`. - - #[lua(kind = "Method", output(proxy))] - fn as_dvec3(&self) -> bevy::math::DVec3; - -"#, - r#" -/// Casts all elements of `self` to `i32`. - - #[lua(kind = "Method", output(proxy))] - fn as_ivec3(&self) -> bevy::math::IVec3; - -"#, - r#" -/// Casts all elements of `self` to `u32`. - - #[lua(kind = "Method", output(proxy))] - fn as_uvec3(&self) -> bevy::math::UVec3; - -"#, - r#" -/// Casts all elements of `self` to `i64`. - - #[lua(kind = "Method", output(proxy))] - fn as_i64vec3(&self) -> bevy::math::I64Vec3; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_add(rhs.x), self.y.wrapping_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" -/// Returns a vector containing the wrapping subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_sub(rhs.x), self.y.wrapping_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_sub(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" -/// Returns a vector containing the wrapping multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_mul(rhs.x), self.y.wrapping_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_mul(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" -/// Returns a vector containing the wrapping division of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_div(rhs.x), self.y.wrapping_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_div(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" -/// Returns a vector containing the saturating addition of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_add(rhs.x), self.y.saturating_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" -/// Returns a vector containing the saturating subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_sub(rhs.x), self.y.saturating_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" -/// Returns a vector containing the saturating multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_mul(rhs.x), self.y.saturating_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_mul(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" -/// Returns a vector containing the saturating division of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_div(rhs.x), self.y.saturating_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_div(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and signed vector `rhs`. -/// In other words this computes `[self.x.wrapping_add_signed(rhs.x), self.y.wrapping_add_signed(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add_signed( - self, - #[proxy] - rhs: bevy::math::I64Vec3, - ) -> bevy::math::U64Vec3; - -"#, - r#" -/// Returns a vector containing the saturating addition of `self` and signed vector `rhs`. -/// In other words this computes `[self.x.saturating_add_signed(rhs.x), self.y.saturating_add_signed(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add_signed( - self, - #[proxy] - rhs: bevy::math::I64Vec3, - ) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: u64) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: u64) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: u64) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: u64) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: u64) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::U64Vec3) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::U64Vec3) -> bevy::math::U64Vec3; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct U64Vec3 { - x: u64, - y: u64, - z: u64, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::U64Vec4", - functions[r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::U64Vec4) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: u64) -> bevy::math::U64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: u64) -> bevy::math::U64Vec4; - -"#, - r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: u64, y: u64, z: u64, w: u64) -> bevy::math::U64Vec4; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: u64) -> bevy::math::U64Vec4; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec4, - #[proxy] - if_true: bevy::math::U64Vec4, - #[proxy] - if_false: bevy::math::U64Vec4, - ) -> bevy::math::U64Vec4; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [u64; 4]) -> bevy::math::U64Vec4; - -"#, - r#" -/// `[x, y, z, w]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [u64; 4]; - -"#, - r#" -/// Creates a 3D vector from the `x`, `y` and `z` elements of `self`, discarding `w`. -/// Truncation to [`U64Vec3`] may also be performed by using [`self.xyz()`][crate::swizzles::Vec4Swizzles::xyz()]. - - #[lua(kind = "Method", output(proxy))] - fn truncate(self) -> bevy::math::U64Vec3; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: u64) -> bevy::math::U64Vec4; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: u64) -> bevy::math::U64Vec4; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `z`. - - #[lua(kind = "Method", output(proxy))] - fn with_z(self, z: u64) -> bevy::math::U64Vec4; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `w`. - - #[lua(kind = "Method", output(proxy))] - fn with_w(self, w: u64) -> bevy::math::U64Vec4; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::U64Vec4) -> u64; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" -/// Component-wise clamping of values, similar to [`u64::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::U64Vec4, - #[proxy] - max: bevy::math::U64Vec4, - ) -> bevy::math::U64Vec4; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> u64; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> u64; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> u64; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> u64; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::BVec4; - -"#, - r#" -/// Computes the squared length of `self`. - - #[lua(kind = "Method")] - fn length_squared(self) -> u64; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec4(&self) -> bevy::math::Vec4; - -"#, - r#" -/// Casts all elements of `self` to `f64`. - - #[lua(kind = "Method", output(proxy))] - fn as_dvec4(&self) -> bevy::math::DVec4; - -"#, - r#" -/// Casts all elements of `self` to `i32`. - - #[lua(kind = "Method", output(proxy))] - fn as_ivec4(&self) -> bevy::math::IVec4; - -"#, - r#" -/// Casts all elements of `self` to `u32`. - - #[lua(kind = "Method", output(proxy))] - fn as_uvec4(&self) -> bevy::math::UVec4; - -"#, - r#" -/// Casts all elements of `self` to `i64`. - - #[lua(kind = "Method", output(proxy))] - fn as_i64vec4(&self) -> bevy::math::I64Vec4; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_add(rhs.x), self.y.wrapping_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" -/// Returns a vector containing the wrapping subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_sub(rhs.x), self.y.wrapping_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_sub(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" -/// Returns a vector containing the wrapping multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_mul(rhs.x), self.y.wrapping_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_mul(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" -/// Returns a vector containing the wrapping division of `self` and `rhs`. -/// In other words this computes `[self.x.wrapping_div(rhs.x), self.y.wrapping_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_div(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" -/// Returns a vector containing the saturating addition of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_add(rhs.x), self.y.saturating_add(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" -/// Returns a vector containing the saturating subtraction of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_sub(rhs.x), self.y.saturating_sub(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_sub(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" -/// Returns a vector containing the saturating multiplication of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_mul(rhs.x), self.y.saturating_mul(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_mul(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" -/// Returns a vector containing the saturating division of `self` and `rhs`. -/// In other words this computes `[self.x.saturating_div(rhs.x), self.y.saturating_div(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_div(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" -/// Returns a vector containing the wrapping addition of `self` and signed vector `rhs`. -/// In other words this computes `[self.x.wrapping_add_signed(rhs.x), self.y.wrapping_add_signed(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn wrapping_add_signed( - self, - #[proxy] - rhs: bevy::math::I64Vec4, - ) -> bevy::math::U64Vec4; - -"#, - r#" -/// Returns a vector containing the saturating addition of `self` and signed vector `rhs`. -/// In other words this computes `[self.x.saturating_add_signed(rhs.x), self.y.saturating_add_signed(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn saturating_add_signed( - self, - #[proxy] - rhs: bevy::math::I64Vec4, - ) -> bevy::math::U64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: u64) -> bevy::math::U64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: u64) -> bevy::math::U64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::U64Vec4) -> bevy::math::U64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: u64) -> bevy::math::U64Vec4; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::U64Vec4; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct U64Vec4 { - x: u64, - y: u64, - z: u64, - w: u64, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::Vec2", - functions[r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::Vec2) -> bevy::math::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: f32) -> bevy::math::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::Vec2) -> bevy::math::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::Vec2) -> bevy::math::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f32) -> bevy::math::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: f32) -> bevy::math::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: f32) -> bevy::math::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::Vec2) -> bool; - -"#, - r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: f32, y: f32) -> bevy::math::Vec2; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: f32) -> bevy::math::Vec2; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec2, - #[proxy] - if_true: bevy::math::Vec2, - #[proxy] - if_false: bevy::math::Vec2, - ) -> bevy::math::Vec2; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [f32; 2]) -> bevy::math::Vec2; - -"#, - r#" -/// `[x, y]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [f32; 2]; - -"#, - r#" -/// Creates a 3D vector from `self` and the given `z` value. - - #[lua(kind = "Method", output(proxy))] - fn extend(self, z: f32) -> bevy::math::Vec3; - -"#, - r#" -/// Creates a 2D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: f32) -> bevy::math::Vec2; - -"#, - r#" -/// Creates a 2D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: f32) -> bevy::math::Vec2; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::Vec2) -> f32; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Component-wise clamping of values, similar to [`f32::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::Vec2, - #[proxy] - max: bevy::math::Vec2, - ) -> bevy::math::Vec2; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> f32; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> f32; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> f32; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> f32; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector containing the absolute value of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn abs(self) -> bevy::math::Vec2; - -"#, - r#" -/// Returns a vector with elements representing the sign of `self`. -/// - `1.0` if the number is positive, `+0.0` or `INFINITY` -/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` -/// - `NAN` if the number is `NAN` - - #[lua(kind = "Method", output(proxy))] - fn signum(self) -> bevy::math::Vec2; - -"#, - r#" -/// Returns a vector with signs of `rhs` and the magnitudes of `self`. - - #[lua(kind = "Method", output(proxy))] - fn copysign(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Returns a bitmask with the lowest 2 bits set to the sign bits from the elements of `self`. -/// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes -/// into the first lowest bit, element `y` into the second, etc. - - #[lua(kind = "Method")] - fn is_negative_bitmask(self) -> u32; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. If any element is either -/// `NaN`, positive or negative infinity, this will return `false`. - - #[lua(kind = "Method")] - fn is_finite(self) -> bool; - -"#, - r#" -/// Performs `is_finite` on each element of self, returning a vector mask of the results. -/// In other words, this computes `[x.is_finite(), y.is_finite(), ...]`. - - #[lua(kind = "Method", output(proxy))] - fn is_finite_mask(self) -> bevy::math::BVec2; - -"#, - r#" -/// Returns `true` if any elements are `NaN`. - - #[lua(kind = "Method")] - fn is_nan(self) -> bool; - -"#, - r#" -/// Performs `is_nan` on each element of self, returning a vector mask of the results. -/// In other words, this computes `[x.is_nan(), y.is_nan(), ...]`. - - #[lua(kind = "Method", output(proxy))] - fn is_nan_mask(self) -> bevy::math::BVec2; - -"#, - r#" -/// Computes the length of `self`. - - #[lua(kind = "Method")] - fn length(self) -> f32; - -"#, - r#" -/// Computes the squared length of `self`. -/// This is faster than `length()` as it avoids a square root operation. - - #[lua(kind = "Method")] - fn length_squared(self) -> f32; - -"#, - r#" -/// Computes `1.0 / length()`. -/// For valid results, `self` must _not_ be of length zero. - - #[lua(kind = "Method")] - fn length_recip(self) -> f32; - -"#, - r#" -/// Computes the Euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance(self, #[proxy] rhs: bevy::math::Vec2) -> f32; - -"#, - r#" -/// Compute the squared euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance_squared(self, #[proxy] rhs: bevy::math::Vec2) -> f32; - -"#, - r#" -/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn div_euclid(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. -/// [Euclidean division]: f32::rem_euclid - - #[lua(kind = "Method", output(proxy))] - fn rem_euclid(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Returns `self` normalized to length 1.0. -/// For valid results, `self` must be finite and _not_ of length zero, nor very close to zero. -/// See also [`Self::try_normalize()`] and [`Self::normalize_or_zero()`]. -/// Panics -/// Will panic if the resulting normalized vector is not finite when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn normalize(self) -> bevy::math::Vec2; - -"#, - r#" -/// Returns `self` normalized to length 1.0 if possible, else returns a -/// fallback value. -/// In particular, if the input is zero (or very close to zero), or non-finite, -/// the result of this operation will be the fallback value. -/// See also [`Self::try_normalize()`]. - - #[lua(kind = "Method", output(proxy))] - fn normalize_or(self, #[proxy] fallback: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Returns `self` normalized to length 1.0 if possible, else returns zero. -/// In particular, if the input is zero (or very close to zero), or non-finite, -/// the result of this operation will be zero. -/// See also [`Self::try_normalize()`]. - - #[lua(kind = "Method", output(proxy))] - fn normalize_or_zero(self) -> bevy::math::Vec2; - -"#, - r#" -/// Returns whether `self` is length `1.0` or not. -/// Uses a precision threshold of approximately `1e-4`. - - #[lua(kind = "Method")] - fn is_normalized(self) -> bool; - -"#, - r#" -/// Returns the vector projection of `self` onto `rhs`. -/// `rhs` must be of non-zero length. -/// # Panics -/// Will panic if `rhs` is zero length when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn project_onto(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Returns the vector rejection of `self` from `rhs`. -/// The vector rejection is the vector perpendicular to the projection of `self` onto -/// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`. -/// `rhs` must be of non-zero length. -/// # Panics -/// Will panic if `rhs` has a length of zero when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reject_from(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Returns the vector projection of `self` onto `rhs`. -/// `rhs` must be normalized. -/// # Panics -/// Will panic if `rhs` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn project_onto_normalized(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Returns the vector rejection of `self` from `rhs`. -/// The vector rejection is the vector perpendicular to the projection of `self` onto -/// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`. -/// `rhs` must be normalized. -/// # Panics -/// Will panic if `rhs` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reject_from_normalized(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Returns a vector containing the nearest integer to a number for each element of `self`. -/// Round half-way cases away from 0.0. - - #[lua(kind = "Method", output(proxy))] - fn round(self) -> bevy::math::Vec2; - -"#, - r#" -/// Returns a vector containing the largest integer less than or equal to a number for each -/// element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn floor(self) -> bevy::math::Vec2; - -"#, - r#" -/// Returns a vector containing the smallest integer greater than or equal to a number for -/// each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn ceil(self) -> bevy::math::Vec2; - -"#, - r#" -/// Returns a vector containing the integer part each element of `self`. This means numbers are -/// always truncated towards zero. - - #[lua(kind = "Method", output(proxy))] - fn trunc(self) -> bevy::math::Vec2; - -"#, - r#" -/// Returns a vector containing the fractional part of the vector as `self - self.trunc()`. -/// Note that this differs from the GLSL implementation of `fract` which returns -/// `self - self.floor()`. -/// Note that this is fast but not precise for large numbers. - - #[lua(kind = "Method", output(proxy))] - fn fract(self) -> bevy::math::Vec2; - -"#, - r#" -/// Returns a vector containing the fractional part of the vector as `self - self.floor()`. -/// Note that this differs from the Rust implementation of `fract` which returns -/// `self - self.trunc()`. -/// Note that this is fast but not precise for large numbers. - - #[lua(kind = "Method", output(proxy))] - fn fract_gl(self) -> bevy::math::Vec2; - -"#, - r#" -/// Returns a vector containing `e^self` (the exponential function) for each element of -/// `self`. - - #[lua(kind = "Method", output(proxy))] - fn exp(self) -> bevy::math::Vec2; - -"#, - r#" -/// Returns a vector containing each element of `self` raised to the power of `n`. - - #[lua(kind = "Method", output(proxy))] - fn powf(self, n: f32) -> bevy::math::Vec2; - -"#, - r#" -/// Returns a vector containing the reciprocal `1.0/n` of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn recip(self) -> bevy::math::Vec2; - -"#, - r#" -/// Performs a linear interpolation between `self` and `rhs` based on the value `s`. -/// When `s` is `0.0`, the result will be equal to `self`. When `s` is `1.0`, the result -/// will be equal to `rhs`. When `s` is outside of range `[0, 1]`, the result is linearly -/// extrapolated. - - #[lua(kind = "Method", output(proxy))] - fn lerp(self, #[proxy] rhs: bevy::math::Vec2, s: f32) -> bevy::math::Vec2; - -"#, - r#" -/// Moves towards `rhs` based on the value `d`. -/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to -/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn move_towards(&self, #[proxy] rhs: bevy::math::Vec2, d: f32) -> bevy::math::Vec2; - -"#, - r#" -/// Calculates the midpoint between `self` and `rhs`. -/// The midpoint is the average of, or halfway point between, two vectors. -/// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)` -/// while being slightly cheaper to compute. - - #[lua(kind = "Method", output(proxy))] - fn midpoint(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` is -/// less than or equal to `max_abs_diff`. -/// This can be used to compare if two vectors contain similar elements. It works best when -/// comparing with a known value. The `max_abs_diff` that should be used used depends on -/// the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(self, #[proxy] rhs: bevy::math::Vec2, max_abs_diff: f32) -> bool; - -"#, - r#" -/// Returns a vector with a length no less than `min` and no more than `max`. -/// # Panics -/// Will panic if `min` is greater than `max`, or if either `min` or `max` is negative, when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length(self, min: f32, max: f32) -> bevy::math::Vec2; - -"#, - r#" -/// Returns a vector with a length no more than `max`. -/// # Panics -/// Will panic if `max` is negative when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length_max(self, max: f32) -> bevy::math::Vec2; - -"#, - r#" -/// Returns a vector with a length no less than `min`. -/// # Panics -/// Will panic if `min` is negative when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length_min(self, min: f32) -> bevy::math::Vec2; - -"#, - r#" -/// Fused multiply-add. Computes `(self * a) + b` element-wise with only one rounding -/// error, yielding a more accurate result than an unfused multiply-add. -/// Using `mul_add` *may* be more performant than an unfused multiply-add if the target -/// architecture has a dedicated fma CPU instruction. However, this is not always true, -/// and will be heavily dependant on designing algorithms with specific target hardware in -/// mind. - - #[lua(kind = "Method", output(proxy))] - fn mul_add( - self, - #[proxy] - a: bevy::math::Vec2, - #[proxy] - b: bevy::math::Vec2, - ) -> bevy::math::Vec2; - -"#, - r#" -/// Returns the reflection vector for a given incident vector `self` and surface normal -/// `normal`. -/// `normal` must be normalized. -/// # Panics -/// Will panic if `normal` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reflect(self, #[proxy] normal: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Returns the refraction direction for a given incident vector `self`, surface normal -/// `normal` and ratio of indices of refraction, `eta`. When total internal reflection occurs, -/// a zero vector will be returned. -/// `self` and `normal` must be normalized. -/// # Panics -/// Will panic if `self` or `normal` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn refract(self, #[proxy] normal: bevy::math::Vec2, eta: f32) -> bevy::math::Vec2; - -"#, - r#" -/// Creates a 2D vector containing `[angle.cos(), angle.sin()]`. This can be used in -/// conjunction with the [`rotate()`][Self::rotate()] method, e.g. -/// `Vec2::from_angle(PI).rotate(Vec2::Y)` will create the vector `[-1, 0]` -/// and rotate [`Vec2::Y`] around it returning `-Vec2::Y`. - - #[lua(kind = "Function", output(proxy))] - fn from_angle(angle: f32) -> bevy::math::Vec2; - -"#, - r#" -/// Returns the angle (in radians) of this vector in the range `[-π, +π]`. -/// The input does not need to be a unit vector however it must be non-zero. - - #[lua(kind = "Method")] - fn to_angle(self) -> f32; - -"#, - r#" - - #[lua(kind = "Method")] - fn angle_between(self, #[proxy] rhs: bevy::math::Vec2) -> f32; - -"#, - r#" -/// Returns the angle of rotation (in radians) from `self` to `rhs` in the range `[-π, +π]`. -/// The inputs do not need to be unit vectors however they must be non-zero. - - #[lua(kind = "Method")] - fn angle_to(self, #[proxy] rhs: bevy::math::Vec2) -> f32; - -"#, - r#" -/// Returns a vector that is equal to `self` rotated by 90 degrees. - - #[lua(kind = "Method", output(proxy))] - fn perp(self) -> bevy::math::Vec2; - -"#, - r#" -/// The perpendicular dot product of `self` and `rhs`. -/// Also known as the wedge product, 2D cross product, and determinant. - - #[lua(kind = "Method")] - fn perp_dot(self, #[proxy] rhs: bevy::math::Vec2) -> f32; - -"#, - r#" -/// Returns `rhs` rotated by the angle of `self`. If `self` is normalized, -/// then this just rotation. This is what you usually want. Otherwise, -/// it will be like a rotation with a multiplication by `self`'s length. - - #[lua(kind = "Method", output(proxy))] - fn rotate(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Rotates towards `rhs` up to `max_angle` (in radians). -/// When `max_angle` is `0.0`, the result will be equal to `self`. When `max_angle` is equal to -/// `self.angle_between(rhs)`, the result will be equal to `rhs`. If `max_angle` is negative, -/// rotates towards the exact opposite of `rhs`. Will not go past the target. - - #[lua(kind = "Method", output(proxy))] - fn rotate_towards( - &self, - #[proxy] - rhs: bevy::math::Vec2, - max_angle: f32, - ) -> bevy::math::Vec2; - -"#, - r#" -/// Casts all elements of `self` to `f64`. - - #[lua(kind = "Method", output(proxy))] - fn as_dvec2(&self) -> bevy::math::DVec2; - -"#, - r#" -/// Casts all elements of `self` to `i32`. - - #[lua(kind = "Method", output(proxy))] - fn as_ivec2(&self) -> bevy::math::IVec2; - -"#, - r#" -/// Casts all elements of `self` to `u32`. - - #[lua(kind = "Method", output(proxy))] - fn as_uvec2(&self) -> bevy::math::UVec2; - -"#, - r#" -/// Casts all elements of `self` to `i64`. - - #[lua(kind = "Method", output(proxy))] - fn as_i64vec2(&self) -> bevy::math::I64Vec2; - -"#, - r#" -/// Casts all elements of `self` to `u64`. - - #[lua(kind = "Method", output(proxy))] - fn as_u64vec2(&self) -> bevy::math::U64Vec2; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: f32) -> bevy::math::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::Vec2) -> bevy::math::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::Vec2) -> bevy::math::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::Vec2; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind="MetaMethod", raw , metamethod="Index")] -fn index(&self, lua: &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(self.inner()?[*idx]) -} -"#, - r#" -#[lua(kind="MutatingMetaMethod", raw, metamethod="NewIndex")] -fn index(&mut self, lua: &Lua, idx: crate::lua::util::LuaIndex, val: f32) -> Result<(),_> { - self.val_mut(|s| Ok(s[*idx] = val))? -} -"#] -)] -struct Vec2 { - x: f32, - y: f32, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::Vec3A", - functions[r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f32) -> bevy::math::Vec3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: f32) -> bevy::math::Vec3A; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] rhs: &glam::Vec3A) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::Vec3A; - -"#, - r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: f32, y: f32, z: f32) -> bevy::math::Vec3A; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: f32) -> bevy::math::Vec3A; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec3A, - #[proxy] - if_true: bevy::math::Vec3A, - #[proxy] - if_false: bevy::math::Vec3A, - ) -> bevy::math::Vec3A; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [f32; 3]) -> bevy::math::Vec3A; - -"#, - r#" -/// `[x, y, z]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [f32; 3]; - -"#, - r#" -/// Creates a [`Vec3A`] from the `x`, `y` and `z` elements of `self` discarding `w`. -/// On architectures where SIMD is supported such as SSE2 on `x86_64` this conversion is a noop. - - #[lua(kind = "Function", output(proxy))] - fn from_vec4(#[proxy] v: bevy::math::Vec4) -> bevy::math::Vec3A; - -"#, - r#" -/// Creates a 4D vector from `self` and the given `w` value. - - #[lua(kind = "Method", output(proxy))] - fn extend(self, w: f32) -> bevy::math::Vec4; - -"#, - r#" -/// Creates a 2D vector from the `x` and `y` elements of `self`, discarding `z`. -/// Truncation may also be performed by using [`self.xy()`][crate::swizzles::Vec3Swizzles::xy()]. - - #[lua(kind = "Method", output(proxy))] - fn truncate(self) -> bevy::math::Vec2; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: f32) -> bevy::math::Vec3A; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: f32) -> bevy::math::Vec3A; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `z`. - - #[lua(kind = "Method", output(proxy))] - fn with_z(self, z: f32) -> bevy::math::Vec3A; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::Vec3A) -> f32; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Computes the cross product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn cross(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Component-wise clamping of values, similar to [`f32::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::Vec3A, - #[proxy] - max: bevy::math::Vec3A, - ) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> f32; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> f32; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> f32; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> f32; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::BVec3A; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::BVec3A; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::BVec3A; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::BVec3A; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::BVec3A; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::BVec3A; - -"#, - r#" -/// Returns a vector containing the absolute value of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn abs(self) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns a vector with elements representing the sign of `self`. -/// - `1.0` if the number is positive, `+0.0` or `INFINITY` -/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` -/// - `NAN` if the number is `NAN` - - #[lua(kind = "Method", output(proxy))] - fn signum(self) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns a vector with signs of `rhs` and the magnitudes of `self`. - - #[lua(kind = "Method", output(proxy))] - fn copysign(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns a bitmask with the lowest 3 bits set to the sign bits from the elements of `self`. -/// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes -/// into the first lowest bit, element `y` into the second, etc. - - #[lua(kind = "Method")] - fn is_negative_bitmask(self) -> u32; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. If any element is either -/// `NaN`, positive or negative infinity, this will return `false`. - - #[lua(kind = "Method")] - fn is_finite(self) -> bool; - -"#, - r#" -/// Performs `is_finite` on each element of self, returning a vector mask of the results. -/// In other words, this computes `[x.is_finite(), y.is_finite(), ...]`. - - #[lua(kind = "Method", output(proxy))] - fn is_finite_mask(self) -> bevy::math::BVec3A; - -"#, - r#" -/// Returns `true` if any elements are `NaN`. - - #[lua(kind = "Method")] - fn is_nan(self) -> bool; - -"#, - r#" -/// Performs `is_nan` on each element of self, returning a vector mask of the results. -/// In other words, this computes `[x.is_nan(), y.is_nan(), ...]`. - - #[lua(kind = "Method", output(proxy))] - fn is_nan_mask(self) -> bevy::math::BVec3A; - -"#, - r#" -/// Computes the length of `self`. - - #[lua(kind = "Method")] - fn length(self) -> f32; - -"#, - r#" -/// Computes the squared length of `self`. -/// This is faster than `length()` as it avoids a square root operation. - - #[lua(kind = "Method")] - fn length_squared(self) -> f32; - -"#, - r#" -/// Computes `1.0 / length()`. -/// For valid results, `self` must _not_ be of length zero. - - #[lua(kind = "Method")] - fn length_recip(self) -> f32; - -"#, - r#" -/// Computes the Euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance(self, #[proxy] rhs: bevy::math::Vec3A) -> f32; - -"#, - r#" -/// Compute the squared euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance_squared(self, #[proxy] rhs: bevy::math::Vec3A) -> f32; - -"#, - r#" -/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn div_euclid(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. -/// [Euclidean division]: f32::rem_euclid - - #[lua(kind = "Method", output(proxy))] - fn rem_euclid(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns `self` normalized to length 1.0. -/// For valid results, `self` must be finite and _not_ of length zero, nor very close to zero. -/// See also [`Self::try_normalize()`] and [`Self::normalize_or_zero()`]. -/// Panics -/// Will panic if the resulting normalized vector is not finite when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn normalize(self) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns `self` normalized to length 1.0 if possible, else returns a -/// fallback value. -/// In particular, if the input is zero (or very close to zero), or non-finite, -/// the result of this operation will be the fallback value. -/// See also [`Self::try_normalize()`]. - - #[lua(kind = "Method", output(proxy))] - fn normalize_or(self, #[proxy] fallback: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns `self` normalized to length 1.0 if possible, else returns zero. -/// In particular, if the input is zero (or very close to zero), or non-finite, -/// the result of this operation will be zero. -/// See also [`Self::try_normalize()`]. - - #[lua(kind = "Method", output(proxy))] - fn normalize_or_zero(self) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns whether `self` is length `1.0` or not. -/// Uses a precision threshold of approximately `1e-4`. - - #[lua(kind = "Method")] - fn is_normalized(self) -> bool; - -"#, - r#" -/// Returns the vector projection of `self` onto `rhs`. -/// `rhs` must be of non-zero length. -/// # Panics -/// Will panic if `rhs` is zero length when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn project_onto(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns the vector rejection of `self` from `rhs`. -/// The vector rejection is the vector perpendicular to the projection of `self` onto -/// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`. -/// `rhs` must be of non-zero length. -/// # Panics -/// Will panic if `rhs` has a length of zero when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reject_from(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns the vector projection of `self` onto `rhs`. -/// `rhs` must be normalized. -/// # Panics -/// Will panic if `rhs` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn project_onto_normalized( - self, - #[proxy] - rhs: bevy::math::Vec3A, - ) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns the vector rejection of `self` from `rhs`. -/// The vector rejection is the vector perpendicular to the projection of `self` onto -/// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`. -/// `rhs` must be normalized. -/// # Panics -/// Will panic if `rhs` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reject_from_normalized( - self, - #[proxy] - rhs: bevy::math::Vec3A, - ) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns a vector containing the nearest integer to a number for each element of `self`. -/// Round half-way cases away from 0.0. - - #[lua(kind = "Method", output(proxy))] - fn round(self) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns a vector containing the largest integer less than or equal to a number for each -/// element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn floor(self) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns a vector containing the smallest integer greater than or equal to a number for -/// each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn ceil(self) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns a vector containing the integer part each element of `self`. This means numbers are -/// always truncated towards zero. - - #[lua(kind = "Method", output(proxy))] - fn trunc(self) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns a vector containing the fractional part of the vector as `self - self.trunc()`. -/// Note that this differs from the GLSL implementation of `fract` which returns -/// `self - self.floor()`. -/// Note that this is fast but not precise for large numbers. - - #[lua(kind = "Method", output(proxy))] - fn fract(self) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns a vector containing the fractional part of the vector as `self - self.floor()`. -/// Note that this differs from the Rust implementation of `fract` which returns -/// `self - self.trunc()`. -/// Note that this is fast but not precise for large numbers. - - #[lua(kind = "Method", output(proxy))] - fn fract_gl(self) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns a vector containing `e^self` (the exponential function) for each element of -/// `self`. - - #[lua(kind = "Method", output(proxy))] - fn exp(self) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns a vector containing each element of `self` raised to the power of `n`. - - #[lua(kind = "Method", output(proxy))] - fn powf(self, n: f32) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns a vector containing the reciprocal `1.0/n` of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn recip(self) -> bevy::math::Vec3A; - -"#, - r#" -/// Performs a linear interpolation between `self` and `rhs` based on the value `s`. -/// When `s` is `0.0`, the result will be equal to `self`. When `s` is `1.0`, the result -/// will be equal to `rhs`. When `s` is outside of range `[0, 1]`, the result is linearly -/// extrapolated. - - #[lua(kind = "Method", output(proxy))] - fn lerp(self, #[proxy] rhs: bevy::math::Vec3A, s: f32) -> bevy::math::Vec3A; - -"#, - r#" -/// Moves towards `rhs` based on the value `d`. -/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to -/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn move_towards(&self, #[proxy] rhs: bevy::math::Vec3A, d: f32) -> bevy::math::Vec3A; - -"#, - r#" -/// Calculates the midpoint between `self` and `rhs`. -/// The midpoint is the average of, or halfway point between, two vectors. -/// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)` -/// while being slightly cheaper to compute. - - #[lua(kind = "Method", output(proxy))] - fn midpoint(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` is -/// less than or equal to `max_abs_diff`. -/// This can be used to compare if two vectors contain similar elements. It works best when -/// comparing with a known value. The `max_abs_diff` that should be used used depends on -/// the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(self, #[proxy] rhs: bevy::math::Vec3A, max_abs_diff: f32) -> bool; - -"#, - r#" -/// Returns a vector with a length no less than `min` and no more than `max`. -/// # Panics -/// Will panic if `min` is greater than `max`, or if either `min` or `max` is negative, when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length(self, min: f32, max: f32) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns a vector with a length no more than `max`. -/// # Panics -/// Will panic if `max` is negative when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length_max(self, max: f32) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns a vector with a length no less than `min`. -/// # Panics -/// Will panic if `min` is negative when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length_min(self, min: f32) -> bevy::math::Vec3A; - -"#, - r#" -/// Fused multiply-add. Computes `(self * a) + b` element-wise with only one rounding -/// error, yielding a more accurate result than an unfused multiply-add. -/// Using `mul_add` *may* be more performant than an unfused multiply-add if the target -/// architecture has a dedicated fma CPU instruction. However, this is not always true, -/// and will be heavily dependant on designing algorithms with specific target hardware in -/// mind. - - #[lua(kind = "Method", output(proxy))] - fn mul_add( - self, - #[proxy] - a: bevy::math::Vec3A, - #[proxy] - b: bevy::math::Vec3A, - ) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns the reflection vector for a given incident vector `self` and surface normal -/// `normal`. -/// `normal` must be normalized. -/// # Panics -/// Will panic if `normal` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reflect(self, #[proxy] normal: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns the refraction direction for a given incident vector `self`, surface normal -/// `normal` and ratio of indices of refraction, `eta`. When total internal reflection occurs, -/// a zero vector will be returned. -/// `self` and `normal` must be normalized. -/// # Panics -/// Will panic if `self` or `normal` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn refract(self, #[proxy] normal: bevy::math::Vec3A, eta: f32) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns the angle (in radians) between two vectors in the range `[0, +π]`. -/// The inputs do not need to be unit vectors however they must be non-zero. - - #[lua(kind = "Method")] - fn angle_between(self, #[proxy] rhs: bevy::math::Vec3A) -> f32; - -"#, - r#" -/// Returns some vector that is orthogonal to the given one. -/// The input vector must be finite and non-zero. -/// The output vector is not necessarily unit length. For that use -/// [`Self::any_orthonormal_vector()`] instead. - - #[lua(kind = "Method", output(proxy))] - fn any_orthogonal_vector(&self) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns any unit vector that is orthogonal to the given one. -/// The input vector must be unit length. -/// # Panics -/// Will panic if `self` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn any_orthonormal_vector(&self) -> bevy::math::Vec3A; - -"#, - r#" -/// Casts all elements of `self` to `f64`. - - #[lua(kind = "Method", output(proxy))] - fn as_dvec3(&self) -> bevy::math::DVec3; - -"#, - r#" -/// Casts all elements of `self` to `i32`. - - #[lua(kind = "Method", output(proxy))] - fn as_ivec3(&self) -> bevy::math::IVec3; - -"#, - r#" -/// Casts all elements of `self` to `u32`. - - #[lua(kind = "Method", output(proxy))] - fn as_uvec3(&self) -> bevy::math::UVec3; - -"#, - r#" -/// Casts all elements of `self` to `i64`. - - #[lua(kind = "Method", output(proxy))] - fn as_i64vec3(&self) -> bevy::math::I64Vec3; - -"#, - r#" -/// Casts all elements of `self` to `u64`. - - #[lua(kind = "Method", output(proxy))] - fn as_u64vec3(&self) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::Vec3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: f32) -> bevy::math::Vec3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: f32) -> bevy::math::Vec3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: f32) -> bevy::math::Vec3A; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind="MetaMethod", raw , metamethod="Index")] -fn index(&self, lua: &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(self.inner()?[*idx]) -} -"#, - r#" -#[lua(kind="MutatingMetaMethod", raw, metamethod="NewIndex")] -fn index(&mut self, lua: &Lua, idx: crate::lua::util::LuaIndex, val: f32) -> Result<(),_> { - self.val_mut(|s| Ok(s[*idx] = val))? -} -"#] -)] -struct Vec3A(); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::Vec4", - functions[r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::Vec4) -> bevy::math::Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: f32) -> bevy::math::Vec4; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: f32) -> bevy::math::Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] rhs: &glam::Vec4) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f32) -> bevy::math::Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::Vec4) -> bevy::math::Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: f32) -> bevy::math::Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::Vec4) -> bevy::math::Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::Vec4) -> bevy::math::Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::Vec4; - -"#, - r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: f32, y: f32, z: f32, w: f32) -> bevy::math::Vec4; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: f32) -> bevy::math::Vec4; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec4A, - #[proxy] - if_true: bevy::math::Vec4, - #[proxy] - if_false: bevy::math::Vec4, - ) -> bevy::math::Vec4; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [f32; 4]) -> bevy::math::Vec4; - -"#, - r#" -/// `[x, y, z, w]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [f32; 4]; - -"#, - r#" -/// Creates a 3D vector from the `x`, `y` and `z` elements of `self`, discarding `w`. -/// Truncation to [`Vec3`] may also be performed by using [`self.xyz()`][crate::swizzles::Vec4Swizzles::xyz()]. -/// To truncate to [`Vec3A`] use [`Vec3A::from()`]. - - #[lua(kind = "Method", output(proxy))] - fn truncate(self) -> bevy::math::Vec3; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: f32) -> bevy::math::Vec4; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: f32) -> bevy::math::Vec4; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `z`. - - #[lua(kind = "Method", output(proxy))] - fn with_z(self, z: f32) -> bevy::math::Vec4; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `w`. - - #[lua(kind = "Method", output(proxy))] - fn with_w(self, w: f32) -> bevy::math::Vec4; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::Vec4) -> f32; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" -/// Component-wise clamping of values, similar to [`f32::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::Vec4, - #[proxy] - max: bevy::math::Vec4, - ) -> bevy::math::Vec4; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> f32; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> f32; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> f32; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> f32; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::BVec4A; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::BVec4A; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::BVec4A; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::BVec4A; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::BVec4A; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::BVec4A; - -"#, - r#" -/// Returns a vector containing the absolute value of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn abs(self) -> bevy::math::Vec4; - -"#, - r#" -/// Returns a vector with elements representing the sign of `self`. -/// - `1.0` if the number is positive, `+0.0` or `INFINITY` -/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` -/// - `NAN` if the number is `NAN` - - #[lua(kind = "Method", output(proxy))] - fn signum(self) -> bevy::math::Vec4; - -"#, - r#" -/// Returns a vector with signs of `rhs` and the magnitudes of `self`. - - #[lua(kind = "Method", output(proxy))] - fn copysign(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" -/// Returns a bitmask with the lowest 4 bits set to the sign bits from the elements of `self`. -/// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes -/// into the first lowest bit, element `y` into the second, etc. - - #[lua(kind = "Method")] - fn is_negative_bitmask(self) -> u32; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. If any element is either -/// `NaN`, positive or negative infinity, this will return `false`. - - #[lua(kind = "Method")] - fn is_finite(self) -> bool; - -"#, - r#" -/// Performs `is_finite` on each element of self, returning a vector mask of the results. -/// In other words, this computes `[x.is_finite(), y.is_finite(), ...]`. - - #[lua(kind = "Method", output(proxy))] - fn is_finite_mask(self) -> bevy::math::BVec4A; - -"#, - r#" -/// Returns `true` if any elements are `NaN`. - - #[lua(kind = "Method")] - fn is_nan(self) -> bool; - -"#, - r#" -/// Performs `is_nan` on each element of self, returning a vector mask of the results. -/// In other words, this computes `[x.is_nan(), y.is_nan(), ...]`. - - #[lua(kind = "Method", output(proxy))] - fn is_nan_mask(self) -> bevy::math::BVec4A; - -"#, - r#" -/// Computes the length of `self`. - - #[lua(kind = "Method")] - fn length(self) -> f32; - -"#, - r#" -/// Computes the squared length of `self`. -/// This is faster than `length()` as it avoids a square root operation. - - #[lua(kind = "Method")] - fn length_squared(self) -> f32; - -"#, - r#" -/// Computes `1.0 / length()`. -/// For valid results, `self` must _not_ be of length zero. - - #[lua(kind = "Method")] - fn length_recip(self) -> f32; - -"#, - r#" -/// Computes the Euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance(self, #[proxy] rhs: bevy::math::Vec4) -> f32; - -"#, - r#" -/// Compute the squared euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance_squared(self, #[proxy] rhs: bevy::math::Vec4) -> f32; - -"#, - r#" -/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn div_euclid(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" -/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. -/// [Euclidean division]: f32::rem_euclid - - #[lua(kind = "Method", output(proxy))] - fn rem_euclid(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" -/// Returns `self` normalized to length 1.0. -/// For valid results, `self` must be finite and _not_ of length zero, nor very close to zero. -/// See also [`Self::try_normalize()`] and [`Self::normalize_or_zero()`]. -/// Panics -/// Will panic if the resulting normalized vector is not finite when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn normalize(self) -> bevy::math::Vec4; - -"#, - r#" -/// Returns `self` normalized to length 1.0 if possible, else returns a -/// fallback value. -/// In particular, if the input is zero (or very close to zero), or non-finite, -/// the result of this operation will be the fallback value. -/// See also [`Self::try_normalize()`]. - - #[lua(kind = "Method", output(proxy))] - fn normalize_or(self, #[proxy] fallback: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" -/// Returns `self` normalized to length 1.0 if possible, else returns zero. -/// In particular, if the input is zero (or very close to zero), or non-finite, -/// the result of this operation will be zero. -/// See also [`Self::try_normalize()`]. - - #[lua(kind = "Method", output(proxy))] - fn normalize_or_zero(self) -> bevy::math::Vec4; - -"#, - r#" -/// Returns whether `self` is length `1.0` or not. -/// Uses a precision threshold of approximately `1e-4`. - - #[lua(kind = "Method")] - fn is_normalized(self) -> bool; - -"#, - r#" -/// Returns the vector projection of `self` onto `rhs`. -/// `rhs` must be of non-zero length. -/// # Panics -/// Will panic if `rhs` is zero length when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn project_onto(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" -/// Returns the vector rejection of `self` from `rhs`. -/// The vector rejection is the vector perpendicular to the projection of `self` onto -/// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`. -/// `rhs` must be of non-zero length. -/// # Panics -/// Will panic if `rhs` has a length of zero when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reject_from(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" -/// Returns the vector projection of `self` onto `rhs`. -/// `rhs` must be normalized. -/// # Panics -/// Will panic if `rhs` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn project_onto_normalized(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" -/// Returns the vector rejection of `self` from `rhs`. -/// The vector rejection is the vector perpendicular to the projection of `self` onto -/// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`. -/// `rhs` must be normalized. -/// # Panics -/// Will panic if `rhs` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reject_from_normalized(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" -/// Returns a vector containing the nearest integer to a number for each element of `self`. -/// Round half-way cases away from 0.0. - - #[lua(kind = "Method", output(proxy))] - fn round(self) -> bevy::math::Vec4; - -"#, - r#" -/// Returns a vector containing the largest integer less than or equal to a number for each -/// element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn floor(self) -> bevy::math::Vec4; - -"#, - r#" -/// Returns a vector containing the smallest integer greater than or equal to a number for -/// each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn ceil(self) -> bevy::math::Vec4; - -"#, - r#" -/// Returns a vector containing the integer part each element of `self`. This means numbers are -/// always truncated towards zero. - - #[lua(kind = "Method", output(proxy))] - fn trunc(self) -> bevy::math::Vec4; - -"#, - r#" -/// Returns a vector containing the fractional part of the vector as `self - self.trunc()`. -/// Note that this differs from the GLSL implementation of `fract` which returns -/// `self - self.floor()`. -/// Note that this is fast but not precise for large numbers. - - #[lua(kind = "Method", output(proxy))] - fn fract(self) -> bevy::math::Vec4; - -"#, - r#" -/// Returns a vector containing the fractional part of the vector as `self - self.floor()`. -/// Note that this differs from the Rust implementation of `fract` which returns -/// `self - self.trunc()`. -/// Note that this is fast but not precise for large numbers. - - #[lua(kind = "Method", output(proxy))] - fn fract_gl(self) -> bevy::math::Vec4; - -"#, - r#" -/// Returns a vector containing `e^self` (the exponential function) for each element of -/// `self`. - - #[lua(kind = "Method", output(proxy))] - fn exp(self) -> bevy::math::Vec4; - -"#, - r#" -/// Returns a vector containing each element of `self` raised to the power of `n`. - - #[lua(kind = "Method", output(proxy))] - fn powf(self, n: f32) -> bevy::math::Vec4; - -"#, - r#" -/// Returns a vector containing the reciprocal `1.0/n` of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn recip(self) -> bevy::math::Vec4; - -"#, - r#" -/// Performs a linear interpolation between `self` and `rhs` based on the value `s`. -/// When `s` is `0.0`, the result will be equal to `self`. When `s` is `1.0`, the result -/// will be equal to `rhs`. When `s` is outside of range `[0, 1]`, the result is linearly -/// extrapolated. - - #[lua(kind = "Method", output(proxy))] - fn lerp(self, #[proxy] rhs: bevy::math::Vec4, s: f32) -> bevy::math::Vec4; - -"#, - r#" -/// Moves towards `rhs` based on the value `d`. -/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to -/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn move_towards(&self, #[proxy] rhs: bevy::math::Vec4, d: f32) -> bevy::math::Vec4; - -"#, - r#" -/// Calculates the midpoint between `self` and `rhs`. -/// The midpoint is the average of, or halfway point between, two vectors. -/// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)` -/// while being slightly cheaper to compute. - - #[lua(kind = "Method", output(proxy))] - fn midpoint(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` is -/// less than or equal to `max_abs_diff`. -/// This can be used to compare if two vectors contain similar elements. It works best when -/// comparing with a known value. The `max_abs_diff` that should be used used depends on -/// the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(self, #[proxy] rhs: bevy::math::Vec4, max_abs_diff: f32) -> bool; - -"#, - r#" -/// Returns a vector with a length no less than `min` and no more than `max`. -/// # Panics -/// Will panic if `min` is greater than `max`, or if either `min` or `max` is negative, when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length(self, min: f32, max: f32) -> bevy::math::Vec4; - -"#, - r#" -/// Returns a vector with a length no more than `max`. -/// # Panics -/// Will panic if `max` is negative when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length_max(self, max: f32) -> bevy::math::Vec4; - -"#, - r#" -/// Returns a vector with a length no less than `min`. -/// # Panics -/// Will panic if `min` is negative when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length_min(self, min: f32) -> bevy::math::Vec4; - -"#, - r#" -/// Fused multiply-add. Computes `(self * a) + b` element-wise with only one rounding -/// error, yielding a more accurate result than an unfused multiply-add. -/// Using `mul_add` *may* be more performant than an unfused multiply-add if the target -/// architecture has a dedicated fma CPU instruction. However, this is not always true, -/// and will be heavily dependant on designing algorithms with specific target hardware in -/// mind. - - #[lua(kind = "Method", output(proxy))] - fn mul_add( - self, - #[proxy] - a: bevy::math::Vec4, - #[proxy] - b: bevy::math::Vec4, - ) -> bevy::math::Vec4; - -"#, - r#" -/// Returns the reflection vector for a given incident vector `self` and surface normal -/// `normal`. -/// `normal` must be normalized. -/// # Panics -/// Will panic if `normal` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reflect(self, #[proxy] normal: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" -/// Returns the refraction direction for a given incident vector `self`, surface normal -/// `normal` and ratio of indices of refraction, `eta`. When total internal reflection occurs, -/// a zero vector will be returned. -/// `self` and `normal` must be normalized. -/// # Panics -/// Will panic if `self` or `normal` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn refract(self, #[proxy] normal: bevy::math::Vec4, eta: f32) -> bevy::math::Vec4; - -"#, - r#" -/// Casts all elements of `self` to `f64`. - - #[lua(kind = "Method", output(proxy))] - fn as_dvec4(&self) -> bevy::math::DVec4; - -"#, - r#" -/// Casts all elements of `self` to `i32`. - - #[lua(kind = "Method", output(proxy))] - fn as_ivec4(&self) -> bevy::math::IVec4; - -"#, - r#" -/// Casts all elements of `self` to `u32`. - - #[lua(kind = "Method", output(proxy))] - fn as_uvec4(&self) -> bevy::math::UVec4; - -"#, - r#" -/// Casts all elements of `self` to `i64`. - - #[lua(kind = "Method", output(proxy))] - fn as_i64vec4(&self) -> bevy::math::I64Vec4; - -"#, - r#" -/// Casts all elements of `self` to `u64`. - - #[lua(kind = "Method", output(proxy))] - fn as_u64vec4(&self) -> bevy::math::U64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: f32) -> bevy::math::Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::Vec4) -> bevy::math::Vec4; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind="MetaMethod", raw , metamethod="Index")] -fn index(&self, lua: &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(self.inner()?[*idx]) -} -"#, - r#" -#[lua(kind="MutatingMetaMethod", raw, metamethod="NewIndex")] -fn index(&mut self, lua: &Lua, idx: crate::lua::util::LuaIndex, val: f32) -> Result<(),_> { - self.val_mut(|s| Ok(s[*idx] = val))? -} -"#] -)] -struct Vec4(); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::BVec2", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::BVec2) -> bool; - -"#, - r#" -/// Creates a new vector mask. - - #[lua(kind = "Function", output(proxy))] - fn new(x: bool, y: bool) -> bevy::math::BVec2; - -"#, - r#" -/// Creates a vector mask with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: bool) -> bevy::math::BVec2; - -"#, - r#" -/// Creates a new vector mask from a bool array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [bool; 2]) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a bitmask with the lowest 2 bits set from the elements of `self`. -/// A true element results in a `1` bit and a false element in a `0` bit. Element `x` goes -/// into the first lowest bit, element `y` into the second, etc. - - #[lua(kind = "Method")] - fn bitmask(self) -> u32; - -"#, - r#" -/// Returns true if any of the elements are true, false otherwise. - - #[lua(kind = "Method")] - fn any(self) -> bool; - -"#, - r#" -/// Returns true if all the elements are true, false otherwise. - - #[lua(kind = "Method")] - fn all(self) -> bool; - -"#, - r#" -/// Tests the value at `index`. -/// Panics if `index` is greater than 1. - - #[lua(kind = "Method")] - fn test(&self, index: usize) -> bool; - -"#, - r#" -/// Sets the element at `index`. -/// Panics if `index` is greater than 1. - - #[lua(kind = "MutatingMethod")] - fn set(&mut self, index: usize, value: bool) -> (); - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::BVec2; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct BVec2 { - x: bool, - y: bool, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::BVec3", - functions[r#" -/// Creates a new vector mask. - - #[lua(kind = "Function", output(proxy))] - fn new(x: bool, y: bool, z: bool) -> bevy::math::BVec3; - -"#, - r#" -/// Creates a vector mask with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: bool) -> bevy::math::BVec3; - -"#, - r#" -/// Creates a new vector mask from a bool array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [bool; 3]) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a bitmask with the lowest 3 bits set from the elements of `self`. -/// A true element results in a `1` bit and a false element in a `0` bit. Element `x` goes -/// into the first lowest bit, element `y` into the second, etc. - - #[lua(kind = "Method")] - fn bitmask(self) -> u32; - -"#, - r#" -/// Returns true if any of the elements are true, false otherwise. - - #[lua(kind = "Method")] - fn any(self) -> bool; - -"#, - r#" -/// Returns true if all the elements are true, false otherwise. - - #[lua(kind = "Method")] - fn all(self) -> bool; - -"#, - r#" -/// Tests the value at `index`. -/// Panics if `index` is greater than 2. - - #[lua(kind = "Method")] - fn test(&self, index: usize) -> bool; - -"#, - r#" -/// Sets the element at `index`. -/// Panics if `index` is greater than 2. - - #[lua(kind = "MutatingMethod")] - fn set(&mut self, index: usize, value: bool) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::BVec3) -> bool; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::BVec3; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct BVec3 { - x: bool, - y: bool, - z: bool, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::BVec4", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::BVec4) -> bool; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::BVec4; - -"#, - r#" -/// Creates a new vector mask. - - #[lua(kind = "Function", output(proxy))] - fn new(x: bool, y: bool, z: bool, w: bool) -> bevy::math::BVec4; - -"#, - r#" -/// Creates a vector mask with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: bool) -> bevy::math::BVec4; - -"#, - r#" -/// Creates a new vector mask from a bool array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [bool; 4]) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a bitmask with the lowest 4 bits set from the elements of `self`. -/// A true element results in a `1` bit and a false element in a `0` bit. Element `x` goes -/// into the first lowest bit, element `y` into the second, etc. - - #[lua(kind = "Method")] - fn bitmask(self) -> u32; - -"#, - r#" -/// Returns true if any of the elements are true, false otherwise. - - #[lua(kind = "Method")] - fn any(self) -> bool; - -"#, - r#" -/// Returns true if all the elements are true, false otherwise. - - #[lua(kind = "Method")] - fn all(self) -> bool; - -"#, - r#" -/// Tests the value at `index`. -/// Panics if `index` is greater than 3. - - #[lua(kind = "Method")] - fn test(&self, index: usize) -> bool; - -"#, - r#" -/// Sets the element at `index`. -/// Panics if `index` is greater than 3. - - #[lua(kind = "MutatingMethod")] - fn set(&mut self, index: usize, value: bool) -> (); - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct BVec4 { - x: bool, - y: bool, - z: bool, - w: bool, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::DVec2", - functions[r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: f64) -> bevy::math::DVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::DVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::DVec2) -> bevy::math::DVec2; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::DVec2) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: f64) -> bevy::math::DVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f64) -> bevy::math::DVec2; - -"#, - r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: f64, y: f64) -> bevy::math::DVec2; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: f64) -> bevy::math::DVec2; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec2, - #[proxy] - if_true: bevy::math::DVec2, - #[proxy] - if_false: bevy::math::DVec2, - ) -> bevy::math::DVec2; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [f64; 2]) -> bevy::math::DVec2; - -"#, - r#" -/// `[x, y]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [f64; 2]; - -"#, - r#" -/// Creates a 3D vector from `self` and the given `z` value. - - #[lua(kind = "Method", output(proxy))] - fn extend(self, z: f64) -> bevy::math::DVec3; - -"#, - r#" -/// Creates a 2D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: f64) -> bevy::math::DVec2; - -"#, - r#" -/// Creates a 2D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: f64) -> bevy::math::DVec2; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::DVec2) -> f64; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" -/// Component-wise clamping of values, similar to [`f64::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::DVec2, - #[proxy] - max: bevy::math::DVec2, - ) -> bevy::math::DVec2; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> f64; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> f64; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> f64; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> f64; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::BVec2; - -"#, - r#" -/// Returns a vector containing the absolute value of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn abs(self) -> bevy::math::DVec2; - -"#, - r#" -/// Returns a vector with elements representing the sign of `self`. -/// - `1.0` if the number is positive, `+0.0` or `INFINITY` -/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` -/// - `NAN` if the number is `NAN` - - #[lua(kind = "Method", output(proxy))] - fn signum(self) -> bevy::math::DVec2; - -"#, - r#" -/// Returns a vector with signs of `rhs` and the magnitudes of `self`. - - #[lua(kind = "Method", output(proxy))] - fn copysign(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" -/// Returns a bitmask with the lowest 2 bits set to the sign bits from the elements of `self`. -/// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes -/// into the first lowest bit, element `y` into the second, etc. - - #[lua(kind = "Method")] - fn is_negative_bitmask(self) -> u32; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. If any element is either -/// `NaN`, positive or negative infinity, this will return `false`. - - #[lua(kind = "Method")] - fn is_finite(self) -> bool; - -"#, - r#" -/// Performs `is_finite` on each element of self, returning a vector mask of the results. -/// In other words, this computes `[x.is_finite(), y.is_finite(), ...]`. - - #[lua(kind = "Method", output(proxy))] - fn is_finite_mask(self) -> bevy::math::BVec2; - -"#, - r#" -/// Returns `true` if any elements are `NaN`. - - #[lua(kind = "Method")] - fn is_nan(self) -> bool; - -"#, - r#" -/// Performs `is_nan` on each element of self, returning a vector mask of the results. -/// In other words, this computes `[x.is_nan(), y.is_nan(), ...]`. - - #[lua(kind = "Method", output(proxy))] - fn is_nan_mask(self) -> bevy::math::BVec2; - -"#, - r#" -/// Computes the length of `self`. - - #[lua(kind = "Method")] - fn length(self) -> f64; - -"#, - r#" -/// Computes the squared length of `self`. -/// This is faster than `length()` as it avoids a square root operation. - - #[lua(kind = "Method")] - fn length_squared(self) -> f64; - -"#, - r#" -/// Computes `1.0 / length()`. -/// For valid results, `self` must _not_ be of length zero. - - #[lua(kind = "Method")] - fn length_recip(self) -> f64; - -"#, - r#" -/// Computes the Euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance(self, #[proxy] rhs: bevy::math::DVec2) -> f64; - -"#, - r#" -/// Compute the squared euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance_squared(self, #[proxy] rhs: bevy::math::DVec2) -> f64; - -"#, - r#" -/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn div_euclid(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" -/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. -/// [Euclidean division]: f64::rem_euclid - - #[lua(kind = "Method", output(proxy))] - fn rem_euclid(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" -/// Returns `self` normalized to length 1.0. -/// For valid results, `self` must be finite and _not_ of length zero, nor very close to zero. -/// See also [`Self::try_normalize()`] and [`Self::normalize_or_zero()`]. -/// Panics -/// Will panic if the resulting normalized vector is not finite when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn normalize(self) -> bevy::math::DVec2; - -"#, - r#" -/// Returns `self` normalized to length 1.0 if possible, else returns a -/// fallback value. -/// In particular, if the input is zero (or very close to zero), or non-finite, -/// the result of this operation will be the fallback value. -/// See also [`Self::try_normalize()`]. - - #[lua(kind = "Method", output(proxy))] - fn normalize_or(self, #[proxy] fallback: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" -/// Returns `self` normalized to length 1.0 if possible, else returns zero. -/// In particular, if the input is zero (or very close to zero), or non-finite, -/// the result of this operation will be zero. -/// See also [`Self::try_normalize()`]. - - #[lua(kind = "Method", output(proxy))] - fn normalize_or_zero(self) -> bevy::math::DVec2; - -"#, - r#" -/// Returns whether `self` is length `1.0` or not. -/// Uses a precision threshold of approximately `1e-4`. - - #[lua(kind = "Method")] - fn is_normalized(self) -> bool; - -"#, - r#" -/// Returns the vector projection of `self` onto `rhs`. -/// `rhs` must be of non-zero length. -/// # Panics -/// Will panic if `rhs` is zero length when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn project_onto(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" -/// Returns the vector rejection of `self` from `rhs`. -/// The vector rejection is the vector perpendicular to the projection of `self` onto -/// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`. -/// `rhs` must be of non-zero length. -/// # Panics -/// Will panic if `rhs` has a length of zero when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reject_from(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" -/// Returns the vector projection of `self` onto `rhs`. -/// `rhs` must be normalized. -/// # Panics -/// Will panic if `rhs` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn project_onto_normalized( - self, - #[proxy] - rhs: bevy::math::DVec2, - ) -> bevy::math::DVec2; - -"#, - r#" -/// Returns the vector rejection of `self` from `rhs`. -/// The vector rejection is the vector perpendicular to the projection of `self` onto -/// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`. -/// `rhs` must be normalized. -/// # Panics -/// Will panic if `rhs` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reject_from_normalized( - self, - #[proxy] - rhs: bevy::math::DVec2, - ) -> bevy::math::DVec2; - -"#, - r#" -/// Returns a vector containing the nearest integer to a number for each element of `self`. -/// Round half-way cases away from 0.0. - - #[lua(kind = "Method", output(proxy))] - fn round(self) -> bevy::math::DVec2; - -"#, - r#" -/// Returns a vector containing the largest integer less than or equal to a number for each -/// element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn floor(self) -> bevy::math::DVec2; - -"#, - r#" -/// Returns a vector containing the smallest integer greater than or equal to a number for -/// each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn ceil(self) -> bevy::math::DVec2; - -"#, - r#" -/// Returns a vector containing the integer part each element of `self`. This means numbers are -/// always truncated towards zero. - - #[lua(kind = "Method", output(proxy))] - fn trunc(self) -> bevy::math::DVec2; - -"#, - r#" -/// Returns a vector containing the fractional part of the vector as `self - self.trunc()`. -/// Note that this differs from the GLSL implementation of `fract` which returns -/// `self - self.floor()`. -/// Note that this is fast but not precise for large numbers. - - #[lua(kind = "Method", output(proxy))] - fn fract(self) -> bevy::math::DVec2; - -"#, - r#" -/// Returns a vector containing the fractional part of the vector as `self - self.floor()`. -/// Note that this differs from the Rust implementation of `fract` which returns -/// `self - self.trunc()`. -/// Note that this is fast but not precise for large numbers. - - #[lua(kind = "Method", output(proxy))] - fn fract_gl(self) -> bevy::math::DVec2; - -"#, - r#" -/// Returns a vector containing `e^self` (the exponential function) for each element of -/// `self`. - - #[lua(kind = "Method", output(proxy))] - fn exp(self) -> bevy::math::DVec2; - -"#, - r#" -/// Returns a vector containing each element of `self` raised to the power of `n`. - - #[lua(kind = "Method", output(proxy))] - fn powf(self, n: f64) -> bevy::math::DVec2; - -"#, - r#" -/// Returns a vector containing the reciprocal `1.0/n` of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn recip(self) -> bevy::math::DVec2; - -"#, - r#" -/// Performs a linear interpolation between `self` and `rhs` based on the value `s`. -/// When `s` is `0.0`, the result will be equal to `self`. When `s` is `1.0`, the result -/// will be equal to `rhs`. When `s` is outside of range `[0, 1]`, the result is linearly -/// extrapolated. - - #[lua(kind = "Method", output(proxy))] - fn lerp(self, #[proxy] rhs: bevy::math::DVec2, s: f64) -> bevy::math::DVec2; - -"#, - r#" -/// Moves towards `rhs` based on the value `d`. -/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to -/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn move_towards(&self, #[proxy] rhs: bevy::math::DVec2, d: f64) -> bevy::math::DVec2; - -"#, - r#" -/// Calculates the midpoint between `self` and `rhs`. -/// The midpoint is the average of, or halfway point between, two vectors. -/// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)` -/// while being slightly cheaper to compute. - - #[lua(kind = "Method", output(proxy))] - fn midpoint(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` is -/// less than or equal to `max_abs_diff`. -/// This can be used to compare if two vectors contain similar elements. It works best when -/// comparing with a known value. The `max_abs_diff` that should be used used depends on -/// the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(self, #[proxy] rhs: bevy::math::DVec2, max_abs_diff: f64) -> bool; - -"#, - r#" -/// Returns a vector with a length no less than `min` and no more than `max`. -/// # Panics -/// Will panic if `min` is greater than `max`, or if either `min` or `max` is negative, when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length(self, min: f64, max: f64) -> bevy::math::DVec2; - -"#, - r#" -/// Returns a vector with a length no more than `max`. -/// # Panics -/// Will panic if `max` is negative when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length_max(self, max: f64) -> bevy::math::DVec2; - -"#, - r#" -/// Returns a vector with a length no less than `min`. -/// # Panics -/// Will panic if `min` is negative when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length_min(self, min: f64) -> bevy::math::DVec2; - -"#, - r#" -/// Fused multiply-add. Computes `(self * a) + b` element-wise with only one rounding -/// error, yielding a more accurate result than an unfused multiply-add. -/// Using `mul_add` *may* be more performant than an unfused multiply-add if the target -/// architecture has a dedicated fma CPU instruction. However, this is not always true, -/// and will be heavily dependant on designing algorithms with specific target hardware in -/// mind. - - #[lua(kind = "Method", output(proxy))] - fn mul_add( - self, - #[proxy] - a: bevy::math::DVec2, - #[proxy] - b: bevy::math::DVec2, - ) -> bevy::math::DVec2; - -"#, - r#" -/// Returns the reflection vector for a given incident vector `self` and surface normal -/// `normal`. -/// `normal` must be normalized. -/// # Panics -/// Will panic if `normal` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reflect(self, #[proxy] normal: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" -/// Returns the refraction direction for a given incident vector `self`, surface normal -/// `normal` and ratio of indices of refraction, `eta`. When total internal reflection occurs, -/// a zero vector will be returned. -/// `self` and `normal` must be normalized. -/// # Panics -/// Will panic if `self` or `normal` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn refract(self, #[proxy] normal: bevy::math::DVec2, eta: f64) -> bevy::math::DVec2; - -"#, - r#" -/// Creates a 2D vector containing `[angle.cos(), angle.sin()]`. This can be used in -/// conjunction with the [`rotate()`][Self::rotate()] method, e.g. -/// `DVec2::from_angle(PI).rotate(DVec2::Y)` will create the vector `[-1, 0]` -/// and rotate [`DVec2::Y`] around it returning `-DVec2::Y`. - - #[lua(kind = "Function", output(proxy))] - fn from_angle(angle: f64) -> bevy::math::DVec2; - -"#, - r#" -/// Returns the angle (in radians) of this vector in the range `[-π, +π]`. -/// The input does not need to be a unit vector however it must be non-zero. - - #[lua(kind = "Method")] - fn to_angle(self) -> f64; - -"#, - r#" - - #[lua(kind = "Method")] - fn angle_between(self, #[proxy] rhs: bevy::math::DVec2) -> f64; - -"#, - r#" -/// Returns the angle of rotation (in radians) from `self` to `rhs` in the range `[-π, +π]`. -/// The inputs do not need to be unit vectors however they must be non-zero. - - #[lua(kind = "Method")] - fn angle_to(self, #[proxy] rhs: bevy::math::DVec2) -> f64; - -"#, - r#" -/// Returns a vector that is equal to `self` rotated by 90 degrees. - - #[lua(kind = "Method", output(proxy))] - fn perp(self) -> bevy::math::DVec2; - -"#, - r#" -/// The perpendicular dot product of `self` and `rhs`. -/// Also known as the wedge product, 2D cross product, and determinant. - - #[lua(kind = "Method")] - fn perp_dot(self, #[proxy] rhs: bevy::math::DVec2) -> f64; - -"#, - r#" -/// Returns `rhs` rotated by the angle of `self`. If `self` is normalized, -/// then this just rotation. This is what you usually want. Otherwise, -/// it will be like a rotation with a multiplication by `self`'s length. - - #[lua(kind = "Method", output(proxy))] - fn rotate(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" -/// Rotates towards `rhs` up to `max_angle` (in radians). -/// When `max_angle` is `0.0`, the result will be equal to `self`. When `max_angle` is equal to -/// `self.angle_between(rhs)`, the result will be equal to `rhs`. If `max_angle` is negative, -/// rotates towards the exact opposite of `rhs`. Will not go past the target. - - #[lua(kind = "Method", output(proxy))] - fn rotate_towards( - &self, - #[proxy] - rhs: bevy::math::DVec2, - max_angle: f64, - ) -> bevy::math::DVec2; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec2(&self) -> bevy::math::Vec2; - -"#, - r#" -/// Casts all elements of `self` to `i32`. - - #[lua(kind = "Method", output(proxy))] - fn as_ivec2(&self) -> bevy::math::IVec2; - -"#, - r#" -/// Casts all elements of `self` to `u32`. - - #[lua(kind = "Method", output(proxy))] - fn as_uvec2(&self) -> bevy::math::UVec2; - -"#, - r#" -/// Casts all elements of `self` to `i64`. - - #[lua(kind = "Method", output(proxy))] - fn as_i64vec2(&self) -> bevy::math::I64Vec2; - -"#, - r#" -/// Casts all elements of `self` to `u64`. - - #[lua(kind = "Method", output(proxy))] - fn as_u64vec2(&self) -> bevy::math::U64Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::DVec2) -> bevy::math::DVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::DVec2) -> bevy::math::DVec2; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::DVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: f64) -> bevy::math::DVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: f64) -> bevy::math::DVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::DVec2) -> bevy::math::DVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::DVec2) -> bevy::math::DVec2; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind="MetaMethod", raw , metamethod="Index")] -fn index(&self, lua: &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(self.inner()?[*idx]) -} -"#, - r#" -#[lua(kind="MutatingMetaMethod", raw, metamethod="NewIndex")] -fn index(&mut self, lua: &Lua, idx: crate::lua::util::LuaIndex, val: f64) -> Result<(),_> { - self.val_mut(|s| Ok(s[*idx] = val))? -} -"#] -)] -struct DVec2 { - x: f64, - y: f64, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::DVec3", - functions[r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: f64) -> bevy::math::DVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: f64) -> bevy::math::DVec3; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::DVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::DVec3) -> bevy::math::DVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::DVec3) -> bevy::math::DVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: f64) -> bevy::math::DVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f64) -> bevy::math::DVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: f64) -> bevy::math::DVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::DVec3) -> bevy::math::DVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::DVec3) -> bevy::math::DVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::DVec3) -> bevy::math::DVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: f64, y: f64, z: f64) -> bevy::math::DVec3; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: f64) -> bevy::math::DVec3; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec3, - #[proxy] - if_true: bevy::math::DVec3, - #[proxy] - if_false: bevy::math::DVec3, - ) -> bevy::math::DVec3; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [f64; 3]) -> bevy::math::DVec3; - -"#, - r#" -/// `[x, y, z]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [f64; 3]; - -"#, - r#" -/// Creates a 4D vector from `self` and the given `w` value. - - #[lua(kind = "Method", output(proxy))] - fn extend(self, w: f64) -> bevy::math::DVec4; - -"#, - r#" -/// Creates a 2D vector from the `x` and `y` elements of `self`, discarding `z`. -/// Truncation may also be performed by using [`self.xy()`][crate::swizzles::Vec3Swizzles::xy()]. - - #[lua(kind = "Method", output(proxy))] - fn truncate(self) -> bevy::math::DVec2; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: f64) -> bevy::math::DVec3; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: f64) -> bevy::math::DVec3; - -"#, - r#" -/// Creates a 3D vector from `self` with the given value of `z`. - - #[lua(kind = "Method", output(proxy))] - fn with_z(self, z: f64) -> bevy::math::DVec3; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::DVec3) -> f64; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Computes the cross product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn cross(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Component-wise clamping of values, similar to [`f64::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::DVec3, - #[proxy] - max: bevy::math::DVec3, - ) -> bevy::math::DVec3; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> f64; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> f64; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> f64; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> f64; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::BVec3; - -"#, - r#" -/// Returns a vector containing the absolute value of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn abs(self) -> bevy::math::DVec3; - -"#, - r#" -/// Returns a vector with elements representing the sign of `self`. -/// - `1.0` if the number is positive, `+0.0` or `INFINITY` -/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` -/// - `NAN` if the number is `NAN` - - #[lua(kind = "Method", output(proxy))] - fn signum(self) -> bevy::math::DVec3; - -"#, - r#" -/// Returns a vector with signs of `rhs` and the magnitudes of `self`. - - #[lua(kind = "Method", output(proxy))] - fn copysign(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Returns a bitmask with the lowest 3 bits set to the sign bits from the elements of `self`. -/// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes -/// into the first lowest bit, element `y` into the second, etc. - - #[lua(kind = "Method")] - fn is_negative_bitmask(self) -> u32; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. If any element is either -/// `NaN`, positive or negative infinity, this will return `false`. - - #[lua(kind = "Method")] - fn is_finite(self) -> bool; - -"#, - r#" -/// Performs `is_finite` on each element of self, returning a vector mask of the results. -/// In other words, this computes `[x.is_finite(), y.is_finite(), ...]`. - - #[lua(kind = "Method", output(proxy))] - fn is_finite_mask(self) -> bevy::math::BVec3; - -"#, - r#" -/// Returns `true` if any elements are `NaN`. - - #[lua(kind = "Method")] - fn is_nan(self) -> bool; - -"#, - r#" -/// Performs `is_nan` on each element of self, returning a vector mask of the results. -/// In other words, this computes `[x.is_nan(), y.is_nan(), ...]`. - - #[lua(kind = "Method", output(proxy))] - fn is_nan_mask(self) -> bevy::math::BVec3; - -"#, - r#" -/// Computes the length of `self`. - - #[lua(kind = "Method")] - fn length(self) -> f64; - -"#, - r#" -/// Computes the squared length of `self`. -/// This is faster than `length()` as it avoids a square root operation. - - #[lua(kind = "Method")] - fn length_squared(self) -> f64; - -"#, - r#" -/// Computes `1.0 / length()`. -/// For valid results, `self` must _not_ be of length zero. - - #[lua(kind = "Method")] - fn length_recip(self) -> f64; - -"#, - r#" -/// Computes the Euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance(self, #[proxy] rhs: bevy::math::DVec3) -> f64; - -"#, - r#" -/// Compute the squared euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance_squared(self, #[proxy] rhs: bevy::math::DVec3) -> f64; - -"#, - r#" -/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn div_euclid(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. -/// [Euclidean division]: f64::rem_euclid - - #[lua(kind = "Method", output(proxy))] - fn rem_euclid(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Returns `self` normalized to length 1.0. -/// For valid results, `self` must be finite and _not_ of length zero, nor very close to zero. -/// See also [`Self::try_normalize()`] and [`Self::normalize_or_zero()`]. -/// Panics -/// Will panic if the resulting normalized vector is not finite when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn normalize(self) -> bevy::math::DVec3; - -"#, - r#" -/// Returns `self` normalized to length 1.0 if possible, else returns a -/// fallback value. -/// In particular, if the input is zero (or very close to zero), or non-finite, -/// the result of this operation will be the fallback value. -/// See also [`Self::try_normalize()`]. - - #[lua(kind = "Method", output(proxy))] - fn normalize_or(self, #[proxy] fallback: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Returns `self` normalized to length 1.0 if possible, else returns zero. -/// In particular, if the input is zero (or very close to zero), or non-finite, -/// the result of this operation will be zero. -/// See also [`Self::try_normalize()`]. - - #[lua(kind = "Method", output(proxy))] - fn normalize_or_zero(self) -> bevy::math::DVec3; - -"#, - r#" -/// Returns whether `self` is length `1.0` or not. -/// Uses a precision threshold of approximately `1e-4`. - - #[lua(kind = "Method")] - fn is_normalized(self) -> bool; - -"#, - r#" -/// Returns the vector projection of `self` onto `rhs`. -/// `rhs` must be of non-zero length. -/// # Panics -/// Will panic if `rhs` is zero length when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn project_onto(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Returns the vector rejection of `self` from `rhs`. -/// The vector rejection is the vector perpendicular to the projection of `self` onto -/// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`. -/// `rhs` must be of non-zero length. -/// # Panics -/// Will panic if `rhs` has a length of zero when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reject_from(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Returns the vector projection of `self` onto `rhs`. -/// `rhs` must be normalized. -/// # Panics -/// Will panic if `rhs` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn project_onto_normalized( - self, - #[proxy] - rhs: bevy::math::DVec3, - ) -> bevy::math::DVec3; - -"#, - r#" -/// Returns the vector rejection of `self` from `rhs`. -/// The vector rejection is the vector perpendicular to the projection of `self` onto -/// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`. -/// `rhs` must be normalized. -/// # Panics -/// Will panic if `rhs` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reject_from_normalized( - self, - #[proxy] - rhs: bevy::math::DVec3, - ) -> bevy::math::DVec3; - -"#, - r#" -/// Returns a vector containing the nearest integer to a number for each element of `self`. -/// Round half-way cases away from 0.0. - - #[lua(kind = "Method", output(proxy))] - fn round(self) -> bevy::math::DVec3; - -"#, - r#" -/// Returns a vector containing the largest integer less than or equal to a number for each -/// element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn floor(self) -> bevy::math::DVec3; - -"#, - r#" -/// Returns a vector containing the smallest integer greater than or equal to a number for -/// each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn ceil(self) -> bevy::math::DVec3; - -"#, - r#" -/// Returns a vector containing the integer part each element of `self`. This means numbers are -/// always truncated towards zero. - - #[lua(kind = "Method", output(proxy))] - fn trunc(self) -> bevy::math::DVec3; - -"#, - r#" -/// Returns a vector containing the fractional part of the vector as `self - self.trunc()`. -/// Note that this differs from the GLSL implementation of `fract` which returns -/// `self - self.floor()`. -/// Note that this is fast but not precise for large numbers. - - #[lua(kind = "Method", output(proxy))] - fn fract(self) -> bevy::math::DVec3; - -"#, - r#" -/// Returns a vector containing the fractional part of the vector as `self - self.floor()`. -/// Note that this differs from the Rust implementation of `fract` which returns -/// `self - self.trunc()`. -/// Note that this is fast but not precise for large numbers. - - #[lua(kind = "Method", output(proxy))] - fn fract_gl(self) -> bevy::math::DVec3; - -"#, - r#" -/// Returns a vector containing `e^self` (the exponential function) for each element of -/// `self`. - - #[lua(kind = "Method", output(proxy))] - fn exp(self) -> bevy::math::DVec3; - -"#, - r#" -/// Returns a vector containing each element of `self` raised to the power of `n`. - - #[lua(kind = "Method", output(proxy))] - fn powf(self, n: f64) -> bevy::math::DVec3; - -"#, - r#" -/// Returns a vector containing the reciprocal `1.0/n` of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn recip(self) -> bevy::math::DVec3; - -"#, - r#" -/// Performs a linear interpolation between `self` and `rhs` based on the value `s`. -/// When `s` is `0.0`, the result will be equal to `self`. When `s` is `1.0`, the result -/// will be equal to `rhs`. When `s` is outside of range `[0, 1]`, the result is linearly -/// extrapolated. - - #[lua(kind = "Method", output(proxy))] - fn lerp(self, #[proxy] rhs: bevy::math::DVec3, s: f64) -> bevy::math::DVec3; - -"#, - r#" -/// Moves towards `rhs` based on the value `d`. -/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to -/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn move_towards(&self, #[proxy] rhs: bevy::math::DVec3, d: f64) -> bevy::math::DVec3; - -"#, - r#" -/// Calculates the midpoint between `self` and `rhs`. -/// The midpoint is the average of, or halfway point between, two vectors. -/// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)` -/// while being slightly cheaper to compute. - - #[lua(kind = "Method", output(proxy))] - fn midpoint(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` is -/// less than or equal to `max_abs_diff`. -/// This can be used to compare if two vectors contain similar elements. It works best when -/// comparing with a known value. The `max_abs_diff` that should be used used depends on -/// the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(self, #[proxy] rhs: bevy::math::DVec3, max_abs_diff: f64) -> bool; - -"#, - r#" -/// Returns a vector with a length no less than `min` and no more than `max`. -/// # Panics -/// Will panic if `min` is greater than `max`, or if either `min` or `max` is negative, when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length(self, min: f64, max: f64) -> bevy::math::DVec3; - -"#, - r#" -/// Returns a vector with a length no more than `max`. -/// # Panics -/// Will panic if `max` is negative when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length_max(self, max: f64) -> bevy::math::DVec3; - -"#, - r#" -/// Returns a vector with a length no less than `min`. -/// # Panics -/// Will panic if `min` is negative when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length_min(self, min: f64) -> bevy::math::DVec3; - -"#, - r#" -/// Fused multiply-add. Computes `(self * a) + b` element-wise with only one rounding -/// error, yielding a more accurate result than an unfused multiply-add. -/// Using `mul_add` *may* be more performant than an unfused multiply-add if the target -/// architecture has a dedicated fma CPU instruction. However, this is not always true, -/// and will be heavily dependant on designing algorithms with specific target hardware in -/// mind. - - #[lua(kind = "Method", output(proxy))] - fn mul_add( - self, - #[proxy] - a: bevy::math::DVec3, - #[proxy] - b: bevy::math::DVec3, - ) -> bevy::math::DVec3; - -"#, - r#" -/// Returns the reflection vector for a given incident vector `self` and surface normal -/// `normal`. -/// `normal` must be normalized. -/// # Panics -/// Will panic if `normal` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reflect(self, #[proxy] normal: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Returns the refraction direction for a given incident vector `self`, surface normal -/// `normal` and ratio of indices of refraction, `eta`. When total internal reflection occurs, -/// a zero vector will be returned. -/// `self` and `normal` must be normalized. -/// # Panics -/// Will panic if `self` or `normal` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn refract(self, #[proxy] normal: bevy::math::DVec3, eta: f64) -> bevy::math::DVec3; - -"#, - r#" -/// Returns the angle (in radians) between two vectors in the range `[0, +π]`. -/// The inputs do not need to be unit vectors however they must be non-zero. - - #[lua(kind = "Method")] - fn angle_between(self, #[proxy] rhs: bevy::math::DVec3) -> f64; - -"#, - r#" -/// Returns some vector that is orthogonal to the given one. -/// The input vector must be finite and non-zero. -/// The output vector is not necessarily unit length. For that use -/// [`Self::any_orthonormal_vector()`] instead. - - #[lua(kind = "Method", output(proxy))] - fn any_orthogonal_vector(&self) -> bevy::math::DVec3; - -"#, - r#" -/// Returns any unit vector that is orthogonal to the given one. -/// The input vector must be unit length. -/// # Panics -/// Will panic if `self` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn any_orthonormal_vector(&self) -> bevy::math::DVec3; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec3(&self) -> bevy::math::Vec3; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec3a(&self) -> bevy::math::Vec3A; - -"#, - r#" -/// Casts all elements of `self` to `i32`. - - #[lua(kind = "Method", output(proxy))] - fn as_ivec3(&self) -> bevy::math::IVec3; - -"#, - r#" -/// Casts all elements of `self` to `u32`. - - #[lua(kind = "Method", output(proxy))] - fn as_uvec3(&self) -> bevy::math::UVec3; - -"#, - r#" -/// Casts all elements of `self` to `i64`. - - #[lua(kind = "Method", output(proxy))] - fn as_i64vec3(&self) -> bevy::math::I64Vec3; - -"#, - r#" -/// Casts all elements of `self` to `u64`. - - #[lua(kind = "Method", output(proxy))] - fn as_u64vec3(&self) -> bevy::math::U64Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::DVec3) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::DVec3; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind="MetaMethod", raw , metamethod="Index")] -fn index(&self, lua: &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(self.inner()?[*idx]) -} -"#, - r#" -#[lua(kind="MutatingMetaMethod", raw, metamethod="NewIndex")] -fn index(&mut self, lua: &Lua, idx: crate::lua::util::LuaIndex, val: f64) -> Result<(),_> { - self.val_mut(|s| Ok(s[*idx] = val))? -} -"#] -)] -struct DVec3 { - x: f64, - y: f64, - z: f64, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::DVec4", - functions[r#" -/// Creates a new vector. - - #[lua(kind = "Function", output(proxy))] - fn new(x: f64, y: f64, z: f64, w: f64) -> bevy::math::DVec4; - -"#, - r#" -/// Creates a vector with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: f64) -> bevy::math::DVec4; - -"#, - r#" -/// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use -/// for each element of `self`. -/// A true element in the mask uses the corresponding element from `if_true`, and false -/// uses the element from `if_false`. - - #[lua(kind = "Function", output(proxy))] - fn select( - #[proxy] - mask: bevy::math::BVec4, - #[proxy] - if_true: bevy::math::DVec4, - #[proxy] - if_false: bevy::math::DVec4, - ) -> bevy::math::DVec4; - -"#, - r#" -/// Creates a new vector from an array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [f64; 4]) -> bevy::math::DVec4; - -"#, - r#" -/// `[x, y, z, w]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [f64; 4]; - -"#, - r#" -/// Creates a 3D vector from the `x`, `y` and `z` elements of `self`, discarding `w`. -/// Truncation to [`DVec3`] may also be performed by using [`self.xyz()`][crate::swizzles::Vec4Swizzles::xyz()]. - - #[lua(kind = "Method", output(proxy))] - fn truncate(self) -> bevy::math::DVec3; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `x`. - - #[lua(kind = "Method", output(proxy))] - fn with_x(self, x: f64) -> bevy::math::DVec4; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `y`. - - #[lua(kind = "Method", output(proxy))] - fn with_y(self, y: f64) -> bevy::math::DVec4; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `z`. - - #[lua(kind = "Method", output(proxy))] - fn with_z(self, z: f64) -> bevy::math::DVec4; - -"#, - r#" -/// Creates a 4D vector from `self` with the given value of `w`. - - #[lua(kind = "Method", output(proxy))] - fn with_w(self, w: f64) -> bevy::math::DVec4; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::DVec4) -> f64; - -"#, - r#" -/// Returns a vector where every component is the dot product of `self` and `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn dot_into_vec(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::DVec4; - -"#, - r#" -/// Returns a vector containing the minimum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn min(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::DVec4; - -"#, - r#" -/// Returns a vector containing the maximum values for each element of `self` and `rhs`. -/// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`. - - #[lua(kind = "Method", output(proxy))] - fn max(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::DVec4; - -"#, - r#" -/// Component-wise clamping of values, similar to [`f64::clamp`]. -/// Each element in `min` must be less-or-equal to the corresponding element in `max`. -/// # Panics -/// Will panic if `min` is greater than `max` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp( - self, - #[proxy] - min: bevy::math::DVec4, - #[proxy] - max: bevy::math::DVec4, - ) -> bevy::math::DVec4; - -"#, - r#" -/// Returns the horizontal minimum of `self`. -/// In other words this computes `min(x, y, ..)`. - - #[lua(kind = "Method")] - fn min_element(self) -> f64; - -"#, - r#" -/// Returns the horizontal maximum of `self`. -/// In other words this computes `max(x, y, ..)`. - - #[lua(kind = "Method")] - fn max_element(self) -> f64; - -"#, - r#" -/// Returns the sum of all elements of `self`. -/// In other words, this computes `self.x + self.y + ..`. - - #[lua(kind = "Method")] - fn element_sum(self) -> f64; - -"#, - r#" -/// Returns the product of all elements of `self`. -/// In other words, this computes `self.x * self.y * ..`. - - #[lua(kind = "Method")] - fn element_product(self) -> f64; - -"#, - r#" -/// Returns a vector mask containing the result of a `==` comparison for each element of -/// `self` and `rhs`. -/// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpeq(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `!=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpne(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `>=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpge(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `>` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmpgt(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `<=` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmple(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector mask containing the result of a `<` comparison for each element of -/// `self` and `rhs`. -/// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all -/// elements. - - #[lua(kind = "Method", output(proxy))] - fn cmplt(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::BVec4; - -"#, - r#" -/// Returns a vector containing the absolute value of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn abs(self) -> bevy::math::DVec4; - -"#, - r#" -/// Returns a vector with elements representing the sign of `self`. -/// - `1.0` if the number is positive, `+0.0` or `INFINITY` -/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` -/// - `NAN` if the number is `NAN` - - #[lua(kind = "Method", output(proxy))] - fn signum(self) -> bevy::math::DVec4; - -"#, - r#" -/// Returns a vector with signs of `rhs` and the magnitudes of `self`. - - #[lua(kind = "Method", output(proxy))] - fn copysign(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::DVec4; - -"#, - r#" -/// Returns a bitmask with the lowest 4 bits set to the sign bits from the elements of `self`. -/// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes -/// into the first lowest bit, element `y` into the second, etc. - - #[lua(kind = "Method")] - fn is_negative_bitmask(self) -> u32; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. If any element is either -/// `NaN`, positive or negative infinity, this will return `false`. - - #[lua(kind = "Method")] - fn is_finite(self) -> bool; - -"#, - r#" -/// Performs `is_finite` on each element of self, returning a vector mask of the results. -/// In other words, this computes `[x.is_finite(), y.is_finite(), ...]`. - - #[lua(kind = "Method", output(proxy))] - fn is_finite_mask(self) -> bevy::math::BVec4; - -"#, - r#" -/// Returns `true` if any elements are `NaN`. - - #[lua(kind = "Method")] - fn is_nan(self) -> bool; - -"#, - r#" -/// Performs `is_nan` on each element of self, returning a vector mask of the results. -/// In other words, this computes `[x.is_nan(), y.is_nan(), ...]`. - - #[lua(kind = "Method", output(proxy))] - fn is_nan_mask(self) -> bevy::math::BVec4; - -"#, - r#" -/// Computes the length of `self`. - - #[lua(kind = "Method")] - fn length(self) -> f64; - -"#, - r#" -/// Computes the squared length of `self`. -/// This is faster than `length()` as it avoids a square root operation. - - #[lua(kind = "Method")] - fn length_squared(self) -> f64; - -"#, - r#" -/// Computes `1.0 / length()`. -/// For valid results, `self` must _not_ be of length zero. - - #[lua(kind = "Method")] - fn length_recip(self) -> f64; - -"#, - r#" -/// Computes the Euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance(self, #[proxy] rhs: bevy::math::DVec4) -> f64; - -"#, - r#" -/// Compute the squared euclidean distance between two points in space. - - #[lua(kind = "Method")] - fn distance_squared(self, #[proxy] rhs: bevy::math::DVec4) -> f64; - -"#, - r#" -/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn div_euclid(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::DVec4; - -"#, - r#" -/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. -/// [Euclidean division]: f64::rem_euclid - - #[lua(kind = "Method", output(proxy))] - fn rem_euclid(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::DVec4; - -"#, - r#" -/// Returns `self` normalized to length 1.0. -/// For valid results, `self` must be finite and _not_ of length zero, nor very close to zero. -/// See also [`Self::try_normalize()`] and [`Self::normalize_or_zero()`]. -/// Panics -/// Will panic if the resulting normalized vector is not finite when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn normalize(self) -> bevy::math::DVec4; - -"#, - r#" -/// Returns `self` normalized to length 1.0 if possible, else returns a -/// fallback value. -/// In particular, if the input is zero (or very close to zero), or non-finite, -/// the result of this operation will be the fallback value. -/// See also [`Self::try_normalize()`]. - - #[lua(kind = "Method", output(proxy))] - fn normalize_or(self, #[proxy] fallback: bevy::math::DVec4) -> bevy::math::DVec4; - -"#, - r#" -/// Returns `self` normalized to length 1.0 if possible, else returns zero. -/// In particular, if the input is zero (or very close to zero), or non-finite, -/// the result of this operation will be zero. -/// See also [`Self::try_normalize()`]. - - #[lua(kind = "Method", output(proxy))] - fn normalize_or_zero(self) -> bevy::math::DVec4; - -"#, - r#" -/// Returns whether `self` is length `1.0` or not. -/// Uses a precision threshold of approximately `1e-4`. - - #[lua(kind = "Method")] - fn is_normalized(self) -> bool; - -"#, - r#" -/// Returns the vector projection of `self` onto `rhs`. -/// `rhs` must be of non-zero length. -/// # Panics -/// Will panic if `rhs` is zero length when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn project_onto(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::DVec4; - -"#, - r#" -/// Returns the vector rejection of `self` from `rhs`. -/// The vector rejection is the vector perpendicular to the projection of `self` onto -/// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`. -/// `rhs` must be of non-zero length. -/// # Panics -/// Will panic if `rhs` has a length of zero when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reject_from(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::DVec4; - -"#, - r#" -/// Returns the vector projection of `self` onto `rhs`. -/// `rhs` must be normalized. -/// # Panics -/// Will panic if `rhs` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn project_onto_normalized( - self, - #[proxy] - rhs: bevy::math::DVec4, - ) -> bevy::math::DVec4; - -"#, - r#" -/// Returns the vector rejection of `self` from `rhs`. -/// The vector rejection is the vector perpendicular to the projection of `self` onto -/// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`. -/// `rhs` must be normalized. -/// # Panics -/// Will panic if `rhs` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reject_from_normalized( - self, - #[proxy] - rhs: bevy::math::DVec4, - ) -> bevy::math::DVec4; - -"#, - r#" -/// Returns a vector containing the nearest integer to a number for each element of `self`. -/// Round half-way cases away from 0.0. - - #[lua(kind = "Method", output(proxy))] - fn round(self) -> bevy::math::DVec4; - -"#, - r#" -/// Returns a vector containing the largest integer less than or equal to a number for each -/// element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn floor(self) -> bevy::math::DVec4; - -"#, - r#" -/// Returns a vector containing the smallest integer greater than or equal to a number for -/// each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn ceil(self) -> bevy::math::DVec4; - -"#, - r#" -/// Returns a vector containing the integer part each element of `self`. This means numbers are -/// always truncated towards zero. - - #[lua(kind = "Method", output(proxy))] - fn trunc(self) -> bevy::math::DVec4; - -"#, - r#" -/// Returns a vector containing the fractional part of the vector as `self - self.trunc()`. -/// Note that this differs from the GLSL implementation of `fract` which returns -/// `self - self.floor()`. -/// Note that this is fast but not precise for large numbers. - - #[lua(kind = "Method", output(proxy))] - fn fract(self) -> bevy::math::DVec4; - -"#, - r#" -/// Returns a vector containing the fractional part of the vector as `self - self.floor()`. -/// Note that this differs from the Rust implementation of `fract` which returns -/// `self - self.trunc()`. -/// Note that this is fast but not precise for large numbers. - - #[lua(kind = "Method", output(proxy))] - fn fract_gl(self) -> bevy::math::DVec4; - -"#, - r#" -/// Returns a vector containing `e^self` (the exponential function) for each element of -/// `self`. - - #[lua(kind = "Method", output(proxy))] - fn exp(self) -> bevy::math::DVec4; - -"#, - r#" -/// Returns a vector containing each element of `self` raised to the power of `n`. - - #[lua(kind = "Method", output(proxy))] - fn powf(self, n: f64) -> bevy::math::DVec4; - -"#, - r#" -/// Returns a vector containing the reciprocal `1.0/n` of each element of `self`. - - #[lua(kind = "Method", output(proxy))] - fn recip(self) -> bevy::math::DVec4; - -"#, - r#" -/// Performs a linear interpolation between `self` and `rhs` based on the value `s`. -/// When `s` is `0.0`, the result will be equal to `self`. When `s` is `1.0`, the result -/// will be equal to `rhs`. When `s` is outside of range `[0, 1]`, the result is linearly -/// extrapolated. - - #[lua(kind = "Method", output(proxy))] - fn lerp(self, #[proxy] rhs: bevy::math::DVec4, s: f64) -> bevy::math::DVec4; - -"#, - r#" -/// Moves towards `rhs` based on the value `d`. -/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to -/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`. - - #[lua(kind = "Method", output(proxy))] - fn move_towards(&self, #[proxy] rhs: bevy::math::DVec4, d: f64) -> bevy::math::DVec4; - -"#, - r#" -/// Calculates the midpoint between `self` and `rhs`. -/// The midpoint is the average of, or halfway point between, two vectors. -/// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)` -/// while being slightly cheaper to compute. - - #[lua(kind = "Method", output(proxy))] - fn midpoint(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::DVec4; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` is -/// less than or equal to `max_abs_diff`. -/// This can be used to compare if two vectors contain similar elements. It works best when -/// comparing with a known value. The `max_abs_diff` that should be used used depends on -/// the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(self, #[proxy] rhs: bevy::math::DVec4, max_abs_diff: f64) -> bool; - -"#, - r#" -/// Returns a vector with a length no less than `min` and no more than `max`. -/// # Panics -/// Will panic if `min` is greater than `max`, or if either `min` or `max` is negative, when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length(self, min: f64, max: f64) -> bevy::math::DVec4; - -"#, - r#" -/// Returns a vector with a length no more than `max`. -/// # Panics -/// Will panic if `max` is negative when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length_max(self, max: f64) -> bevy::math::DVec4; - -"#, - r#" -/// Returns a vector with a length no less than `min`. -/// # Panics -/// Will panic if `min` is negative when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn clamp_length_min(self, min: f64) -> bevy::math::DVec4; - -"#, - r#" -/// Fused multiply-add. Computes `(self * a) + b` element-wise with only one rounding -/// error, yielding a more accurate result than an unfused multiply-add. -/// Using `mul_add` *may* be more performant than an unfused multiply-add if the target -/// architecture has a dedicated fma CPU instruction. However, this is not always true, -/// and will be heavily dependant on designing algorithms with specific target hardware in -/// mind. - - #[lua(kind = "Method", output(proxy))] - fn mul_add( - self, - #[proxy] - a: bevy::math::DVec4, - #[proxy] - b: bevy::math::DVec4, - ) -> bevy::math::DVec4; - -"#, - r#" -/// Returns the reflection vector for a given incident vector `self` and surface normal -/// `normal`. -/// `normal` must be normalized. -/// # Panics -/// Will panic if `normal` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn reflect(self, #[proxy] normal: bevy::math::DVec4) -> bevy::math::DVec4; - -"#, - r#" -/// Returns the refraction direction for a given incident vector `self`, surface normal -/// `normal` and ratio of indices of refraction, `eta`. When total internal reflection occurs, -/// a zero vector will be returned. -/// `self` and `normal` must be normalized. -/// # Panics -/// Will panic if `self` or `normal` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn refract(self, #[proxy] normal: bevy::math::DVec4, eta: f64) -> bevy::math::DVec4; - -"#, - r#" -/// Casts all elements of `self` to `f32`. - - #[lua(kind = "Method", output(proxy))] - fn as_vec4(&self) -> bevy::math::Vec4; - -"#, - r#" -/// Casts all elements of `self` to `i32`. - - #[lua(kind = "Method", output(proxy))] - fn as_ivec4(&self) -> bevy::math::IVec4; - -"#, - r#" -/// Casts all elements of `self` to `u32`. - - #[lua(kind = "Method", output(proxy))] - fn as_uvec4(&self) -> bevy::math::UVec4; - -"#, - r#" -/// Casts all elements of `self` to `i64`. - - #[lua(kind = "Method", output(proxy))] - fn as_i64vec4(&self) -> bevy::math::I64Vec4; - -"#, - r#" -/// Casts all elements of `self` to `u64`. - - #[lua(kind = "Method", output(proxy))] - fn as_u64vec4(&self) -> bevy::math::U64Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: &glam::DVec4) -> bevy::math::DVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, rhs: f64) -> bevy::math::DVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::DVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: &glam::DVec4) -> bevy::math::DVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::DVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: &glam::DVec4) -> bevy::math::DVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, rhs: f64) -> bevy::math::DVec4; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::DVec4) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::DVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::DVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f64) -> bevy::math::DVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: &glam::DVec4) -> bevy::math::DVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, rhs: f64) -> bevy::math::DVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, #[proxy] rhs: &glam::DVec4) -> bevy::math::DVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::DVec4; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::DVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Rem", - kind = "MetaFunction", - output(proxy), - composite = "rem", - metamethod = "Mod", - )] - fn rem(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::DVec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: f64) -> bevy::math::DVec4; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind="MetaMethod", raw , metamethod="Index")] -fn index(&self, lua: &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(self.inner()?[*idx]) -} -"#, - r#" -#[lua(kind="MutatingMetaMethod", raw, metamethod="NewIndex")] -fn index(&mut self, lua: &Lua, idx: crate::lua::util::LuaIndex, val: f64) -> Result<(),_> { - self.val_mut(|s| Ok(s[*idx] = val))? -} -"#] -)] -struct DVec4 { - x: f64, - y: f64, - z: f64, - w: f64, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::Mat2", - functions[r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::Mat2) -> bevy::math::Mat2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Mat2) -> bevy::math::Mat2; - -"#, - r#" -/// Creates a 2x2 matrix from two column vectors. - - #[lua(kind = "Function", output(proxy))] - fn from_cols( - #[proxy] - x_axis: bevy::math::Vec2, - #[proxy] - y_axis: bevy::math::Vec2, - ) -> bevy::math::Mat2; - -"#, - r#" -/// Creates a `[f32; 4]` array storing data in column major order. -/// If you require data in row major order `transpose` the matrix first. - - #[lua(kind = "Method")] - fn to_cols_array(&self) -> [f32; 4]; - -"#, - r#" -/// Creates a `[[f32; 2]; 2]` 2D array storing data in column major order. -/// If you require data in row major order `transpose` the matrix first. - - #[lua(kind = "Method")] - fn to_cols_array_2d(&self) -> [[f32; 2]; 2]; - -"#, - r#" -/// Creates a 2x2 matrix with its diagonal set to `diagonal` and all other entries set to 0. - - #[lua(kind = "Function", output(proxy))] - fn from_diagonal(#[proxy] diagonal: bevy::math::Vec2) -> bevy::math::Mat2; - -"#, - r#" -/// Creates a 2x2 matrix containing the combining non-uniform `scale` and rotation of -/// `angle` (in radians). - - #[lua(kind = "Function", output(proxy))] - fn from_scale_angle( - #[proxy] - scale: bevy::math::Vec2, - angle: f32, - ) -> bevy::math::Mat2; - -"#, - r#" -/// Creates a 2x2 matrix containing a rotation of `angle` (in radians). - - #[lua(kind = "Function", output(proxy))] - fn from_angle(angle: f32) -> bevy::math::Mat2; - -"#, - r#" -/// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column. - - #[lua(kind = "Function", output(proxy))] - fn from_mat3(#[proxy] m: bevy::math::Mat3) -> bevy::math::Mat2; - -"#, - r#" -/// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column -/// and `j`th row. -/// # Panics -/// Panics if `i` or `j` is greater than 2. - - #[lua(kind = "Function", output(proxy))] - fn from_mat3_minor( - #[proxy] - m: bevy::math::Mat3, - i: usize, - j: usize, - ) -> bevy::math::Mat2; - -"#, - r#" -/// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column. - - #[lua(kind = "Function", output(proxy))] - fn from_mat3a(#[proxy] m: bevy::math::Mat3A) -> bevy::math::Mat2; - -"#, - r#" -/// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column -/// and `j`th row. -/// # Panics -/// Panics if `i` or `j` is greater than 2. - - #[lua(kind = "Function", output(proxy))] - fn from_mat3a_minor( - #[proxy] - m: bevy::math::Mat3A, - i: usize, - j: usize, - ) -> bevy::math::Mat2; - -"#, - r#" -/// Returns the matrix column for the given `index`. -/// # Panics -/// Panics if `index` is greater than 1. - - #[lua(kind = "Method", output(proxy))] - fn col(&self, index: usize) -> bevy::math::Vec2; - -"#, - r#" -/// Returns the matrix row for the given `index`. -/// # Panics -/// Panics if `index` is greater than 1. - - #[lua(kind = "Method", output(proxy))] - fn row(&self, index: usize) -> bevy::math::Vec2; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. -/// If any element is either `NaN`, positive or negative infinity, this will return `false`. - - #[lua(kind = "Method")] - fn is_finite(&self) -> bool; - -"#, - r#" -/// Returns `true` if any elements are `NaN`. - - #[lua(kind = "Method")] - fn is_nan(&self) -> bool; - -"#, - r#" -/// Returns the transpose of `self`. - - #[lua(kind = "Method", output(proxy))] - fn transpose(&self) -> bevy::math::Mat2; - -"#, - r#" -/// Returns the determinant of `self`. - - #[lua(kind = "Method")] - fn determinant(&self) -> f32; - -"#, - r#" -/// Returns the inverse of `self`. -/// If the matrix is not invertible the returned matrix will be invalid. -/// # Panics -/// Will panic if the determinant of `self` is zero when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn inverse(&self) -> bevy::math::Mat2; - -"#, - r#" -/// Transforms a 2D vector. - - #[lua(kind = "Method", output(proxy))] - fn mul_vec2(&self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Multiplies two 2x2 matrices. - - #[lua(kind = "Method", output(proxy))] - fn mul_mat2(&self, #[proxy] rhs: &glam::Mat2) -> bevy::math::Mat2; - -"#, - r#" -/// Adds two 2x2 matrices. - - #[lua(kind = "Method", output(proxy))] - fn add_mat2(&self, #[proxy] rhs: &glam::Mat2) -> bevy::math::Mat2; - -"#, - r#" -/// Subtracts two 2x2 matrices. - - #[lua(kind = "Method", output(proxy))] - fn sub_mat2(&self, #[proxy] rhs: &glam::Mat2) -> bevy::math::Mat2; - -"#, - r#" -/// Multiplies a 2x2 matrix by a scalar. - - #[lua(kind = "Method", output(proxy))] - fn mul_scalar(&self, rhs: f32) -> bevy::math::Mat2; - -"#, - r#" -/// Divides a 2x2 matrix by a scalar. - - #[lua(kind = "Method", output(proxy))] - fn div_scalar(&self, rhs: f32) -> bevy::math::Mat2; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` -/// is less than or equal to `max_abs_diff`. -/// This can be used to compare if two matrices contain similar elements. It works best -/// when comparing with a known value. The `max_abs_diff` that should be used used -/// depends on the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(&self, #[proxy] rhs: bevy::math::Mat2, max_abs_diff: f32) -> bool; - -"#, - r#" -/// Takes the absolute value of each element in `self` - - #[lua(kind = "Method", output(proxy))] - fn abs(&self) -> bevy::math::Mat2; - -"#, - r#" - - #[lua(kind = "Method", output(proxy))] - fn as_dmat2(&self) -> bevy::math::DMat2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::Mat2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: f32) -> bevy::math::Mat2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f32) -> bevy::math::Mat2; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] rhs: &glam::Mat2) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::Mat2) -> bevy::math::Mat2; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::Mat2; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind = "MetaMethod", raw, metamethod="Index")] -fn index(&self, ctx : &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(LuaVec2::new_ref( - self.reflect_ref(ctx.get_world()?).sub_ref(bevy_script_api::ReflectionPathElement::SubReflection{ - label:"col", - get: std::sync::Arc::new(|ref_| Err(bevy_script_api::error::ReflectionError::InsufficientProvenance{ - path: "".to_owned(), - msg: "Cannot get column of matrix with immutable reference".to_owned() - })), - get_mut: std::sync::Arc::new(move |ref_| { - if ref_.is::(){ - Ok(ref_.downcast_mut::() - .unwrap() - .col_mut(*idx)) - } else { - Err(bevy_script_api::error::ReflectionError::CannotDowncast{from: ref_.get_represented_type_info().unwrap().type_path().into(), to:"Mat3".into()}) - } - }) - }) - ) - ) -} -"#] -)] -struct Mat2(); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::Mat3", - functions[r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::Mat3) -> bevy::math::Mat3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Mat3) -> bevy::math::Mat3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: f32) -> bevy::math::Mat3; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] rhs: &glam::Mat3) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::Mat3) -> bevy::math::Mat3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::Mat3; - -"#, - r#" -/// Creates a 3x3 matrix from three column vectors. - - #[lua(kind = "Function", output(proxy))] - fn from_cols( - #[proxy] - x_axis: bevy::math::Vec3, - #[proxy] - y_axis: bevy::math::Vec3, - #[proxy] - z_axis: bevy::math::Vec3, - ) -> bevy::math::Mat3; - -"#, - r#" -/// Creates a `[f32; 9]` array storing data in column major order. -/// If you require data in row major order `transpose` the matrix first. - - #[lua(kind = "Method")] - fn to_cols_array(&self) -> [f32; 9]; - -"#, - r#" -/// Creates a `[[f32; 3]; 3]` 3D array storing data in column major order. -/// If you require data in row major order `transpose` the matrix first. - - #[lua(kind = "Method")] - fn to_cols_array_2d(&self) -> [[f32; 3]; 3]; - -"#, - r#" -/// Creates a 3x3 matrix with its diagonal set to `diagonal` and all other entries set to 0. - - #[lua(kind = "Function", output(proxy))] - fn from_diagonal(#[proxy] diagonal: bevy::math::Vec3) -> bevy::math::Mat3; - -"#, - r#" -/// Creates a 3x3 matrix from a 4x4 matrix, discarding the 4th row and column. - - #[lua(kind = "Function", output(proxy))] - fn from_mat4(#[proxy] m: bevy::math::Mat4) -> bevy::math::Mat3; - -"#, - r#" -/// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column -/// and `j`th row. -/// # Panics -/// Panics if `i` or `j` is greater than 3. - - #[lua(kind = "Function", output(proxy))] - fn from_mat4_minor( - #[proxy] - m: bevy::math::Mat4, - i: usize, - j: usize, - ) -> bevy::math::Mat3; - -"#, - r#" -/// Creates a 3D rotation matrix from the given quaternion. -/// # Panics -/// Will panic if `rotation` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_quat(#[proxy] rotation: bevy::math::Quat) -> bevy::math::Mat3; - -"#, - r#" -/// Creates a 3D rotation matrix from a normalized rotation `axis` and `angle` (in -/// radians). -/// # Panics -/// Will panic if `axis` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_axis_angle(#[proxy] axis: bevy::math::Vec3, angle: f32) -> bevy::math::Mat3; - -"#, - r#" -/// Creates a 3D rotation matrix from the given euler rotation sequence and the angles (in -/// radians). - - #[lua(kind = "Function", output(proxy))] - fn from_euler( - #[proxy] - order: bevy::math::EulerRot, - a: f32, - b: f32, - c: f32, - ) -> bevy::math::Mat3; - -"#, - r#" -/// Extract Euler angles with the given Euler rotation order. -/// Note if the input matrix contains scales, shears, or other non-rotation transformations then -/// the resulting Euler angles will be ill-defined. -/// # Panics -/// Will panic if any input matrix column is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method")] - fn to_euler(&self, #[proxy] order: bevy::math::EulerRot) -> (f32, f32, f32); - -"#, - r#" -/// Creates a 3D rotation matrix from `angle` (in radians) around the x axis. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_x(angle: f32) -> bevy::math::Mat3; - -"#, - r#" -/// Creates a 3D rotation matrix from `angle` (in radians) around the y axis. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_y(angle: f32) -> bevy::math::Mat3; - -"#, - r#" -/// Creates a 3D rotation matrix from `angle` (in radians) around the z axis. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_z(angle: f32) -> bevy::math::Mat3; - -"#, - r#" -/// Creates an affine transformation matrix from the given 2D `translation`. -/// The resulting matrix can be used to transform 2D points and vectors. See -/// [`Self::transform_point2()`] and [`Self::transform_vector2()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_translation(#[proxy] translation: bevy::math::Vec2) -> bevy::math::Mat3; - -"#, - r#" -/// Creates an affine transformation matrix from the given 2D rotation `angle` (in -/// radians). -/// The resulting matrix can be used to transform 2D points and vectors. See -/// [`Self::transform_point2()`] and [`Self::transform_vector2()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_angle(angle: f32) -> bevy::math::Mat3; - -"#, - r#" -/// Creates an affine transformation matrix from the given 2D `scale`, rotation `angle` (in -/// radians) and `translation`. -/// The resulting matrix can be used to transform 2D points and vectors. See -/// [`Self::transform_point2()`] and [`Self::transform_vector2()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_scale_angle_translation( - #[proxy] - scale: bevy::math::Vec2, - angle: f32, - #[proxy] - translation: bevy::math::Vec2, - ) -> bevy::math::Mat3; - -"#, - r#" -/// Creates an affine transformation matrix from the given non-uniform 2D `scale`. -/// The resulting matrix can be used to transform 2D points and vectors. See -/// [`Self::transform_point2()`] and [`Self::transform_vector2()`]. -/// # Panics -/// Will panic if all elements of `scale` are zero when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_scale(#[proxy] scale: bevy::math::Vec2) -> bevy::math::Mat3; - -"#, - r#" -/// Creates an affine transformation matrix from the given 2x2 matrix. -/// The resulting matrix can be used to transform 2D points and vectors. See -/// [`Self::transform_point2()`] and [`Self::transform_vector2()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_mat2(#[proxy] m: bevy::math::Mat2) -> bevy::math::Mat3; - -"#, - r#" -/// Returns the matrix column for the given `index`. -/// # Panics -/// Panics if `index` is greater than 2. - - #[lua(kind = "Method", output(proxy))] - fn col(&self, index: usize) -> bevy::math::Vec3; - -"#, - r#" -/// Returns the matrix row for the given `index`. -/// # Panics -/// Panics if `index` is greater than 2. - - #[lua(kind = "Method", output(proxy))] - fn row(&self, index: usize) -> bevy::math::Vec3; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. -/// If any element is either `NaN`, positive or negative infinity, this will return `false`. - - #[lua(kind = "Method")] - fn is_finite(&self) -> bool; - -"#, - r#" -/// Returns `true` if any elements are `NaN`. - - #[lua(kind = "Method")] - fn is_nan(&self) -> bool; - -"#, - r#" -/// Returns the transpose of `self`. - - #[lua(kind = "Method", output(proxy))] - fn transpose(&self) -> bevy::math::Mat3; - -"#, - r#" -/// Returns the determinant of `self`. - - #[lua(kind = "Method")] - fn determinant(&self) -> f32; - -"#, - r#" -/// Returns the inverse of `self`. -/// If the matrix is not invertible the returned matrix will be invalid. -/// # Panics -/// Will panic if the determinant of `self` is zero when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn inverse(&self) -> bevy::math::Mat3; - -"#, - r#" -/// Transforms the given 2D vector as a point. -/// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `1`. -/// This method assumes that `self` contains a valid affine transform. -/// # Panics -/// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn transform_point2(&self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Rotates the given 2D vector. -/// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `0`. -/// This method assumes that `self` contains a valid affine transform. -/// # Panics -/// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn transform_vector2(&self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Transforms a 3D vector. - - #[lua(kind = "Method", output(proxy))] - fn mul_vec3(&self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Transforms a [`Vec3A`]. - - #[lua(kind = "Method", output(proxy))] - fn mul_vec3a(&self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Multiplies two 3x3 matrices. - - #[lua(kind = "Method", output(proxy))] - fn mul_mat3(&self, #[proxy] rhs: &glam::Mat3) -> bevy::math::Mat3; - -"#, - r#" -/// Adds two 3x3 matrices. - - #[lua(kind = "Method", output(proxy))] - fn add_mat3(&self, #[proxy] rhs: &glam::Mat3) -> bevy::math::Mat3; - -"#, - r#" -/// Subtracts two 3x3 matrices. - - #[lua(kind = "Method", output(proxy))] - fn sub_mat3(&self, #[proxy] rhs: &glam::Mat3) -> bevy::math::Mat3; - -"#, - r#" -/// Multiplies a 3x3 matrix by a scalar. - - #[lua(kind = "Method", output(proxy))] - fn mul_scalar(&self, rhs: f32) -> bevy::math::Mat3; - -"#, - r#" -/// Divides a 3x3 matrix by a scalar. - - #[lua(kind = "Method", output(proxy))] - fn div_scalar(&self, rhs: f32) -> bevy::math::Mat3; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` -/// is less than or equal to `max_abs_diff`. -/// This can be used to compare if two matrices contain similar elements. It works best -/// when comparing with a known value. The `max_abs_diff` that should be used used -/// depends on the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(&self, #[proxy] rhs: bevy::math::Mat3, max_abs_diff: f32) -> bool; - -"#, - r#" -/// Takes the absolute value of each element in `self` - - #[lua(kind = "Method", output(proxy))] - fn abs(&self) -> bevy::math::Mat3; - -"#, - r#" - - #[lua(kind = "Method", output(proxy))] - fn as_dmat3(&self) -> bevy::math::DMat3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Affine2) -> bevy::math::Mat3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::Mat3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f32) -> bevy::math::Mat3; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind = "MetaMethod", raw, metamethod="Index")] -fn index(&self, ctx : &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(LuaVec3::new_ref( - self.reflect_ref(ctx.get_world()?).sub_ref(bevy_script_api::ReflectionPathElement::SubReflection{ - label:"col", - get: std::sync::Arc::new(|ref_| Err(bevy_script_api::error::ReflectionError::InsufficientProvenance{ - path: "".to_owned(), - msg: "Cannot get column of matrix with immutable reference".to_owned() - })), - get_mut: std::sync::Arc::new(move |ref_| { - if ref_.is::(){ - Ok(ref_.downcast_mut::() - .unwrap() - .col_mut(*idx)) - } else { - Err(bevy_script_api::error::ReflectionError::CannotDowncast{from: ref_.get_represented_type_info().unwrap().type_path().into(), to:"Mat3".into()}) - } - }) - }) - ) - ) -} -"#] -)] -struct Mat3 { - #[lua(output(proxy))] - x_axis: bevy::math::Vec3, - #[lua(output(proxy))] - y_axis: bevy::math::Vec3, - #[lua(output(proxy))] - z_axis: bevy::math::Vec3, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::Mat3A", - functions[r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::Mat3A) -> bevy::math::Mat3A; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] rhs: &glam::Mat3A) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Mat3A) -> bevy::math::Mat3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::Mat3A) -> bevy::math::Mat3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::Mat3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Creates a 3x3 matrix from three column vectors. - - #[lua(kind = "Function", output(proxy))] - fn from_cols( - #[proxy] - x_axis: bevy::math::Vec3A, - #[proxy] - y_axis: bevy::math::Vec3A, - #[proxy] - z_axis: bevy::math::Vec3A, - ) -> bevy::math::Mat3A; - -"#, - r#" -/// Creates a `[f32; 9]` array storing data in column major order. -/// If you require data in row major order `transpose` the matrix first. - - #[lua(kind = "Method")] - fn to_cols_array(&self) -> [f32; 9]; - -"#, - r#" -/// Creates a `[[f32; 3]; 3]` 3D array storing data in column major order. -/// If you require data in row major order `transpose` the matrix first. - - #[lua(kind = "Method")] - fn to_cols_array_2d(&self) -> [[f32; 3]; 3]; - -"#, - r#" -/// Creates a 3x3 matrix with its diagonal set to `diagonal` and all other entries set to 0. - - #[lua(kind = "Function", output(proxy))] - fn from_diagonal(#[proxy] diagonal: bevy::math::Vec3) -> bevy::math::Mat3A; - -"#, - r#" -/// Creates a 3x3 matrix from a 4x4 matrix, discarding the 4th row and column. - - #[lua(kind = "Function", output(proxy))] - fn from_mat4(#[proxy] m: bevy::math::Mat4) -> bevy::math::Mat3A; - -"#, - r#" -/// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column -/// and `j`th row. -/// # Panics -/// Panics if `i` or `j` is greater than 3. - - #[lua(kind = "Function", output(proxy))] - fn from_mat4_minor( - #[proxy] - m: bevy::math::Mat4, - i: usize, - j: usize, - ) -> bevy::math::Mat3A; - -"#, - r#" -/// Creates a 3D rotation matrix from the given quaternion. -/// # Panics -/// Will panic if `rotation` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_quat(#[proxy] rotation: bevy::math::Quat) -> bevy::math::Mat3A; - -"#, - r#" -/// Creates a 3D rotation matrix from a normalized rotation `axis` and `angle` (in -/// radians). -/// # Panics -/// Will panic if `axis` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_axis_angle(#[proxy] axis: bevy::math::Vec3, angle: f32) -> bevy::math::Mat3A; - -"#, - r#" -/// Creates a 3D rotation matrix from the given euler rotation sequence and the angles (in -/// radians). - - #[lua(kind = "Function", output(proxy))] - fn from_euler( - #[proxy] - order: bevy::math::EulerRot, - a: f32, - b: f32, - c: f32, - ) -> bevy::math::Mat3A; - -"#, - r#" -/// Extract Euler angles with the given Euler rotation order. -/// Note if the input matrix contains scales, shears, or other non-rotation transformations then -/// the resulting Euler angles will be ill-defined. -/// # Panics -/// Will panic if any input matrix column is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method")] - fn to_euler(&self, #[proxy] order: bevy::math::EulerRot) -> (f32, f32, f32); - -"#, - r#" -/// Creates a 3D rotation matrix from `angle` (in radians) around the x axis. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_x(angle: f32) -> bevy::math::Mat3A; - -"#, - r#" -/// Creates a 3D rotation matrix from `angle` (in radians) around the y axis. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_y(angle: f32) -> bevy::math::Mat3A; - -"#, - r#" -/// Creates a 3D rotation matrix from `angle` (in radians) around the z axis. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_z(angle: f32) -> bevy::math::Mat3A; - -"#, - r#" -/// Creates an affine transformation matrix from the given 2D `translation`. -/// The resulting matrix can be used to transform 2D points and vectors. See -/// [`Self::transform_point2()`] and [`Self::transform_vector2()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_translation(#[proxy] translation: bevy::math::Vec2) -> bevy::math::Mat3A; - -"#, - r#" -/// Creates an affine transformation matrix from the given 2D rotation `angle` (in -/// radians). -/// The resulting matrix can be used to transform 2D points and vectors. See -/// [`Self::transform_point2()`] and [`Self::transform_vector2()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_angle(angle: f32) -> bevy::math::Mat3A; - -"#, - r#" -/// Creates an affine transformation matrix from the given 2D `scale`, rotation `angle` (in -/// radians) and `translation`. -/// The resulting matrix can be used to transform 2D points and vectors. See -/// [`Self::transform_point2()`] and [`Self::transform_vector2()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_scale_angle_translation( - #[proxy] - scale: bevy::math::Vec2, - angle: f32, - #[proxy] - translation: bevy::math::Vec2, - ) -> bevy::math::Mat3A; - -"#, - r#" -/// Creates an affine transformation matrix from the given non-uniform 2D `scale`. -/// The resulting matrix can be used to transform 2D points and vectors. See -/// [`Self::transform_point2()`] and [`Self::transform_vector2()`]. -/// # Panics -/// Will panic if all elements of `scale` are zero when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_scale(#[proxy] scale: bevy::math::Vec2) -> bevy::math::Mat3A; - -"#, - r#" -/// Creates an affine transformation matrix from the given 2x2 matrix. -/// The resulting matrix can be used to transform 2D points and vectors. See -/// [`Self::transform_point2()`] and [`Self::transform_vector2()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_mat2(#[proxy] m: bevy::math::Mat2) -> bevy::math::Mat3A; - -"#, - r#" -/// Returns the matrix column for the given `index`. -/// # Panics -/// Panics if `index` is greater than 2. - - #[lua(kind = "Method", output(proxy))] - fn col(&self, index: usize) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns the matrix row for the given `index`. -/// # Panics -/// Panics if `index` is greater than 2. - - #[lua(kind = "Method", output(proxy))] - fn row(&self, index: usize) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. -/// If any element is either `NaN`, positive or negative infinity, this will return `false`. - - #[lua(kind = "Method")] - fn is_finite(&self) -> bool; - -"#, - r#" -/// Returns `true` if any elements are `NaN`. - - #[lua(kind = "Method")] - fn is_nan(&self) -> bool; - -"#, - r#" -/// Returns the transpose of `self`. - - #[lua(kind = "Method", output(proxy))] - fn transpose(&self) -> bevy::math::Mat3A; - -"#, - r#" -/// Returns the determinant of `self`. - - #[lua(kind = "Method")] - fn determinant(&self) -> f32; - -"#, - r#" -/// Returns the inverse of `self`. -/// If the matrix is not invertible the returned matrix will be invalid. -/// # Panics -/// Will panic if the determinant of `self` is zero when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn inverse(&self) -> bevy::math::Mat3A; - -"#, - r#" -/// Transforms the given 2D vector as a point. -/// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `1`. -/// This method assumes that `self` contains a valid affine transform. -/// # Panics -/// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn transform_point2(&self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Rotates the given 2D vector. -/// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `0`. -/// This method assumes that `self` contains a valid affine transform. -/// # Panics -/// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn transform_vector2(&self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Transforms a 3D vector. - - #[lua(kind = "Method", output(proxy))] - fn mul_vec3(&self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Transforms a [`Vec3A`]. - - #[lua(kind = "Method", output(proxy))] - fn mul_vec3a(&self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Multiplies two 3x3 matrices. - - #[lua(kind = "Method", output(proxy))] - fn mul_mat3(&self, #[proxy] rhs: &glam::Mat3A) -> bevy::math::Mat3A; - -"#, - r#" -/// Adds two 3x3 matrices. - - #[lua(kind = "Method", output(proxy))] - fn add_mat3(&self, #[proxy] rhs: &glam::Mat3A) -> bevy::math::Mat3A; - -"#, - r#" -/// Subtracts two 3x3 matrices. - - #[lua(kind = "Method", output(proxy))] - fn sub_mat3(&self, #[proxy] rhs: &glam::Mat3A) -> bevy::math::Mat3A; - -"#, - r#" -/// Multiplies a 3x3 matrix by a scalar. - - #[lua(kind = "Method", output(proxy))] - fn mul_scalar(&self, rhs: f32) -> bevy::math::Mat3A; - -"#, - r#" -/// Divides a 3x3 matrix by a scalar. - - #[lua(kind = "Method", output(proxy))] - fn div_scalar(&self, rhs: f32) -> bevy::math::Mat3A; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` -/// is less than or equal to `max_abs_diff`. -/// This can be used to compare if two matrices contain similar elements. It works best -/// when comparing with a known value. The `max_abs_diff` that should be used used -/// depends on the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(&self, #[proxy] rhs: bevy::math::Mat3A, max_abs_diff: f32) -> bool; - -"#, - r#" -/// Takes the absolute value of each element in `self` - - #[lua(kind = "Method", output(proxy))] - fn abs(&self) -> bevy::math::Mat3A; - -"#, - r#" - - #[lua(kind = "Method", output(proxy))] - fn as_dmat3(&self) -> bevy::math::DMat3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: f32) -> bevy::math::Mat3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Affine2) -> bevy::math::Mat3A; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::Mat3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f32) -> bevy::math::Mat3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind = "MetaMethod", raw, metamethod="Index")] -fn index(&self, ctx : &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(LuaVec3A::new_ref( - self.reflect_ref(ctx.get_world()?).sub_ref(bevy_script_api::ReflectionPathElement::SubReflection{ - label:"col", - get: std::sync::Arc::new(|ref_| Err(bevy_script_api::error::ReflectionError::InsufficientProvenance{ - path: "".to_owned(), - msg: "Cannot get column of matrix with immutable reference".to_owned() - })), - get_mut: std::sync::Arc::new(move |ref_| { - if ref_.is::(){ - Ok(ref_.downcast_mut::() - .unwrap() - .col_mut(*idx)) - } else { - Err(bevy_script_api::error::ReflectionError::CannotDowncast{from: ref_.get_represented_type_info().unwrap().type_path().into(), to:"Mat3".into()}) - } - }) - }) - ) - ) -} -"#] -)] -struct Mat3A { - #[lua(output(proxy))] - x_axis: bevy::math::Vec3A, - #[lua(output(proxy))] - y_axis: bevy::math::Vec3A, - #[lua(output(proxy))] - z_axis: bevy::math::Vec3A, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::Mat4", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] rhs: &glam::Mat4) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: f32) -> bevy::math::Mat4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Mat4) -> bevy::math::Mat4; - -"#, - r#" -/// Creates a 4x4 matrix from four column vectors. - - #[lua(kind = "Function", output(proxy))] - fn from_cols( - #[proxy] - x_axis: bevy::math::Vec4, - #[proxy] - y_axis: bevy::math::Vec4, - #[proxy] - z_axis: bevy::math::Vec4, - #[proxy] - w_axis: bevy::math::Vec4, - ) -> bevy::math::Mat4; - -"#, - r#" -/// Creates a `[f32; 16]` array storing data in column major order. -/// If you require data in row major order `transpose` the matrix first. - - #[lua(kind = "Method")] - fn to_cols_array(&self) -> [f32; 16]; - -"#, - r#" -/// Creates a `[[f32; 4]; 4]` 4D array storing data in column major order. -/// If you require data in row major order `transpose` the matrix first. - - #[lua(kind = "Method")] - fn to_cols_array_2d(&self) -> [[f32; 4]; 4]; - -"#, - r#" -/// Creates a 4x4 matrix with its diagonal set to `diagonal` and all other entries set to 0. - - #[lua(kind = "Function", output(proxy))] - fn from_diagonal(#[proxy] diagonal: bevy::math::Vec4) -> bevy::math::Mat4; - -"#, - r#" -/// Creates an affine transformation matrix from the given 3D `scale`, `rotation` and -/// `translation`. -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. -/// # Panics -/// Will panic if `rotation` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_scale_rotation_translation( - #[proxy] - scale: bevy::math::Vec3, - #[proxy] - rotation: bevy::math::Quat, - #[proxy] - translation: bevy::math::Vec3, - ) -> bevy::math::Mat4; - -"#, - r#" -/// Creates an affine transformation matrix from the given 3D `translation`. -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. -/// # Panics -/// Will panic if `rotation` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_translation( - #[proxy] - rotation: bevy::math::Quat, - #[proxy] - translation: bevy::math::Vec3, - ) -> bevy::math::Mat4; - -"#, - r#" -/// Creates an affine transformation matrix from the given `rotation` quaternion. -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. -/// # Panics -/// Will panic if `rotation` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_quat(#[proxy] rotation: bevy::math::Quat) -> bevy::math::Mat4; - -"#, - r#" -/// Creates an affine transformation matrix from the given 3x3 linear transformation -/// matrix. -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_mat3(#[proxy] m: bevy::math::Mat3) -> bevy::math::Mat4; - -"#, - r#" -/// Creates an affine transformation matrix from the given 3x3 linear transformation -/// matrix. -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_mat3a(#[proxy] m: bevy::math::Mat3A) -> bevy::math::Mat4; - -"#, - r#" -/// Creates an affine transformation matrix from the given 3D `translation`. -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_translation(#[proxy] translation: bevy::math::Vec3) -> bevy::math::Mat4; - -"#, - r#" -/// Creates an affine transformation matrix containing a 3D rotation around a normalized -/// rotation `axis` of `angle` (in radians). -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. -/// # Panics -/// Will panic if `axis` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_axis_angle(#[proxy] axis: bevy::math::Vec3, angle: f32) -> bevy::math::Mat4; - -"#, - r#" -/// Creates a affine transformation matrix containing a rotation from the given euler -/// rotation sequence and angles (in radians). -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_euler( - #[proxy] - order: bevy::math::EulerRot, - a: f32, - b: f32, - c: f32, - ) -> bevy::math::Mat4; - -"#, - r#" -/// Extract Euler angles with the given Euler rotation order. -/// Note if the upper 3x3 matrix contain scales, shears, or other non-rotation transformations -/// then the resulting Euler angles will be ill-defined. -/// # Panics -/// Will panic if any column of the upper 3x3 rotation matrix is not normalized when -/// `glam_assert` is enabled. - - #[lua(kind = "Method")] - fn to_euler(&self, #[proxy] order: bevy::math::EulerRot) -> (f32, f32, f32); - -"#, - r#" -/// Creates an affine transformation matrix containing a 3D rotation around the x axis of -/// `angle` (in radians). -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_x(angle: f32) -> bevy::math::Mat4; - -"#, - r#" -/// Creates an affine transformation matrix containing a 3D rotation around the y axis of -/// `angle` (in radians). -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_y(angle: f32) -> bevy::math::Mat4; - -"#, - r#" -/// Creates an affine transformation matrix containing a 3D rotation around the z axis of -/// `angle` (in radians). -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_z(angle: f32) -> bevy::math::Mat4; - -"#, - r#" -/// Creates an affine transformation matrix containing the given 3D non-uniform `scale`. -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. -/// # Panics -/// Will panic if all elements of `scale` are zero when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_scale(#[proxy] scale: bevy::math::Vec3) -> bevy::math::Mat4; - -"#, - r#" -/// Returns the matrix column for the given `index`. -/// # Panics -/// Panics if `index` is greater than 3. - - #[lua(kind = "Method", output(proxy))] - fn col(&self, index: usize) -> bevy::math::Vec4; - -"#, - r#" -/// Returns the matrix row for the given `index`. -/// # Panics -/// Panics if `index` is greater than 3. - - #[lua(kind = "Method", output(proxy))] - fn row(&self, index: usize) -> bevy::math::Vec4; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. -/// If any element is either `NaN`, positive or negative infinity, this will return `false`. - - #[lua(kind = "Method")] - fn is_finite(&self) -> bool; - -"#, - r#" -/// Returns `true` if any elements are `NaN`. - - #[lua(kind = "Method")] - fn is_nan(&self) -> bool; - -"#, - r#" -/// Returns the transpose of `self`. - - #[lua(kind = "Method", output(proxy))] - fn transpose(&self) -> bevy::math::Mat4; - -"#, - r#" -/// Returns the determinant of `self`. - - #[lua(kind = "Method")] - fn determinant(&self) -> f32; - -"#, - r#" -/// Returns the inverse of `self`. -/// If the matrix is not invertible the returned matrix will be invalid. -/// # Panics -/// Will panic if the determinant of `self` is zero when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn inverse(&self) -> bevy::math::Mat4; - -"#, - r#" -/// Creates a left-handed view matrix using a camera position, an up direction, and a facing -/// direction. -/// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`. - - #[lua(kind = "Function", output(proxy))] - fn look_to_lh( - #[proxy] - eye: bevy::math::Vec3, - #[proxy] - dir: bevy::math::Vec3, - #[proxy] - up: bevy::math::Vec3, - ) -> bevy::math::Mat4; - -"#, - r#" -/// Creates a right-handed view matrix using a camera position, an up direction, and a facing -/// direction. -/// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`. - - #[lua(kind = "Function", output(proxy))] - fn look_to_rh( - #[proxy] - eye: bevy::math::Vec3, - #[proxy] - dir: bevy::math::Vec3, - #[proxy] - up: bevy::math::Vec3, - ) -> bevy::math::Mat4; - -"#, - r#" -/// Creates a left-handed view matrix using a camera position, an up direction, and a focal -/// point. -/// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`. -/// # Panics -/// Will panic if `up` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn look_at_lh( - #[proxy] - eye: bevy::math::Vec3, - #[proxy] - center: bevy::math::Vec3, - #[proxy] - up: bevy::math::Vec3, - ) -> bevy::math::Mat4; - -"#, - r#" -/// Creates a right-handed view matrix using a camera position, an up direction, and a focal -/// point. -/// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`. -/// # Panics -/// Will panic if `up` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn look_at_rh( - #[proxy] - eye: bevy::math::Vec3, - #[proxy] - center: bevy::math::Vec3, - #[proxy] - up: bevy::math::Vec3, - ) -> bevy::math::Mat4; - -"#, - r#" -/// Creates a right-handed perspective projection matrix with `[-1,1]` depth range. -/// Useful to map the standard right-handed coordinate system into what OpenGL expects. -/// This is the same as the OpenGL `gluPerspective` function. -/// See - - #[lua(kind = "Function", output(proxy))] - fn perspective_rh_gl( - fov_y_radians: f32, - aspect_ratio: f32, - z_near: f32, - z_far: f32, - ) -> bevy::math::Mat4; - -"#, - r#" -/// Creates a left-handed perspective projection matrix with `[0,1]` depth range. -/// Useful to map the standard left-handed coordinate system into what WebGPU/Metal/Direct3D expect. -/// # Panics -/// Will panic if `z_near` or `z_far` are less than or equal to zero when `glam_assert` is -/// enabled. - - #[lua(kind = "Function", output(proxy))] - fn perspective_lh( - fov_y_radians: f32, - aspect_ratio: f32, - z_near: f32, - z_far: f32, - ) -> bevy::math::Mat4; - -"#, - r#" -/// Creates a right-handed perspective projection matrix with `[0,1]` depth range. -/// Useful to map the standard right-handed coordinate system into what WebGPU/Metal/Direct3D expect. -/// # Panics -/// Will panic if `z_near` or `z_far` are less than or equal to zero when `glam_assert` is -/// enabled. - - #[lua(kind = "Function", output(proxy))] - fn perspective_rh( - fov_y_radians: f32, - aspect_ratio: f32, - z_near: f32, - z_far: f32, - ) -> bevy::math::Mat4; - -"#, - r#" -/// Creates an infinite left-handed perspective projection matrix with `[0,1]` depth range. -/// Like `perspective_lh`, but with an infinite value for `z_far`. -/// The result is that points near `z_near` are mapped to depth `0`, and as they move towards infinity the depth approaches `1`. -/// # Panics -/// Will panic if `z_near` or `z_far` are less than or equal to zero when `glam_assert` is -/// enabled. - - #[lua(kind = "Function", output(proxy))] - fn perspective_infinite_lh( - fov_y_radians: f32, - aspect_ratio: f32, - z_near: f32, - ) -> bevy::math::Mat4; - -"#, - r#" -/// Creates an infinite reverse left-handed perspective projection matrix with `[0,1]` depth range. -/// Similar to `perspective_infinite_lh`, but maps `Z = z_near` to a depth of `1` and `Z = infinity` to a depth of `0`. -/// # Panics -/// Will panic if `z_near` is less than or equal to zero when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn perspective_infinite_reverse_lh( - fov_y_radians: f32, - aspect_ratio: f32, - z_near: f32, - ) -> bevy::math::Mat4; - -"#, - r#" -/// Creates an infinite right-handed perspective projection matrix with `[0,1]` depth range. -/// Like `perspective_rh`, but with an infinite value for `z_far`. -/// The result is that points near `z_near` are mapped to depth `0`, and as they move towards infinity the depth approaches `1`. -/// # Panics -/// Will panic if `z_near` or `z_far` are less than or equal to zero when `glam_assert` is -/// enabled. - - #[lua(kind = "Function", output(proxy))] - fn perspective_infinite_rh( - fov_y_radians: f32, - aspect_ratio: f32, - z_near: f32, - ) -> bevy::math::Mat4; - -"#, - r#" -/// Creates an infinite reverse right-handed perspective projection matrix with `[0,1]` depth range. -/// Similar to `perspective_infinite_rh`, but maps `Z = z_near` to a depth of `1` and `Z = infinity` to a depth of `0`. -/// # Panics -/// Will panic if `z_near` is less than or equal to zero when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn perspective_infinite_reverse_rh( - fov_y_radians: f32, - aspect_ratio: f32, - z_near: f32, - ) -> bevy::math::Mat4; - -"#, - r#" -/// Creates a right-handed orthographic projection matrix with `[-1,1]` depth -/// range. This is the same as the OpenGL `glOrtho` function in OpenGL. -/// See -/// -/// Useful to map a right-handed coordinate system to the normalized device coordinates that OpenGL expects. - - #[lua(kind = "Function", output(proxy))] - fn orthographic_rh_gl( - left: f32, - right: f32, - bottom: f32, - top: f32, - near: f32, - far: f32, - ) -> bevy::math::Mat4; - -"#, - r#" -/// Creates a left-handed orthographic projection matrix with `[0,1]` depth range. -/// Useful to map a left-handed coordinate system to the normalized device coordinates that WebGPU/Direct3D/Metal expect. - - #[lua(kind = "Function", output(proxy))] - fn orthographic_lh( - left: f32, - right: f32, - bottom: f32, - top: f32, - near: f32, - far: f32, - ) -> bevy::math::Mat4; - -"#, - r#" -/// Creates a right-handed orthographic projection matrix with `[0,1]` depth range. -/// Useful to map a right-handed coordinate system to the normalized device coordinates that WebGPU/Direct3D/Metal expect. - - #[lua(kind = "Function", output(proxy))] - fn orthographic_rh( - left: f32, - right: f32, - bottom: f32, - top: f32, - near: f32, - far: f32, - ) -> bevy::math::Mat4; - -"#, - r#" -/// Transforms the given 3D vector as a point, applying perspective correction. -/// This is the equivalent of multiplying the 3D vector as a 4D vector where `w` is `1.0`. -/// The perspective divide is performed meaning the resulting 3D vector is divided by `w`. -/// This method assumes that `self` contains a projective transform. - - #[lua(kind = "Method", output(proxy))] - fn project_point3(&self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Transforms the given 3D vector as a point. -/// This is the equivalent of multiplying the 3D vector as a 4D vector where `w` is -/// `1.0`. -/// This method assumes that `self` contains a valid affine transform. It does not perform -/// a perspective divide, if `self` contains a perspective transform, or if you are unsure, -/// the [`Self::project_point3()`] method should be used instead. -/// # Panics -/// Will panic if the 3rd row of `self` is not `(0, 0, 0, 1)` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn transform_point3(&self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Transforms the give 3D vector as a direction. -/// This is the equivalent of multiplying the 3D vector as a 4D vector where `w` is -/// `0.0`. -/// This method assumes that `self` contains a valid affine transform. -/// # Panics -/// Will panic if the 3rd row of `self` is not `(0, 0, 0, 1)` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn transform_vector3(&self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Transforms the given [`Vec3A`] as a 3D point, applying perspective correction. -/// This is the equivalent of multiplying the [`Vec3A`] as a 4D vector where `w` is `1.0`. -/// The perspective divide is performed meaning the resulting 3D vector is divided by `w`. -/// This method assumes that `self` contains a projective transform. - - #[lua(kind = "Method", output(proxy))] - fn project_point3a(&self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Transforms the given [`Vec3A`] as 3D point. -/// This is the equivalent of multiplying the [`Vec3A`] as a 4D vector where `w` is `1.0`. - - #[lua(kind = "Method", output(proxy))] - fn transform_point3a(&self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Transforms the give [`Vec3A`] as 3D vector. -/// This is the equivalent of multiplying the [`Vec3A`] as a 4D vector where `w` is `0.0`. - - #[lua(kind = "Method", output(proxy))] - fn transform_vector3a(&self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Transforms a 4D vector. - - #[lua(kind = "Method", output(proxy))] - fn mul_vec4(&self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" -/// Multiplies two 4x4 matrices. - - #[lua(kind = "Method", output(proxy))] - fn mul_mat4(&self, #[proxy] rhs: &glam::Mat4) -> bevy::math::Mat4; - -"#, - r#" -/// Adds two 4x4 matrices. - - #[lua(kind = "Method", output(proxy))] - fn add_mat4(&self, #[proxy] rhs: &glam::Mat4) -> bevy::math::Mat4; - -"#, - r#" -/// Subtracts two 4x4 matrices. - - #[lua(kind = "Method", output(proxy))] - fn sub_mat4(&self, #[proxy] rhs: &glam::Mat4) -> bevy::math::Mat4; - -"#, - r#" -/// Multiplies a 4x4 matrix by a scalar. - - #[lua(kind = "Method", output(proxy))] - fn mul_scalar(&self, rhs: f32) -> bevy::math::Mat4; - -"#, - r#" -/// Divides a 4x4 matrix by a scalar. - - #[lua(kind = "Method", output(proxy))] - fn div_scalar(&self, rhs: f32) -> bevy::math::Mat4; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` -/// is less than or equal to `max_abs_diff`. -/// This can be used to compare if two matrices contain similar elements. It works best -/// when comparing with a known value. The `max_abs_diff` that should be used used -/// depends on the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(&self, #[proxy] rhs: bevy::math::Mat4, max_abs_diff: f32) -> bool; - -"#, - r#" -/// Takes the absolute value of each element in `self` - - #[lua(kind = "Method", output(proxy))] - fn abs(&self) -> bevy::math::Mat4; - -"#, - r#" - - #[lua(kind = "Method", output(proxy))] - fn as_dmat4(&self) -> bevy::math::DMat4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::Mat4) -> bevy::math::Mat4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f32) -> bevy::math::Mat4; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::Mat4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::Mat4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Vec4) -> bevy::math::Vec4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Affine3A) -> bevy::math::Mat4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::Mat4) -> bevy::math::Mat4; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind = "MetaMethod", raw, metamethod="Index")] -fn index(&self, ctx : &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(LuaVec4::new_ref( - self.reflect_ref(ctx.get_world()?).sub_ref(bevy_script_api::ReflectionPathElement::SubReflection{ - label:"col", - get: std::sync::Arc::new(|ref_| Err(bevy_script_api::error::ReflectionError::InsufficientProvenance{ - path: "".to_owned(), - msg: "Cannot get column of matrix with immutable reference".to_owned() - })), - get_mut: std::sync::Arc::new(move |ref_| { - if ref_.is::(){ - Ok(ref_.downcast_mut::() - .unwrap() - .col_mut(*idx)) - } else { - Err(bevy_script_api::error::ReflectionError::CannotDowncast{from: ref_.get_represented_type_info().unwrap().type_path().into(), to:"Mat3".into()}) - } - }) - }) - ) - ) -} -"#] -)] -struct Mat4 { - #[lua(output(proxy))] - x_axis: bevy::math::Vec4, - #[lua(output(proxy))] - y_axis: bevy::math::Vec4, - #[lua(output(proxy))] - z_axis: bevy::math::Vec4, - #[lua(output(proxy))] - w_axis: bevy::math::Vec4, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::DMat2", - functions[r#" -/// Creates a 2x2 matrix from two column vectors. - - #[lua(kind = "Function", output(proxy))] - fn from_cols( - #[proxy] - x_axis: bevy::math::DVec2, - #[proxy] - y_axis: bevy::math::DVec2, - ) -> bevy::math::DMat2; - -"#, - r#" -/// Creates a `[f64; 4]` array storing data in column major order. -/// If you require data in row major order `transpose` the matrix first. - - #[lua(kind = "Method")] - fn to_cols_array(&self) -> [f64; 4]; - -"#, - r#" -/// Creates a `[[f64; 2]; 2]` 2D array storing data in column major order. -/// If you require data in row major order `transpose` the matrix first. - - #[lua(kind = "Method")] - fn to_cols_array_2d(&self) -> [[f64; 2]; 2]; - -"#, - r#" -/// Creates a 2x2 matrix with its diagonal set to `diagonal` and all other entries set to 0. - - #[lua(kind = "Function", output(proxy))] - fn from_diagonal(#[proxy] diagonal: bevy::math::DVec2) -> bevy::math::DMat2; - -"#, - r#" -/// Creates a 2x2 matrix containing the combining non-uniform `scale` and rotation of -/// `angle` (in radians). - - #[lua(kind = "Function", output(proxy))] - fn from_scale_angle( - #[proxy] - scale: bevy::math::DVec2, - angle: f64, - ) -> bevy::math::DMat2; - -"#, - r#" -/// Creates a 2x2 matrix containing a rotation of `angle` (in radians). - - #[lua(kind = "Function", output(proxy))] - fn from_angle(angle: f64) -> bevy::math::DMat2; - -"#, - r#" -/// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column. - - #[lua(kind = "Function", output(proxy))] - fn from_mat3(#[proxy] m: bevy::math::DMat3) -> bevy::math::DMat2; - -"#, - r#" -/// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column -/// and `j`th row. -/// # Panics -/// Panics if `i` or `j` is greater than 2. - - #[lua(kind = "Function", output(proxy))] - fn from_mat3_minor( - #[proxy] - m: bevy::math::DMat3, - i: usize, - j: usize, - ) -> bevy::math::DMat2; - -"#, - r#" -/// Returns the matrix column for the given `index`. -/// # Panics -/// Panics if `index` is greater than 1. - - #[lua(kind = "Method", output(proxy))] - fn col(&self, index: usize) -> bevy::math::DVec2; - -"#, - r#" -/// Returns the matrix row for the given `index`. -/// # Panics -/// Panics if `index` is greater than 1. - - #[lua(kind = "Method", output(proxy))] - fn row(&self, index: usize) -> bevy::math::DVec2; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. -/// If any element is either `NaN`, positive or negative infinity, this will return `false`. - - #[lua(kind = "Method")] - fn is_finite(&self) -> bool; - -"#, - r#" -/// Returns `true` if any elements are `NaN`. - - #[lua(kind = "Method")] - fn is_nan(&self) -> bool; - -"#, - r#" -/// Returns the transpose of `self`. - - #[lua(kind = "Method", output(proxy))] - fn transpose(&self) -> bevy::math::DMat2; - -"#, - r#" -/// Returns the determinant of `self`. - - #[lua(kind = "Method")] - fn determinant(&self) -> f64; - -"#, - r#" -/// Returns the inverse of `self`. -/// If the matrix is not invertible the returned matrix will be invalid. -/// # Panics -/// Will panic if the determinant of `self` is zero when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn inverse(&self) -> bevy::math::DMat2; - -"#, - r#" -/// Transforms a 2D vector. - - #[lua(kind = "Method", output(proxy))] - fn mul_vec2(&self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" -/// Multiplies two 2x2 matrices. - - #[lua(kind = "Method", output(proxy))] - fn mul_mat2(&self, #[proxy] rhs: &glam::DMat2) -> bevy::math::DMat2; - -"#, - r#" -/// Adds two 2x2 matrices. - - #[lua(kind = "Method", output(proxy))] - fn add_mat2(&self, #[proxy] rhs: &glam::DMat2) -> bevy::math::DMat2; - -"#, - r#" -/// Subtracts two 2x2 matrices. - - #[lua(kind = "Method", output(proxy))] - fn sub_mat2(&self, #[proxy] rhs: &glam::DMat2) -> bevy::math::DMat2; - -"#, - r#" -/// Multiplies a 2x2 matrix by a scalar. - - #[lua(kind = "Method", output(proxy))] - fn mul_scalar(&self, rhs: f64) -> bevy::math::DMat2; - -"#, - r#" -/// Divides a 2x2 matrix by a scalar. - - #[lua(kind = "Method", output(proxy))] - fn div_scalar(&self, rhs: f64) -> bevy::math::DMat2; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` -/// is less than or equal to `max_abs_diff`. -/// This can be used to compare if two matrices contain similar elements. It works best -/// when comparing with a known value. The `max_abs_diff` that should be used used -/// depends on the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(&self, #[proxy] rhs: bevy::math::DMat2, max_abs_diff: f64) -> bool; - -"#, - r#" -/// Takes the absolute value of each element in `self` - - #[lua(kind = "Method", output(proxy))] - fn abs(&self) -> bevy::math::DMat2; - -"#, - r#" - - #[lua(kind = "Method", output(proxy))] - fn as_mat2(&self) -> bevy::math::Mat2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f64) -> bevy::math::DMat2; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::DMat2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::DMat2) -> bevy::math::DMat2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: f64) -> bevy::math::DMat2; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] rhs: &glam::DMat2) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::DMat2) -> bevy::math::DMat2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::DMat2) -> bevy::math::DMat2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::DMat2; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind = "MetaMethod", raw, metamethod="Index")] -fn index(&self, ctx : &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(LuaDVec2::new_ref( - self.reflect_ref(ctx.get_world()?).sub_ref(bevy_script_api::ReflectionPathElement::SubReflection{ - label:"col", - get: std::sync::Arc::new(|ref_| Err(bevy_script_api::error::ReflectionError::InsufficientProvenance{ - path: "".to_owned(), - msg: "Cannot get column of matrix with immutable reference".to_owned() - })), - get_mut: std::sync::Arc::new(move |ref_| { - if ref_.is::(){ - Ok(ref_.downcast_mut::() - .unwrap() - .col_mut(*idx)) - } else { - Err(bevy_script_api::error::ReflectionError::CannotDowncast{from: ref_.get_represented_type_info().unwrap().type_path().into(), to:"Mat3".into()}) - } - }) - }) - ) - ) -} -"#] -)] -struct DMat2 { - #[lua(output(proxy))] - x_axis: bevy::math::DVec2, - #[lua(output(proxy))] - y_axis: bevy::math::DVec2, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::DMat3", - functions[r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::DMat3) -> bevy::math::DMat3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f64) -> bevy::math::DMat3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::DMat3) -> bevy::math::DMat3; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::DMat3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::DMat3) -> bevy::math::DMat3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::DAffine2) -> bevy::math::DMat3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: f64) -> bevy::math::DMat3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::DMat3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] rhs: &glam::DMat3) -> bool; - -"#, - r#" -/// Creates a 3x3 matrix from three column vectors. - - #[lua(kind = "Function", output(proxy))] - fn from_cols( - #[proxy] - x_axis: bevy::math::DVec3, - #[proxy] - y_axis: bevy::math::DVec3, - #[proxy] - z_axis: bevy::math::DVec3, - ) -> bevy::math::DMat3; - -"#, - r#" -/// Creates a `[f64; 9]` array storing data in column major order. -/// If you require data in row major order `transpose` the matrix first. - - #[lua(kind = "Method")] - fn to_cols_array(&self) -> [f64; 9]; - -"#, - r#" -/// Creates a `[[f64; 3]; 3]` 3D array storing data in column major order. -/// If you require data in row major order `transpose` the matrix first. - - #[lua(kind = "Method")] - fn to_cols_array_2d(&self) -> [[f64; 3]; 3]; - -"#, - r#" -/// Creates a 3x3 matrix with its diagonal set to `diagonal` and all other entries set to 0. - - #[lua(kind = "Function", output(proxy))] - fn from_diagonal(#[proxy] diagonal: bevy::math::DVec3) -> bevy::math::DMat3; - -"#, - r#" -/// Creates a 3x3 matrix from a 4x4 matrix, discarding the 4th row and column. - - #[lua(kind = "Function", output(proxy))] - fn from_mat4(#[proxy] m: bevy::math::DMat4) -> bevy::math::DMat3; - -"#, - r#" -/// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column -/// and `j`th row. -/// # Panics -/// Panics if `i` or `j` is greater than 3. - - #[lua(kind = "Function", output(proxy))] - fn from_mat4_minor( - #[proxy] - m: bevy::math::DMat4, - i: usize, - j: usize, - ) -> bevy::math::DMat3; - -"#, - r#" -/// Creates a 3D rotation matrix from the given quaternion. -/// # Panics -/// Will panic if `rotation` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_quat(#[proxy] rotation: bevy::math::DQuat) -> bevy::math::DMat3; - -"#, - r#" -/// Creates a 3D rotation matrix from a normalized rotation `axis` and `angle` (in -/// radians). -/// # Panics -/// Will panic if `axis` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_axis_angle( - #[proxy] - axis: bevy::math::DVec3, - angle: f64, - ) -> bevy::math::DMat3; - -"#, - r#" -/// Creates a 3D rotation matrix from the given euler rotation sequence and the angles (in -/// radians). - - #[lua(kind = "Function", output(proxy))] - fn from_euler( - #[proxy] - order: bevy::math::EulerRot, - a: f64, - b: f64, - c: f64, - ) -> bevy::math::DMat3; - -"#, - r#" -/// Extract Euler angles with the given Euler rotation order. -/// Note if the input matrix contains scales, shears, or other non-rotation transformations then -/// the resulting Euler angles will be ill-defined. -/// # Panics -/// Will panic if any input matrix column is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method")] - fn to_euler(&self, #[proxy] order: bevy::math::EulerRot) -> (f64, f64, f64); - -"#, - r#" -/// Creates a 3D rotation matrix from `angle` (in radians) around the x axis. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_x(angle: f64) -> bevy::math::DMat3; - -"#, - r#" -/// Creates a 3D rotation matrix from `angle` (in radians) around the y axis. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_y(angle: f64) -> bevy::math::DMat3; - -"#, - r#" -/// Creates a 3D rotation matrix from `angle` (in radians) around the z axis. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_z(angle: f64) -> bevy::math::DMat3; - -"#, - r#" -/// Creates an affine transformation matrix from the given 2D `translation`. -/// The resulting matrix can be used to transform 2D points and vectors. See -/// [`Self::transform_point2()`] and [`Self::transform_vector2()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_translation(#[proxy] translation: bevy::math::DVec2) -> bevy::math::DMat3; - -"#, - r#" -/// Creates an affine transformation matrix from the given 2D rotation `angle` (in -/// radians). -/// The resulting matrix can be used to transform 2D points and vectors. See -/// [`Self::transform_point2()`] and [`Self::transform_vector2()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_angle(angle: f64) -> bevy::math::DMat3; - -"#, - r#" -/// Creates an affine transformation matrix from the given 2D `scale`, rotation `angle` (in -/// radians) and `translation`. -/// The resulting matrix can be used to transform 2D points and vectors. See -/// [`Self::transform_point2()`] and [`Self::transform_vector2()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_scale_angle_translation( - #[proxy] - scale: bevy::math::DVec2, - angle: f64, - #[proxy] - translation: bevy::math::DVec2, - ) -> bevy::math::DMat3; - -"#, - r#" -/// Creates an affine transformation matrix from the given non-uniform 2D `scale`. -/// The resulting matrix can be used to transform 2D points and vectors. See -/// [`Self::transform_point2()`] and [`Self::transform_vector2()`]. -/// # Panics -/// Will panic if all elements of `scale` are zero when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_scale(#[proxy] scale: bevy::math::DVec2) -> bevy::math::DMat3; - -"#, - r#" -/// Creates an affine transformation matrix from the given 2x2 matrix. -/// The resulting matrix can be used to transform 2D points and vectors. See -/// [`Self::transform_point2()`] and [`Self::transform_vector2()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_mat2(#[proxy] m: bevy::math::DMat2) -> bevy::math::DMat3; - -"#, - r#" -/// Returns the matrix column for the given `index`. -/// # Panics -/// Panics if `index` is greater than 2. - - #[lua(kind = "Method", output(proxy))] - fn col(&self, index: usize) -> bevy::math::DVec3; - -"#, - r#" -/// Returns the matrix row for the given `index`. -/// # Panics -/// Panics if `index` is greater than 2. - - #[lua(kind = "Method", output(proxy))] - fn row(&self, index: usize) -> bevy::math::DVec3; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. -/// If any element is either `NaN`, positive or negative infinity, this will return `false`. - - #[lua(kind = "Method")] - fn is_finite(&self) -> bool; - -"#, - r#" -/// Returns `true` if any elements are `NaN`. - - #[lua(kind = "Method")] - fn is_nan(&self) -> bool; - -"#, - r#" -/// Returns the transpose of `self`. - - #[lua(kind = "Method", output(proxy))] - fn transpose(&self) -> bevy::math::DMat3; - -"#, - r#" -/// Returns the determinant of `self`. - - #[lua(kind = "Method")] - fn determinant(&self) -> f64; - -"#, - r#" -/// Returns the inverse of `self`. -/// If the matrix is not invertible the returned matrix will be invalid. -/// # Panics -/// Will panic if the determinant of `self` is zero when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn inverse(&self) -> bevy::math::DMat3; - -"#, - r#" -/// Transforms the given 2D vector as a point. -/// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `1`. -/// This method assumes that `self` contains a valid affine transform. -/// # Panics -/// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn transform_point2(&self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" -/// Rotates the given 2D vector. -/// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `0`. -/// This method assumes that `self` contains a valid affine transform. -/// # Panics -/// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn transform_vector2(&self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" -/// Transforms a 3D vector. - - #[lua(kind = "Method", output(proxy))] - fn mul_vec3(&self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Multiplies two 3x3 matrices. - - #[lua(kind = "Method", output(proxy))] - fn mul_mat3(&self, #[proxy] rhs: &glam::DMat3) -> bevy::math::DMat3; - -"#, - r#" -/// Adds two 3x3 matrices. - - #[lua(kind = "Method", output(proxy))] - fn add_mat3(&self, #[proxy] rhs: &glam::DMat3) -> bevy::math::DMat3; - -"#, - r#" -/// Subtracts two 3x3 matrices. - - #[lua(kind = "Method", output(proxy))] - fn sub_mat3(&self, #[proxy] rhs: &glam::DMat3) -> bevy::math::DMat3; - -"#, - r#" -/// Multiplies a 3x3 matrix by a scalar. - - #[lua(kind = "Method", output(proxy))] - fn mul_scalar(&self, rhs: f64) -> bevy::math::DMat3; - -"#, - r#" -/// Divides a 3x3 matrix by a scalar. - - #[lua(kind = "Method", output(proxy))] - fn div_scalar(&self, rhs: f64) -> bevy::math::DMat3; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` -/// is less than or equal to `max_abs_diff`. -/// This can be used to compare if two matrices contain similar elements. It works best -/// when comparing with a known value. The `max_abs_diff` that should be used used -/// depends on the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(&self, #[proxy] rhs: bevy::math::DMat3, max_abs_diff: f64) -> bool; - -"#, - r#" -/// Takes the absolute value of each element in `self` - - #[lua(kind = "Method", output(proxy))] - fn abs(&self) -> bevy::math::DMat3; - -"#, - r#" - - #[lua(kind = "Method", output(proxy))] - fn as_mat3(&self) -> bevy::math::Mat3; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind = "MetaMethod", raw, metamethod="Index")] -fn index(&self, ctx : &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(LuaDVec3::new_ref( - self.reflect_ref(ctx.get_world()?).sub_ref(bevy_script_api::ReflectionPathElement::SubReflection{ - label:"col", - get: std::sync::Arc::new(|ref_| Err(bevy_script_api::error::ReflectionError::InsufficientProvenance{ - path: "".to_owned(), - msg: "Cannot get column of matrix with immutable reference".to_owned() - })), - get_mut: std::sync::Arc::new(move |ref_| { - if ref_.is::(){ - Ok(ref_.downcast_mut::() - .unwrap() - .col_mut(*idx)) - } else { - Err(bevy_script_api::error::ReflectionError::CannotDowncast{from: ref_.get_represented_type_info().unwrap().type_path().into(), to:"Mat3".into()}) - } - }) - }) - ) - ) -} -"#] -)] -struct DMat3 { - #[lua(output(proxy))] - x_axis: bevy::math::DVec3, - #[lua(output(proxy))] - y_axis: bevy::math::DVec3, - #[lua(output(proxy))] - z_axis: bevy::math::DVec3, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::DMat4", - functions[r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::DMat4) -> bevy::math::DMat4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: f64) -> bevy::math::DMat4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::DAffine3) -> bevy::math::DMat4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::DMat4) -> bevy::math::DMat4; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] rhs: &glam::DMat4) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f64) -> bevy::math::DMat4; - -"#, - r#" -/// Creates a 4x4 matrix from four column vectors. - - #[lua(kind = "Function", output(proxy))] - fn from_cols( - #[proxy] - x_axis: bevy::math::DVec4, - #[proxy] - y_axis: bevy::math::DVec4, - #[proxy] - z_axis: bevy::math::DVec4, - #[proxy] - w_axis: bevy::math::DVec4, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Creates a `[f64; 16]` array storing data in column major order. -/// If you require data in row major order `transpose` the matrix first. - - #[lua(kind = "Method")] - fn to_cols_array(&self) -> [f64; 16]; - -"#, - r#" -/// Creates a `[[f64; 4]; 4]` 4D array storing data in column major order. -/// If you require data in row major order `transpose` the matrix first. - - #[lua(kind = "Method")] - fn to_cols_array_2d(&self) -> [[f64; 4]; 4]; - -"#, - r#" -/// Creates a 4x4 matrix with its diagonal set to `diagonal` and all other entries set to 0. - - #[lua(kind = "Function", output(proxy))] - fn from_diagonal(#[proxy] diagonal: bevy::math::DVec4) -> bevy::math::DMat4; - -"#, - r#" -/// Creates an affine transformation matrix from the given 3D `scale`, `rotation` and -/// `translation`. -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. -/// # Panics -/// Will panic if `rotation` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_scale_rotation_translation( - #[proxy] - scale: bevy::math::DVec3, - #[proxy] - rotation: bevy::math::DQuat, - #[proxy] - translation: bevy::math::DVec3, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Creates an affine transformation matrix from the given 3D `translation`. -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. -/// # Panics -/// Will panic if `rotation` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_translation( - #[proxy] - rotation: bevy::math::DQuat, - #[proxy] - translation: bevy::math::DVec3, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Creates an affine transformation matrix from the given `rotation` quaternion. -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. -/// # Panics -/// Will panic if `rotation` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_quat(#[proxy] rotation: bevy::math::DQuat) -> bevy::math::DMat4; - -"#, - r#" -/// Creates an affine transformation matrix from the given 3x3 linear transformation -/// matrix. -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_mat3(#[proxy] m: bevy::math::DMat3) -> bevy::math::DMat4; - -"#, - r#" -/// Creates an affine transformation matrix from the given 3D `translation`. -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_translation(#[proxy] translation: bevy::math::DVec3) -> bevy::math::DMat4; - -"#, - r#" -/// Creates an affine transformation matrix containing a 3D rotation around a normalized -/// rotation `axis` of `angle` (in radians). -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. -/// # Panics -/// Will panic if `axis` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_axis_angle( - #[proxy] - axis: bevy::math::DVec3, - angle: f64, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Creates a affine transformation matrix containing a rotation from the given euler -/// rotation sequence and angles (in radians). -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_euler( - #[proxy] - order: bevy::math::EulerRot, - a: f64, - b: f64, - c: f64, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Extract Euler angles with the given Euler rotation order. -/// Note if the upper 3x3 matrix contain scales, shears, or other non-rotation transformations -/// then the resulting Euler angles will be ill-defined. -/// # Panics -/// Will panic if any column of the upper 3x3 rotation matrix is not normalized when -/// `glam_assert` is enabled. - - #[lua(kind = "Method")] - fn to_euler(&self, #[proxy] order: bevy::math::EulerRot) -> (f64, f64, f64); - -"#, - r#" -/// Creates an affine transformation matrix containing a 3D rotation around the x axis of -/// `angle` (in radians). -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_x(angle: f64) -> bevy::math::DMat4; - -"#, - r#" -/// Creates an affine transformation matrix containing a 3D rotation around the y axis of -/// `angle` (in radians). -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_y(angle: f64) -> bevy::math::DMat4; - -"#, - r#" -/// Creates an affine transformation matrix containing a 3D rotation around the z axis of -/// `angle` (in radians). -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_z(angle: f64) -> bevy::math::DMat4; - -"#, - r#" -/// Creates an affine transformation matrix containing the given 3D non-uniform `scale`. -/// The resulting matrix can be used to transform 3D points and vectors. See -/// [`Self::transform_point3()`] and [`Self::transform_vector3()`]. -/// # Panics -/// Will panic if all elements of `scale` are zero when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_scale(#[proxy] scale: bevy::math::DVec3) -> bevy::math::DMat4; - -"#, - r#" -/// Returns the matrix column for the given `index`. -/// # Panics -/// Panics if `index` is greater than 3. - - #[lua(kind = "Method", output(proxy))] - fn col(&self, index: usize) -> bevy::math::DVec4; - -"#, - r#" -/// Returns the matrix row for the given `index`. -/// # Panics -/// Panics if `index` is greater than 3. - - #[lua(kind = "Method", output(proxy))] - fn row(&self, index: usize) -> bevy::math::DVec4; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. -/// If any element is either `NaN`, positive or negative infinity, this will return `false`. - - #[lua(kind = "Method")] - fn is_finite(&self) -> bool; - -"#, - r#" -/// Returns `true` if any elements are `NaN`. - - #[lua(kind = "Method")] - fn is_nan(&self) -> bool; - -"#, - r#" -/// Returns the transpose of `self`. - - #[lua(kind = "Method", output(proxy))] - fn transpose(&self) -> bevy::math::DMat4; - -"#, - r#" -/// Returns the determinant of `self`. - - #[lua(kind = "Method")] - fn determinant(&self) -> f64; - -"#, - r#" -/// Returns the inverse of `self`. -/// If the matrix is not invertible the returned matrix will be invalid. -/// # Panics -/// Will panic if the determinant of `self` is zero when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn inverse(&self) -> bevy::math::DMat4; - -"#, - r#" -/// Creates a left-handed view matrix using a camera position, an up direction, and a facing -/// direction. -/// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`. - - #[lua(kind = "Function", output(proxy))] - fn look_to_lh( - #[proxy] - eye: bevy::math::DVec3, - #[proxy] - dir: bevy::math::DVec3, - #[proxy] - up: bevy::math::DVec3, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Creates a right-handed view matrix using a camera position, an up direction, and a facing -/// direction. -/// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`. - - #[lua(kind = "Function", output(proxy))] - fn look_to_rh( - #[proxy] - eye: bevy::math::DVec3, - #[proxy] - dir: bevy::math::DVec3, - #[proxy] - up: bevy::math::DVec3, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Creates a left-handed view matrix using a camera position, an up direction, and a focal -/// point. -/// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`. -/// # Panics -/// Will panic if `up` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn look_at_lh( - #[proxy] - eye: bevy::math::DVec3, - #[proxy] - center: bevy::math::DVec3, - #[proxy] - up: bevy::math::DVec3, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Creates a right-handed view matrix using a camera position, an up direction, and a focal -/// point. -/// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`. -/// # Panics -/// Will panic if `up` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn look_at_rh( - #[proxy] - eye: bevy::math::DVec3, - #[proxy] - center: bevy::math::DVec3, - #[proxy] - up: bevy::math::DVec3, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Creates a right-handed perspective projection matrix with `[-1,1]` depth range. -/// Useful to map the standard right-handed coordinate system into what OpenGL expects. -/// This is the same as the OpenGL `gluPerspective` function. -/// See - - #[lua(kind = "Function", output(proxy))] - fn perspective_rh_gl( - fov_y_radians: f64, - aspect_ratio: f64, - z_near: f64, - z_far: f64, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Creates a left-handed perspective projection matrix with `[0,1]` depth range. -/// Useful to map the standard left-handed coordinate system into what WebGPU/Metal/Direct3D expect. -/// # Panics -/// Will panic if `z_near` or `z_far` are less than or equal to zero when `glam_assert` is -/// enabled. - - #[lua(kind = "Function", output(proxy))] - fn perspective_lh( - fov_y_radians: f64, - aspect_ratio: f64, - z_near: f64, - z_far: f64, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Creates a right-handed perspective projection matrix with `[0,1]` depth range. -/// Useful to map the standard right-handed coordinate system into what WebGPU/Metal/Direct3D expect. -/// # Panics -/// Will panic if `z_near` or `z_far` are less than or equal to zero when `glam_assert` is -/// enabled. - - #[lua(kind = "Function", output(proxy))] - fn perspective_rh( - fov_y_radians: f64, - aspect_ratio: f64, - z_near: f64, - z_far: f64, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Creates an infinite left-handed perspective projection matrix with `[0,1]` depth range. -/// Like `perspective_lh`, but with an infinite value for `z_far`. -/// The result is that points near `z_near` are mapped to depth `0`, and as they move towards infinity the depth approaches `1`. -/// # Panics -/// Will panic if `z_near` or `z_far` are less than or equal to zero when `glam_assert` is -/// enabled. - - #[lua(kind = "Function", output(proxy))] - fn perspective_infinite_lh( - fov_y_radians: f64, - aspect_ratio: f64, - z_near: f64, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Creates an infinite reverse left-handed perspective projection matrix with `[0,1]` depth range. -/// Similar to `perspective_infinite_lh`, but maps `Z = z_near` to a depth of `1` and `Z = infinity` to a depth of `0`. -/// # Panics -/// Will panic if `z_near` is less than or equal to zero when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn perspective_infinite_reverse_lh( - fov_y_radians: f64, - aspect_ratio: f64, - z_near: f64, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Creates an infinite right-handed perspective projection matrix with `[0,1]` depth range. -/// Like `perspective_rh`, but with an infinite value for `z_far`. -/// The result is that points near `z_near` are mapped to depth `0`, and as they move towards infinity the depth approaches `1`. -/// # Panics -/// Will panic if `z_near` or `z_far` are less than or equal to zero when `glam_assert` is -/// enabled. - - #[lua(kind = "Function", output(proxy))] - fn perspective_infinite_rh( - fov_y_radians: f64, - aspect_ratio: f64, - z_near: f64, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Creates an infinite reverse right-handed perspective projection matrix with `[0,1]` depth range. -/// Similar to `perspective_infinite_rh`, but maps `Z = z_near` to a depth of `1` and `Z = infinity` to a depth of `0`. -/// # Panics -/// Will panic if `z_near` is less than or equal to zero when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn perspective_infinite_reverse_rh( - fov_y_radians: f64, - aspect_ratio: f64, - z_near: f64, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Creates a right-handed orthographic projection matrix with `[-1,1]` depth -/// range. This is the same as the OpenGL `glOrtho` function in OpenGL. -/// See -/// -/// Useful to map a right-handed coordinate system to the normalized device coordinates that OpenGL expects. - - #[lua(kind = "Function", output(proxy))] - fn orthographic_rh_gl( - left: f64, - right: f64, - bottom: f64, - top: f64, - near: f64, - far: f64, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Creates a left-handed orthographic projection matrix with `[0,1]` depth range. -/// Useful to map a left-handed coordinate system to the normalized device coordinates that WebGPU/Direct3D/Metal expect. - - #[lua(kind = "Function", output(proxy))] - fn orthographic_lh( - left: f64, - right: f64, - bottom: f64, - top: f64, - near: f64, - far: f64, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Creates a right-handed orthographic projection matrix with `[0,1]` depth range. -/// Useful to map a right-handed coordinate system to the normalized device coordinates that WebGPU/Direct3D/Metal expect. - - #[lua(kind = "Function", output(proxy))] - fn orthographic_rh( - left: f64, - right: f64, - bottom: f64, - top: f64, - near: f64, - far: f64, - ) -> bevy::math::DMat4; - -"#, - r#" -/// Transforms the given 3D vector as a point, applying perspective correction. -/// This is the equivalent of multiplying the 3D vector as a 4D vector where `w` is `1.0`. -/// The perspective divide is performed meaning the resulting 3D vector is divided by `w`. -/// This method assumes that `self` contains a projective transform. - - #[lua(kind = "Method", output(proxy))] - fn project_point3(&self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Transforms the given 3D vector as a point. -/// This is the equivalent of multiplying the 3D vector as a 4D vector where `w` is -/// `1.0`. -/// This method assumes that `self` contains a valid affine transform. It does not perform -/// a perspective divide, if `self` contains a perspective transform, or if you are unsure, -/// the [`Self::project_point3()`] method should be used instead. -/// # Panics -/// Will panic if the 3rd row of `self` is not `(0, 0, 0, 1)` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn transform_point3(&self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Transforms the give 3D vector as a direction. -/// This is the equivalent of multiplying the 3D vector as a 4D vector where `w` is -/// `0.0`. -/// This method assumes that `self` contains a valid affine transform. -/// # Panics -/// Will panic if the 3rd row of `self` is not `(0, 0, 0, 1)` when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn transform_vector3(&self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Transforms a 4D vector. - - #[lua(kind = "Method", output(proxy))] - fn mul_vec4(&self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::DVec4; - -"#, - r#" -/// Multiplies two 4x4 matrices. - - #[lua(kind = "Method", output(proxy))] - fn mul_mat4(&self, #[proxy] rhs: &glam::DMat4) -> bevy::math::DMat4; - -"#, - r#" -/// Adds two 4x4 matrices. - - #[lua(kind = "Method", output(proxy))] - fn add_mat4(&self, #[proxy] rhs: &glam::DMat4) -> bevy::math::DMat4; - -"#, - r#" -/// Subtracts two 4x4 matrices. - - #[lua(kind = "Method", output(proxy))] - fn sub_mat4(&self, #[proxy] rhs: &glam::DMat4) -> bevy::math::DMat4; - -"#, - r#" -/// Multiplies a 4x4 matrix by a scalar. - - #[lua(kind = "Method", output(proxy))] - fn mul_scalar(&self, rhs: f64) -> bevy::math::DMat4; - -"#, - r#" -/// Divides a 4x4 matrix by a scalar. - - #[lua(kind = "Method", output(proxy))] - fn div_scalar(&self, rhs: f64) -> bevy::math::DMat4; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` -/// is less than or equal to `max_abs_diff`. -/// This can be used to compare if two matrices contain similar elements. It works best -/// when comparing with a known value. The `max_abs_diff` that should be used used -/// depends on the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(&self, #[proxy] rhs: bevy::math::DMat4, max_abs_diff: f64) -> bool; - -"#, - r#" -/// Takes the absolute value of each element in `self` - - #[lua(kind = "Method", output(proxy))] - fn abs(&self) -> bevy::math::DMat4; - -"#, - r#" - - #[lua(kind = "Method", output(proxy))] - fn as_mat4(&self) -> bevy::math::Mat4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::DMat4; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::DMat4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::DMat4) -> bevy::math::DMat4; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::DVec4) -> bevy::math::DVec4; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#, - r#" -#[lua(kind = "MetaMethod", raw, metamethod="Index")] -fn index(&self, ctx : &Lua, idx: crate::lua::util::LuaIndex) -> Result { - Ok(LuaDVec4::new_ref( - self.reflect_ref(ctx.get_world()?).sub_ref(bevy_script_api::ReflectionPathElement::SubReflection{ - label:"col", - get: std::sync::Arc::new(|ref_| Err(bevy_script_api::error::ReflectionError::InsufficientProvenance{ - path: "".to_owned(), - msg: "Cannot get column of matrix with immutable reference".to_owned() - })), - get_mut: std::sync::Arc::new(move |ref_| { - if ref_.is::(){ - Ok(ref_.downcast_mut::() - .unwrap() - .col_mut(*idx)) - } else { - Err(bevy_script_api::error::ReflectionError::CannotDowncast{from: ref_.get_represented_type_info().unwrap().type_path().into(), to:"Mat3".into()}) - } - }) - }) - ) - ) -} -"#] -)] -struct DMat4 { - #[lua(output(proxy))] - x_axis: bevy::math::DVec4, - #[lua(output(proxy))] - y_axis: bevy::math::DVec4, - #[lua(output(proxy))] - z_axis: bevy::math::DVec4, - #[lua(output(proxy))] - w_axis: bevy::math::DVec4, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::Affine2", - functions[r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Affine2) -> bevy::math::Affine2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Mat3) -> bevy::math::Mat3; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::Affine2; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Mat3A) -> bevy::math::Mat3A; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] rhs: &glam::Affine2) -> bool; - -"#, - r#" -/// Creates an affine transform from three column vectors. - - #[lua(kind = "Function", output(proxy))] - fn from_cols( - #[proxy] - x_axis: bevy::math::Vec2, - #[proxy] - y_axis: bevy::math::Vec2, - #[proxy] - z_axis: bevy::math::Vec2, - ) -> bevy::math::Affine2; - -"#, - r#" -/// Creates a `[f32; 6]` array storing data in column major order. - - #[lua(kind = "Method")] - fn to_cols_array(&self) -> [f32; 6]; - -"#, - r#" -/// Creates a `[[f32; 2]; 3]` 2D array storing data in -/// column major order. -/// If you require data in row major order `transpose` the matrix first. - - #[lua(kind = "Method")] - fn to_cols_array_2d(&self) -> [[f32; 2]; 3]; - -"#, - r#" -/// Creates an affine transform that changes scale. -/// Note that if any scale is zero the transform will be non-invertible. - - #[lua(kind = "Function", output(proxy))] - fn from_scale(#[proxy] scale: bevy::math::Vec2) -> bevy::math::Affine2; - -"#, - r#" -/// Creates an affine transform from the given rotation `angle`. - - #[lua(kind = "Function", output(proxy))] - fn from_angle(angle: f32) -> bevy::math::Affine2; - -"#, - r#" -/// Creates an affine transformation from the given 2D `translation`. - - #[lua(kind = "Function", output(proxy))] - fn from_translation(#[proxy] translation: bevy::math::Vec2) -> bevy::math::Affine2; - -"#, - r#" -/// Creates an affine transform from a 2x2 matrix (expressing scale, shear and rotation) - - #[lua(kind = "Function", output(proxy))] - fn from_mat2(#[proxy] matrix2: bevy::math::Mat2) -> bevy::math::Affine2; - -"#, - r#" -/// Creates an affine transform from a 2x2 matrix (expressing scale, shear and rotation) and a -/// translation vector. -/// Equivalent to -/// `Affine2::from_translation(translation) * Affine2::from_mat2(mat2)` - - #[lua(kind = "Function", output(proxy))] - fn from_mat2_translation( - #[proxy] - matrix2: bevy::math::Mat2, - #[proxy] - translation: bevy::math::Vec2, - ) -> bevy::math::Affine2; - -"#, - r#" -/// Creates an affine transform from the given 2D `scale`, rotation `angle` (in radians) and -/// `translation`. -/// Equivalent to `Affine2::from_translation(translation) * -/// Affine2::from_angle(angle) * Affine2::from_scale(scale)` - - #[lua(kind = "Function", output(proxy))] - fn from_scale_angle_translation( - #[proxy] - scale: bevy::math::Vec2, - angle: f32, - #[proxy] - translation: bevy::math::Vec2, - ) -> bevy::math::Affine2; - -"#, - r#" -/// Creates an affine transform from the given 2D rotation `angle` (in radians) and -/// `translation`. -/// Equivalent to `Affine2::from_translation(translation) * Affine2::from_angle(angle)` - - #[lua(kind = "Function", output(proxy))] - fn from_angle_translation( - angle: f32, - #[proxy] - translation: bevy::math::Vec2, - ) -> bevy::math::Affine2; - -"#, - r#" -/// The given `Mat3` must be an affine transform, - - #[lua(kind = "Function", output(proxy))] - fn from_mat3(#[proxy] m: bevy::math::Mat3) -> bevy::math::Affine2; - -"#, - r#" -/// The given [`Mat3A`] must be an affine transform, - - #[lua(kind = "Function", output(proxy))] - fn from_mat3a(#[proxy] m: bevy::math::Mat3A) -> bevy::math::Affine2; - -"#, - r#" -/// Transforms the given 2D point, applying shear, scale, rotation and translation. - - #[lua(kind = "Method", output(proxy))] - fn transform_point2(&self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Transforms the given 2D vector, applying shear, scale and rotation (but NOT -/// translation). -/// To also apply translation, use [`Self::transform_point2()`] instead. - - #[lua(kind = "Method", output(proxy))] - fn transform_vector2(&self, #[proxy] rhs: bevy::math::Vec2) -> bevy::math::Vec2; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. -/// If any element is either `NaN`, positive or negative infinity, this will return -/// `false`. - - #[lua(kind = "Method")] - fn is_finite(&self) -> bool; - -"#, - r#" -/// Returns `true` if any elements are `NaN`. - - #[lua(kind = "Method")] - fn is_nan(&self) -> bool; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` -/// is less than or equal to `max_abs_diff`. -/// This can be used to compare if two 3x4 matrices contain similar elements. It works -/// best when comparing with a known value. The `max_abs_diff` that should be used used -/// depends on the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(&self, #[proxy] rhs: bevy::math::Affine2, max_abs_diff: f32) -> bool; - -"#, - r#" -/// Return the inverse of this transform. -/// Note that if the transform is not invertible the result will be invalid. - - #[lua(kind = "Method", output(proxy))] - fn inverse(&self) -> bevy::math::Affine2; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Affine2 { - #[lua(output(proxy))] - matrix2: bevy::math::Mat2, - #[lua(output(proxy))] - translation: bevy::math::Vec2, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::Affine3A", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] rhs: &glam::Affine3A) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Affine3A) -> bevy::math::Affine3A; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::Affine3A; - -"#, - r#" -/// Creates an affine transform from three column vectors. - - #[lua(kind = "Function", output(proxy))] - fn from_cols( - #[proxy] - x_axis: bevy::math::Vec3A, - #[proxy] - y_axis: bevy::math::Vec3A, - #[proxy] - z_axis: bevy::math::Vec3A, - #[proxy] - w_axis: bevy::math::Vec3A, - ) -> bevy::math::Affine3A; - -"#, - r#" -/// Creates a `[f32; 12]` array storing data in column major order. - - #[lua(kind = "Method")] - fn to_cols_array(&self) -> [f32; 12]; - -"#, - r#" -/// Creates a `[[f32; 3]; 4]` 3D array storing data in -/// column major order. -/// If you require data in row major order `transpose` the matrix first. - - #[lua(kind = "Method")] - fn to_cols_array_2d(&self) -> [[f32; 3]; 4]; - -"#, - r#" -/// Creates an affine transform that changes scale. -/// Note that if any scale is zero the transform will be non-invertible. - - #[lua(kind = "Function", output(proxy))] - fn from_scale(#[proxy] scale: bevy::math::Vec3) -> bevy::math::Affine3A; - -"#, - r#" -/// Creates an affine transform from the given `rotation` quaternion. - - #[lua(kind = "Function", output(proxy))] - fn from_quat(#[proxy] rotation: bevy::math::Quat) -> bevy::math::Affine3A; - -"#, - r#" -/// Creates an affine transform containing a 3D rotation around a normalized -/// rotation `axis` of `angle` (in radians). - - #[lua(kind = "Function", output(proxy))] - fn from_axis_angle( - #[proxy] - axis: bevy::math::Vec3, - angle: f32, - ) -> bevy::math::Affine3A; - -"#, - r#" -/// Creates an affine transform containing a 3D rotation around the x axis of -/// `angle` (in radians). - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_x(angle: f32) -> bevy::math::Affine3A; - -"#, - r#" -/// Creates an affine transform containing a 3D rotation around the y axis of -/// `angle` (in radians). - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_y(angle: f32) -> bevy::math::Affine3A; - -"#, - r#" -/// Creates an affine transform containing a 3D rotation around the z axis of -/// `angle` (in radians). - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_z(angle: f32) -> bevy::math::Affine3A; - -"#, - r#" -/// Creates an affine transformation from the given 3D `translation`. - - #[lua(kind = "Function", output(proxy))] - fn from_translation(#[proxy] translation: bevy::math::Vec3) -> bevy::math::Affine3A; - -"#, - r#" -/// Creates an affine transform from a 3x3 matrix (expressing scale, shear and -/// rotation) - - #[lua(kind = "Function", output(proxy))] - fn from_mat3(#[proxy] mat3: bevy::math::Mat3) -> bevy::math::Affine3A; - -"#, - r#" -/// Creates an affine transform from a 3x3 matrix (expressing scale, shear and rotation) -/// and a translation vector. -/// Equivalent to `Affine3A::from_translation(translation) * Affine3A::from_mat3(mat3)` - - #[lua(kind = "Function", output(proxy))] - fn from_mat3_translation( - #[proxy] - mat3: bevy::math::Mat3, - #[proxy] - translation: bevy::math::Vec3, - ) -> bevy::math::Affine3A; - -"#, - r#" -/// Creates an affine transform from the given 3D `scale`, `rotation` and -/// `translation`. -/// Equivalent to `Affine3A::from_translation(translation) * -/// Affine3A::from_quat(rotation) * Affine3A::from_scale(scale)` - - #[lua(kind = "Function", output(proxy))] - fn from_scale_rotation_translation( - #[proxy] - scale: bevy::math::Vec3, - #[proxy] - rotation: bevy::math::Quat, - #[proxy] - translation: bevy::math::Vec3, - ) -> bevy::math::Affine3A; - -"#, - r#" -/// Creates an affine transform from the given 3D `rotation` and `translation`. -/// Equivalent to `Affine3A::from_translation(translation) * Affine3A::from_quat(rotation)` - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_translation( - #[proxy] - rotation: bevy::math::Quat, - #[proxy] - translation: bevy::math::Vec3, - ) -> bevy::math::Affine3A; - -"#, - r#" -/// The given `Mat4` must be an affine transform, -/// i.e. contain no perspective transform. - - #[lua(kind = "Function", output(proxy))] - fn from_mat4(#[proxy] m: bevy::math::Mat4) -> bevy::math::Affine3A; - -"#, - r#" -/// Creates a left-handed view transform using a camera position, an up direction, and a facing -/// direction. -/// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`. - - #[lua(kind = "Function", output(proxy))] - fn look_to_lh( - #[proxy] - eye: bevy::math::Vec3, - #[proxy] - dir: bevy::math::Vec3, - #[proxy] - up: bevy::math::Vec3, - ) -> bevy::math::Affine3A; - -"#, - r#" -/// Creates a right-handed view transform using a camera position, an up direction, and a facing -/// direction. -/// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`. - - #[lua(kind = "Function", output(proxy))] - fn look_to_rh( - #[proxy] - eye: bevy::math::Vec3, - #[proxy] - dir: bevy::math::Vec3, - #[proxy] - up: bevy::math::Vec3, - ) -> bevy::math::Affine3A; - -"#, - r#" -/// Creates a left-handed view transform using a camera position, an up direction, and a focal -/// point. -/// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`. -/// # Panics -/// Will panic if `up` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn look_at_lh( - #[proxy] - eye: bevy::math::Vec3, - #[proxy] - center: bevy::math::Vec3, - #[proxy] - up: bevy::math::Vec3, - ) -> bevy::math::Affine3A; - -"#, - r#" -/// Creates a right-handed view transform using a camera position, an up direction, and a focal -/// point. -/// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`. -/// # Panics -/// Will panic if `up` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn look_at_rh( - #[proxy] - eye: bevy::math::Vec3, - #[proxy] - center: bevy::math::Vec3, - #[proxy] - up: bevy::math::Vec3, - ) -> bevy::math::Affine3A; - -"#, - r#" -/// Transforms the given 3D points, applying shear, scale, rotation and translation. - - #[lua(kind = "Method", output(proxy))] - fn transform_point3(&self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Transforms the given 3D vector, applying shear, scale and rotation (but NOT -/// translation). -/// To also apply translation, use [`Self::transform_point3()`] instead. - - #[lua(kind = "Method", output(proxy))] - fn transform_vector3(&self, #[proxy] rhs: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Transforms the given [`Vec3A`], applying shear, scale, rotation and translation. - - #[lua(kind = "Method", output(proxy))] - fn transform_point3a(&self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Transforms the given [`Vec3A`], applying shear, scale and rotation (but NOT -/// translation). -/// To also apply translation, use [`Self::transform_point3a()`] instead. - - #[lua(kind = "Method", output(proxy))] - fn transform_vector3a(&self, #[proxy] rhs: bevy::math::Vec3A) -> bevy::math::Vec3A; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. -/// If any element is either `NaN`, positive or negative infinity, this will return -/// `false`. - - #[lua(kind = "Method")] - fn is_finite(&self) -> bool; - -"#, - r#" -/// Returns `true` if any elements are `NaN`. - - #[lua(kind = "Method")] - fn is_nan(&self) -> bool; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` -/// is less than or equal to `max_abs_diff`. -/// This can be used to compare if two 3x4 matrices contain similar elements. It works -/// best when comparing with a known value. The `max_abs_diff` that should be used used -/// depends on the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(&self, #[proxy] rhs: bevy::math::Affine3A, max_abs_diff: f32) -> bool; - -"#, - r#" -/// Return the inverse of this transform. -/// Note that if the transform is not invertible the result will be invalid. - - #[lua(kind = "Method", output(proxy))] - fn inverse(&self) -> bevy::math::Affine3A; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::Mat4) -> bevy::math::Mat4; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Affine3A { - #[lua(output(proxy))] - matrix3: bevy::math::Mat3A, - #[lua(output(proxy))] - translation: bevy::math::Vec3A, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::DAffine2", - functions[r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::DMat3) -> bevy::math::DMat3; - -"#, - r#" -/// Creates an affine transform from three column vectors. - - #[lua(kind = "Function", output(proxy))] - fn from_cols( - #[proxy] - x_axis: bevy::math::DVec2, - #[proxy] - y_axis: bevy::math::DVec2, - #[proxy] - z_axis: bevy::math::DVec2, - ) -> bevy::math::DAffine2; - -"#, - r#" -/// Creates a `[f64; 6]` array storing data in column major order. - - #[lua(kind = "Method")] - fn to_cols_array(&self) -> [f64; 6]; - -"#, - r#" -/// Creates a `[[f64; 2]; 3]` 2D array storing data in -/// column major order. -/// If you require data in row major order `transpose` the matrix first. - - #[lua(kind = "Method")] - fn to_cols_array_2d(&self) -> [[f64; 2]; 3]; - -"#, - r#" -/// Creates an affine transform that changes scale. -/// Note that if any scale is zero the transform will be non-invertible. - - #[lua(kind = "Function", output(proxy))] - fn from_scale(#[proxy] scale: bevy::math::DVec2) -> bevy::math::DAffine2; - -"#, - r#" -/// Creates an affine transform from the given rotation `angle`. - - #[lua(kind = "Function", output(proxy))] - fn from_angle(angle: f64) -> bevy::math::DAffine2; - -"#, - r#" -/// Creates an affine transformation from the given 2D `translation`. - - #[lua(kind = "Function", output(proxy))] - fn from_translation(#[proxy] translation: bevy::math::DVec2) -> bevy::math::DAffine2; - -"#, - r#" -/// Creates an affine transform from a 2x2 matrix (expressing scale, shear and rotation) - - #[lua(kind = "Function", output(proxy))] - fn from_mat2(#[proxy] matrix2: bevy::math::DMat2) -> bevy::math::DAffine2; - -"#, - r#" -/// Creates an affine transform from a 2x2 matrix (expressing scale, shear and rotation) and a -/// translation vector. -/// Equivalent to -/// `DAffine2::from_translation(translation) * DAffine2::from_mat2(mat2)` - - #[lua(kind = "Function", output(proxy))] - fn from_mat2_translation( - #[proxy] - matrix2: bevy::math::DMat2, - #[proxy] - translation: bevy::math::DVec2, - ) -> bevy::math::DAffine2; - -"#, - r#" -/// Creates an affine transform from the given 2D `scale`, rotation `angle` (in radians) and -/// `translation`. -/// Equivalent to `DAffine2::from_translation(translation) * -/// DAffine2::from_angle(angle) * DAffine2::from_scale(scale)` - - #[lua(kind = "Function", output(proxy))] - fn from_scale_angle_translation( - #[proxy] - scale: bevy::math::DVec2, - angle: f64, - #[proxy] - translation: bevy::math::DVec2, - ) -> bevy::math::DAffine2; - -"#, - r#" -/// Creates an affine transform from the given 2D rotation `angle` (in radians) and -/// `translation`. -/// Equivalent to `DAffine2::from_translation(translation) * DAffine2::from_angle(angle)` - - #[lua(kind = "Function", output(proxy))] - fn from_angle_translation( - angle: f64, - #[proxy] - translation: bevy::math::DVec2, - ) -> bevy::math::DAffine2; - -"#, - r#" -/// The given `DMat3` must be an affine transform, - - #[lua(kind = "Function", output(proxy))] - fn from_mat3(#[proxy] m: bevy::math::DMat3) -> bevy::math::DAffine2; - -"#, - r#" -/// Transforms the given 2D point, applying shear, scale, rotation and translation. - - #[lua(kind = "Method", output(proxy))] - fn transform_point2(&self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" -/// Transforms the given 2D vector, applying shear, scale and rotation (but NOT -/// translation). -/// To also apply translation, use [`Self::transform_point2()`] instead. - - #[lua(kind = "Method", output(proxy))] - fn transform_vector2(&self, #[proxy] rhs: bevy::math::DVec2) -> bevy::math::DVec2; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. -/// If any element is either `NaN`, positive or negative infinity, this will return -/// `false`. - - #[lua(kind = "Method")] - fn is_finite(&self) -> bool; - -"#, - r#" -/// Returns `true` if any elements are `NaN`. - - #[lua(kind = "Method")] - fn is_nan(&self) -> bool; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` -/// is less than or equal to `max_abs_diff`. -/// This can be used to compare if two 3x4 matrices contain similar elements. It works -/// best when comparing with a known value. The `max_abs_diff` that should be used used -/// depends on the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(&self, #[proxy] rhs: bevy::math::DAffine2, max_abs_diff: f64) -> bool; - -"#, - r#" -/// Return the inverse of this transform. -/// Note that if the transform is not invertible the result will be invalid. - - #[lua(kind = "Method", output(proxy))] - fn inverse(&self) -> bevy::math::DAffine2; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::DAffine2; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] rhs: &glam::DAffine2) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::DAffine2) -> bevy::math::DAffine2; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct DAffine2 { - #[lua(output(proxy))] - matrix2: bevy::math::DMat2, - #[lua(output(proxy))] - translation: bevy::math::DVec2, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::DAffine3", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] rhs: &glam::DAffine3) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::DAffine3) -> bevy::math::DAffine3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::DMat4) -> bevy::math::DMat4; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::DAffine3; - -"#, - r#" -/// Creates an affine transform from three column vectors. - - #[lua(kind = "Function", output(proxy))] - fn from_cols( - #[proxy] - x_axis: bevy::math::DVec3, - #[proxy] - y_axis: bevy::math::DVec3, - #[proxy] - z_axis: bevy::math::DVec3, - #[proxy] - w_axis: bevy::math::DVec3, - ) -> bevy::math::DAffine3; - -"#, - r#" -/// Creates a `[f64; 12]` array storing data in column major order. - - #[lua(kind = "Method")] - fn to_cols_array(&self) -> [f64; 12]; - -"#, - r#" -/// Creates a `[[f64; 3]; 4]` 3D array storing data in -/// column major order. -/// If you require data in row major order `transpose` the matrix first. - - #[lua(kind = "Method")] - fn to_cols_array_2d(&self) -> [[f64; 3]; 4]; - -"#, - r#" -/// Creates an affine transform that changes scale. -/// Note that if any scale is zero the transform will be non-invertible. - - #[lua(kind = "Function", output(proxy))] - fn from_scale(#[proxy] scale: bevy::math::DVec3) -> bevy::math::DAffine3; - -"#, - r#" -/// Creates an affine transform from the given `rotation` quaternion. - - #[lua(kind = "Function", output(proxy))] - fn from_quat(#[proxy] rotation: bevy::math::DQuat) -> bevy::math::DAffine3; - -"#, - r#" -/// Creates an affine transform containing a 3D rotation around a normalized -/// rotation `axis` of `angle` (in radians). - - #[lua(kind = "Function", output(proxy))] - fn from_axis_angle( - #[proxy] - axis: bevy::math::DVec3, - angle: f64, - ) -> bevy::math::DAffine3; - -"#, - r#" -/// Creates an affine transform containing a 3D rotation around the x axis of -/// `angle` (in radians). - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_x(angle: f64) -> bevy::math::DAffine3; - -"#, - r#" -/// Creates an affine transform containing a 3D rotation around the y axis of -/// `angle` (in radians). - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_y(angle: f64) -> bevy::math::DAffine3; - -"#, - r#" -/// Creates an affine transform containing a 3D rotation around the z axis of -/// `angle` (in radians). - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_z(angle: f64) -> bevy::math::DAffine3; - -"#, - r#" -/// Creates an affine transformation from the given 3D `translation`. - - #[lua(kind = "Function", output(proxy))] - fn from_translation(#[proxy] translation: bevy::math::DVec3) -> bevy::math::DAffine3; - -"#, - r#" -/// Creates an affine transform from a 3x3 matrix (expressing scale, shear and -/// rotation) - - #[lua(kind = "Function", output(proxy))] - fn from_mat3(#[proxy] mat3: bevy::math::DMat3) -> bevy::math::DAffine3; - -"#, - r#" -/// Creates an affine transform from a 3x3 matrix (expressing scale, shear and rotation) -/// and a translation vector. -/// Equivalent to `DAffine3::from_translation(translation) * DAffine3::from_mat3(mat3)` - - #[lua(kind = "Function", output(proxy))] - fn from_mat3_translation( - #[proxy] - mat3: bevy::math::DMat3, - #[proxy] - translation: bevy::math::DVec3, - ) -> bevy::math::DAffine3; - -"#, - r#" -/// Creates an affine transform from the given 3D `scale`, `rotation` and -/// `translation`. -/// Equivalent to `DAffine3::from_translation(translation) * -/// DAffine3::from_quat(rotation) * DAffine3::from_scale(scale)` - - #[lua(kind = "Function", output(proxy))] - fn from_scale_rotation_translation( - #[proxy] - scale: bevy::math::DVec3, - #[proxy] - rotation: bevy::math::DQuat, - #[proxy] - translation: bevy::math::DVec3, - ) -> bevy::math::DAffine3; - -"#, - r#" -/// Creates an affine transform from the given 3D `rotation` and `translation`. -/// Equivalent to `DAffine3::from_translation(translation) * DAffine3::from_quat(rotation)` - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_translation( - #[proxy] - rotation: bevy::math::DQuat, - #[proxy] - translation: bevy::math::DVec3, - ) -> bevy::math::DAffine3; - -"#, - r#" -/// The given `DMat4` must be an affine transform, -/// i.e. contain no perspective transform. - - #[lua(kind = "Function", output(proxy))] - fn from_mat4(#[proxy] m: bevy::math::DMat4) -> bevy::math::DAffine3; - -"#, - r#" -/// Creates a left-handed view transform using a camera position, an up direction, and a facing -/// direction. -/// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`. - - #[lua(kind = "Function", output(proxy))] - fn look_to_lh( - #[proxy] - eye: bevy::math::DVec3, - #[proxy] - dir: bevy::math::DVec3, - #[proxy] - up: bevy::math::DVec3, - ) -> bevy::math::DAffine3; - -"#, - r#" -/// Creates a right-handed view transform using a camera position, an up direction, and a facing -/// direction. -/// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`. - - #[lua(kind = "Function", output(proxy))] - fn look_to_rh( - #[proxy] - eye: bevy::math::DVec3, - #[proxy] - dir: bevy::math::DVec3, - #[proxy] - up: bevy::math::DVec3, - ) -> bevy::math::DAffine3; - -"#, - r#" -/// Creates a left-handed view transform using a camera position, an up direction, and a focal -/// point. -/// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`. -/// # Panics -/// Will panic if `up` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn look_at_lh( - #[proxy] - eye: bevy::math::DVec3, - #[proxy] - center: bevy::math::DVec3, - #[proxy] - up: bevy::math::DVec3, - ) -> bevy::math::DAffine3; - -"#, - r#" -/// Creates a right-handed view transform using a camera position, an up direction, and a focal -/// point. -/// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`. -/// # Panics -/// Will panic if `up` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn look_at_rh( - #[proxy] - eye: bevy::math::DVec3, - #[proxy] - center: bevy::math::DVec3, - #[proxy] - up: bevy::math::DVec3, - ) -> bevy::math::DAffine3; - -"#, - r#" -/// Transforms the given 3D points, applying shear, scale, rotation and translation. - - #[lua(kind = "Method", output(proxy))] - fn transform_point3(&self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Transforms the given 3D vector, applying shear, scale and rotation (but NOT -/// translation). -/// To also apply translation, use [`Self::transform_point3()`] instead. - - #[lua(kind = "Method", output(proxy))] - fn transform_vector3(&self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. -/// If any element is either `NaN`, positive or negative infinity, this will return -/// `false`. - - #[lua(kind = "Method")] - fn is_finite(&self) -> bool; - -"#, - r#" -/// Returns `true` if any elements are `NaN`. - - #[lua(kind = "Method")] - fn is_nan(&self) -> bool; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` -/// is less than or equal to `max_abs_diff`. -/// This can be used to compare if two 3x4 matrices contain similar elements. It works -/// best when comparing with a known value. The `max_abs_diff` that should be used used -/// depends on the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(&self, #[proxy] rhs: bevy::math::DAffine3, max_abs_diff: f64) -> bool; - -"#, - r#" -/// Return the inverse of this transform. -/// Note that if the transform is not invertible the result will be invalid. - - #[lua(kind = "Method", output(proxy))] - fn inverse(&self) -> bevy::math::DAffine3; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct DAffine3 { - #[lua(output(proxy))] - matrix3: bevy::math::DMat3, - #[lua(output(proxy))] - translation: bevy::math::DVec3, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::DQuat", - functions[r#" -/// Adds two quaternions. -/// The sum is not guaranteed to be normalized. -/// Note that addition is not the same as combining the rotations represented by the -/// two quaternions! That corresponds to multiplication. - - #[lua( - as_trait = "std::ops::Add", - kind = "MetaFunction", - output(proxy), - composite = "add", - metamethod = "Add", - )] - fn add(self, #[proxy] rhs: bevy::math::DQuat) -> bevy::math::DQuat; - -"#, - r#" -/// Multiplies a quaternion by a scalar value. -/// The product is not guaranteed to be normalized. - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, rhs: f64) -> bevy::math::DQuat; - -"#, - r#" -/// Multiplies two quaternions. If they each represent a rotation, the result will -/// represent the combined rotation. -/// Note that due to floating point rounding the result may not be perfectly -/// normalized. -/// # Panics -/// Will panic if `self` or `rhs` are not normalized when `glam_assert` is enabled. - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::DQuat) -> bevy::math::DQuat; - -"#, - r#" -/// Creates a new rotation quaternion. -/// This should generally not be called manually unless you know what you are doing. -/// Use one of the other constructors instead such as `identity` or `from_axis_angle`. -/// `from_xyzw` is mostly used by unit tests and `serde` deserialization. -/// # Preconditions -/// This function does not check if the input is normalized, it is up to the user to -/// provide normalized input or to normalized the resulting quaternion. - - #[lua(kind = "Function", output(proxy))] - fn from_xyzw(x: f64, y: f64, z: f64, w: f64) -> bevy::math::DQuat; - -"#, - r#" -/// Creates a rotation quaternion from an array. -/// # Preconditions -/// This function does not check if the input is normalized, it is up to the user to -/// provide normalized input or to normalized the resulting quaternion. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [f64; 4]) -> bevy::math::DQuat; - -"#, - r#" -/// Creates a new rotation quaternion from a 4D vector. -/// # Preconditions -/// This function does not check if the input is normalized, it is up to the user to -/// provide normalized input or to normalized the resulting quaternion. - - #[lua(kind = "Function", output(proxy))] - fn from_vec4(#[proxy] v: bevy::math::DVec4) -> bevy::math::DQuat; - -"#, - r#" -/// Create a quaternion for a normalized rotation `axis` and `angle` (in radians). -/// The axis must be a unit vector. -/// # Panics -/// Will panic if `axis` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_axis_angle( - #[proxy] - axis: bevy::math::DVec3, - angle: f64, - ) -> bevy::math::DQuat; - -"#, - r#" -/// Create a quaternion that rotates `v.length()` radians around `v.normalize()`. -/// `from_scaled_axis(Vec3::ZERO)` results in the identity quaternion. - - #[lua(kind = "Function", output(proxy))] - fn from_scaled_axis(#[proxy] v: bevy::math::DVec3) -> bevy::math::DQuat; - -"#, - r#" -/// Creates a quaternion from the `angle` (in radians) around the x axis. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_x(angle: f64) -> bevy::math::DQuat; - -"#, - r#" -/// Creates a quaternion from the `angle` (in radians) around the y axis. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_y(angle: f64) -> bevy::math::DQuat; - -"#, - r#" -/// Creates a quaternion from the `angle` (in radians) around the z axis. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_z(angle: f64) -> bevy::math::DQuat; - -"#, - r#" -/// Creates a quaternion from the given Euler rotation sequence and the angles (in radians). - - #[lua(kind = "Function", output(proxy))] - fn from_euler( - #[proxy] - euler: bevy::math::EulerRot, - a: f64, - b: f64, - c: f64, - ) -> bevy::math::DQuat; - -"#, - r#" -/// Creates a quaternion from a 3x3 rotation matrix. -/// Note if the input matrix contain scales, shears, or other non-rotation transformations then -/// the resulting quaternion will be ill-defined. -/// # Panics -/// Will panic if any input matrix column is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_mat3(#[proxy] mat: &glam::DMat3) -> bevy::math::DQuat; - -"#, - r#" -/// Creates a quaternion from the upper 3x3 rotation matrix inside a homogeneous 4x4 matrix. -/// Note if the upper 3x3 matrix contain scales, shears, or other non-rotation transformations -/// then the resulting quaternion will be ill-defined. -/// # Panics -/// Will panic if any column of the upper 3x3 rotation matrix is not normalized when -/// `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_mat4(#[proxy] mat: &glam::DMat4) -> bevy::math::DQuat; - -"#, - r#" -/// Gets the minimal rotation for transforming `from` to `to`. The rotation is in the -/// plane spanned by the two vectors. Will rotate at most 180 degrees. -/// The inputs must be unit vectors. -/// `from_rotation_arc(from, to) * from ≈ to`. -/// For near-singular cases (from≈to and from≈-to) the current implementation -/// is only accurate to about 0.001 (for `f32`). -/// # Panics -/// Will panic if `from` or `to` are not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_arc( - #[proxy] - from: bevy::math::DVec3, - #[proxy] - to: bevy::math::DVec3, - ) -> bevy::math::DQuat; - -"#, - r#" -/// Gets the minimal rotation for transforming `from` to either `to` or `-to`. This means -/// that the resulting quaternion will rotate `from` so that it is colinear with `to`. -/// The rotation is in the plane spanned by the two vectors. Will rotate at most 90 -/// degrees. -/// The inputs must be unit vectors. -/// `to.dot(from_rotation_arc_colinear(from, to) * from).abs() ≈ 1`. -/// # Panics -/// Will panic if `from` or `to` are not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_arc_colinear( - #[proxy] - from: bevy::math::DVec3, - #[proxy] - to: bevy::math::DVec3, - ) -> bevy::math::DQuat; - -"#, - r#" -/// Gets the minimal rotation for transforming `from` to `to`. The resulting rotation is -/// around the z axis. Will rotate at most 180 degrees. -/// The inputs must be unit vectors. -/// `from_rotation_arc_2d(from, to) * from ≈ to`. -/// For near-singular cases (from≈to and from≈-to) the current implementation -/// is only accurate to about 0.001 (for `f32`). -/// # Panics -/// Will panic if `from` or `to` are not normalized when `glam_assert` is enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation_arc_2d( - #[proxy] - from: bevy::math::DVec2, - #[proxy] - to: bevy::math::DVec2, - ) -> bevy::math::DQuat; - -"#, - r#" -/// Returns the rotation axis scaled by the rotation in radians. - - #[lua(kind = "Method", output(proxy))] - fn to_scaled_axis(self) -> bevy::math::DVec3; - -"#, - r#" -/// Returns the rotation angles for the given euler rotation sequence. - - #[lua(kind = "Method")] - fn to_euler(self, #[proxy] order: bevy::math::EulerRot) -> (f64, f64, f64); - -"#, - r#" -/// `[x, y, z, w]` - - #[lua(kind = "Method")] - fn to_array(&self) -> [f64; 4]; - -"#, - r#" -/// Returns the vector part of the quaternion. - - #[lua(kind = "Method", output(proxy))] - fn xyz(self) -> bevy::math::DVec3; - -"#, - r#" -/// Returns the quaternion conjugate of `self`. For a unit quaternion the -/// conjugate is also the inverse. - - #[lua(kind = "Method", output(proxy))] - fn conjugate(self) -> bevy::math::DQuat; - -"#, - r#" -/// Returns the inverse of a normalized quaternion. -/// Typically quaternion inverse returns the conjugate of a normalized quaternion. -/// Because `self` is assumed to already be unit length this method *does not* normalize -/// before returning the conjugate. -/// # Panics -/// Will panic if `self` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn inverse(self) -> bevy::math::DQuat; - -"#, - r#" -/// Computes the dot product of `self` and `rhs`. The dot product is -/// equal to the cosine of the angle between two quaternion rotations. - - #[lua(kind = "Method")] - fn dot(self, #[proxy] rhs: bevy::math::DQuat) -> f64; - -"#, - r#" -/// Computes the length of `self`. - - #[lua(kind = "Method")] - fn length(self) -> f64; - -"#, - r#" -/// Computes the squared length of `self`. -/// This is generally faster than `length()` as it avoids a square -/// root operation. - - #[lua(kind = "Method")] - fn length_squared(self) -> f64; - -"#, - r#" -/// Computes `1.0 / length()`. -/// For valid results, `self` must _not_ be of length zero. - - #[lua(kind = "Method")] - fn length_recip(self) -> f64; - -"#, - r#" -/// Returns `self` normalized to length 1.0. -/// For valid results, `self` must _not_ be of length zero. -/// Panics -/// Will panic if `self` is zero length when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn normalize(self) -> bevy::math::DQuat; - -"#, - r#" -/// Returns `true` if, and only if, all elements are finite. -/// If any element is either `NaN`, positive or negative infinity, this will return `false`. - - #[lua(kind = "Method")] - fn is_finite(self) -> bool; - -"#, - r#" -/// Returns `true` if any elements are `NAN`. - - #[lua(kind = "Method")] - fn is_nan(self) -> bool; - -"#, - r#" -/// Returns whether `self` of length `1.0` or not. -/// Uses a precision threshold of `1e-6`. - - #[lua(kind = "Method")] - fn is_normalized(self) -> bool; - -"#, - r#" - - #[lua(kind = "Method")] - fn is_near_identity(self) -> bool; - -"#, - r#" -/// Returns the angle (in radians) for the minimal rotation -/// for transforming this quaternion into another. -/// Both quaternions must be normalized. -/// # Panics -/// Will panic if `self` or `rhs` are not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method")] - fn angle_between(self, #[proxy] rhs: bevy::math::DQuat) -> f64; - -"#, - r#" -/// Rotates towards `rhs` up to `max_angle` (in radians). -/// When `max_angle` is `0.0`, the result will be equal to `self`. When `max_angle` is equal to -/// `self.angle_between(rhs)`, the result will be equal to `rhs`. If `max_angle` is negative, -/// rotates towards the exact opposite of `rhs`. Will not go past the target. -/// Both quaternions must be normalized. -/// # Panics -/// Will panic if `self` or `rhs` are not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn rotate_towards( - &self, - #[proxy] - rhs: bevy::math::DQuat, - max_angle: f64, - ) -> bevy::math::DQuat; - -"#, - r#" -/// Returns true if the absolute difference of all elements between `self` and `rhs` -/// is less than or equal to `max_abs_diff`. -/// This can be used to compare if two quaternions contain similar elements. It works -/// best when comparing with a known value. The `max_abs_diff` that should be used used -/// depends on the values being compared against. -/// For more see -/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). - - #[lua(kind = "Method")] - fn abs_diff_eq(self, #[proxy] rhs: bevy::math::DQuat, max_abs_diff: f64) -> bool; - -"#, - r#" -/// Performs a linear interpolation between `self` and `rhs` based on -/// the value `s`. -/// When `s` is `0.0`, the result will be equal to `self`. When `s` -/// is `1.0`, the result will be equal to `rhs`. -/// # Panics -/// Will panic if `self` or `end` are not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn lerp(self, #[proxy] end: bevy::math::DQuat, s: f64) -> bevy::math::DQuat; - -"#, - r#" -/// Performs a spherical linear interpolation between `self` and `end` -/// based on the value `s`. -/// When `s` is `0.0`, the result will be equal to `self`. When `s` -/// is `1.0`, the result will be equal to `end`. -/// # Panics -/// Will panic if `self` or `end` are not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn slerp(self, #[proxy] end: bevy::math::DQuat, s: f64) -> bevy::math::DQuat; - -"#, - r#" -/// Multiplies a quaternion and a 3D vector, returning the rotated vector. -/// # Panics -/// Will panic if `self` is not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn mul_vec3(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" -/// Multiplies two quaternions. If they each represent a rotation, the result will -/// represent the combined rotation. -/// Note that due to floating point rounding the result may not be perfectly normalized. -/// # Panics -/// Will panic if `self` or `rhs` are not normalized when `glam_assert` is enabled. - - #[lua(kind = "Method", output(proxy))] - fn mul_quat(self, #[proxy] rhs: bevy::math::DQuat) -> bevy::math::DQuat; - -"#, - r#" -/// Creates a quaternion from a 3x3 rotation matrix inside a 3D affine transform. -/// Note if the input affine matrix contain scales, shears, or other non-rotation -/// transformations then the resulting quaternion will be ill-defined. -/// # Panics -/// Will panic if any input affine matrix column is not normalized when `glam_assert` is -/// enabled. - - #[lua(kind = "Function", output(proxy))] - fn from_affine3(#[proxy] a: &glam::DAffine3) -> bevy::math::DQuat; - -"#, - r#" - - #[lua(kind = "Method", output(proxy))] - fn as_quat(self) -> bevy::math::Quat; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::DQuat; - -"#, - r#" -/// Multiplies a quaternion and a 3D vector, returning the rotated vector. -/// # Panics -/// Will panic if `self` is not normalized when `glam_assert` is enabled. - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] rhs: bevy::math::DVec3) -> bevy::math::DVec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Neg", - kind = "MetaFunction", - output(proxy), - composite = "neg", - metamethod = "Unm", - )] - fn neg(self) -> bevy::math::DQuat; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] rhs: &glam::DQuat) -> bool; - -"#, - r#" -/// Subtracts the `rhs` quaternion from `self`. -/// The difference is not guaranteed to be normalized. - - #[lua( - as_trait = "std::ops::Sub", - kind = "MetaFunction", - output(proxy), - composite = "sub", - metamethod = "Sub", - )] - fn sub(self, #[proxy] rhs: bevy::math::DQuat) -> bevy::math::DQuat; - -"#, - r#" -/// Divides a quaternion by a scalar value. -/// The quotient is not guaranteed to be normalized. - - #[lua( - as_trait = "std::ops::Div", - kind = "MetaFunction", - output(proxy), - composite = "div", - metamethod = "Div", - )] - fn div(self, rhs: f64) -> bevy::math::DQuat; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct DQuat { - x: f64, - y: f64, - z: f64, - w: f64, -} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::EulerRot", - functions[r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::EulerRot; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &glam::EulerRot) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct EulerRot {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::BVec3A", - functions[r#" -/// Creates a new vector mask. - - #[lua(kind = "Function", output(proxy))] - fn new(x: bool, y: bool, z: bool) -> bevy::math::BVec3A; - -"#, - r#" -/// Creates a vector mask with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: bool) -> bevy::math::BVec3A; - -"#, - r#" -/// Creates a new vector mask from a bool array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [bool; 3]) -> bevy::math::BVec3A; - -"#, - r#" -/// Returns a bitmask with the lowest 3 bits set from the elements of `self`. -/// A true element results in a `1` bit and a false element in a `0` bit. Element `x` goes -/// into the first lowest bit, element `y` into the second, etc. - - #[lua(kind = "Method")] - fn bitmask(self) -> u32; - -"#, - r#" -/// Returns true if any of the elements are true, false otherwise. - - #[lua(kind = "Method")] - fn any(self) -> bool; - -"#, - r#" -/// Returns true if all the elements are true, false otherwise. - - #[lua(kind = "Method")] - fn all(self) -> bool; - -"#, - r#" -/// Tests the value at `index`. -/// Panics if `index` is greater than 2. - - #[lua(kind = "Method")] - fn test(&self, index: usize) -> bool; - -"#, - r#" -/// Sets the element at `index`. -/// Panics if `index` is greater than 2. - - #[lua(kind = "MutatingMethod")] - fn set(&mut self, index: usize, value: bool) -> (); - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::BVec3A; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] rhs: &glam::BVec3A) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct BVec3A(); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::math::BVec4A", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] rhs: &glam::BVec4A) -> bool; - -"#, - r#" -/// Creates a new vector mask. - - #[lua(kind = "Function", output(proxy))] - fn new(x: bool, y: bool, z: bool, w: bool) -> bevy::math::BVec4A; - -"#, - r#" -/// Creates a vector mask with all elements set to `v`. - - #[lua(kind = "Function", output(proxy))] - fn splat(v: bool) -> bevy::math::BVec4A; - -"#, - r#" -/// Creates a new vector mask from a bool array. - - #[lua(kind = "Function", output(proxy))] - fn from_array(a: [bool; 4]) -> bevy::math::BVec4A; - -"#, - r#" -/// Returns a bitmask with the lowest 4 bits set from the elements of `self`. -/// A true element results in a `1` bit and a false element in a `0` bit. Element `x` goes -/// into the first lowest bit, element `y` into the second, etc. - - #[lua(kind = "Method")] - fn bitmask(self) -> u32; - -"#, - r#" -/// Returns true if any of the elements are true, false otherwise. - - #[lua(kind = "Method")] - fn any(self) -> bool; - -"#, - r#" -/// Returns true if all the elements are true, false otherwise. - - #[lua(kind = "Method")] - fn all(self) -> bool; - -"#, - r#" -/// Tests the value at `index`. -/// Panics if `index` is greater than 3. - - #[lua(kind = "Method")] - fn test(&self, index: usize) -> bool; - -"#, - r#" -/// Sets the element at `index`. -/// Panics if `index` is greater than 3. - - #[lua(kind = "MutatingMethod")] - fn set(&mut self, index: usize, value: bool) -> (); - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> bevy::math::BVec4A; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct BVec4A(); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "smol_str::SmolStr", - functions[r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> smol_str::SmolStr; - -"#, - r#" - - #[lua(kind = "Method")] - fn to_string(&self) -> std::string::String; - -"#, - r#" - - #[lua(kind = "Method")] - fn len(&self) -> usize; - -"#, - r#" - - #[lua(kind = "Method")] - fn is_empty(&self) -> bool; - -"#, - r#" - - #[lua(kind = "Method")] - fn is_heap_allocated(&self) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &smol_str::SmolStr) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct SmolStr(); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "uuid::Uuid", - functions[r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" -/// The 'nil UUID' (all zeros). -/// The nil UUID is a special form of UUID that is specified to have all -/// 128 bits set to zero. -/// # References -/// * [Nil UUID in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.9) -/// # Examples -/// Basic usage: -/// ``` -/// # use uuid::Uuid; -/// let uuid = Uuid::nil(); -/// assert_eq!( -/// "00000000-0000-0000-0000-000000000000", -/// uuid.hyphenated().to_string(), -/// ); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn nil() -> uuid::Uuid; - -"#, - r#" -/// The 'max UUID' (all ones). -/// The max UUID is a special form of UUID that is specified to have all -/// 128 bits set to one. -/// # References -/// * [Max UUID in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.10) -/// # Examples -/// Basic usage: -/// ``` -/// # use uuid::Uuid; -/// let uuid = Uuid::max(); -/// assert_eq!( -/// "ffffffff-ffff-ffff-ffff-ffffffffffff", -/// uuid.hyphenated().to_string(), -/// ); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn max() -> uuid::Uuid; - -"#, - r#" -/// Creates a UUID from a 128bit value. -/// # Examples -/// Basic usage: -/// ``` -/// # use uuid::Uuid; -/// let v = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8u128; -/// let uuid = Uuid::from_u128(v); -/// assert_eq!( -/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8", -/// uuid.hyphenated().to_string(), -/// ); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_u128(v: u128) -> uuid::Uuid; - -"#, - r#" -/// Creates a UUID from a 128bit value in little-endian order. -/// The entire value will be flipped to convert into big-endian order. -/// This is based on the endianness of the UUID, rather than the target -/// environment so bytes will be flipped on both big and little endian -/// machines. -/// # Examples -/// Basic usage: -/// ``` -/// # use uuid::Uuid; -/// let v = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8u128; -/// let uuid = Uuid::from_u128_le(v); -/// assert_eq!( -/// "d8d7d6d5-d4d3-d2d1-c2c1-b2b1a4a3a2a1", -/// uuid.hyphenated().to_string(), -/// ); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_u128_le(v: u128) -> uuid::Uuid; - -"#, - r#" -/// Creates a UUID from two 64bit values. -/// # Examples -/// Basic usage: -/// ``` -/// # use uuid::Uuid; -/// let hi = 0xa1a2a3a4b1b2c1c2u64; -/// let lo = 0xd1d2d3d4d5d6d7d8u64; -/// let uuid = Uuid::from_u64_pair(hi, lo); -/// assert_eq!( -/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8", -/// uuid.hyphenated().to_string(), -/// ); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_u64_pair(high_bits: u64, low_bits: u64) -> uuid::Uuid; - -"#, - r#" -/// Creates a UUID using the supplied bytes. -/// # Examples -/// Basic usage: -/// ``` -/// # fn main() -> Result<(), uuid::Error> { -/// # use uuid::Uuid; -/// let bytes = [ -/// 0xa1, 0xa2, 0xa3, 0xa4, -/// 0xb1, 0xb2, -/// 0xc1, 0xc2, -/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, -/// ]; -/// let uuid = Uuid::from_bytes(bytes); -/// assert_eq!( -/// uuid.hyphenated().to_string(), -/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8" -/// ); -/// # Ok(()) -/// # } -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_bytes(bytes: [u8; 16]) -> uuid::Uuid; - -"#, - r#" -/// Creates a UUID using the supplied bytes in little endian order. -/// The individual fields encoded in the buffer will be flipped. -/// # Examples -/// Basic usage: -/// ``` -/// # fn main() -> Result<(), uuid::Error> { -/// # use uuid::Uuid; -/// let bytes = [ -/// 0xa1, 0xa2, 0xa3, 0xa4, -/// 0xb1, 0xb2, -/// 0xc1, 0xc2, -/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, -/// ]; -/// let uuid = Uuid::from_bytes_le(bytes); -/// assert_eq!( -/// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8", -/// uuid.hyphenated().to_string(), -/// ); -/// # Ok(()) -/// # } -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_bytes_le(b: [u8; 16]) -> uuid::Uuid; - -"#, - r#" -/// Creates a random UUID. -/// This uses the [`getrandom`] crate to utilise the operating system's RNG -/// as the source of random numbers. If you'd like to use a custom -/// generator, don't use this method: generate random bytes using your -/// custom generator and pass them to the -/// [`uuid::Builder::from_random_bytes`][from_random_bytes] function -/// instead. -/// Note that usage of this method requires the `v4` feature of this crate -/// to be enabled. -/// # Examples -/// Basic usage: -/// ``` -/// # use uuid::{Uuid, Version}; -/// let uuid = Uuid::new_v4(); -/// assert_eq!(Some(Version::Random), uuid.get_version()); -/// ``` -/// # References -/// * [UUID Version 4 in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.4) -/// [`getrandom`]: https://crates.io/crates/getrandom -/// [from_random_bytes]: struct.Builder.html#method.from_random_bytes - - #[lua(kind = "Function", output(proxy))] - fn new_v4() -> uuid::Uuid; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &uuid::Uuid) -> bool; - -"#, - r#" - - #[lua( - as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone", - kind = "Method", - output(proxy), - )] - fn clone(&self) -> uuid::Uuid; - -"#, - r#" -/// Returns the version number of the UUID. -/// This represents the algorithm used to generate the value. -/// This method is the future-proof alternative to [`Uuid::get_version`]. -/// # Examples -/// Basic usage: -/// ``` -/// # use uuid::Uuid; -/// # fn main() -> Result<(), uuid::Error> { -/// let my_uuid = Uuid::parse_str("02f09a3f-1624-3b1d-8409-44eff7708208")?; -/// assert_eq!(3, my_uuid.get_version_num()); -/// # Ok(()) -/// # } -/// ``` -/// # References -/// * [Version Field in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-4.2) - - #[lua(kind = "Method")] - fn get_version_num(&self) -> usize; - -"#, - r#" -/// Returns a 128bit value containing the value. -/// The bytes in the UUID will be packed directly into a `u128`. -/// # Examples -/// ``` -/// # use uuid::Uuid; -/// # fn main() -> Result<(), uuid::Error> { -/// let uuid = Uuid::parse_str("a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8")?; -/// assert_eq!( -/// uuid.as_u128(), -/// 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8, -/// ); -/// # Ok(()) -/// # } -/// ``` - - #[lua(kind = "Method")] - fn as_u128(&self) -> u128; - -"#, - r#" -/// Returns a 128bit little-endian value containing the value. -/// The bytes in the `u128` will be flipped to convert into big-endian -/// order. This is based on the endianness of the UUID, rather than the -/// target environment so bytes will be flipped on both big and little -/// endian machines. -/// Note that this will produce a different result than -/// [`Uuid::to_fields_le`], because the entire UUID is reversed, rather -/// than reversing the individual fields in-place. -/// # Examples -/// ``` -/// # use uuid::Uuid; -/// # fn main() -> Result<(), uuid::Error> { -/// let uuid = Uuid::parse_str("a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8")?; -/// assert_eq!( -/// uuid.to_u128_le(), -/// 0xd8d7d6d5d4d3d2d1c2c1b2b1a4a3a2a1, -/// ); -/// # Ok(()) -/// # } -/// ``` - - #[lua(kind = "Method")] - fn to_u128_le(&self) -> u128; - -"#, - r#" -/// Returns two 64bit values containing the value. -/// The bytes in the UUID will be split into two `u64`. -/// The first u64 represents the 64 most significant bits, -/// the second one represents the 64 least significant. -/// # Examples -/// ``` -/// # use uuid::Uuid; -/// # fn main() -> Result<(), uuid::Error> { -/// let uuid = Uuid::parse_str("a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8")?; -/// assert_eq!( -/// uuid.as_u64_pair(), -/// (0xa1a2a3a4b1b2c1c2, 0xd1d2d3d4d5d6d7d8), -/// ); -/// # Ok(()) -/// # } -/// ``` - - #[lua(kind = "Method")] - fn as_u64_pair(&self) -> (u64, u64); - -"#, - r#" -/// Consumes self and returns the underlying byte value of the UUID. -/// # Examples -/// ``` -/// # use uuid::Uuid; -/// let bytes = [ -/// 0xa1, 0xa2, 0xa3, 0xa4, -/// 0xb1, 0xb2, -/// 0xc1, 0xc2, -/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, -/// ]; -/// let uuid = Uuid::from_bytes(bytes); -/// assert_eq!(bytes, uuid.into_bytes()); -/// ``` - - #[lua(kind = "Method")] - fn into_bytes(self) -> [u8; 16]; - -"#, - r#" -/// Returns the bytes of the UUID in little-endian order. -/// The bytes will be flipped to convert into little-endian order. This is -/// based on the endianness of the UUID, rather than the target environment -/// so bytes will be flipped on both big and little endian machines. -/// # Examples -/// ``` -/// use uuid::Uuid; -/// # fn main() -> Result<(), uuid::Error> { -/// let uuid = Uuid::parse_str("a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8")?; -/// assert_eq!( -/// uuid.to_bytes_le(), -/// ([ -/// 0xa4, 0xa3, 0xa2, 0xa1, 0xb2, 0xb1, 0xc2, 0xc1, 0xd1, 0xd2, -/// 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8 -/// ]) -/// ); -/// # Ok(()) -/// # } -/// ``` - - #[lua(kind = "Method")] - fn to_bytes_le(&self) -> [u8; 16]; - -"#, - r#" -/// Tests if the UUID is nil (all zeros). - - #[lua(kind = "Method")] - fn is_nil(&self) -> bool; - -"#, - r#" -/// Tests if the UUID is max (all ones). - - #[lua(kind = "Method")] - fn is_max(&self) -> bool; - -"#, - r#" -/// A buffer that can be used for `encode_...` calls, that is -/// guaranteed to be long enough for any of the format adapters. -/// # Examples -/// ``` -/// # use uuid::Uuid; -/// let uuid = Uuid::nil(); -/// assert_eq!( -/// uuid.simple().encode_lower(&mut Uuid::encode_buffer()), -/// "00000000000000000000000000000000" -/// ); -/// assert_eq!( -/// uuid.hyphenated() -/// .encode_lower(&mut Uuid::encode_buffer()), -/// "00000000-0000-0000-0000-000000000000" -/// ); -/// assert_eq!( -/// uuid.urn().encode_lower(&mut Uuid::encode_buffer()), -/// "urn:uuid:00000000-0000-0000-0000-000000000000" -/// ); -/// ``` - - #[lua(kind = "Function")] - fn encode_buffer() -> [u8; 45]; - -"#, - r#" -/// If the UUID is the correct version (v1, or v6) this will return the -/// node value as a 6-byte array. For other versions this will return `None`. - - #[lua(kind = "Method")] - fn get_node_id( - &self, - ) -> bevy::reflect::erased_serde::__private::serde::__private::Option<[u8; 6]>; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Uuid(); -#[derive(Default)] -pub(crate) struct Globals; -impl bevy_mod_scripting_lua::tealr::mlu::ExportInstances for Globals { - fn add_instances< - 'lua, - T: bevy_mod_scripting_lua::tealr::mlu::InstanceCollector<'lua>, - >(self, instances: &mut T) -> bevy_mod_scripting_lua::tealr::mlu::mlua::Result<()> { - instances - .add_instance( - "AtomicBool", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "AtomicI16", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "AtomicI32", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "AtomicI64", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "AtomicI8", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "AtomicIsize", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "AtomicU16", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "AtomicU32", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "AtomicU64", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "AtomicU8", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "AtomicUsize", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Duration", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Instant", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "PathBuf", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Quat", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Vec3", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "IVec2", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "IVec3", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "IVec4", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "I64Vec2", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "I64Vec3", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "I64Vec4", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "UVec2", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "UVec3", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "UVec4", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "U64Vec2", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "U64Vec3", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "U64Vec4", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Vec2", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Vec3A", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Vec4", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "BVec2", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "BVec3", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "BVec4", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "DVec2", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "DVec3", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "DVec4", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Mat2", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Mat3", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Mat3A", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Mat4", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "DMat2", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "DMat3", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "DMat4", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Affine2", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Affine3A", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "DAffine2", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "DAffine3", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "DQuat", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "BVec3A", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "BVec4A", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Uuid", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - Ok(()) - } -} -pub struct BevyReflectAPIProvider; -impl bevy_mod_scripting_core::hosts::APIProvider for BevyReflectAPIProvider { - type APITarget = std::sync::Mutex; - type ScriptContext = std::sync::Mutex; - type DocTarget = bevy_mod_scripting_lua::docs::LuaDocFragment; - fn attach_api( - &mut self, - ctx: &mut Self::APITarget, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - let ctx = ctx.get_mut().expect("Unable to acquire lock on Lua context"); - bevy_mod_scripting_lua::tealr::mlu::set_global_env(Globals, ctx) - .map_err(|e| bevy_mod_scripting_core::error::ScriptError::Other( - e.to_string(), - )) - } - fn get_doc_fragment(&self) -> Option { - Some( - bevy_mod_scripting_lua::docs::LuaDocFragment::new( - "BevyReflectAPI", - |tw| { - tw.document_global_instance::() - .expect("Something went wrong documenting globals") - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaAtomicBool, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaAtomicI16, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaAtomicI32, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaAtomicI64, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaAtomicI8, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaAtomicIsize, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaAtomicU16, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaAtomicU32, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaAtomicU64, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaAtomicU8, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaAtomicUsize, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaDuration, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaAffine3A, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaDAffine2, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaDAffine3, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - }, - ), - ) - } - fn setup_script( - &mut self, - script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - fn setup_script_runtime( - &mut self, - world_ptr: bevy_mod_scripting_core::world::WorldPointer, - _script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - fn register_with_app(&self, app: &mut bevy::app::App) { - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - } -} diff --git a/crates/bevy_script_api/src/providers/bevy_time.rs b/crates/bevy_script_api/src/providers/bevy_time.rs deleted file mode 100644 index 715be7fd..00000000 --- a/crates/bevy_script_api/src/providers/bevy_time.rs +++ /dev/null @@ -1,736 +0,0 @@ -// @generated by cargo bevy-api-gen generate, modify the templates not this file -#![allow(clippy::all)] -#![allow(unused, deprecated, dead_code)] -#![cfg_attr(rustfmt, rustfmt_skip)] -use super::bevy_ecs::*; -use super::bevy_reflect::*; -extern crate self as bevy_script_api; -use bevy_script_api::{ - lua::RegisterForeignLuaType, ReflectedValue, common::bevy::GetWorld, -}; -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::time::prelude::Fixed", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::time::prelude::Fixed; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Fixed {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::time::prelude::Real", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::time::prelude::Real; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Real {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::time::prelude::Timer", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::time::prelude::Timer; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &timer::Timer) -> bool; - -"#, - r#" -/// Creates a new timer with a given duration. -/// See also [`Timer::from_seconds`](Timer::from_seconds). - - #[lua(kind = "Function", output(proxy))] - fn new( - #[proxy] - duration: bevy::utils::Duration, - #[proxy] - mode: bevy::time::prelude::TimerMode, - ) -> bevy::time::prelude::Timer; - -"#, - r#" -/// Creates a new timer with a given duration in seconds. -/// # Example -/// ``` -/// # use bevy_time::*; -/// let mut timer = Timer::from_seconds(1.0, TimerMode::Once); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn from_seconds( - duration: f32, - #[proxy] - mode: bevy::time::prelude::TimerMode, - ) -> bevy::time::prelude::Timer; - -"#, - r#" -/// Returns `true` if the timer has reached its duration. -/// For repeating timers, this method behaves identically to [`Timer::just_finished`]. -/// # Examples -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let mut timer_once = Timer::from_seconds(1.0, TimerMode::Once); -/// timer_once.tick(Duration::from_secs_f32(1.5)); -/// assert!(timer_once.finished()); -/// timer_once.tick(Duration::from_secs_f32(0.5)); -/// assert!(timer_once.finished()); -/// let mut timer_repeating = Timer::from_seconds(1.0, TimerMode::Repeating); -/// timer_repeating.tick(Duration::from_secs_f32(1.1)); -/// assert!(timer_repeating.finished()); -/// timer_repeating.tick(Duration::from_secs_f32(0.8)); -/// assert!(!timer_repeating.finished()); -/// timer_repeating.tick(Duration::from_secs_f32(0.6)); -/// assert!(timer_repeating.finished()); -/// ``` - - #[lua(kind = "Method")] - fn finished(&self) -> bool; - -"#, - r#" -/// Returns `true` only on the tick the timer reached its duration. -/// # Examples -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let mut timer = Timer::from_seconds(1.0, TimerMode::Once); -/// timer.tick(Duration::from_secs_f32(1.5)); -/// assert!(timer.just_finished()); -/// timer.tick(Duration::from_secs_f32(0.5)); -/// assert!(!timer.just_finished()); -/// ``` - - #[lua(kind = "Method")] - fn just_finished(&self) -> bool; - -"#, - r#" -/// Returns the time elapsed on the timer. Guaranteed to be between 0.0 and `duration`. -/// Will only equal `duration` when the timer is finished and non repeating. -/// See also [`Stopwatch::elapsed`](Stopwatch::elapsed). -/// # Examples -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let mut timer = Timer::from_seconds(1.0, TimerMode::Once); -/// timer.tick(Duration::from_secs_f32(0.5)); -/// assert_eq!(timer.elapsed(), Duration::from_secs_f32(0.5)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn elapsed(&self) -> bevy::utils::Duration; - -"#, - r#" -/// Returns the time elapsed on the timer as an `f32`. -/// See also [`Timer::elapsed`](Timer::elapsed). - - #[lua(kind = "Method")] - fn elapsed_secs(&self) -> f32; - -"#, - r#" -/// Returns the time elapsed on the timer as an `f64`. -/// See also [`Timer::elapsed`](Timer::elapsed). - - #[lua(kind = "Method")] - fn elapsed_secs_f64(&self) -> f64; - -"#, - r#" -/// Sets the elapsed time of the timer without any other considerations. -/// See also [`Stopwatch::set`](Stopwatch::set). -/// # -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let mut timer = Timer::from_seconds(1.0, TimerMode::Once); -/// timer.set_elapsed(Duration::from_secs(2)); -/// assert_eq!(timer.elapsed(), Duration::from_secs(2)); -/// // the timer is not finished even if the elapsed time is greater than the duration. -/// assert!(!timer.finished()); -/// ``` - - #[lua(kind = "MutatingMethod")] - fn set_elapsed(&mut self, #[proxy] time: bevy::utils::Duration) -> (); - -"#, - r#" -/// Returns the duration of the timer. -/// # Examples -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let timer = Timer::new(Duration::from_secs(1), TimerMode::Once); -/// assert_eq!(timer.duration(), Duration::from_secs(1)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn duration(&self) -> bevy::utils::Duration; - -"#, - r#" -/// Sets the duration of the timer. -/// # Examples -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let mut timer = Timer::from_seconds(1.5, TimerMode::Once); -/// timer.set_duration(Duration::from_secs(1)); -/// assert_eq!(timer.duration(), Duration::from_secs(1)); -/// ``` - - #[lua(kind = "MutatingMethod")] - fn set_duration(&mut self, #[proxy] duration: bevy::utils::Duration) -> (); - -"#, - r#" -/// Returns the mode of the timer. -/// # Examples -/// ``` -/// # use bevy_time::*; -/// let mut timer = Timer::from_seconds(1.0, TimerMode::Repeating); -/// assert_eq!(timer.mode(), TimerMode::Repeating); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn mode(&self) -> bevy::time::prelude::TimerMode; - -"#, - r#" -/// Sets the mode of the timer. -/// # Examples -/// ``` -/// # use bevy_time::*; -/// let mut timer = Timer::from_seconds(1.0, TimerMode::Repeating); -/// timer.set_mode(TimerMode::Once); -/// assert_eq!(timer.mode(), TimerMode::Once); -/// ``` - - #[lua(kind = "MutatingMethod")] - fn set_mode(&mut self, #[proxy] mode: bevy::time::prelude::TimerMode) -> (); - -"#, - r#" -/// Pauses the Timer. Disables the ticking of the timer. -/// See also [`Stopwatch::pause`](Stopwatch::pause). -/// # Examples -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let mut timer = Timer::from_seconds(1.0, TimerMode::Once); -/// timer.pause(); -/// timer.tick(Duration::from_secs_f32(0.5)); -/// assert_eq!(timer.elapsed_secs(), 0.0); -/// ``` - - #[lua(kind = "MutatingMethod")] - fn pause(&mut self) -> (); - -"#, - r#" -/// Unpauses the Timer. Resumes the ticking of the timer. -/// See also [`Stopwatch::unpause()`](Stopwatch::unpause). -/// # Examples -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let mut timer = Timer::from_seconds(1.0, TimerMode::Once); -/// timer.pause(); -/// timer.tick(Duration::from_secs_f32(0.5)); -/// timer.unpause(); -/// timer.tick(Duration::from_secs_f32(0.5)); -/// assert_eq!(timer.elapsed_secs(), 0.5); -/// ``` - - #[lua(kind = "MutatingMethod")] - fn unpause(&mut self) -> (); - -"#, - r#" -/// Returns `true` if the timer is paused. -/// See also [`Stopwatch::is_paused`](Stopwatch::is_paused). -/// # Examples -/// ``` -/// # use bevy_time::*; -/// let mut timer = Timer::from_seconds(1.0, TimerMode::Once); -/// assert!(!timer.paused()); -/// timer.pause(); -/// assert!(timer.paused()); -/// timer.unpause(); -/// assert!(!timer.paused()); -/// ``` - - #[lua(kind = "Method")] - fn paused(&self) -> bool; - -"#, - r#" -/// Resets the timer. The reset doesn't affect the `paused` state of the timer. -/// See also [`Stopwatch::reset`](Stopwatch::reset). -/// Examples -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let mut timer = Timer::from_seconds(1.0, TimerMode::Once); -/// timer.tick(Duration::from_secs_f32(1.5)); -/// timer.reset(); -/// assert!(!timer.finished()); -/// assert!(!timer.just_finished()); -/// assert_eq!(timer.elapsed_secs(), 0.0); -/// ``` - - #[lua(kind = "MutatingMethod")] - fn reset(&mut self) -> (); - -"#, - r#" -/// Returns the fraction of the timer elapsed time (goes from 0.0 to 1.0). -/// # Examples -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let mut timer = Timer::from_seconds(2.0, TimerMode::Once); -/// timer.tick(Duration::from_secs_f32(0.5)); -/// assert_eq!(timer.fraction(), 0.25); -/// ``` - - #[lua(kind = "Method")] - fn fraction(&self) -> f32; - -"#, - r#" -/// Returns the fraction of the timer remaining time (goes from 1.0 to 0.0). -/// # Examples -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let mut timer = Timer::from_seconds(2.0, TimerMode::Once); -/// timer.tick(Duration::from_secs_f32(0.5)); -/// assert_eq!(timer.fraction_remaining(), 0.75); -/// ``` - - #[lua(kind = "Method")] - fn fraction_remaining(&self) -> f32; - -"#, - r#" -/// Returns the remaining time in seconds -/// # Examples -/// ``` -/// # use bevy_time::*; -/// use std::cmp::Ordering; -/// use std::time::Duration; -/// let mut timer = Timer::from_seconds(2.0, TimerMode::Once); -/// timer.tick(Duration::from_secs_f32(0.5)); -/// let result = timer.remaining_secs().total_cmp(&1.5); -/// assert_eq!(Ordering::Equal, result); -/// ``` - - #[lua(kind = "Method")] - fn remaining_secs(&self) -> f32; - -"#, - r#" -/// Returns the remaining time using Duration -/// # Examples -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let mut timer = Timer::from_seconds(2.0, TimerMode::Once); -/// timer.tick(Duration::from_secs_f32(0.5)); -/// assert_eq!(timer.remaining(), Duration::from_secs_f32(1.5)); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn remaining(&self) -> bevy::utils::Duration; - -"#, - r#" -/// Returns the number of times a repeating timer -/// finished during the last [`tick`](Timer::tick) call. -/// For non repeating-timers, this method will only ever -/// return 0 or 1. -/// # Examples -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let mut timer = Timer::from_seconds(1.0, TimerMode::Repeating); -/// timer.tick(Duration::from_secs_f32(6.0)); -/// assert_eq!(timer.times_finished_this_tick(), 6); -/// timer.tick(Duration::from_secs_f32(2.0)); -/// assert_eq!(timer.times_finished_this_tick(), 2); -/// timer.tick(Duration::from_secs_f32(0.5)); -/// assert_eq!(timer.times_finished_this_tick(), 0); -/// ``` - - #[lua(kind = "Method")] - fn times_finished_this_tick(&self) -> u32; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Timer {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::time::prelude::TimerMode", - functions[r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &timer::TimerMode) -> bool; - -"#, - r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::time::prelude::TimerMode; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct TimerMode {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::time::prelude::Virtual", - functions[r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::time::prelude::Virtual; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Virtual {} -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::time::Stopwatch", - functions[r#" - - #[lua(as_trait = "std::cmp::Eq", kind = "Method")] - fn assert_receiver_is_total_eq(&self) -> (); - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::time::Stopwatch; - -"#, - r#" -/// Create a new unpaused `Stopwatch` with no elapsed time. -/// # Examples -/// ``` -/// # use bevy_time::*; -/// let stopwatch = Stopwatch::new(); -/// assert_eq!(stopwatch.elapsed_secs(), 0.0); -/// assert_eq!(stopwatch.is_paused(), false); -/// ``` - - #[lua(kind = "Function", output(proxy))] - fn new() -> bevy::time::Stopwatch; - -"#, - r#" -/// Returns the elapsed time since the last [`reset`](Stopwatch::reset) -/// of the stopwatch. -/// # Examples -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let mut stopwatch = Stopwatch::new(); -/// stopwatch.tick(Duration::from_secs(1)); -/// assert_eq!(stopwatch.elapsed(), Duration::from_secs(1)); -/// ``` -/// # See Also -/// [`elapsed_secs`](Stopwatch::elapsed_secs) - if an `f32` value is desirable instead. -/// [`elapsed_secs_f64`](Stopwatch::elapsed_secs_f64) - if an `f64` is desirable instead. - - #[lua(kind = "Method", output(proxy))] - fn elapsed(&self) -> bevy::utils::Duration; - -"#, - r#" -/// Returns the elapsed time since the last [`reset`](Stopwatch::reset) -/// of the stopwatch, in seconds. -/// # Examples -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let mut stopwatch = Stopwatch::new(); -/// stopwatch.tick(Duration::from_secs(1)); -/// assert_eq!(stopwatch.elapsed_secs(), 1.0); -/// ``` -/// # See Also -/// [`elapsed`](Stopwatch::elapsed) - if a `Duration` is desirable instead. -/// [`elapsed_secs_f64`](Stopwatch::elapsed_secs_f64) - if an `f64` is desirable instead. - - #[lua(kind = "Method")] - fn elapsed_secs(&self) -> f32; - -"#, - r#" -/// Returns the elapsed time since the last [`reset`](Stopwatch::reset) -/// of the stopwatch, in seconds, as f64. -/// # See Also -/// [`elapsed`](Stopwatch::elapsed) - if a `Duration` is desirable instead. -/// [`elapsed_secs`](Stopwatch::elapsed_secs) - if an `f32` is desirable instead. - - #[lua(kind = "Method")] - fn elapsed_secs_f64(&self) -> f64; - -"#, - r#" -/// Sets the elapsed time of the stopwatch. -/// # Examples -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let mut stopwatch = Stopwatch::new(); -/// stopwatch.set_elapsed(Duration::from_secs_f32(1.0)); -/// assert_eq!(stopwatch.elapsed_secs(), 1.0); -/// ``` - - #[lua(kind = "MutatingMethod")] - fn set_elapsed(&mut self, #[proxy] time: bevy::utils::Duration) -> (); - -"#, - r#" -/// Pauses the stopwatch. Any call to [`tick`](Stopwatch::tick) while -/// paused will not have any effect on the elapsed time. -/// # Examples -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let mut stopwatch = Stopwatch::new(); -/// stopwatch.pause(); -/// stopwatch.tick(Duration::from_secs_f32(1.5)); -/// assert!(stopwatch.is_paused()); -/// assert_eq!(stopwatch.elapsed_secs(), 0.0); -/// ``` - - #[lua(kind = "MutatingMethod")] - fn pause(&mut self) -> (); - -"#, - r#" -/// Unpauses the stopwatch. Resume the effect of ticking on elapsed time. -/// # Examples -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let mut stopwatch = Stopwatch::new(); -/// stopwatch.pause(); -/// stopwatch.tick(Duration::from_secs_f32(1.0)); -/// stopwatch.unpause(); -/// stopwatch.tick(Duration::from_secs_f32(1.0)); -/// assert!(!stopwatch.is_paused()); -/// assert_eq!(stopwatch.elapsed_secs(), 1.0); -/// ``` - - #[lua(kind = "MutatingMethod")] - fn unpause(&mut self) -> (); - -"#, - r#" -/// Returns `true` if the stopwatch is paused. -/// # Examples -/// ``` -/// # use bevy_time::*; -/// let mut stopwatch = Stopwatch::new(); -/// assert!(!stopwatch.is_paused()); -/// stopwatch.pause(); -/// assert!(stopwatch.is_paused()); -/// stopwatch.unpause(); -/// assert!(!stopwatch.is_paused()); -/// ``` - - #[lua(kind = "Method")] - fn is_paused(&self) -> bool; - -"#, - r#" -/// Resets the stopwatch. The reset doesn't affect the paused state of the stopwatch. -/// # Examples -/// ``` -/// # use bevy_time::*; -/// use std::time::Duration; -/// let mut stopwatch = Stopwatch::new(); -/// stopwatch.tick(Duration::from_secs_f32(1.5)); -/// stopwatch.reset(); -/// assert_eq!(stopwatch.elapsed_secs(), 0.0); -/// ``` - - #[lua(kind = "MutatingMethod")] - fn reset(&mut self) -> (); - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &stopwatch::Stopwatch) -> bool; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Stopwatch {} -#[derive(Default)] -pub(crate) struct Globals; -impl bevy_mod_scripting_lua::tealr::mlu::ExportInstances for Globals { - fn add_instances< - 'lua, - T: bevy_mod_scripting_lua::tealr::mlu::InstanceCollector<'lua>, - >(self, instances: &mut T) -> bevy_mod_scripting_lua::tealr::mlu::mlua::Result<()> { - instances - .add_instance( - "Timer", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - instances - .add_instance( - "Stopwatch", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - Ok(()) - } -} -pub struct BevyTimeAPIProvider; -impl bevy_mod_scripting_core::hosts::APIProvider for BevyTimeAPIProvider { - type APITarget = std::sync::Mutex; - type ScriptContext = std::sync::Mutex; - type DocTarget = bevy_mod_scripting_lua::docs::LuaDocFragment; - fn attach_api( - &mut self, - ctx: &mut Self::APITarget, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - let ctx = ctx.get_mut().expect("Unable to acquire lock on Lua context"); - bevy_mod_scripting_lua::tealr::mlu::set_global_env(Globals, ctx) - .map_err(|e| bevy_mod_scripting_core::error::ScriptError::Other( - e.to_string(), - )) - } - fn get_doc_fragment(&self) -> Option { - Some( - bevy_mod_scripting_lua::docs::LuaDocFragment::new( - "BevyTimeAPI", - |tw| { - tw.document_global_instance::() - .expect("Something went wrong documenting globals") - .process_type::() - .process_type::() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy, - >() - .process_type::() - .process_type::() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaStopwatch, - >, - >() - }, - ), - ) - } - fn setup_script( - &mut self, - script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - fn setup_script_runtime( - &mut self, - world_ptr: bevy_mod_scripting_core::world::WorldPointer, - _script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - fn register_with_app(&self, app: &mut bevy::app::App) { - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - } -} diff --git a/crates/bevy_script_api/src/providers/bevy_transform.rs b/crates/bevy_script_api/src/providers/bevy_transform.rs deleted file mode 100644 index 57bcb23f..00000000 --- a/crates/bevy_script_api/src/providers/bevy_transform.rs +++ /dev/null @@ -1,819 +0,0 @@ -// @generated by cargo bevy-api-gen generate, modify the templates not this file -#![allow(clippy::all)] -#![allow(unused, deprecated, dead_code)] -#![cfg_attr(rustfmt, rustfmt_skip)] -use super::bevy_ecs::*; -use super::bevy_reflect::*; -use super::bevy_core::*; -use super::bevy_math::*; -use super::bevy_hierarchy::*; -extern crate self as bevy_script_api; -use bevy_script_api::{ - lua::RegisterForeignLuaType, ReflectedValue, common::bevy::GetWorld, -}; -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::transform::components::GlobalTransform", - functions[r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] value: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul( - self, - #[proxy] - global_transform: bevy::transform::components::GlobalTransform, - ) -> bevy::transform::components::GlobalTransform; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::transform::components::GlobalTransform; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul( - self, - #[proxy] - transform: bevy::transform::components::Transform, - ) -> bevy::transform::components::GlobalTransform; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &components::global_transform::GlobalTransform) -> bool; - -"#, - r#" - - #[lua(kind = "Function", output(proxy))] - fn from_xyz(x: f32, y: f32, z: f32) -> bevy::transform::components::GlobalTransform; - -"#, - r#" - - #[lua(kind = "Function", output(proxy))] - fn from_translation( - #[proxy] - translation: bevy::math::Vec3, - ) -> bevy::transform::components::GlobalTransform; - -"#, - r#" - - #[lua(kind = "Function", output(proxy))] - fn from_rotation( - #[proxy] - rotation: bevy::math::Quat, - ) -> bevy::transform::components::GlobalTransform; - -"#, - r#" - - #[lua(kind = "Function", output(proxy))] - fn from_scale( - #[proxy] - scale: bevy::math::Vec3, - ) -> bevy::transform::components::GlobalTransform; - -"#, - r#" - - #[lua(kind = "Function", output(proxy))] - fn from_isometry( - #[proxy] - iso: bevy::math::Isometry3d, - ) -> bevy::transform::components::GlobalTransform; - -"#, - r#" -/// Returns the 3d affine transformation matrix as a [`Mat4`]. - - #[lua(kind = "Method", output(proxy))] - fn compute_matrix(&self) -> bevy::math::Mat4; - -"#, - r#" -/// Returns the 3d affine transformation matrix as an [`Affine3A`]. - - #[lua(kind = "Method", output(proxy))] - fn affine(&self) -> bevy::math::Affine3A; - -"#, - r#" -/// Returns the transformation as a [`Transform`]. -/// The transform is expected to be non-degenerate and without shearing, or the output -/// will be invalid. - - #[lua(kind = "Method", output(proxy))] - fn compute_transform(&self) -> bevy::transform::components::Transform; - -"#, - r#" -/// Returns the isometric part of the transformation as an [isometry]. Any scaling done by the -/// transformation will be ignored. -/// The transform is expected to be non-degenerate and without shearing, or the output -/// will be invalid. -/// [isometry]: Isometry3d - - #[lua(kind = "Method", output(proxy))] - fn to_isometry(&self) -> bevy::math::Isometry3d; - -"#, - r#" -/// Returns the [`Transform`] `self` would have if it was a child of an entity -/// with the `parent` [`GlobalTransform`]. -/// This is useful if you want to "reparent" an [`Entity`](bevy_ecs::entity::Entity). -/// Say you have an entity `e1` that you want to turn into a child of `e2`, -/// but you want `e1` to keep the same global transform, even after re-parenting. You would use: -/// ``` -/// # use bevy_transform::prelude::{GlobalTransform, Transform}; -/// # use bevy_ecs::prelude::{Entity, Query, Component, Commands}; -/// # use bevy_hierarchy::{prelude::Parent, BuildChildren}; -/// #[derive(Component)] -/// struct ToReparent { -/// new_parent: Entity, -/// } -/// fn reparent_system( -/// mut commands: Commands, -/// mut targets: Query<(&mut Transform, Entity, &GlobalTransform, &ToReparent)>, -/// transforms: Query<&GlobalTransform>, -/// ) { -/// for (mut transform, entity, initial, to_reparent) in targets.iter_mut() { -/// if let Ok(parent_transform) = transforms.get(to_reparent.new_parent) { -/// *transform = initial.reparented_to(parent_transform); -/// commands.entity(entity) -/// .remove::() -/// .set_parent(to_reparent.new_parent); -/// } -/// } -/// } -/// ``` -/// The transform is expected to be non-degenerate and without shearing, or the output -/// will be invalid. - - #[lua(kind = "Method", output(proxy))] - fn reparented_to( - &self, - #[proxy] - parent: &components::global_transform::GlobalTransform, - ) -> bevy::transform::components::Transform; - -"#, - r#" -///Return the local right vector (X). - - #[lua(kind = "Method", output(proxy))] - fn right(&self) -> bevy::math::Dir3; - -"#, - r#" -///Return the local left vector (-X). - - #[lua(kind = "Method", output(proxy))] - fn left(&self) -> bevy::math::Dir3; - -"#, - r#" -///Return the local up vector (Y). - - #[lua(kind = "Method", output(proxy))] - fn up(&self) -> bevy::math::Dir3; - -"#, - r#" -///Return the local down vector (-Y). - - #[lua(kind = "Method", output(proxy))] - fn down(&self) -> bevy::math::Dir3; - -"#, - r#" -///Return the local back vector (Z). - - #[lua(kind = "Method", output(proxy))] - fn back(&self) -> bevy::math::Dir3; - -"#, - r#" -///Return the local forward vector (-Z). - - #[lua(kind = "Method", output(proxy))] - fn forward(&self) -> bevy::math::Dir3; - -"#, - r#" -/// Get the translation as a [`Vec3`]. - - #[lua(kind = "Method", output(proxy))] - fn translation(&self) -> bevy::math::Vec3; - -"#, - r#" -/// Get the translation as a [`Vec3A`]. - - #[lua(kind = "Method", output(proxy))] - fn translation_vec3a(&self) -> bevy::math::Vec3A; - -"#, - r#" -/// Get the rotation as a [`Quat`]. -/// The transform is expected to be non-degenerate and without shearing, or the output will be invalid. -/// # Warning -/// This is calculated using `to_scale_rotation_translation`, meaning that you -/// should probably use it directly if you also need translation or scale. - - #[lua(kind = "Method", output(proxy))] - fn rotation(&self) -> bevy::math::Quat; - -"#, - r#" -/// Get the scale as a [`Vec3`]. -/// The transform is expected to be non-degenerate and without shearing, or the output will be invalid. -/// Some of the computations overlap with `to_scale_rotation_translation`, which means you should use -/// it instead if you also need rotation. - - #[lua(kind = "Method", output(proxy))] - fn scale(&self) -> bevy::math::Vec3; - -"#, - r#" -/// Get an upper bound of the radius from the given `extents`. - - #[lua(kind = "Method")] - fn radius_vec3a(&self, #[proxy] extents: bevy::math::Vec3A) -> f32; - -"#, - r#" -/// Transforms the given point from local space to global space, applying shear, scale, rotation and translation. -/// It can be used like this: -/// ``` -/// # use bevy_transform::prelude::{GlobalTransform}; -/// # use bevy_math::prelude::Vec3; -/// let global_transform = GlobalTransform::from_xyz(1., 2., 3.); -/// let local_point = Vec3::new(1., 2., 3.); -/// let global_point = global_transform.transform_point(local_point); -/// assert_eq!(global_point, Vec3::new(2., 4., 6.)); -/// ``` -/// ``` -/// # use bevy_transform::prelude::{GlobalTransform}; -/// # use bevy_math::Vec3; -/// let global_point = Vec3::new(2., 4., 6.); -/// let global_transform = GlobalTransform::from_xyz(1., 2., 3.); -/// let local_point = global_transform.affine().inverse().transform_point3(global_point); -/// assert_eq!(local_point, Vec3::new(1., 2., 3.)) -/// ``` -/// To apply shear, scale, and rotation *without* applying translation, different functions are available: -/// ``` -/// # use bevy_transform::prelude::{GlobalTransform}; -/// # use bevy_math::prelude::Vec3; -/// let global_transform = GlobalTransform::from_xyz(1., 2., 3.); -/// let local_direction = Vec3::new(1., 2., 3.); -/// let global_direction = global_transform.affine().transform_vector3(local_direction); -/// assert_eq!(global_direction, Vec3::new(1., 2., 3.)); -/// let roundtripped_local_direction = global_transform.affine().inverse().transform_vector3(global_direction); -/// assert_eq!(roundtripped_local_direction, local_direction); -/// ``` - - #[lua(kind = "Method", output(proxy))] - fn transform_point(&self, #[proxy] point: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Multiplies `self` with `transform` component by component, returning the -/// resulting [`GlobalTransform`] - - #[lua(kind = "Method", output(proxy))] - fn mul_transform( - &self, - #[proxy] - transform: bevy::transform::components::Transform, - ) -> bevy::transform::components::GlobalTransform; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct GlobalTransform(); -#[derive(bevy_mod_scripting_lua_derive::LuaProxy)] -#[proxy( - derive(clone), - remote = "bevy::transform::components::Transform", - functions[r#" -/// Creates a new [`Transform`] at the position `(x, y, z)`. In 2d, the `z` component -/// is used for z-ordering elements: higher `z`-value will be in front of lower -/// `z`-value. - - #[lua(kind = "Function", output(proxy))] - fn from_xyz(x: f32, y: f32, z: f32) -> bevy::transform::components::Transform; - -"#, - r#" -/// Extracts the translation, rotation, and scale from `matrix`. It must be a 3d affine -/// transformation matrix. - - #[lua(kind = "Function", output(proxy))] - fn from_matrix( - #[proxy] - world_from_local: bevy::math::Mat4, - ) -> bevy::transform::components::Transform; - -"#, - r#" -/// Creates a new [`Transform`], with `translation`. Rotation will be 0 and scale 1 on -/// all axes. - - #[lua(kind = "Function", output(proxy))] - fn from_translation( - #[proxy] - translation: bevy::math::Vec3, - ) -> bevy::transform::components::Transform; - -"#, - r#" -/// Creates a new [`Transform`], with `rotation`. Translation will be 0 and scale 1 on -/// all axes. - - #[lua(kind = "Function", output(proxy))] - fn from_rotation( - #[proxy] - rotation: bevy::math::Quat, - ) -> bevy::transform::components::Transform; - -"#, - r#" -/// Creates a new [`Transform`], with `scale`. Translation will be 0 and rotation 0 on -/// all axes. - - #[lua(kind = "Function", output(proxy))] - fn from_scale( - #[proxy] - scale: bevy::math::Vec3, - ) -> bevy::transform::components::Transform; - -"#, - r#" -/// Creates a new [`Transform`] that is equivalent to the given [isometry]. -/// [isometry]: Isometry3d - - #[lua(kind = "Function", output(proxy))] - fn from_isometry( - #[proxy] - iso: bevy::math::Isometry3d, - ) -> bevy::transform::components::Transform; - -"#, - r#" -/// Returns this [`Transform`] with a new translation. - - #[lua(kind = "Method", output(proxy))] - fn with_translation( - self, - #[proxy] - translation: bevy::math::Vec3, - ) -> bevy::transform::components::Transform; - -"#, - r#" -/// Returns this [`Transform`] with a new rotation. - - #[lua(kind = "Method", output(proxy))] - fn with_rotation( - self, - #[proxy] - rotation: bevy::math::Quat, - ) -> bevy::transform::components::Transform; - -"#, - r#" -/// Returns this [`Transform`] with a new scale. - - #[lua(kind = "Method", output(proxy))] - fn with_scale( - self, - #[proxy] - scale: bevy::math::Vec3, - ) -> bevy::transform::components::Transform; - -"#, - r#" -/// Returns the 3d affine transformation matrix from this transforms translation, -/// rotation, and scale. - - #[lua(kind = "Method", output(proxy))] - fn compute_matrix(&self) -> bevy::math::Mat4; - -"#, - r#" -/// Returns the 3d affine transformation matrix from this transforms translation, -/// rotation, and scale. - - #[lua(kind = "Method", output(proxy))] - fn compute_affine(&self) -> bevy::math::Affine3A; - -"#, - r#" -/// Get the unit vector in the local `X` direction. - - #[lua(kind = "Method", output(proxy))] - fn local_x(&self) -> bevy::math::Dir3; - -"#, - r#" -/// Equivalent to [`-local_x()`][Transform::local_x()] - - #[lua(kind = "Method", output(proxy))] - fn left(&self) -> bevy::math::Dir3; - -"#, - r#" -/// Equivalent to [`local_x()`][Transform::local_x()] - - #[lua(kind = "Method", output(proxy))] - fn right(&self) -> bevy::math::Dir3; - -"#, - r#" -/// Get the unit vector in the local `Y` direction. - - #[lua(kind = "Method", output(proxy))] - fn local_y(&self) -> bevy::math::Dir3; - -"#, - r#" -/// Equivalent to [`local_y()`][Transform::local_y] - - #[lua(kind = "Method", output(proxy))] - fn up(&self) -> bevy::math::Dir3; - -"#, - r#" -/// Equivalent to [`-local_y()`][Transform::local_y] - - #[lua(kind = "Method", output(proxy))] - fn down(&self) -> bevy::math::Dir3; - -"#, - r#" -/// Get the unit vector in the local `Z` direction. - - #[lua(kind = "Method", output(proxy))] - fn local_z(&self) -> bevy::math::Dir3; - -"#, - r#" -/// Equivalent to [`-local_z()`][Transform::local_z] - - #[lua(kind = "Method", output(proxy))] - fn forward(&self) -> bevy::math::Dir3; - -"#, - r#" -/// Equivalent to [`local_z()`][Transform::local_z] - - #[lua(kind = "Method", output(proxy))] - fn back(&self) -> bevy::math::Dir3; - -"#, - r#" -/// Rotates this [`Transform`] by the given rotation. -/// If this [`Transform`] has a parent, the `rotation` is relative to the rotation of the parent. -/// # Examples -/// - [`3d_rotation`] -/// [`3d_rotation`]: https://github.com/bevyengine/bevy/blob/latest/examples/transforms/3d_rotation.rs - - #[lua(kind = "MutatingMethod")] - fn rotate(&mut self, #[proxy] rotation: bevy::math::Quat) -> (); - -"#, - r#" -/// Rotates this [`Transform`] around the given `axis` by `angle` (in radians). -/// If this [`Transform`] has a parent, the `axis` is relative to the rotation of the parent. - - #[lua(kind = "MutatingMethod")] - fn rotate_axis(&mut self, #[proxy] axis: bevy::math::Dir3, angle: f32) -> (); - -"#, - r#" -/// Rotates this [`Transform`] around the `X` axis by `angle` (in radians). -/// If this [`Transform`] has a parent, the axis is relative to the rotation of the parent. - - #[lua(kind = "MutatingMethod")] - fn rotate_x(&mut self, angle: f32) -> (); - -"#, - r#" -/// Rotates this [`Transform`] around the `Y` axis by `angle` (in radians). -/// If this [`Transform`] has a parent, the axis is relative to the rotation of the parent. - - #[lua(kind = "MutatingMethod")] - fn rotate_y(&mut self, angle: f32) -> (); - -"#, - r#" -/// Rotates this [`Transform`] around the `Z` axis by `angle` (in radians). -/// If this [`Transform`] has a parent, the axis is relative to the rotation of the parent. - - #[lua(kind = "MutatingMethod")] - fn rotate_z(&mut self, angle: f32) -> (); - -"#, - r#" -/// Rotates this [`Transform`] by the given `rotation`. -/// The `rotation` is relative to this [`Transform`]'s current rotation. - - #[lua(kind = "MutatingMethod")] - fn rotate_local(&mut self, #[proxy] rotation: bevy::math::Quat) -> (); - -"#, - r#" -/// Rotates this [`Transform`] around its local `axis` by `angle` (in radians). - - #[lua(kind = "MutatingMethod")] - fn rotate_local_axis(&mut self, #[proxy] axis: bevy::math::Dir3, angle: f32) -> (); - -"#, - r#" -/// Rotates this [`Transform`] around its local `X` axis by `angle` (in radians). - - #[lua(kind = "MutatingMethod")] - fn rotate_local_x(&mut self, angle: f32) -> (); - -"#, - r#" -/// Rotates this [`Transform`] around its local `Y` axis by `angle` (in radians). - - #[lua(kind = "MutatingMethod")] - fn rotate_local_y(&mut self, angle: f32) -> (); - -"#, - r#" -/// Rotates this [`Transform`] around its local `Z` axis by `angle` (in radians). - - #[lua(kind = "MutatingMethod")] - fn rotate_local_z(&mut self, angle: f32) -> (); - -"#, - r#" -/// Translates this [`Transform`] around a `point` in space. -/// If this [`Transform`] has a parent, the `point` is relative to the [`Transform`] of the parent. - - #[lua(kind = "MutatingMethod")] - fn translate_around( - &mut self, - #[proxy] - point: bevy::math::Vec3, - #[proxy] - rotation: bevy::math::Quat, - ) -> (); - -"#, - r#" -/// Rotates this [`Transform`] around a `point` in space. -/// If this [`Transform`] has a parent, the `point` is relative to the [`Transform`] of the parent. - - #[lua(kind = "MutatingMethod")] - fn rotate_around( - &mut self, - #[proxy] - point: bevy::math::Vec3, - #[proxy] - rotation: bevy::math::Quat, - ) -> (); - -"#, - r#" -/// Multiplies `self` with `transform` component by component, returning the -/// resulting [`Transform`] - - #[lua(kind = "Method", output(proxy))] - fn mul_transform( - &self, - #[proxy] - transform: bevy::transform::components::Transform, - ) -> bevy::transform::components::Transform; - -"#, - r#" -/// Transforms the given `point`, applying scale, rotation and translation. -/// If this [`Transform`] has an ancestor entity with a [`Transform`] component, -/// [`Transform::transform_point`] will transform a point in local space into its -/// parent transform's space. -/// If this [`Transform`] does not have a parent, [`Transform::transform_point`] will -/// transform a point in local space into worldspace coordinates. -/// If you always want to transform a point in local space to worldspace, or if you need -/// the inverse transformations, see [`GlobalTransform::transform_point()`]. - - #[lua(kind = "Method", output(proxy))] - fn transform_point(&self, #[proxy] point: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -/// Returns `true` if, and only if, translation, rotation and scale all are -/// finite. If any of them contains a `NaN`, positive or negative infinity, -/// this will return `false`. - - #[lua(kind = "Method")] - fn is_finite(&self) -> bool; - -"#, - r#" -/// Get the [isometry] defined by this transform's rotation and translation, ignoring scale. -/// [isometry]: Isometry3d - - #[lua(kind = "Method", output(proxy))] - fn to_isometry(&self) -> bevy::math::Isometry3d; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul( - self, - #[proxy] - global_transform: bevy::transform::components::GlobalTransform, - ) -> bevy::transform::components::GlobalTransform; - -"#, - r#" - - #[lua( - as_trait = "std::cmp::PartialEq", - kind = "MetaFunction", - composite = "eq", - metamethod = "Eq", - )] - fn eq(&self, #[proxy] other: &components::transform::Transform) -> bool; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul( - self, - #[proxy] - transform: bevy::transform::components::Transform, - ) -> bevy::transform::components::Transform; - -"#, - r#" - - #[lua(as_trait = "std::clone::Clone", kind = "Method", output(proxy))] - fn clone(&self) -> bevy::transform::components::Transform; - -"#, - r#" - - #[lua( - as_trait = "std::ops::Mul", - kind = "MetaFunction", - output(proxy), - composite = "mul", - metamethod = "Mul", - )] - fn mul(self, #[proxy] value: bevy::math::Vec3) -> bevy::math::Vec3; - -"#, - r#" -#[lua(kind="MetaMethod", metamethod="ToString")] -fn index(&self) -> String { - format!("{:?}", _self) -} -"#] -)] -struct Transform { - #[lua(output(proxy))] - translation: bevy::math::Vec3, - #[lua(output(proxy))] - rotation: bevy::math::Quat, - #[lua(output(proxy))] - scale: bevy::math::Vec3, -} -#[derive(Default)] -pub(crate) struct Globals; -impl bevy_mod_scripting_lua::tealr::mlu::ExportInstances for Globals { - fn add_instances< - 'lua, - T: bevy_mod_scripting_lua::tealr::mlu::InstanceCollector<'lua>, - >(self, instances: &mut T) -> bevy_mod_scripting_lua::tealr::mlu::mlua::Result<()> { - instances - .add_instance( - "GlobalTransform", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::< - LuaGlobalTransform, - >::new, - )?; - instances - .add_instance( - "Transform", - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy::::new, - )?; - Ok(()) - } -} -pub struct BevyTransformAPIProvider; -impl bevy_mod_scripting_core::hosts::APIProvider for BevyTransformAPIProvider { - type APITarget = std::sync::Mutex; - type ScriptContext = std::sync::Mutex; - type DocTarget = bevy_mod_scripting_lua::docs::LuaDocFragment; - fn attach_api( - &mut self, - ctx: &mut Self::APITarget, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - let ctx = ctx.get_mut().expect("Unable to acquire lock on Lua context"); - bevy_mod_scripting_lua::tealr::mlu::set_global_env(Globals, ctx) - .map_err(|e| bevy_mod_scripting_core::error::ScriptError::Other( - e.to_string(), - )) - } - fn get_doc_fragment(&self) -> Option { - Some( - bevy_mod_scripting_lua::docs::LuaDocFragment::new( - "BevyTransformAPI", - |tw| { - tw.document_global_instance::() - .expect("Something went wrong documenting globals") - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaGlobalTransform, - >, - >() - .process_type::() - .process_type::< - bevy_mod_scripting_lua::tealr::mlu::UserDataProxy< - LuaTransform, - >, - >() - }, - ), - ) - } - fn setup_script( - &mut self, - script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - fn setup_script_runtime( - &mut self, - world_ptr: bevy_mod_scripting_core::world::WorldPointer, - _script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - fn register_with_app(&self, app: &mut bevy::app::App) { - app.register_foreign_lua_type::(); - app.register_foreign_lua_type::(); - } -} diff --git a/crates/bevy_script_api/src/providers/mod.rs b/crates/bevy_script_api/src/providers/mod.rs deleted file mode 100644 index 1c5636d2..00000000 --- a/crates/bevy_script_api/src/providers/mod.rs +++ /dev/null @@ -1,80 +0,0 @@ -// @generated by cargo bevy-api-gen collect, modify the templates not this file -#![allow(clippy::all)] -#![allow(unused, deprecated, dead_code)] -#![cfg_attr(rustfmt, rustfmt_skip)] -pub mod bevy_ecs; -pub mod bevy_transform; -pub mod bevy_math; -pub mod bevy_input; -pub mod bevy_core; -pub mod bevy_time; -pub mod bevy_hierarchy; -pub mod bevy_reflect; -extern crate self as bevy_script_api; -use bevy_mod_scripting_core::docs::DocFragment; -pub struct LuaBevyAPIProvider; -impl bevy_mod_scripting_core::hosts::APIProvider for LuaBevyAPIProvider { - type APITarget = std::sync::Mutex; - type ScriptContext = std::sync::Mutex; - type DocTarget = bevy_mod_scripting_lua::docs::LuaDocFragment; - fn attach_api( - &mut self, - ctx: &mut Self::APITarget, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - bevy_ecs::BevyEcsAPIProvider.attach_api(ctx)?; - bevy_transform::BevyTransformAPIProvider.attach_api(ctx)?; - bevy_math::BevyMathAPIProvider.attach_api(ctx)?; - bevy_input::BevyInputAPIProvider.attach_api(ctx)?; - bevy_core::BevyCoreAPIProvider.attach_api(ctx)?; - bevy_time::BevyTimeAPIProvider.attach_api(ctx)?; - bevy_hierarchy::BevyHierarchyAPIProvider.attach_api(ctx)?; - bevy_reflect::BevyReflectAPIProvider.attach_api(ctx)?; - Ok(()) - } - fn get_doc_fragment(&self) -> Option { - [ - bevy_ecs::BevyEcsAPIProvider.get_doc_fragment(), - bevy_transform::BevyTransformAPIProvider.get_doc_fragment(), - bevy_math::BevyMathAPIProvider.get_doc_fragment(), - bevy_input::BevyInputAPIProvider.get_doc_fragment(), - bevy_core::BevyCoreAPIProvider.get_doc_fragment(), - bevy_time::BevyTimeAPIProvider.get_doc_fragment(), - bevy_hierarchy::BevyHierarchyAPIProvider.get_doc_fragment(), - bevy_reflect::BevyReflectAPIProvider.get_doc_fragment(), - ] - .into_iter() - .filter_map(|a: Option<_>| a) - .fold( - None, - |a, b| match a { - Some(a) => Some(a.merge(b)), - None => Some(b), - }, - ) - } - fn setup_script( - &mut self, - script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - fn setup_script_runtime( - &mut self, - world_ptr: bevy_mod_scripting_core::world::WorldPointer, - _script_data: &bevy_mod_scripting_core::hosts::ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { - Ok(()) - } - fn register_with_app(&self, app: &mut bevy::app::App) { - bevy_ecs::BevyEcsAPIProvider.register_with_app(app); - bevy_transform::BevyTransformAPIProvider.register_with_app(app); - bevy_math::BevyMathAPIProvider.register_with_app(app); - bevy_input::BevyInputAPIProvider.register_with_app(app); - bevy_core::BevyCoreAPIProvider.register_with_app(app); - bevy_time::BevyTimeAPIProvider.register_with_app(app); - bevy_hierarchy::BevyHierarchyAPIProvider.register_with_app(app); - bevy_reflect::BevyReflectAPIProvider.register_with_app(app); - } -} diff --git a/crates/bevy_script_api/src/rhai/bevy/mod.rs b/crates/bevy_script_api/src/rhai/bevy/mod.rs deleted file mode 100644 index 3f4ea2a8..00000000 --- a/crates/bevy_script_api/src/rhai/bevy/mod.rs +++ /dev/null @@ -1,359 +0,0 @@ -use bevy::prelude::Entity; -use bevy_mod_scripting_core::{prelude::*, world::WorldPointer}; - -#[allow(deprecated)] -use bevy_mod_scripting_rhai::{ - prelude::*, - rhai::{self, CustomType, INT}, -}; -use rhai::plugin::*; - -use crate::{ - common::bevy::{ScriptQueryBuilder, ScriptTypeRegistration, ScriptWorld}, - ReflectedValue, -}; - -use super::{RegisterForeignRhaiType, ToDynamic}; - -#[allow(deprecated)] -impl CustomType for ScriptTypeRegistration { - fn build(mut builder: rhai::TypeBuilder) { - builder - .with_name("TypeRegistration") - .with_fn("short_name", |self_: &mut Self| { - ImmutableString::from(self_.short_name()) - }) - .with_fn("type_name", |self_: &mut Self| self_.type_name()) - .with_fn("to_string", |self_: &mut Self| self_.to_string()) - .with_fn("to_debug", |self_: &mut Self| format!("{:?}", self_)); - } -} - -impl CustomType for ScriptQueryBuilder { - fn build(mut builder: rhai::TypeBuilder) { - builder - .with_name("QueryBuilder") - // `with` is a reserved keyword, so we add _components on the end - .with_fn("with_components", |self_: &mut Self, with: Vec| { - self_.with( - with.into_iter() - .map(Dynamic::cast::) - .collect(), - ); - - Dynamic::from(self_.clone()) - }) - .with_fn( - "without_components", - |self_: &mut Self, without: Vec| { - self_.without( - without - .into_iter() - .map(Dynamic::cast::) - .collect(), - ); - - Dynamic::from(self_.clone()) - }, - ); - } -} - -impl IntoIterator for ScriptQueryBuilder { - type Item = rhai::Map; - type IntoIter = std::vec::IntoIter; - - fn into_iter(mut self) -> Self::IntoIter { - self.build() - .expect("Query failed!") - .into_iter() - .map(|result| { - let mut map = rhai::Map::new(); - map.insert("Entity".into(), Dynamic::from(result.0)); - - for component in result.1.into_iter() { - let name = component - .get(|value| value.get_represented_type_info()?.type_path_table().ident()) - .unwrap() - .unwrap(); - - map.insert( - name.into(), - component.to_dynamic().unwrap_or_else(|_| { - panic!("Converting component {} to dynamic failed!", &name) - }), - ); - } - - map - }) - .collect::>() - .into_iter() - } -} - -#[allow(deprecated)] -impl CustomType for ScriptWorld { - fn build(mut builder: rhai::TypeBuilder) { - builder - .with_name("World") - .with_fn("get_type_by_name", |self_: ScriptWorld, type_name: &str| { - self_ - .get_type_by_name(type_name) - .map(Dynamic::from) - .unwrap_or_default() - }) - .with_fn( - "add_default_component", - |self_: ScriptWorld, entity: Entity, type_registration: ScriptTypeRegistration| { - self_ - .add_default_component(entity, type_registration) - .map_err(|e| { - Box::new(EvalAltResult::ErrorRuntime( - Dynamic::from(e.to_string()), - Position::NONE, - )) - }) - .and_then(|ok| ok.to_dynamic()) - }, - ) - .with_fn( - "get_component", - |self_: ScriptWorld, entity: Entity, comp_type: ScriptTypeRegistration| { - let component = self_.get_component(entity, comp_type).map_err(|e| { - Box::new(EvalAltResult::ErrorRuntime( - e.to_string().into(), - Position::NONE, - )) - })?; - if let Some(c) = component { - c.to_dynamic() - } else { - Ok(Default::default()) - } - }, - ) - .with_fn( - "has_component", - |self_: ScriptWorld, entity: Entity, comp_type: ScriptTypeRegistration| { - self_.has_component(entity, comp_type).map_err(|e| { - Box::new(EvalAltResult::ErrorRuntime( - e.to_string().into(), - Position::NONE, - )) - }) - }, - ) - .with_fn( - "remove_component", - |mut self_: ScriptWorld, entity: Entity, comp_type: ScriptTypeRegistration| { - self_.remove_component(entity, comp_type).map_err(|e| { - Box::new(EvalAltResult::ErrorRuntime( - e.to_string().into(), - Position::NONE, - )) - }) - }, - ) - .with_fn( - "get_resource", - |self_: ScriptWorld, res_type: ScriptTypeRegistration| { - let resource = self_.get_resource(res_type).map_err(|err| { - Box::new(EvalAltResult::ErrorRuntime( - err.to_string().into(), - Position::NONE, - )) - })?; - - if let Some(c) = resource { - c.to_dynamic() - } else { - Ok(Default::default()) - } - }, - ) - .with_fn( - "has_resource", - |self_: &mut ScriptWorld, res_type: ScriptTypeRegistration| { - self_.has_resource(res_type).map_err(|e| { - Box::new(EvalAltResult::ErrorRuntime( - e.to_string().into(), - Position::NONE, - )) - }) - }, - ) - .with_fn( - "remove_resource", - |self_: &mut ScriptWorld, res_type: ScriptTypeRegistration| { - self_.remove_resource(res_type).map_err(|e| { - Box::new(EvalAltResult::ErrorRuntime( - e.to_string().into(), - Position::NONE, - )) - }) - }, - ) - .with_fn("get_parent", |self_: ScriptWorld, entity: Entity| { - if let Some(parent) = self_.get_parent(entity) { - Dynamic::from(parent) - } else { - Dynamic::UNIT - } - }) - .with_fn("get_children", |self_: ScriptWorld, parent: Entity| { - self_ - .get_children(parent) - .into_iter() - .map(Dynamic::from) - .collect::>() - }) - .with_fn( - "push_child", - |self_: &mut ScriptWorld, parent: Entity, child: Entity| { - self_.push_child(parent, child) - }, - ) - .with_fn( - "remove_children", - |self_: &mut ScriptWorld, parent: Entity, children: Vec| { - self_.remove_children( - parent, - &children - .into_iter() - .map(Dynamic::cast::) - .collect::>(), - ) - }, - ) - .with_fn( - "remove_child", - |self_: &mut ScriptWorld, parent: Entity, child: Entity| { - self_.remove_children(parent, &[child]) - }, - ) - .with_fn( - "insert_children", - |self_: &mut ScriptWorld, parent: Entity, index: INT, children: Vec| { - self_.insert_children( - parent, - index.try_into().expect("number too large"), - &children - .into_iter() - .map(Dynamic::cast::) - .collect::>(), - ) - }, - ) - .with_fn( - "insert_child", - |self_: &mut ScriptWorld, parent: Entity, index: INT, child: Entity| { - self_.insert_children( - parent, - index.try_into().expect("number too large"), - &[child], - ) - }, - ) - .with_fn( - "despawn_children_recursive", - |self_: &mut ScriptWorld, entity: Entity| self_.despawn_children_recursive(entity), - ) - .with_fn( - "despawn_recursive", - |self_: &mut ScriptWorld, entity: Entity| self_.despawn_recursive(entity), - ) - .with_fn("spawn", |self_: &mut ScriptWorld| { - let mut w = self_.write(); - w.spawn(()).id() - }) - .with_fn("despawn", |self_: &mut ScriptWorld, entity: Entity| { - let mut w = self_.write(); - - w.despawn(entity) - }) - .with_fn("to_string", |self_: &mut ScriptWorld| self_.to_string()) - .with_fn("to_debug", |self_: &mut ScriptWorld| format!("{:?}", self_)) - .with_fn( - "query", - |self_: &mut ScriptWorld, component: ScriptTypeRegistration| { - ScriptQueryBuilder::new(self_.clone()) - .components(vec![component]) - .clone() - }, - ) - .with_fn( - "query", - |self_: &mut ScriptWorld, components: Vec| { - ScriptQueryBuilder::new(self_.clone()) - .components( - components - .into_iter() - .map(Dynamic::cast::) - .collect::>(), - ) - .clone() - }, - ); - } -} - -pub struct RhaiBevyAPIProvider; - -impl APIProvider for RhaiBevyAPIProvider { - type APITarget = Engine; - type ScriptContext = RhaiContext; - type DocTarget = RhaiDocFragment; - - fn attach_api(&mut self, engine: &mut Self::APITarget) -> Result<(), ScriptError> { - engine.build_type::(); - engine.build_type::(); - engine.build_type::(); - engine.build_type::(); - engine.register_iterator::>(); - engine.register_iterator::(); - Ok(()) - } - - fn setup_script_runtime( - &mut self, - world_ptr: WorldPointer, - _script_data: &ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), ScriptError> { - ctx.scope.set_value("world", ScriptWorld::new(world_ptr)); - Ok(()) - } - - fn setup_script( - &mut self, - script_data: &ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), ScriptError> { - ctx.scope.set_value("entity", script_data.entity); - Ok(()) - } - - fn get_doc_fragment(&self) -> Option { - None - } - - fn register_with_app(&self, app: &mut bevy::prelude::App) { - app.register_foreign_rhai_type::(); - app.register_foreign_rhai_type::(); - app.register_foreign_rhai_type::(); - app.register_foreign_rhai_type::(); - app.register_foreign_rhai_type::(); - app.register_foreign_rhai_type::(); - app.register_foreign_rhai_type::(); - app.register_foreign_rhai_type::(); - app.register_foreign_rhai_type::(); - app.register_foreign_rhai_type::(); - app.register_foreign_rhai_type::(); - app.register_foreign_rhai_type::(); - app.register_foreign_rhai_type::(); - app.register_foreign_rhai_type::(); - app.register_foreign_rhai_type::(); - app.register_foreign_rhai_type::(); - } -} diff --git a/crates/bevy_script_api/src/rhai/mod.rs b/crates/bevy_script_api/src/rhai/mod.rs deleted file mode 100644 index 26d40884..00000000 --- a/crates/bevy_script_api/src/rhai/mod.rs +++ /dev/null @@ -1,194 +0,0 @@ -use ::std::borrow::Cow; - -use ::bevy::{ - prelude::{App, AppTypeRegistry}, - reflect::{FromType, GetTypeRegistration, Reflect}, -}; -#[allow(deprecated)] -use bevy_mod_scripting_rhai::rhai::{CustomType, Dynamic, EvalAltResult, INT}; - -use crate::{ReflectReference, ReflectedValue, ValueIndex}; - -pub mod bevy; -pub mod std; - -/// A trait allowing the registration of the [`RhaiProxyable`] trait with the type registry for foreign types -/// -/// If you have access to the type you should prefer to use `#[reflect(RhaiProxyable)]` instead. -/// This is exactly equivalent. -pub trait RegisterForeignRhaiType { - fn register_foreign_rhai_type( - &mut self, - ) -> &mut Self; -} - -impl RegisterForeignRhaiType for App { - fn register_foreign_rhai_type( - &mut self, - ) -> &mut Self { - { - let registry = self.world_mut().resource_mut::(); - let mut registry = registry.write(); - - let rhai_data = >::from_type(); - - if let Some(registration) = registry.get_mut(TypeId::of::()) { - registration.insert(rhai_data) - } else { - let mut registration = T::get_type_registration(); - registration.insert(rhai_data); - registry.add_registration(registration); - } - } - - self - } -} - -pub trait RhaiProxyable { - fn ref_to_rhai(self_: ReflectReference) -> Result>; - fn apply_rhai(self_: &mut ReflectReference, new_val: Dynamic) - -> Result<(), Box>; -} - -pub trait FromRhaiProxy: Sized { - fn from_rhai_proxy(self_: Dynamic) -> Result>; -} - -pub trait ToRhaiProxy { - fn to_rhai_proxy(self) -> Result>; -} - -#[derive(Clone)] -pub struct ReflectRhaiProxyable { - ref_to_rhai: fn(ref_: ReflectReference) -> Result>, - apply_rhai: fn(ref_: &mut ReflectReference, new_val: Dynamic) -> Result<(), Box>, -} - -impl ReflectRhaiProxyable { - pub fn ref_to_rhai(&self, ref_: ReflectReference) -> Result> { - (self.ref_to_rhai)(ref_) - } - - pub fn apply_rhai( - &self, - ref_: &mut ReflectReference, - new_val: Dynamic, - ) -> Result<(), Box> { - (self.apply_rhai)(ref_, new_val) - } -} - -impl FromType for ReflectRhaiProxyable { - fn from_type() -> Self { - Self { - ref_to_rhai: T::ref_to_rhai, - apply_rhai: T::apply_rhai, - } - } -} - -pub trait ToDynamic { - fn to_dynamic(self) -> Result>; -} - -impl ToDynamic for ReflectedValue { - fn to_dynamic(self) -> Result> { - Ok(Dynamic::from(self)) - } -} - -impl ToDynamic for ReflectReference { - fn to_dynamic(self) -> Result> { - // clone since it's cheap and we don't want to clone self later - let world = self.world_ptr.clone(); - let world = world.read(); - - let type_data = world.resource::(); - let g = type_data.read(); - - let type_id = self.get(|s| s.type_id())?; - - if let Some(v) = g.get_type_data::(type_id) { - v.ref_to_rhai(self) - } else { - ReflectedValue { ref_: self }.to_dynamic() - } - } -} - -pub trait ApplyRhai { - fn apply_rhai(&mut self, value: Dynamic) -> Result<(), Box>; -} - -impl ApplyRhai for ReflectReference { - fn apply_rhai(&mut self, value: Dynamic) -> Result<(), Box> { - let world_ptr = self.world_ptr.clone(); - - // remove typedata from the world to be able to manipulate world - let proxyable = { - let world = world_ptr.read(); - let type_registry = world.resource::().read(); - type_registry - .get_type_data::(self.get(|s| s.type_id())?) - .cloned() - }; - - if let Some(ud) = proxyable { - return ud.apply_rhai(self, value); - } else if value.is::() { - let b = value.cast::(); - self.apply(&b.into())?; - return Ok(()); - } - - Err(Box::new(EvalAltResult::ErrorRuntime(self.get(|s| - format!("Attempted to assign `{}` = {value:?}. Did you forget to call `app.register_foreign_rhai_type::<{}>`?", - self.path, - s.get_represented_type_info().unwrap().type_path() - ))?.into(),Position::NONE) - )) - } -} - -impl ValueIndex for ReflectReference { - type Output = Result>; - - fn index(&self, index: Dynamic) -> Self::Output { - if index.is::() { - return Ok(self.index(index.as_int().unwrap() as usize)); - } else if index.is::() { - return Ok(self.index(Cow::Owned(index.into_string().unwrap()))); - }; - - Err(Box::new(EvalAltResult::ErrorMismatchDataType( - index.type_name().to_owned(), - "integer or string".to_owned(), - Position::NONE, - ))) - } -} - -use bevy_mod_scripting_rhai::rhai::plugin::*; - -#[allow(deprecated)] -impl CustomType for ReflectedValue { - fn build(mut builder: bevy_mod_scripting_rhai::rhai::TypeBuilder) { - builder - .with_indexer_get_result(|obj: &mut ReflectedValue, index: Dynamic| { - obj.ref_.index(index)?.to_dynamic() - }) - .with_indexer_set_result(|obj: &mut ReflectedValue, index: Dynamic, value: Dynamic| { - obj.ref_.index(index)?.apply_rhai(value) - }) - .with_fn("to_debug", |self_: &mut ReflectedValue| { - format!("{:?}", self_) - }) - .with_fn("to_string", |self_: &mut ReflectedValue| { - self_ - .ref_ - .get(|s| format!("{:?}", &s)) - .map_err::, _>(|e| e.into()) - }); - } -} diff --git a/crates/bevy_script_api/src/rhai/std.rs b/crates/bevy_script_api/src/rhai/std.rs deleted file mode 100644 index 88e8dc5d..00000000 --- a/crates/bevy_script_api/src/rhai/std.rs +++ /dev/null @@ -1,454 +0,0 @@ -use std::{ - any::type_name, - fmt::{Debug, Display}, - iter::Map, -}; - -use bevy::reflect::{FromReflect, GetTypeRegistration, Reflect, TypePath}; -#[allow(deprecated)] -use bevy_mod_scripting_rhai::rhai::{CustomType, Dynamic, Engine, EvalAltResult, Position}; - -use crate::{ - common::std::ScriptVec, error::ReflectionError, ReflectReference, ReflectionPathElement, - ValueIndex, -}; - -use super::{ApplyRhai, FromRhaiProxy, RhaiProxyable, ToDynamic, ToRhaiProxy}; - -impl RhaiProxyable for T { - fn ref_to_rhai(self_: crate::ReflectReference) -> Result> { - self_.get_typed(|self_: &T| Ok(Dynamic::from(self_.clone())))? - } - - fn apply_rhai( - self_: &mut crate::ReflectReference, - new_val: Dynamic, - ) -> Result<(), Box> { - let other = if new_val.is::() { - new_val.cast::() - } else { - return Err(Box::new(EvalAltResult::ErrorMismatchDataType( - stringify!(T).to_owned(), - new_val.type_name().to_string(), - Position::NONE, - ))); - }; - - self_.set_val(other)?; - Ok(()) - } -} - -/// A marker trait signifying this type is to receive an automatic proxy implementation via `Dynamic::from`. -/// This means the proxy for this type is the type itself, and is created by cloning the original reference. -pub trait RhaiCopy {} - -/// Implements RhaiProxyabel for a numeric type via another proxy type by coercing the type -macro_rules! impl_rhai_proxy { - // i.e. impl_rhai_proxy!(String as Into) - ($type:ty as Into) => { - impl_rhai_proxy!($type,$type,self: {self.into()}, s: {s.into()}); - }; - // i.e. impl_rhai_proxy!(u32 as i64) - ($type:ty as $proxy_type:ty) => { - impl_rhai_proxy!($type, $proxy_type,self:{(self as $proxy_type).into()}, s:{(*s as $proxy_type).into()}); - }; - // i.e. impl_rhai_proxy!(ident, u32, i64, (*ident as i64).into()) expression is used in ref_to_rhai - ($type:ty, $proxy_type:ty,$self:ident: {$($proxy_expr:tt)*}, $self_to_rhai:ident : {$($proxy_expr_to_rhai:tt)*} ) => { - impl RhaiProxyable for $type { - fn ref_to_rhai( - self_: crate::ReflectReference, - ) -> Result> { - self_.get_typed(|$self_to_rhai: &$type| Ok($($proxy_expr_to_rhai)*))? - } - - fn apply_rhai( - self_: &mut crate::ReflectReference, - new_val: Dynamic, - ) -> Result<(), Box> { - self_.set_val(Self::from_rhai_proxy(new_val)?)?; - Ok(()) - } - } - - impl FromRhaiProxy for $type { - #[inline(always)] - fn from_rhai_proxy(self_: Dynamic) -> Result> { - if self_.is::<$proxy_type>(){ - Ok(self_.cast::<$proxy_type>() as $type) - } else { - Err(Box::new(EvalAltResult::ErrorMismatchDataType( - stringify!($type).to_owned(), - self_.type_name().to_owned(), - Position::NONE, - ))) - } - - } - } - - impl ToRhaiProxy for $type { - #[inline(always)] - fn to_rhai_proxy($self) -> Result> { - Ok($($proxy_expr)*) - } - } - }; -} -use bevy_mod_scripting_rhai::rhai::{FLOAT, INT}; - -impl_rhai_proxy!(i8 as INT); -impl_rhai_proxy!(i16 as INT); -impl_rhai_proxy!(i32 as INT); -impl_rhai_proxy!(i64 as INT); -impl_rhai_proxy!(i128 as INT); -impl_rhai_proxy!(isize as INT); -impl_rhai_proxy!(u8 as INT); -impl_rhai_proxy!(u16 as INT); -impl_rhai_proxy!(u32 as INT); -impl_rhai_proxy!(u64 as INT); -impl_rhai_proxy!(u128 as INT); -impl_rhai_proxy!(usize as INT); -impl_rhai_proxy!(f32 as FLOAT); -impl_rhai_proxy!(f64 as FLOAT); -impl_rhai_proxy!(bool as bool); -impl_rhai_proxy!(String as Into); - -impl< - T: RhaiProxyable - + Reflect - + FromReflect - + TypePath - + Clone - + FromRhaiProxy - + bevy::reflect::Typed - + GetTypeRegistration, - > RhaiProxyable for Option -{ - fn ref_to_rhai(self_: crate::ReflectReference) -> Result> { - self_.get_typed(|s: &Option| match s { - Some(_) => T::ref_to_rhai(self_.sub_ref(ReflectionPathElement::SubReflection { - label: "as_ref", - get: std::sync::Arc::new(|ref_| { - ref_.downcast_ref::>() - .ok_or_else(|| ReflectionError::CannotDowncast { - from: ref_.get_represented_type_info().unwrap().type_path().into(), - to: stringify!(Option).into(), - })? - .as_ref() - .map(|t| t as &dyn Reflect) - .ok_or_else(|| { - ReflectionError::Other( - "Stale reference to Option. Cannot sub reflect.".to_owned(), - ) - }) - }), - get_mut: std::sync::Arc::new(|ref_| { - ref_.downcast_mut::>() - // TODO: there is some weird borrow checker fuckery going on here - // i tried having from: ref_.get_represented_type_info().unwrap().type_path().into() instead of "Reflect" - // and lying this out in an if let expression, but nothing will satisfy the borrow checker here, so leaving this for now - .ok_or_else(|| ReflectionError::CannotDowncast { - from: "Reflect".into(), - to: stringify!(Option).into(), - })? - .as_mut() - .map(|t| t as &mut dyn Reflect) - .ok_or_else(|| { - ReflectionError::Other( - "Stale reference to Option. Cannot sub reflect.".to_owned(), - ) - }) - }), - })), - None => Ok(Dynamic::UNIT), - })? - } - - fn apply_rhai( - self_: &mut crate::ReflectReference, - new_val: Dynamic, - ) -> Result<(), Box> { - if new_val.is::<()>() { - self_.get_mut_typed(|s: &mut Option| { - *s = None; - Ok(()) - })? - } else { - // we need to do this in two passes, first - // ensure that the target type is the 'some' variant to allow a sub reference - - let is_none = self_.get_typed(|s: &Option| s.is_none())?; - - if is_none { - return self_.get_mut_typed(|s: &mut Option| { - *s = Some(T::from_rhai_proxy(new_val)?); - Ok::<_, Box>(()) - })?; - } - - T::apply_rhai( - &mut self_.sub_ref(ReflectionPathElement::SubReflection { - label: "", - get: std::sync::Arc::new(|ref_| { - ref_.downcast_ref::>() - .ok_or_else(|| ReflectionError::CannotDowncast { - from: ref_.get_represented_type_info().unwrap().type_path().into(), - to: stringify!(Option).into(), - })? - .as_ref() - .map(|t| t as &dyn Reflect) - .ok_or_else(|| { - ReflectionError::Other( - "Stale reference to Option. Cannot sub reflect.".to_owned(), - ) - }) - }), - get_mut: std::sync::Arc::new(|ref_| { - if ref_.is::>() { - ref_.downcast_mut::>() - .unwrap() - .as_mut() - .map(|t| t as &mut dyn Reflect) - .ok_or_else(|| { - ReflectionError::Other( - "Stale reference to Option. Cannot sub reflect.".to_owned(), - ) - }) - } else { - Err(ReflectionError::CannotDowncast { - from: ref_.get_represented_type_info().unwrap().type_path().into(), - to: stringify!(Option).into(), - }) - } - }), - }), - new_val, - ) - } - } -} - -impl FromRhaiProxy for Option { - fn from_rhai_proxy(self_: Dynamic) -> Result> { - if self_.is::<()>() { - Ok(None) - } else { - T::from_rhai_proxy(self_).map(Option::Some) - } - } -} - -impl ToRhaiProxy for Option { - fn to_rhai_proxy(self) -> Result> { - match self { - Some(v) => v.to_rhai_proxy(), - None => Ok(Dynamic::UNIT), - } - } -} - -/// Composite trait composing the various traits required for a type `T` to be used as part of a RhaiVec -pub trait RhaiVecElem: - FromReflect - + GetTypeRegistration - + TypePath - + RhaiProxyable - + FromRhaiProxy - + Clone - + bevy::reflect::Typed -{ -} -impl< - T: FromReflect - + GetTypeRegistration - + TypePath - + RhaiProxyable - + FromRhaiProxy - + Clone - + bevy::reflect::Typed, - > RhaiVecElem for T -{ -} - -/// A ScriptVec wrapper which implements a custom iterator ontop of ScriptVec's -pub struct RhaiVec(pub ScriptVec); - -impl Clone for RhaiVec { - fn clone(&self) -> Self { - Self(self.0.clone()) - } -} - -impl Debug for RhaiVec { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.0) - } -} - -impl Display for RhaiVec { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - -impl RhaiVec { - pub fn new_ref(self_: crate::ReflectReference) -> Self { - Self(ScriptVec::::new_ref(self_)) - } -} - -impl std::ops::Deref for RhaiVec { - type Target = ScriptVec; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl std::ops::DerefMut for RhaiVec { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl IntoIterator for RhaiVec { - type Item = Result>; - - type IntoIter = - Map< as IntoIterator>::IntoIter, fn(ReflectReference) -> Self::Item>; - - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter().map(|v| v.to_dynamic()) - } -} - -impl RhaiProxyable for Vec { - fn ref_to_rhai(self_: crate::ReflectReference) -> Result> { - Ok(Dynamic::from(RhaiVec::::new_ref(self_))) - } - - fn apply_rhai( - self_: &mut crate::ReflectReference, - new_val: Dynamic, - ) -> Result<(), Box> { - if new_val.is::>() { - let last_target_idx = self_.get_typed(|s: &Vec| s.len())? - 1; - // there is also another case to consider, Vec has a lua representation available as well (table) - // if we receive one of those, we should also apply it - for (idx, entry) in new_val.cast::>().into_iter().enumerate() { - if idx > last_target_idx { - // here we don't need to do anything special just use LuaProxyable impl - T::apply_rhai(&mut self_.index(idx), entry)?; - } else { - // here we don't have anything to apply this to - // use FromLua impl - self_.get_mut_typed(|s: &mut Vec| { - s[idx] = T::from_rhai_proxy(entry)?; - Ok::<_, Box>(()) - })??; - } - } - Ok(()) - } else if new_val.is::>() { - let vec = new_val.cast::>(); - self_.apply(&vec.ref_)?; - Ok(()) - } else { - Err(Box::new(EvalAltResult::ErrorMismatchDataType( - "Array or Vec".to_owned(), - new_val.type_name().to_owned(), - Position::NONE, - ))) - } - } -} - -impl FromRhaiProxy for Vec { - fn from_rhai_proxy(self_: Dynamic) -> Result> { - if self_.is::>() { - let vec = self_.cast::>(); - vec.ref_.get_typed(|s: &Vec| Ok(s.clone()))? - } else if self_.is::>() { - self_ - .cast::>() - .into_iter() - .map(|v| T::from_rhai_proxy(v)) - .collect::, _>>() - } else { - Err(Box::new(EvalAltResult::ErrorMismatchDataType( - "Array or Vec".to_owned(), - self_.type_name().to_owned(), - Position::NONE, - ))) - } - } -} - -impl ToRhaiProxy for Vec { - fn to_rhai_proxy(self) -> Result> { - self.into_iter() - .map(|v| T::to_rhai_proxy(v)) - .collect::, _>>() - .map(Dynamic::from) - } -} - -#[allow(deprecated)] -impl CustomType for RhaiVec { - fn build(mut builder: bevy_mod_scripting_rhai::rhai::TypeBuilder) { - builder - .with_name(type_name::>()) - .with_fn("to_debug", |vec: &mut RhaiVec| format!("{:?}", vec)) - .with_fn("to_string", |vec: &mut RhaiVec| { - vec.ref_ - .get(|s| format!("{:?}", &s)) - .map_err::, _>(|e| e.into()) - }) - .with_result_fn("is_empty", |vec: &mut RhaiVec| { - vec.is_empty().map_err(Into::into) - }) - .with_result_fn("len", |vec: &mut RhaiVec| { - vec.len().map(|v| v as INT).map_err(Into::into) - }) - .with_result_fn("push", |vec: &mut RhaiVec, val: Dynamic| { - vec.push(T::from_rhai_proxy(val)?).map_err(Into::into) - }) - .with_result_fn("pop", |vec: &mut RhaiVec| vec.pop().map_err(Into::into)) - .with_result_fn("clear", |vec: &mut RhaiVec| { - vec.clear().map_err(Into::into) - }) - .with_result_fn("insert", |vec: &mut RhaiVec, idx: INT, val: Dynamic| { - vec.insert(idx as usize, T::from_rhai_proxy(val)?) - .map_err(Into::into) - }) - .with_result_fn("remove", |vec: &mut RhaiVec, idx: INT| { - vec.remove(idx as usize).map_err(Into::into) - }) - .with_result_fn("index$get$", |vec: &mut RhaiVec, idx: INT| { - vec.index(idx as usize).to_dynamic() - }) - .with_result_fn( - "index$set$", - |vec: &mut RhaiVec, idx: INT, value: Dynamic| { - vec.index(idx as usize).apply_rhai(value) - }, - ); - } -} - -/// A trait for making monomorphization of Vec implementations for any T easier. -/// -/// Rhai does not support the idea of generic types, instead every function is a standalone thing, and hence -/// generics must be monomorphized manually (registered for every type you want to use them with). -pub trait RegisterVecType { - fn register_vec_functions(&mut self) -> &mut Self; -} - -impl RegisterVecType for Engine { - fn register_vec_functions(&mut self) -> &mut Self { - self.build_type::>(); - self.register_iterator_result::, _>(); - self - } -} diff --git a/crates/bevy_script_api/src/script_ref.rs b/crates/bevy_script_api/src/script_ref.rs deleted file mode 100644 index bb9e61ba..00000000 --- a/crates/bevy_script_api/src/script_ref.rs +++ /dev/null @@ -1,185 +0,0 @@ -use bevy::prelude::*; -use parking_lot::RwLock; -use std::fmt::Debug; -use std::{borrow::Cow, sync::Weak}; - -use bevy_mod_scripting_core::world::WorldPointer; - -use crate::{ - error::ReflectionError, - sub_reflect::{ReflectBase, ReflectionPath, ReflectionPathElement}, -}; - -/// A reference to a rust type available from some script language. -/// References can be either to rust or script managed values (created either on the bevy or script side). -/// but also to any subfield of those values (All pointed to values must support `reflect`). -/// Each reference holds a reflection path from the root. -/// -/// Automatically converts to the most convenient lua representation. -/// See [`ReflectReference::to_lua`] -#[derive(Clone, Debug)] -pub struct ReflectReference { - /// The reflection path from the root - pub(crate) path: ReflectionPath, - pub(crate) world_ptr: WorldPointer, -} - -/// Safety: copying just copies the path of reflection, any closures inside, and the world pointer. -/// that itself is safe to copy. -unsafe impl Send for ReflectReference {} -/// Safety: all accesses to value are protected by locking the world pointer. -unsafe impl Sync for ReflectReference {} - -impl ReflectReference { - /// Safely creates a new base component reference - pub fn new_component_ref( - comp: ReflectComponent, - entity: Entity, - world_ptr: WorldPointer, - ) -> Self { - Self { - path: ReflectionPath::new(ReflectBase::Component { comp, entity }), - world_ptr, - } - } - - pub fn new_resource_ref(res: ReflectResource, world_ptr: WorldPointer) -> Self { - Self { - path: ReflectionPath::new(ReflectBase::Resource { res }), - world_ptr, - } - } - - /// Creates a reference to a script owned value - pub fn new_script_ref(ptr: Weak>, world_ptr: WorldPointer) -> Self { - Self { - path: ReflectionPath::new(ReflectBase::ScriptOwned { val: ptr }), - world_ptr, - } - } - - /// Creates a new script reference which points to a sub component of the original data, - /// This also updates the pointer - pub(crate) fn sub_ref(&self, elem: ReflectionPathElement) -> ReflectReference { - let path = self.path.new_sub(elem); - - Self { - path, - ..self.clone() - } - } - - /// Retrieves the underlying `dyn Reflect` reference and applies function which can retrieve a value. - /// Panics if the reference is invalid or world is already borrowed mutably. - #[inline(always)] - pub fn get(&self, f: F) -> Result - where - F: FnOnce(&dyn Reflect) -> O, - { - self.path.get(self.world_ptr.clone(), f) - } - - pub fn get_typed(&self, f: F) -> Result - where - F: FnOnce(&T) -> O, - T: Reflect, - { - self.path.get(self.world_ptr.clone(), |reflect| { - (f)(reflect.downcast_ref::().unwrap_or_else(|| { - panic!( - "Expected `{}` found `{}`", - ::std::any::type_name::(), - reflect.get_represented_type_info().unwrap().type_path() - ) - })) - }) - } - - /// Retrieves the underlying `dyn Reflect` reference and applies function which can retrieve a value. - /// If this is a component it is marked as changed. - /// Panics if the reference is invalid or if the world/value is already borrowed or if r is not a mutable pointer. - #[inline(always)] - pub fn get_mut(&mut self, f: F) -> Result - where - F: FnOnce(&mut dyn Reflect) -> O, - { - self.path.get_mut(self.world_ptr.clone(), f) - } - - pub fn get_mut_typed(&mut self, f: F) -> Result - where - F: FnOnce(&mut T) -> O, - T: Reflect, - { - self.path.get_mut(self.world_ptr.clone(), |reflect| { - (f)(reflect.downcast_mut().unwrap()) - }) - } - - /// applies another [`ReflectReference`] to self by carefuly acquiring locks and cloning if necessary. - /// - /// This is semantically equivalent to the [`Reflect::apply`] method. - /// If you know the type of this value use [`Self::apply_luaref_typed`] since it avoids double cloning and allocating - pub fn apply(&mut self, other: &ReflectReference) -> Result<(), ReflectionError> { - // sadly apply already performs a clone for value types, so this incurs - // a double clone in some cases TODO: is there another way ? - // can we avoid the box ? - let cloned = other.get(|s| s.clone_value())?; - - self.get_mut(|s| s.apply(&*cloned)) - } - - /// Unlike apply this method expects the other type to be identical. Does not allocate so is likely to be faster than apply, uses direct assignment. - /// If you have a concrete value use [`Self::set_val`](TypedReflectReference) unstead - pub fn set(&mut self, other: &Self) -> Result<(), ReflectionError> - where - T: Reflect + Clone, - { - let other: T = other.get_typed(|s: &T| s.clone())?; - self.get_mut_typed(|s| *s = other) - } - - /// Version of [`Self::set`](TypedReflectReference) which directly accepts a `T` value - pub fn set_val(&mut self, other: T) -> Result<(), ReflectionError> - where - T: Reflect, - { - self.get_mut_typed(|s| *s = other) - } -} - -/// A version of index for returning values instead of references -pub trait ValueIndex { - type Output; - - fn index(&self, index: Idx) -> Self::Output; -} - -impl ValueIndex for ReflectReference { - type Output = Self; - - fn index(&self, index: usize) -> Self::Output { - self.sub_ref(ReflectionPathElement::IndexAccess(index)) - } -} - -impl ValueIndex> for ReflectReference { - type Output = Self; - - fn index(&self, index: Cow<'static, str>) -> Self::Output { - self.sub_ref(ReflectionPathElement::FieldAccess(index)) - } -} - -/// A value representing a type which has no special UserData implementation, -/// It exposes the much less convenient reflect interface of the underlying type. -#[derive(Clone, Debug)] -pub struct ReflectedValue { - pub(crate) ref_: ReflectReference, -} - -impl From for ReflectReference { - fn from(ref_: ReflectedValue) -> Self { - ref_.ref_ - } -} diff --git a/crates/bevy_script_api/src/sub_reflect.rs b/crates/bevy_script_api/src/sub_reflect.rs deleted file mode 100644 index fcd5f55d..00000000 --- a/crates/bevy_script_api/src/sub_reflect.rs +++ /dev/null @@ -1,390 +0,0 @@ -use bevy::reflect::PartialReflect; -use parking_lot::RwLock; -use std::fmt; -use std::fmt::{Debug, Display}; -use std::sync::Arc; -use std::{borrow::Cow, sync::Weak}; - -use bevy::{ - prelude::{Entity, ReflectComponent, ReflectResource}, - reflect::{Reflect, ReflectMut, ReflectRef}, -}; - -use crate::error::ReflectionError; -use bevy_mod_scripting_core::world::WorldPointer; - -/// The base of a reflect path, i.e. the top-level object or source. -/// Reflections paths are always relative to some reflect base. -/// -/// If the reflection base and reflection path are both valid we can use them to traverse reflect types -#[derive(Clone)] -pub(crate) enum ReflectBase { - /// A bevy component reference - Component { - comp: ReflectComponent, - entity: Entity, - }, - /// A bevy resource reference - Resource { res: ReflectResource }, - - /// A script owned reflect type (for example a vector constructed in lua) - ScriptOwned { val: Weak> }, -} - -/// Safety: we can safely send this value across thread boundaries -/// the pointer variant is always accessed with the -unsafe impl Send for ReflectBase {} -/// Safety: todo!() -unsafe impl Sync for ReflectBase {} - -impl fmt::Debug for ReflectBase { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Component { entity, .. } => { - f.debug_struct("Component").field("entity", entity).finish() - } - Self::ScriptOwned { .. } => write!(f, "ScriptOwned"), - Self::Resource { .. } => f.debug_struct("Resource").finish(), - } - } -} - -impl fmt::Display for ReflectBase { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - ReflectBase::Component { entity, .. } => { - f.write_str("(Component on ")?; - f.write_str(&entity.index().to_string())?; - f.write_str(")") - } - ReflectBase::Resource { .. } => f.write_str("(Resource)"), - ReflectBase::ScriptOwned { .. } => f.write_str("(ScriptOwned)"), - } - } -} - -pub type Get = dyn Fn(&dyn Reflect) -> Result<&dyn Reflect, ReflectionError>; -pub type GetMut = dyn Fn(&mut dyn Reflect) -> Result<&mut dyn Reflect, ReflectionError>; - -/// Stores a part of the path of reflection + sub reflection from a root reflect reference. -/// Sub reflection allows us to access values unreachable by standard reflection. -#[derive(Clone)] -pub enum ReflectionPathElement { - SubReflection { - label: &'static str, - get: Arc, - get_mut: Arc, - }, - /// Access to a struct field - FieldAccess(Cow<'static, str>), - /// Access to a TupleStruct, Tuple, List or Array element - IndexAccess(usize), // TODO: Map access -} - -impl Debug for ReflectionPathElement { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::SubReflection { label, .. } => f - .debug_struct("SubReflection") - .field("label", label) - .finish(), - Self::FieldAccess(arg0) => f.debug_tuple("FieldAccess").field(arg0).finish(), - Self::IndexAccess(arg0) => f.debug_tuple("IndexAccess").field(arg0).finish(), - } - } -} - -impl Display for ReflectionPathElement { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - ReflectionPathElement::SubReflection { label, .. } => { - f.write_str(".")?; - f.write_str(label)?; - f.write_str("()") - } - ReflectionPathElement::FieldAccess(s) => { - f.write_str(".")?; - f.write_str(s) - } - ReflectionPathElement::IndexAccess(i) => { - f.write_str("[")?; - f.write_str(&i.to_string())?; - f.write_str("]") - } - } - } -} - -impl ReflectionPathElement { - pub(crate) fn sub_ref<'a>( - &self, - base: &'a dyn Reflect, - ) -> Result<&'a dyn Reflect, ReflectionError> { - match self { - ReflectionPathElement::SubReflection { get, .. } => get(base), - ReflectionPathElement::FieldAccess(field) => match base.reflect_ref() { - ReflectRef::Struct(s) => s - .field(field) - .and_then(PartialReflect::try_as_reflect) - .ok_or_else(|| ReflectionError::InvalidReflectionPath { - path: self.to_string(), - msg: "No such field".to_owned(), - }), - _ => Err(ReflectionError::InvalidReflectionPath { - path: self.to_string(), - msg: "No such field".to_owned(), - }), - }, - ReflectionPathElement::IndexAccess(index) => match base.reflect_ref() { - ReflectRef::TupleStruct(s) => s - .field(*index) - .and_then(PartialReflect::try_as_reflect) - .ok_or_else(|| ReflectionError::InvalidReflectionPath { - path: self.to_string(), - msg: "No such element".to_owned(), - }), - ReflectRef::Tuple(s) => s - .field(*index) - .and_then(PartialReflect::try_as_reflect) - .ok_or_else(|| ReflectionError::InvalidReflectionPath { - path: self.to_string(), - msg: "No such element".to_owned(), - }), - ReflectRef::List(s) => s - .get(*index) - .and_then(PartialReflect::try_as_reflect) - .ok_or_else(|| ReflectionError::InvalidReflectionPath { - path: self.to_string(), - msg: "No such element".to_owned(), - }), - ReflectRef::Array(s) => s - .get(*index) - .and_then(PartialReflect::try_as_reflect) - .ok_or_else(|| ReflectionError::InvalidReflectionPath { - path: self.to_string(), - msg: "No such element".to_owned(), - }), - _ => Err(ReflectionError::InvalidReflectionPath { - path: self.to_string(), - msg: "No such element".to_owned(), - }), - }, - } - } - - pub(crate) fn sub_ref_mut<'a>( - &self, - base: &'a mut dyn Reflect, - ) -> Result<&'a mut dyn Reflect, ReflectionError> { - match self { - ReflectionPathElement::SubReflection { get_mut, .. } => get_mut(base), - ReflectionPathElement::FieldAccess(field) => match base.reflect_mut() { - ReflectMut::Struct(s) => s - .field_mut(field) - .and_then(PartialReflect::try_as_reflect_mut) - .ok_or_else(|| ReflectionError::InvalidReflectionPath { - path: self.to_string(), - msg: "No such field".to_owned(), - }), - _ => Err(ReflectionError::InvalidReflectionPath { - path: self.to_string(), - msg: "No such field".to_owned(), - }), - }, - ReflectionPathElement::IndexAccess(index) => match base.reflect_mut() { - ReflectMut::TupleStruct(s) => s - .field_mut(*index) - .and_then(PartialReflect::try_as_reflect_mut) - .ok_or_else(|| ReflectionError::InvalidReflectionPath { - path: self.to_string(), - msg: "No such element".to_owned(), - }), - ReflectMut::Tuple(s) => s - .field_mut(*index) - .and_then(PartialReflect::try_as_reflect_mut) - .ok_or_else(|| ReflectionError::InvalidReflectionPath { - path: self.to_string(), - msg: "No such element".to_owned(), - }), - ReflectMut::List(s) => s - .get_mut(*index) - .and_then(PartialReflect::try_as_reflect_mut) - .ok_or_else(|| ReflectionError::InvalidReflectionPath { - path: self.to_string(), - msg: "No such element".to_owned(), - }), - ReflectMut::Array(s) => s - .get_mut(*index) - .and_then(PartialReflect::try_as_reflect_mut) - .ok_or_else(|| ReflectionError::InvalidReflectionPath { - path: self.to_string(), - msg: "No such element".to_owned(), - }), - _ => Err(ReflectionError::InvalidReflectionPath { - path: self.to_string(), - msg: "No such element".to_owned(), - }), - }, - } - } -} - -#[derive(Clone, Debug)] -pub(crate) struct ReflectionPath { - base: ReflectBase, - // most of these will be very short, people don't make many nested hashmaps vecs etc. - accesses: Vec, -} - -impl Display for ReflectionPath { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(&self.base.to_string())?; - for access in &self.accesses { - f.write_str(&access.to_string())? - } - Ok(()) - } -} - -impl ReflectionPath { - pub fn new(base: ReflectBase) -> Self { - Self { - base, - accesses: Vec::default(), - } - } - - /// Creates a new composite sub reflect - pub fn new_sub(&self, elem: ReflectionPathElement) -> Self { - let mut accesses = self.accesses.clone(); - - accesses.push(elem); - - Self { - accesses, - ..self.clone() - } - } - - /// Walks the path with the given reference as the base - fn walk_path<'a>(&self, ref_: &'a dyn Reflect) -> Result<&'a dyn Reflect, ReflectionError> { - let first = self.accesses.first().map(|s| s.sub_ref(ref_)); - - if let Some(first) = first { - if self.accesses.len() > 1 { - self.accesses[1..] - .iter() - .try_fold(first?, |a, access| access.sub_ref(a)) - } else { - first - } - } else { - Ok(ref_) - } - } - - /// Walks the path with the given mutable reference as the base. - fn walk_path_mut<'a>( - &self, - ref_: &'a mut dyn Reflect, - ) -> Result<&'a mut dyn Reflect, ReflectionError> { - if let Some(first) = self.accesses.first() { - if self.accesses.len() > 1 { - self.accesses[1..] - .iter() - .try_fold(first.sub_ref_mut(ref_)?, |a, access| access.sub_ref_mut(a)) - } else { - first.sub_ref_mut(ref_) - } - } else { - Ok(ref_) - } - } - - pub fn get(&self, world_ptr: WorldPointer, f: F) -> Result - where - F: FnOnce(&dyn Reflect) -> O, - { - match &self.base { - ReflectBase::Component { comp, entity } => { - let g = world_ptr.read(); - - let entity_ref = - g.get_entity(*entity) - .map_err(|e| ReflectionError::InvalidBaseReference { - base: self.base.to_string(), - reason: format!("This entity could not be retrieved. {e}"), - })?; - - let ref_ = self.walk_path(comp.reflect(entity_ref).ok_or_else(|| { - ReflectionError::InvalidBaseReference { - base: self.base.to_string(), - reason: "Given component does not exist on this entity".to_owned(), - } - })?)?; - Ok(f(ref_)) - } - ReflectBase::Resource { res } => { - let g = world_ptr.read(); - - let ref_ = self.walk_path(res.reflect(&g).ok_or_else(|| { - ReflectionError::InvalidBaseReference { - base: self.base.to_string(), - reason: "Given resource does not exist in this world".to_owned(), - } - })?)?; - Ok(f(ref_)) - } - ReflectBase::ScriptOwned { val } => { - let g = val - .upgrade() - .expect("Trying to access cached value from previous frame"); - - let g = g.try_read().expect("Rust safety violation: attempted to borrow value {self:?} while it was already mutably borrowed"); - Ok(f(self.walk_path(&*g)?)) - } - } - } - - pub fn get_mut(&mut self, world_ptr: WorldPointer, f: F) -> Result - where - F: FnOnce(&mut dyn Reflect) -> O, - { - match &self.base { - ReflectBase::Component { comp, entity } => { - let mut g = world_ptr.write(); - - let mut e = g.entity_mut(*entity); - let ref_ = self.walk_path_mut( - comp.reflect_mut(&mut e) - .ok_or_else(|| ReflectionError::InvalidBaseReference { - base: self.base.to_string(), - reason: "Given component does not exist on this entity".to_owned(), - })? - .into_inner(), - )?; - Ok(f(ref_)) - } - ReflectBase::Resource { res } => { - let mut g = world_ptr.write(); - - let ref_ = self.walk_path_mut( - res.reflect_mut(&mut g) - .ok_or_else(|| ReflectionError::InvalidBaseReference { - base: self.base.to_string(), - reason: "Given resource does not exist in this world".to_owned(), - })? - .into_inner(), - )?; - Ok(f(ref_)) - } - ReflectBase::ScriptOwned { val } => { - let g = val - .upgrade() - .expect("Trying to access cached value from previous frame"); - let mut g = g.try_write().expect("Rust safety violation: attempted to borrow value {self:?} while it was already mutably borrowed"); - Ok(f(self.walk_path_mut(&mut *g)?)) - } - } - } -} diff --git a/crates/bevy_script_api/src/wrappers.rs b/crates/bevy_script_api/src/wrappers.rs deleted file mode 100644 index d2110b27..00000000 --- a/crates/bevy_script_api/src/wrappers.rs +++ /dev/null @@ -1,107 +0,0 @@ -#[macro_export] -macro_rules! ref_only_wrapper_methods { - ($type_:path, $wrapper_name: ident) => { - /// Creates a script reference pointing to the wrapped value. - /// - /// Depending on this value it may be a lua owned or reflect relative reference - pub fn reflect_ref( - &self, - world_ptr: bevy_mod_scripting_core::world::WorldPointer, - ) -> $crate::script_ref::ReflectReference { - match self { - Self::Owned(val) => $crate::script_ref::ReflectReference::new_script_ref( - ::std::sync::Arc::downgrade(val), - world_ptr, - ), - Self::Ref(ref_) => ref_.clone(), - } - } - - pub fn new(b: $type_) -> Self { - Self::Owned(::std::sync::Arc::new($crate::parking_lot::RwLock::new(b))) - } - - pub fn new_ref(b: $crate::script_ref::ReflectReference) -> Self { - Self::Ref(b) - } - - /// Perform an operation on the base type and optionally retrieve something by value - /// may require a read lock on the world in case this is a reference - pub fn val(&self, accessor: F) -> Result - where - F: FnOnce(&$type_) -> G, - { - match self { - Self::Owned(v) => Ok(accessor(&v.read())), - Self::Ref(v) => v.get(|s| accessor(s.downcast_ref::<$type_>().unwrap())), - } - } - - pub fn val_mut(&mut self, accessor: F) -> Result - where - F: FnOnce(&mut $type_) -> G, - { - match self { - Self::Owned(v) => Ok(accessor(&mut *v.write())), - Self::Ref(v) => v.get_mut(|s| accessor(s.downcast_mut::<$type_>().unwrap())), - } - } - - /// Applies Self to another ReflectReference. - /// may require a write lock on the world - pub fn apply_self_to_base( - &self, - other: &mut $crate::script_ref::ReflectReference, - ) -> Result<(), $crate::error::ReflectionError> { - match self { - Self::Owned(v) => { - other.get_mut(|other| other.apply(&mut *v.write()))?; - Ok(()) - } - Self::Ref(v) => { - // if we are a ReflectReference, we have to be careful with borrows - // to avoid deadlock - // we take advantage of the fact we know the expected type - other.apply(v) - } - } - } - }; -} - -#[macro_export] -macro_rules! define_wrapper { - ($type_:path, $wrapper_name:ident) => { - #[allow(clippy::large_enum_variant)] - #[doc=concat!("A script wrapper for the type `",stringify!($type_),"`")] - #[derive(Clone)] - pub enum $wrapper_name { - Owned(::std::sync::Arc<$crate::parking_lot::RwLock<$type_>>), - Ref($crate::script_ref::ReflectReference), - } - }; -} - -#[macro_export] -macro_rules! make_script_wrapper { - ($type_:path as $wrapper_name:ident with Clone) => { - $crate::define_wrapper!($type_, $wrapper_name); - impl $wrapper_name { - $crate::ref_only_wrapper_methods!($type_, $wrapper_name); - - /// retrieves the underlying value by cloning it - pub fn inner(&self) -> Result<$type_, $crate::error::ReflectionError> - where - $type_: Clone, - { - self.val(|s| s.clone()) - } - } - }; - ($type_:path as $wrapper_name:ident) => { - $crate::define_wrapper!($type_, $wrapper_name); - impl $wrapper_name { - $crate::ref_only_wrapper_methods!($type_, $wrapper_name); - } - }; -} diff --git a/crates/languages/bevy_mod_scripting_lua/Cargo.toml b/crates/languages/bevy_mod_scripting_lua/Cargo.toml index aac4e1ff..04f422ba 100644 --- a/crates/languages/bevy_mod_scripting_lua/Cargo.toml +++ b/crates/languages/bevy_mod_scripting_lua/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bevy_mod_scripting_lua" -version = "0.8.0" +version = "0.9.0-alpha.1" authors = ["Maksymilian Mozolewski "] edition = "2021" license = "MIT OR Apache-2.0" @@ -21,19 +21,16 @@ enable-features = ["lua54"] # enables loading possibly unsafe lua modules by lua scripts unsafe_lua_modules = [] -# enable teal utilities -teal = [] - -lua51 = ["tealr/mlua_lua51"] -lua52 = ["tealr/mlua_lua52"] -lua53 = ["tealr/mlua_lua53"] -lua54 = ["tealr/mlua_lua54"] -luajit = ["tealr/mlua_luajit"] -luajit52 = ["tealr/mlua_luajit52"] -luau = ["tealr/mlua_luau"] -mlua_serialize = ["tealr/mlua_serialize"] -mlua_macros = ["tealr/mlua_macros"] -mlua_async = ["tealr/mlua_async"] +lua51 = ["mlua/lua51"] +lua52 = ["mlua/lua52"] +lua53 = ["mlua/lua53"] +lua54 = ["mlua/lua54"] +luajit = ["mlua/luajit"] +luajit52 = ["mlua/luajit52"] +luau = ["mlua/luau"] +mlua_serialize = ["mlua/serialize"] +mlua_macros = ["mlua/macros"] +mlua_async = ["mlua/async"] [lib] name = "bevy_mod_scripting_lua" @@ -41,12 +38,19 @@ path = "src/lib.rs" [dependencies] bevy = { workspace = true, default-features = false } -bevy_mod_scripting_core = { workspace = true } -tealr = { version = "0.9", features = [ - "mlua_vendored", - "mlua_send", - "mlua_macros", -] } +bevy_mod_scripting_core = { workspace = true, features = ["mlua_impls"] } +bevy_mod_scripting_functions = { workspace = true, features = [] } +mlua = { workspace = true, features = ["vendored", "send", "macros"] } parking_lot = "0.12.1" -serde_json = "1.0.81" -anyhow = "1.0.75" +uuid = "1.1" +smol_str = "0.2.2" +smallvec = "1.13" + +[dev-dependencies] +test_utils = { workspace = true } +libtest-mimic = "0.8" +regex = "1.11" + +[[test]] +name = "lua_tests" +harness = false diff --git a/crates/languages/bevy_mod_scripting_lua/src/assets.rs b/crates/languages/bevy_mod_scripting_lua/src/assets.rs deleted file mode 100644 index 7e3e50d7..00000000 --- a/crates/languages/bevy_mod_scripting_lua/src/assets.rs +++ /dev/null @@ -1,157 +0,0 @@ -use bevy::{ - asset::{io::Reader, Asset, AssetLoader}, - reflect::TypePath, - utils::BoxedFuture, -}; -use bevy_mod_scripting_core::asset::CodeAsset; - -use anyhow::Error; - -#[derive(Asset, TypePath, Debug)] -/// A lua code file in bytes -pub struct LuaFile { - pub bytes: Vec, -} - -impl CodeAsset for LuaFile { - fn bytes(&self) -> &[u8] { - self.bytes.as_slice() - } -} - -#[derive(Default)] -/// Asset loader for lua scripts -pub struct LuaLoader; - -fn old_lua_load<'a>( - bytes: &'a [u8], - load_context: &'a mut bevy::asset::LoadContext, -) -> BoxedFuture<'a, Result, Error>> { - match load_context.path().extension().map(|s| s.to_str().unwrap()) { - #[cfg(all(feature = "teal", debug_assertions))] - Some("tl") => { - use bevy::asset::io::file::FileAssetReader; - use std::fs; - use std::path::PathBuf; - use std::process::Command; - - let scripts_dir = &FileAssetReader::get_base_path() - .join("assets") - .join("scripts"); - - let temp_file_path = &std::env::temp_dir().join("bevy_mod_scripting.temp.lua"); - bevy::prelude::info!("tl file path {}", scripts_dir.to_str().unwrap()); - // optionally put the output in the /build folder - let build_dir_path: Option = - if load_context.path().starts_with("scripts/build/") { - Some( - load_context - .path() - .strip_prefix("scripts/") - .unwrap() - .to_owned(), - ) - } else if load_context.path().starts_with("scripts/") { - Some( - PathBuf::from("build/") - .join(load_context.path().strip_prefix("scripts/").unwrap()), - ) - } else { - None - }; - - let full_path = &FileAssetReader::get_base_path() - .join("assets") - .join(load_context.path()); - bevy::log::info!( - "tl check {} : {}", - full_path.to_str().unwrap(), - scripts_dir.to_str().unwrap() - ); - if let Ok(e) = Command::new("tl") - .args(["check", full_path.to_str().unwrap()]) - .current_dir(scripts_dir) - .status() - { - if !e.success() { - return Box::pin(async move { - Err(Error::msg(format!( - "Teal file `{}` has errors", - load_context.path().to_str().unwrap() - ))) - }); - } - } else { - fs::remove_file(temp_file_path).expect("Something went wrong running `tl check`"); - panic!("Something went wrong running `tl check`"); - } - - if let Ok(e) = Command::new("tl") - .args([ - "gen", - full_path.to_str().unwrap(), - "-o", - temp_file_path.to_str().unwrap(), - ]) - .current_dir(scripts_dir) - .status() - { - if !e.success() { - return Box::pin(async move { - Err(Error::msg(format!( - "Teal file `{}` could not be compiled!", - load_context.path().to_str().unwrap() - ))) - }); - } - } else { - fs::remove_file(temp_file_path).expect("Something went wrong running `tl gen`"); - panic!("Something went wrong running `tl gen`") - } - - if let Some(mut build_dir_path) = build_dir_path { - build_dir_path = scripts_dir.join(build_dir_path); - let _ = fs::create_dir_all(build_dir_path.parent().unwrap()); - let _ = fs::copy(temp_file_path, build_dir_path.with_extension("lua")); - } - - let lua_code = - fs::read_to_string(temp_file_path).expect("Could not find output lua file"); - fs::remove_file(temp_file_path).unwrap(); - - Box::pin(async move { Ok(lua_code.as_bytes().into()) }) - } - - _ => Box::pin(async move { Ok(bytes.into()) }), - } -} -impl AssetLoader for LuaLoader { - type Asset = LuaFile; - type Settings = (); - type Error = Error; - - async fn load( - &self, - reader: &mut dyn Reader, //bytes: &'a [u8], - _settings: &(), - load_context: &mut bevy::asset::LoadContext<'_>, - ) -> std::result::Result< - ::Asset, - ::Error, - > { - bevy::prelude::info!("lua loader invoked: {:#}", load_context.asset_path()); - let mut bytes = Vec::new(); - reader.read_to_end(&mut bytes).await?; - let bytes = old_lua_load(bytes.as_slice(), load_context).await?; - Ok(LuaFile { bytes }) - } - - #[cfg(feature = "teal")] - fn extensions(&self) -> &[&str] { - &["lua", "tl"] - } - #[cfg(not(feature = "teal"))] - fn extensions(&self) -> &[&str] { - &["lua"] - } -} diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/mod.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/mod.rs new file mode 100644 index 00000000..c589a51f --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/mod.rs @@ -0,0 +1,3 @@ +pub mod reference; +pub mod script_value; +pub mod world; diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs new file mode 100644 index 00000000..8b264422 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs @@ -0,0 +1,368 @@ +use std::any::TypeId; + +use bevy_mod_scripting_core::{ + bindings::{ + function::{ + script_function::{AppScriptFunctionRegistry, DynamicScriptFunction}, + CallScriptFunction, + }, + pretty_print::DisplayWithWorld, + script_value::ScriptValue, + ReflectReference, WorldGuard, + }, + error::InteropError, + reflection_extensions::TypeIdExtensions, +}; +use bevy_mod_scripting_functions::namespaced_register::{GetNamespacedFunction, Namespace}; +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; + +/// 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. +#[derive(Debug, Clone, PartialEq, mlua::FromLua)] +pub struct LuaReflectReference(pub ReflectReference); + +impl AsRef for LuaReflectReference { + fn as_ref(&self) -> &ReflectReference { + &self.0 + } +} + +impl From for ReflectReference { + fn from(value: LuaReflectReference) -> Self { + value.0 + } +} + +impl From for LuaReflectReference { + fn from(value: ReflectReference) -> Self { + Self(value) + } +} + +/// 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 = lua.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 = lua + .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 = lua + .get_world() + .with_resource(|registry: &AppScriptFunctionRegistry| registry.clone()); + let registry = registry.read(); + + registry + .iter_overloads_namespaced(key.to_string(), Namespace::OnType(type_id)) + .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()))) +} + +impl UserData for LuaReflectReference { + fn add_methods>(m: &mut T) { + m.add_meta_function( + MetaMethod::Index, + |lua, (self_, key): (LuaReflectReference, LuaScriptValue)| { + let world = lua.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); + } + }; + + // lookup get index function + let mut index_func = lookup_dynamic_function_typed::(lua, "get") + .expect("No 'get' function registered for a ReflectReference"); + + // 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)| { + 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], + lua.get_world(), + lua_caller_context(Some(std::any::TypeId::of::())), + )?; + + Ok(()) + }, + ); + + m.add_meta_function( + MetaMethod::Sub, + |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { + let world = lua.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)?) + }, + ); + + m.add_meta_function( + MetaMethod::Add, + |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { + let world = lua.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)?) + }, + ); + + m.add_meta_function( + MetaMethod::Mul, + |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { + let world = lua.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)?) + }, + ); + + m.add_meta_function( + MetaMethod::Div, + |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { + let world = lua.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)?) + }, + ); + + m.add_meta_function( + MetaMethod::Mod, + |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { + let world = lua.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)?) + }, + ); + + m.add_meta_function(MetaMethod::Unm, |lua, self_: LuaReflectReference| { + let world = lua.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)?) + }); + + m.add_meta_function( + MetaMethod::Pow, + |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { + let world = lua.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)?) + }, + ); + + m.add_meta_function( + MetaMethod::Eq, + |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { + let world = lua.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)?) + }, + ); + + m.add_meta_function( + MetaMethod::Lt, + |lua, (self_, other): (LuaReflectReference, LuaScriptValue)| { + let world = lua.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)?) + }, + ); + + m.add_meta_function(MetaMethod::Len, |lua, self_: LuaScriptValue| { + let world = lua.get_world(); + let script_value: ScriptValue = self_.into(); + Ok(match script_value { + ScriptValue::Reference(r) => r.len(world)?, + ScriptValue::List(l) => Some(l.len()), + _ => None, + }) + }); + + #[cfg(any( + feature = "lua54", + feature = "lua53", + 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"); + let world = l.get_world(); + + Ok(LuaScriptValue::from(iter_func.call_script_function( + vec![ScriptValue::Reference(s.into())], + world, + lua_caller_context(Some(std::any::TypeId::of::())), + )?)) + }); + + m.add_meta_function(MetaMethod::ToString, |lua, self_: LuaReflectReference| { + let world = lua.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 out = display_func.call_script_function( + vec![ScriptValue::Reference(self_)], + world, + lua_caller_context(Some(std::any::TypeId::of::())), + )?; + + Ok(LuaScriptValue::from(out)) + }); + } +} + +/// A reference to just a type. This is used to provide a static call mechanism when we know the type we want to call a function on. +/// +/// For example if we want `Entity::from_raw(usize)` to be callable as `Entity.from_raw(usize)` in lua, we can set the global `Entity` to a `LuaStaticReflectReference(Entity::type_id())`. + +#[derive(Debug, Clone, Copy, PartialEq, mlua::FromLua)] +pub struct LuaStaticReflectReference(pub TypeId); + +impl UserData for LuaStaticReflectReference { + fn add_methods>(m: &mut T) { + m.add_meta_function( + MetaMethod::Index, + |lua, (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); + } + }; + let world = lua.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 new file mode 100644 index 00000000..946710bc --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs @@ -0,0 +1,124 @@ +use std::{ + any::TypeId, + ops::{Deref, DerefMut}, +}; + +use bevy_mod_scripting_core::bindings::{ + function::{script_function::CallerContext, CallScriptFunction}, + script_value::ScriptValue, +}; +use mlua::{FromLua, IntoLua, Value, Variadic}; + +use super::{reference::LuaReflectReference, world::GetWorld}; + +#[derive(Debug, Clone)] +pub struct LuaScriptValue(ScriptValue); + +impl Deref for LuaScriptValue { + type Target = ScriptValue; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for LuaScriptValue { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From for LuaScriptValue { + fn from(value: ScriptValue) -> Self { + LuaScriptValue(value) + } +} + +impl From for ScriptValue { + fn from(value: LuaScriptValue) -> Self { + value.0 + } +} + +impl FromLua for LuaScriptValue { + fn from_lua(value: mlua::Value, _lua: &mlua::Lua) -> mlua::Result { + Ok(match value { + Value::Nil => ScriptValue::Unit, + Value::Boolean(b) => ScriptValue::Bool(b), + // Value::LightUserData(light_user_data) => todo!(), + Value::Integer(i) => ScriptValue::Integer(i), + Value::Number(n) => ScriptValue::Float(n), + Value::String(s) => ScriptValue::String(s.to_str()?.to_owned().into()), + Value::Table(table) => { + let mut vec = Vec::with_capacity(table.len()? as usize); + for i in table.sequence_values() { + let v: LuaScriptValue = i?; + vec.push(v.into()); + } + ScriptValue::List(vec) + } + // Value::Function(function) => todo!(), + // Value::Thread(thread) => todo!(), + Value::UserData(ud) => { + let ud = ud.borrow::().map_err(|e| { + mlua::Error::FromLuaConversionError { + from: "UserData", + to: "LuaReflectReference".to_owned(), + message: Some(e.to_string()), + } + })?; + ScriptValue::Reference(ud.clone().into()) + } + // Value::Error(error) => todo!(), + _ => { + return Err(mlua::Error::FromLuaConversionError { + from: value.type_name(), + to: "ScriptValue".to_owned(), + message: Some("unsupported value type".to_owned()), + }) + } + } + .into()) + } +} + +pub fn lua_caller_context(self_type: Option) -> CallerContext { + CallerContext { + convert_to_0_indexed: true, + self_type, + } +} + +impl IntoLua for LuaScriptValue { + fn into_lua(self, lua: &mlua::Lua) -> mlua::Result { + Ok(match self.0 { + ScriptValue::Unit => Value::Nil, + ScriptValue::Bool(b) => Value::Boolean(b), + ScriptValue::Integer(i) => Value::Integer(i), + ScriptValue::Float(f) => Value::Number(f), + 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| { + let world = lua.get_world(); + let out = function.call_script_function( + args.into_iter().map(Into::into), + world, + lua_caller_context(None), + )?; + + Ok(LuaScriptValue::from(out)) + })? + .into_lua(lua)?, + ScriptValue::List(vec) => { + let table = lua.create_table_from( + vec.into_iter() + .enumerate() + .map(|(k, v)| (k + 1, LuaScriptValue::from(v))), + )?; + Value::Table(table) + } + }) + } +} diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/world.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/world.rs new file mode 100644 index 00000000..b04a900b --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/world.rs @@ -0,0 +1,45 @@ +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; + +#[derive(Clone, Debug, mlua::FromLua)] +pub struct LuaWorld(pub WorldCallbackAccess); + +impl LuaWorld { + pub fn world_callback_access(self) -> WorldCallbackAccess { + self.0.clone() + } +} + +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") + } +} diff --git a/crates/languages/bevy_mod_scripting_lua/src/docs.rs b/crates/languages/bevy_mod_scripting_lua/src/docs.rs deleted file mode 100644 index 9fbb42b0..00000000 --- a/crates/languages/bevy_mod_scripting_lua/src/docs.rs +++ /dev/null @@ -1,227 +0,0 @@ -use core::str; -use std::{ - borrow::Cow, - env, - fs::{self, File}, - io::Write, - ops::Deref, - process::Command, -}; - -//use bevy::asset::FileAssetIo; -use bevy::asset::io::file::FileAssetReader; -use bevy_mod_scripting_core::prelude::*; -use tealr::{NameContainer, TypeGenerator, TypeWalker}; - -pub type TypeWalkerBuilder = fn(TypeWalker) -> TypeWalker; - -static DEFAULT_DOC_CONFIG: fn(&str) -> String = |s| { - format!( - r#" -{{ - "doc_template": "Builtin", - "page_root": "", - "store_in": "{s}", - "name": "{s}", - "is_global": true, - "type_def_files": {{ - "runner": "Builtin", - "templates": {{ - "teal": {{ - "extension": ".d.tl", - "template": "Teal" - }} - }} - }} - }} - -"# - ) -}; - -#[cfg(feature = "teal")] -static DEFAULT_TEAL_CONFIG: &str = r#" -return { - global_env_def="types/types", - build_dir="build/" -} -"#; - -struct Fragment { - builder: TypeWalkerBuilder, -} - -pub struct LuaDocFragment { - name: &'static str, - walker: Vec, -} - -/// A piece of lua documentation, -/// Each piece is combined into one large documentation page, and also a single teal declaration file if the `teal` feature is enabled -impl LuaDocFragment { - pub fn new(name: &'static str, f: TypeWalkerBuilder) -> Self { - Self { - name, - walker: vec![Fragment { builder: f }], - } - } -} - -impl DocFragment for LuaDocFragment { - fn name(&self) -> &'static str { - self.name - } - - fn merge(mut self, o: Self) -> Self { - self.walker.extend(o.walker); - self - } - - fn gen_docs(self) -> Result<(), ScriptError> { - let script_asset_path = &FileAssetReader::get_base_path() - .join("assets") - .join("scripts"); - - let script_doc_dir = &env::var("SCRIPT_DOC_DIR") - .map(|v| v.into()) - .unwrap_or_else(|_e| script_asset_path.join("doc")); - - fs::create_dir_all(script_doc_dir) - .expect("Could not create `.../assets/scripts/doc` directories"); - - let docs_name = self.name().to_owned(); - - // build the type walker - let mut tw = self - .walker - .into_iter() - .fold(TypeWalker::new(), |a, v| (v.builder)(a)); - - // fixes bug in tealr which causes syntax errors in teal due to duplicate fields (from having both getters and setters) - tw.given_types.iter_mut().for_each(|tg| { - if let TypeGenerator::Record(rg) = tg { - rg.fields - .sort_by(|f1, f2| f1.name.deref().cmp(f2.name.deref())); - rg.fields.dedup_by(|a, b| a.name == b.name); - rg.static_fields - .sort_by(|f1, f2| f1.name.deref().cmp(f2.name.deref())); - rg.static_fields.dedup_by(|a, b| a.name == b.name); - for field in rg.fields.iter_mut().chain(rg.static_fields.iter_mut()) { - escape_name(&mut field.name); - } - for func in rg - .functions - .iter_mut() - .chain(rg.mut_functions.iter_mut()) - .chain(rg.methods.iter_mut()) - .chain(rg.mut_methods.iter_mut()) - { - escape_name(&mut func.name); - } - } - }); - - // generate json file - let json = serde_json::to_string_pretty(&tw) - .map_err(|e| ScriptError::DocGenError(e.to_string()))?; - - // temporary fix for incompatibility in json formats - // json.remove(json.len() - 1); - // json.push_str(",\n\"tealr_version_used\": \"0.9.0-alpha3\",\n\"extra_page\": []\n}"); - - let json_path = script_doc_dir.join(format!("{}.json", docs_name)); - - File::create(json_path) - .and_then(|mut file| { - file.write_all(json.as_bytes())?; - file.flush() - }) - .map_err(|e| ScriptError::DocGenError(e.to_string()))?; - - // generate doc config files if they don't exist - if !script_doc_dir.join("tealr_doc_gen_config.json").exists() { - let config_path = script_doc_dir.join("tealr_doc_gen_config.json"); - File::create(config_path) - .and_then(|mut file| file.write_all(DEFAULT_DOC_CONFIG(&docs_name).as_bytes())) - .map_err(|e| ScriptError::DocGenError(e.to_string()))?; - } - - // generate docs - Command::new("tealr_doc_gen") - .current_dir(script_doc_dir) - .args(["run"]) - .status() - .map_err(|e| ScriptError::DocGenError(e.to_string()))?; - - #[cfg(feature = "teal")] - { - // now manage the definition (d.tl) file - let definition_directory = script_asset_path.join("types"); - fs::create_dir_all(&definition_directory).map_err(|e| { - ScriptError::DocGenError(format!( - "Could not create `{}` directories: {e}", - &definition_directory.display() - )) - })?; - - let definition_file_path = script_doc_dir - .join(&docs_name) - .join("definitions") - .join(docs_name + ".d.tl"); - let output_definition_file_path = script_asset_path.join("types").join("types.d.tl"); - fs::copy(&definition_file_path, &output_definition_file_path).map_err(|e| { - ScriptError::DocGenError(format!( - "Could not copy definition file from `{}` to `{}`: {e}", - definition_file_path.display(), - output_definition_file_path.display() - )) - })?; - - // finally create a tlconfig.lua file if doesn't exist - // we do this to avoid problems with varying teal configurations - // keep em settings consistent everywhere - let tl_config_path = script_asset_path.join("tlconfig.lua"); - if !tl_config_path.exists() { - let mut tl_file = File::create(tl_config_path) - .map_err(|e| ScriptError::DocGenError(e.to_string()))?; - tl_file - .write_all(DEFAULT_TEAL_CONFIG.as_bytes()) - .map_err(|e| ScriptError::DocGenError(e.to_string()))?; - } - } - Ok(()) - } -} - -/// Escapes a name of a table field, if that table field is a reserved keyword. -/// -/// ## Background -/// -/// String keys in a Lua table are allowed to be anything, even reserved -/// keywords. By default when tealr generates the type definition for a table -/// field, the string it generates is `{name} : {type}`. This causes a syntax -/// error when writing a bare keyword, since `nil : {type}` is considered trying -/// to add a type to the *value* nil (which is invalid). -/// -/// To get around this tealr allows us to escape table fields using the -/// `["{name}"] : {value}` syntax. This function detects if a name is one of the -/// Lua reserved words and fixes it if so. -fn escape_name(raw: &mut NameContainer) { - // List of Lua reserved keywords - const KEYWORD_FIELDS: &[&str] = &[ - "false", "true", "nil", // Values - "and", "not", "or", // Operators - "if", "then", "else", "elseif", "end", // If-Else - "for", "in", "break", "do", "repeat", "until", "while", // Loops - "function", "return", // Funcs - "local", // Declarations - "record", // Teal extra - ]; - let Ok(name) = str::from_utf8(raw) else { - return; - }; - if KEYWORD_FIELDS.contains(&name) { - let mapped = format!("[\"{name}\"]"); - *raw = NameContainer::from(Cow::Owned(mapped)); - } -} diff --git a/crates/languages/bevy_mod_scripting_lua/src/lib.rs b/crates/languages/bevy_mod_scripting_lua/src/lib.rs index d356fade..0b904cd7 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/lib.rs @@ -1,197 +1,214 @@ -use crate::{ - assets::{LuaFile, LuaLoader}, - docs::LuaDocFragment, +use bevy::{ + app::{App, Plugin}, + ecs::{entity::Entity, world::World}, }; -use bevy::{ecs::schedule::ScheduleLabel, prelude::*}; -use bevy_mod_scripting_core::{prelude::*, systems::*, world::WorldPointerGuard}; - -use std::fmt; -use std::marker::PhantomData; -use std::sync::Mutex; -use tealr::mlu::mlua::{prelude::*, Function}; - -pub mod assets; -pub mod docs; -pub mod util; -pub use tealr; -pub mod prelude { - pub use crate::{ - assets::{LuaFile, LuaLoader}, - docs::{LuaDocFragment, TypeWalkerBuilder}, - tealr::{ - self, - mlu::{ - mlua::{self, prelude::*, Value}, - TealData, - }, - }, - LuaEvent, LuaScriptHost, - }; -} - -pub trait LuaArg: for<'lua> IntoLuaMulti<'lua> + Clone + Sync + Send + 'static {} - -impl IntoLuaMulti<'lua> + Clone + Sync + Send + 'static> LuaArg for T {} - -#[derive(Clone, Event)] -/// A Lua Hook. The result of creating this event will be -/// a call to the lua script with the hook_name and the given arguments -pub struct LuaEvent { - pub hook_name: String, - pub args: A, - pub recipients: Recipients, -} - -impl fmt::Debug for LuaEvent { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("LuaEvent") - .field("hook_name", &self.hook_name) - .field("recipients", &self.recipients) - .finish() - } -} +use bevy_mod_scripting_core::{ + bindings::{script_value::ScriptValue, WorldCallbackAccess}, + context::{ContextBuilder, ContextInitializer, ContextPreHandlingInitializer}, + error::ScriptError, + event::CallbackLabel, + reflection_extensions::PartialReflectExt, + script::ScriptId, + AddContextInitializer, AddContextPreHandlingInitializer, IntoScriptPluginParams, + ScriptingPlugin, +}; +use bindings::{ + reference::{LuaReflectReference, LuaStaticReflectReference}, + script_value::LuaScriptValue, + world::GetWorld, +}; +pub use mlua; +use mlua::{Function, IntoLua, Lua, MultiValue}; +pub mod bindings; -impl ScriptEvent for LuaEvent { - fn recipients(&self) -> &crate::Recipients { - &self.recipients - } +impl IntoScriptPluginParams for LuaScriptingPlugin { + type C = Lua; + type R = (); } -#[derive(Resource)] -/// Lua script host, enables Lua scripting. -pub struct LuaScriptHost { - _ph: PhantomData, +pub struct LuaScriptingPlugin { + pub scripting_plugin: ScriptingPlugin, } -impl Default for LuaScriptHost { +impl Default for LuaScriptingPlugin { fn default() -> Self { - Self { - _ph: Default::default(), + LuaScriptingPlugin { + scripting_plugin: ScriptingPlugin { + context_assigner: None, + runtime_builder: Default::default, + runtime_settings: None, + callback_handler: Some(lua_handler), + context_builder: Some(ContextBuilder:: { + load: lua_context_load, + reload: lua_context_reload, + }), + }, } } } -impl ScriptHost for LuaScriptHost { - type ScriptContext = Mutex; - type APITarget = Mutex; - type ScriptEvent = LuaEvent; - type ScriptAsset = LuaFile; - type DocTarget = LuaDocFragment; - - fn register_with_app_in_set(app: &mut App, schedule: impl ScheduleLabel, set: impl SystemSet) { - app.add_priority_event::() - .init_asset::() - .init_asset_loader::() - .init_resource::>() - .init_resource::>() - .init_resource::>() - .register_type::>() - .register_type::>() - .register_type::>() - // handle script insertions removal first - // then update their contexts later on script asset changes - .add_systems( - schedule, - ( - script_add_synchronizer::, - script_remove_synchronizer::, - script_hot_reload_handler::, - ) - .chain() - .in_set(set), - ); +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 load_script( - &mut self, - script: &[u8], - script_data: &ScriptData, - providers: &mut APIProviders, - ) -> Result { - #[cfg(feature = "unsafe_lua_modules")] - let lua = unsafe { Lua::unsafe_new() }; - #[cfg(not(feature = "unsafe_lua_modules"))] - let lua = Lua::new(); - - // init lua api before loading script - let mut lua = Mutex::new(lua); - providers.attach_all(&mut lua)?; - - lua.get_mut() - .map_err(|e| ScriptError::FailedToLoad { - script: script_data.name.to_owned(), - msg: e.to_string(), - })? - .load(script) - .set_name(script_data.name) - .exec() - .map_err(|e| ScriptError::FailedToLoad { - script: script_data.name.to_owned(), - msg: e.to_string(), - })?; + 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(); + let type_registry = type_registry.read(); + + for registration in type_registry.iter() { + // only do this for non generic types + // we don't want to see `Vec:function()` in lua + if !registration.type_info().generics().is_empty() { + continue; + } - Ok(lua) - } + if let Some(global_name) = registration.type_info().type_path_table().ident() { + let ref_ = LuaStaticReflectReference(registration.type_id()); + context + .globals() + .set(global_name, ref_) + .map_err(ScriptError::from_mlua_error)?; + } + } + Ok(()) + }); - fn setup_script( - &mut self, - script_data: &ScriptData, - ctx: &mut Self::ScriptContext, - providers: &mut APIProviders, - ) -> Result<(), ScriptError> { - providers.setup_all(script_data, ctx) - } + // let mut type_registry = app.world_mut().get_resource_mut().unwrap(); - fn handle_events<'a>( - &mut self, - world: &mut World, - events: &[Self::ScriptEvent], - ctxs: impl Iterator, &'a mut Self::ScriptContext)>, - providers: &mut APIProviders, - ) { - // safety: - // - we have &mut World access - // - we do not use the original reference again anywhere in this function - let world = unsafe { WorldPointerGuard::new(world) }; - - ctxs.for_each(|(script_data, ctx)| { - providers - .setup_runtime_all(world.clone(), &script_data, ctx) - .expect("Could not setup script runtime"); - - let ctx = ctx.get_mut().expect("Poison error in context"); - - // event order is preserved, but scripts can't rely on any temporal - // guarantees when it comes to other scripts callbacks, - // at least for now. - let globals = ctx.globals(); - for event in events { - // check if this script should handle this event - if !event.recipients().is_recipient(&script_data) { - continue; - } + // 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); + } +} - let f: Function = match globals.raw_get(event.hook_name.clone()) { - Ok(f) => f, - Err(_) => continue, // not subscribed to this event - }; +pub fn lua_context_load( + script_id: &ScriptId, + content: &[u8], + initializers: &[ContextInitializer], + pre_handling_initializers: &[ContextPreHandlingInitializer], + world: &mut World, + _: &mut (), +) -> Result { + #[cfg(feature = "unsafe_lua_modules")] + let mut context = unsafe { Lua::unsafe_new() }; + #[cfg(not(feature = "unsafe_lua_modules"))] + let mut context = Lua::new(); + + with_world(world, &mut context, |context| { + initializers + .iter() + .try_for_each(|init| init(script_id, context))?; + + pre_handling_initializers + .iter() + .try_for_each(|init| init(script_id, Entity::from_raw(0), context))?; + + context + .load(content) + .exec() + .map_err(ScriptError::from_mlua_error)?; + Ok(()) + })?; - if let Err(error) = f.call::<_, ()>(event.args.clone()) { - let mut world = world.write(); - let mut state: CachedScriptState = world.remove_resource().unwrap(); + Ok(context) +} - let (_, mut error_wrt, _) = state.event_state.get_mut(&mut world); +pub fn lua_context_reload( + script: &ScriptId, + content: &[u8], + old_ctxt: &mut Lua, + initializers: &[ContextInitializer], + pre_handling_initializers: &[ContextPreHandlingInitializer], + world: &mut World, + _: &mut (), +) -> Result<(), ScriptError> { + *old_ctxt = lua_context_load( + script, + content, + initializers, + pre_handling_initializers, + world, + &mut (), + )?; + Ok(()) +} - let error = ScriptError::RuntimeError { - script: script_data.name.to_owned(), - msg: error.to_string(), - }; +#[allow(clippy::too_many_arguments)] +pub fn lua_handler( + args: Vec, + entity: bevy::ecs::entity::Entity, + script_id: &ScriptId, + callback_label: &CallbackLabel, + context: &mut Lua, + pre_handling_initializers: &[ContextPreHandlingInitializer], + _: &mut (), + world: &mut bevy::ecs::world::World, +) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { + with_world(world, context, |context| { + pre_handling_initializers + .iter() + .try_for_each(|init| init(script_id, entity, context))?; + + let handler: Function = match context.globals().raw_get(callback_label.as_ref()) { + Ok(handler) => handler, + // not subscribed to this event type + Err(_) => return Ok(()), + }; + + let input = MultiValue::from_vec( + args.into_iter() + .map(|arg| LuaScriptValue::from(arg).into_lua(context)) + .collect::>()?, + ); + + handler.call::<()>(input)?; + Ok(()) + }) +} - error!("{}", error); - error_wrt.send(ScriptErrorEvent { error }); - world.insert_resource(state); - } - } - }); - } +/// Safely scopes world access for a lua context to the given closure's scope +pub fn with_world Result<(), ScriptError>>( + world: &mut World, + context: &mut Lua, + f: F, +) -> Result<(), ScriptError> { + 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()); + f(context) + }) } diff --git a/crates/languages/bevy_mod_scripting_lua/src/util.rs b/crates/languages/bevy_mod_scripting_lua/src/util.rs deleted file mode 100644 index 9b84ba55..00000000 --- a/crates/languages/bevy_mod_scripting_lua/src/util.rs +++ /dev/null @@ -1,155 +0,0 @@ -/// generates path to the given script depending on build configuration. -/// (optimized builds don't have the teal compiler available) -/// -/// Current configuration will provide "scripts/*.tl" paths -/// ```rust -/// use bevy_mod_scripting_lua::lua_path; -/// assert_eq!("scripts/my_script.tl",lua_path!("my_script")) -/// ``` -#[cfg(all(feature = "teal", debug_assertions))] -#[macro_export] -macro_rules! lua_path { - ($v:literal) => { - concat!("scripts/", $v, ".tl") - }; -} - -/// generates path to the given script depending on build configuration. -/// (optimized builds don't have the teal compiler available) -/// -/// Current configuration will provide "scripts/build/*.lua" paths -/// ```rust -/// use bevy_mod_scripting::lua_path; -/// assert_eq!("scripts/build/my_script.lua",lua_path!("my_script")) -/// ``` -#[cfg(all(not(debug_assertions), feature = "teal"))] -#[macro_export] -macro_rules! lua_path { - ($v:literal) => { - concat!("scripts/build/", $v, ".lua") - }; -} - -/// generates path to the given script depending on build configuration. -/// (optimized builds don't have the teal compiler available) -/// -/// Current configuration will provide "/scripts/*.lua" paths -/// ```rust -/// use bevy_mod_scripting_lua::lua_path; -/// assert_eq!("scripts/my_script.lua",lua_path!("my_script")) -/// ``` -#[cfg(not(feature = "teal"))] -#[macro_export] -macro_rules! lua_path { - ($v:literal) => { - concat!("scripts/", $v, ".lua") - }; -} - -#[cfg(feature = "lua51")] -#[doc(hidden)] -#[macro_export] -macro_rules! __cfg_feature_lua51 { - ( $( $tok:tt )* ) => { $( $tok )* } -} - -#[cfg(not(feature = "lua51"))] -#[doc(hidden)] -#[macro_export] -macro_rules! __cfg_feature_lua51 { - ( $( $tok:tt )* ) => {}; -} - -#[cfg(feature = "lua52")] -#[doc(hidden)] -#[macro_export] -macro_rules! __cfg_feature_lua52 { - ( $( $tok:tt )* ) => { $( $tok )* } -} - -#[cfg(not(feature = "lua52"))] -#[doc(hidden)] -#[macro_export] -macro_rules! __cfg_feature_lua52 { - ( $( $tok:tt )* ) => {}; -} - -#[cfg(feature = "lua53")] -#[doc(hidden)] -#[macro_export] -macro_rules! __cfg_feature_lua53 { - ( $( $tok:tt )* ) => { $( $tok )* } -} - -#[cfg(not(feature = "lua53"))] -#[doc(hidden)] -#[macro_export] -macro_rules! __cfg_feature_lua53 { - ( $( $tok:tt )* ) => {}; -} - -#[cfg(feature = "lua54")] -#[doc(hidden)] -#[macro_export] -macro_rules! __cfg_feature_lua54 { - ( $( $tok:tt )* ) => { $( $tok )* } -} - -#[cfg(not(feature = "lua54"))] -#[doc(hidden)] -#[macro_export] -macro_rules! __cfg_feature_lua54 { - ( $( $tok:tt )* ) => {}; -} - -#[cfg(feature = "luajit")] -#[doc(hidden)] -#[macro_export] -macro_rules! __cfg_feature_luajit { - ( $( $tok:tt )* ) => { $( $tok )* } -} - -#[cfg(not(feature = "luajit"))] -#[doc(hidden)] -#[macro_export] -macro_rules! __cfg_feature_luajit { - ( $( $tok:tt )* ) => {}; -} - -#[cfg(feature = "luajit52")] -#[doc(hidden)] -#[macro_export] -macro_rules! __cfg_feature_luajit52 { - ( $( $tok:tt )* ) => { $( $tok )* } -} - -#[cfg(not(feature = "luajit52"))] -#[doc(hidden)] -#[macro_export] -macro_rules! __cfg_feature_luajit52 { - ( $( $tok:tt )* ) => {}; -} - -#[cfg(any( - feature = "lua52", - feature = "lua53", - feature = "lua54", - feature = "luajit52" -))] -#[doc(hidden)] -#[macro_export] -macro_rules! __cfg_feature_any_lua52_lua53_lua54_luajit52 { - ( $( $tok:tt )* ) => { $( $tok )* } -} - -#[cfg(not(any( - feature = "lua52", - feature = "lua53", - feature = "lua54", - feature = "luajit52" -)))] -#[doc(hidden)] -#[macro_export] -macro_rules! __cfg_feature_any_lua52_lua53_lua54_luajit52 { - ( $( $tok:tt )* ) => {}; -} 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 new file mode 100644 index 00000000..8cd73340 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/access/aliasing_global_access.lua @@ -0,0 +1,11 @@ +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 new file mode 100644 index 00000000..85de5ee3 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/access/aliasing_write.lua @@ -0,0 +1,11 @@ +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/access/multiple_read_refs.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/access/multiple_read_refs.lua new file mode 100644 index 00000000..fed59bb9 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/access/multiple_read_refs.lua @@ -0,0 +1,3 @@ +local entity = Entity.from_raw(9999); +-- does not throw +entity:eq(entity); \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/add/vec3.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/add/vec3.lua new file mode 100644 index 00000000..7374655b --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/add/vec3.lua @@ -0,0 +1,11 @@ +local a = Vec3.new(1.0, 2.0, 3.0) +local b = Vec3.new(4.0, 5.0, 6.0) + +assert((a + 1).x == 2.0, "Addition did not work") +assert((a + 1).y == 3.0, "Addition did not work") +assert((a + 1).z == 4.0, "Addition did not work") + +assert((a + b).x == 5.0, "Addition did not work") +assert((a + b).y == 7.0, "Addition did not work") +assert((a + b).z == 9.0, "Addition did not work") + diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_no_default_or_from_world_data_errors.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_no_default_or_from_world_data_errors.lua new file mode 100644 index 00000000..54b8408a --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_no_default_or_from_world_data_errors.lua @@ -0,0 +1,7 @@ +local entity = world.spawn() +local type = world.get_type_by_name('TestComponent') + +assert_throws(function() + world.add_default_component(entity, type) + +end, "Missing type data ReflectDefault or ReflectFromWorld for type: .*TestComponent.*") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_with_default_and_component_data_adds_default.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_with_default_and_component_data_adds_default.lua new file mode 100644 index 00000000..8895f0b9 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_with_default_and_component_data_adds_default.lua @@ -0,0 +1,9 @@ +local entity = world.spawn() +local _type = world.get_type_by_name('CompWithDefaultAndComponentData') +world.add_default_component(entity, _type) + +local added = world.has_component(entity, _type) +assert(added ~= nil, 'Component not added') + +local component = world.get_component(entity, _type) +assert(component._1 == "Default", 'Component did not have default value, got: ' .. component._1) \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_with_default_no_component_data_errors.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_with_default_no_component_data_errors.lua new file mode 100644 index 00000000..f6324926 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_with_default_no_component_data_errors.lua @@ -0,0 +1,6 @@ +local entity = world.spawn() +local _type = world.get_type_by_name('CompWithDefault') + +assert_throws(function() + world.add_default_component(entity, _type) +end, "Missing type data ReflectComponent for type: .*CompWithDefault.*") diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_with_from_world_and_component_data_adds_default.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_with_from_world_and_component_data_adds_default.lua new file mode 100644 index 00000000..c4725e72 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_with_from_world_and_component_data_adds_default.lua @@ -0,0 +1,9 @@ +local entity = world.spawn() +local _type = world.get_type_by_name('CompWithFromWorldAndComponentData') +world.add_default_component(entity, _type) + +local added = world.has_component(entity, _type) +assert(added ~= nil, 'Component not added') + +local component = world.get_component(entity, _type) +assert(component._1 == "Default", 'Component did not have default value, got: ' .. component._1) \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_with_from_world_no_component_data_errors.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_with_from_world_no_component_data_errors.lua new file mode 100644 index 00000000..9f6652ad --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/add_default_component/component_with_from_world_no_component_data_errors.lua @@ -0,0 +1,6 @@ +local entity = world.spawn() +local _type = world.get_type_by_name('CompWithFromWorld') + +assert_throws(function() + world.add_default_component(entity, _type) +end, 'Missing type data ReflectComponent for type: .*CompWithFromWorld.*') \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/api_availability/api_available_on_callback.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/api_availability/api_available_on_callback.lua new file mode 100644 index 00000000..63de9239 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/api_availability/api_available_on_callback.lua @@ -0,0 +1,5 @@ +function on_test() + assert(world ~= nil, "World was not found") + assert(world.get_type_by_name("TestComponent") ~= nil, "Could not find TestComponent type") + Entity.from_raw(1) +end \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/api_availability/api_available_on_script_load.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/api_availability/api_available_on_script_load.lua new file mode 100644 index 00000000..5831854a --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/api_availability/api_available_on_script_load.lua @@ -0,0 +1,3 @@ +assert(world ~= nil, "World was not found") +assert(world.get_type_by_name("TestComponent") ~= nil, "Could not find TestComponent type") +Entity.from_raw(1) \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/clear/vec.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/clear/vec.lua new file mode 100644 index 00000000..7604eb15 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/clear/vec.lua @@ -0,0 +1,6 @@ +local res_type = world.get_type_by_name("TestResourceWithVariousFields") +local res = world.get_resource(res_type) + +res.vec_usize:clear() + +assert(res.vec_usize:len() == 0, "Clear did not work") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/despawn/despawns_only_root.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/despawn/despawns_only_root.lua new file mode 100644 index 00000000..fdb87565 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/despawn/despawns_only_root.lua @@ -0,0 +1,7 @@ +local entity = world.spawn() +local child = world.spawn() +world.push_children(entity, {child}) +world.despawn(entity) + +assert(world.has_entity(entity) == false, "Parent should be despawned") +assert(world.has_entity(child) == true, "Child should not be despawned") diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/despawn/invalid_entity_errors.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/despawn/invalid_entity_errors.lua new file mode 100644 index 00000000..207bd322 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/despawn/invalid_entity_errors.lua @@ -0,0 +1,3 @@ +assert_throws(function() + world.despawn_recursive(Entity.from_raw(9999)) +end, "Missing or invalid entity") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/despawn_descendants/despawns_only_child.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/despawn_descendants/despawns_only_child.lua new file mode 100644 index 00000000..8161ac87 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/despawn_descendants/despawns_only_child.lua @@ -0,0 +1,7 @@ +local entity = world.spawn() +local child = world.spawn() +world.push_children(entity, {child}) +world.despawn_descendants(entity) + +assert(world.has_entity(entity) == true, "Parent should not be despawned") +assert(world.has_entity(child) == false, "Child should be despawned") diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/despawn_descendants/invalid_entity_errors.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/despawn_descendants/invalid_entity_errors.lua new file mode 100644 index 00000000..207bd322 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/despawn_descendants/invalid_entity_errors.lua @@ -0,0 +1,3 @@ +assert_throws(function() + world.despawn_recursive(Entity.from_raw(9999)) +end, "Missing or invalid entity") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/despawn_recursive/despawns_recursively.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/despawn_recursive/despawns_recursively.lua new file mode 100644 index 00000000..c5b98e0c --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/despawn_recursive/despawns_recursively.lua @@ -0,0 +1,7 @@ +local entity = world.spawn() +local child = world.spawn() +world.push_children(entity, {child}) +world.despawn_recursive(entity) + +assert(world.has_entity(entity) == false, "Parent should be despawned") +assert(world.has_entity(child) == false, "Child should be despawned") diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/despawn_recursive/invalid_entity_errors.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/despawn_recursive/invalid_entity_errors.lua new file mode 100644 index 00000000..207bd322 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/despawn_recursive/invalid_entity_errors.lua @@ -0,0 +1,3 @@ +assert_throws(function() + world.despawn_recursive(Entity.from_raw(9999)) +end, "Missing or invalid entity") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/div/vec3.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/div/vec3.lua new file mode 100644 index 00000000..2e08c9ac --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/div/vec3.lua @@ -0,0 +1,10 @@ +local a = Vec3.new(2.0, 4.0, 6.0) +local b = Vec3.new(1.0, 2.0, 3.0) + +assert((a / 2).x == 1.0, "Division did not work") +assert((a / 2).y == 2.0, "Division did not work") +assert((a / 2).z == 3.0, "Division did not work") + +assert((a / b).x == 2.0, "Division did not work") +assert((a / b).y == 2.0, "Division did not work") +assert((a / b).z == 2.0, "Division did not work") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/eq/vec3.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/eq/vec3.lua new file mode 100644 index 00000000..ffd43bf8 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/eq/vec3.lua @@ -0,0 +1,7 @@ +local a = Vec3.new(2.0, -4.0, 6.0) +local b = Vec3.new(4.0, 5.0, 6.0) + + +assert((a == b) == false, "Equality did not work") +assert((a ~= b) == true, "Inequality did not work") +assert((a == a) == true, "Equality did not work") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/get_children/has_children_returns_them.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/get_children/has_children_returns_them.lua new file mode 100644 index 00000000..2d4eba9a --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/get_children/has_children_returns_them.lua @@ -0,0 +1,9 @@ +local entity = world.spawn() +local child = world.spawn() + +world.push_children(entity, {child}) + +local children = world.get_children(entity) + +assert(#children == 1, "Expected 1 child") +assert(children[1]:index() == child:index(), "Child is the wrong entity") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/get_children/invalid_entity_errors.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/get_children/invalid_entity_errors.lua new file mode 100644 index 00000000..089c9483 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/get_children/invalid_entity_errors.lua @@ -0,0 +1,4 @@ + +assert_throws(function() + world.get_children(Entity.from_raw(9999)) +end, "Missing or invalid entity") diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/get_children/no_children_returns_empty_table.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/get_children/no_children_returns_empty_table.lua new file mode 100644 index 00000000..312bd79f --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/get_children/no_children_returns_empty_table.lua @@ -0,0 +1,4 @@ +local entity = world.spawn() +local children = world.get_children(entity) + +assert(#children == 0) \ No newline at end of file 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 new file mode 100644 index 00000000..683e5362 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/get_component/component_no_component_data.lua @@ -0,0 +1,6 @@ +local component = world.get_type_by_name("CompWithDefault") +local entity = _get_entity_with_test_component("CompWithDefault") +local retrieved = world.get_component(entity, component) + +assert(retrieved ~= nil, "Component was not found") +assert(retrieved._1 == "Initial Value", "Component data was not retrieved correctly, retrieved._1 was: " .. retrieved._1) \ No newline at end of file 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 new file mode 100644 index 00000000..886a6e6c --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/get_component/component_with_component_data.lua @@ -0,0 +1,6 @@ +local component = world.get_type_by_name("TestComponent") +local entity = _get_entity_with_test_component("TestComponent") +local retrieved = world.get_component(entity, component) + +assert(retrieved ~= nil, "Component was not found") +assert(retrieved.strings[1] == "Initial", "Component data was not retrieved correctly, retrieved.strings[1] was: " .. retrieved.strings[1]) \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/get_component/empty_entity_component_with_component_data.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/get_component/empty_entity_component_with_component_data.lua new file mode 100644 index 00000000..31b26ab1 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/get_component/empty_entity_component_with_component_data.lua @@ -0,0 +1,5 @@ +local component = world.get_type_by_name("TestComponent") +local entity = world.spawn() +local retrieved = world.get_component(entity, component) + +assert(retrieved == nil, "Component found") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/get_parent/has_parent_returns_it.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/get_parent/has_parent_returns_it.lua new file mode 100644 index 00000000..312596c3 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/get_parent/has_parent_returns_it.lua @@ -0,0 +1,9 @@ +local entity = world.spawn() +local child = world.spawn() + +world.push_children(entity, {child}) + +local parent = world.get_parent(child) + +assert(parent ~= nil, "Expected a parent") +assert(parent:index() == entity:index(), "Parent is the wrong entity") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/get_parent/invalid_entity_errors.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/get_parent/invalid_entity_errors.lua new file mode 100644 index 00000000..85ce2530 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/get_parent/invalid_entity_errors.lua @@ -0,0 +1,4 @@ + +assert_throws(function() + world.get_parent(Entity.from_raw(9999)) +end, "Missing or invalid entity") diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/get_parent/no_parent_returns_nil.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/get_parent/no_parent_returns_nil.lua new file mode 100644 index 00000000..a7810c4d --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/get_parent/no_parent_returns_nil.lua @@ -0,0 +1,4 @@ +local entity = world.spawn() +local parent = world.get_parent(entity) + +assert(parent == nil, "Expected no parents") 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 new file mode 100644 index 00000000..055d05d8 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/get_resource/missing_resource_returns_nil.lua @@ -0,0 +1,2 @@ +local type = _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/get_resource/no_resource_data_returns_resource.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/get_resource/no_resource_data_returns_resource.lua new file mode 100644 index 00000000..fd7e2ff7 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/get_resource/no_resource_data_returns_resource.lua @@ -0,0 +1,5 @@ +local resource = world.get_type_by_name("ResourceWithDefault") + +local retrieved = world.get_resource(resource) +assert(retrieved ~= nil, "Resource should exist") +assert(retrieved._1 == "Initial Value", "Resource should have default value but got: " .. retrieved._1) diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/get_resource/with_resource_data_returns_resource.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/get_resource/with_resource_data_returns_resource.lua new file mode 100644 index 00000000..6eb1e710 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/get_resource/with_resource_data_returns_resource.lua @@ -0,0 +1,5 @@ +local resource = world.get_type_by_name("TestResource") + +local retrieved = world.get_resource(resource) +assert(retrieved ~= nil, "Resource should exist") +assert(retrieved.bytes[2] == 1, "Resource should have default value but got resource with #retrieved.bytes[1]: " .. tostring(retrieved.bytes[2])) diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/get_type_by_name/missing_type_returns_nothing.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/get_type_by_name/missing_type_returns_nothing.lua new file mode 100644 index 00000000..3799fefe --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/get_type_by_name/missing_type_returns_nothing.lua @@ -0,0 +1 @@ +assert(world.get_type_by_name('UnregisteredType') == nil, 'Unregistered type was found') diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/get_type_by_name/registered_type_returns_correct_type.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/get_type_by_name/registered_type_returns_correct_type.lua new file mode 100644 index 00000000..8b12faa6 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/get_type_by_name/registered_type_returns_correct_type.lua @@ -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 ~= nil, '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_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 new file mode 100644 index 00000000..1de4c06d --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/has_component/empty_entity_mock_component_is_false.lua @@ -0,0 +1,4 @@ +local entity = world.spawn() +local type = _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 new file mode 100644 index 00000000..edbeae9f --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/has_component/no_component_data.lua @@ -0,0 +1,3 @@ +local entity = _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 new file mode 100644 index 00000000..05913787 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/has_component/with_component_data.lua @@ -0,0 +1,3 @@ +local entity = _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/existing_no_resource_data.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/has_resource/existing_no_resource_data.lua new file mode 100644 index 00000000..62f41a2e --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/has_resource/existing_no_resource_data.lua @@ -0,0 +1,2 @@ +local component = world.get_type_by_name("ResourceWithDefault") +assert(world.has_resource(component) == true, "Resource was not found") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/has_resource/existing_with_resource_data.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/has_resource/existing_with_resource_data.lua new file mode 100644 index 00000000..aa1f6580 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/has_resource/existing_with_resource_data.lua @@ -0,0 +1,2 @@ +local component = world.get_type_by_name("TestResource") +assert(world.has_resource(component) == true, "Resource 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 new file mode 100644 index 00000000..1917bb89 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/has_resource/missing_resource_mock_resource_is_false.lua @@ -0,0 +1,2 @@ +local type = _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/insert/vec.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/insert/vec.lua new file mode 100644 index 00000000..abd159b9 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/insert/vec.lua @@ -0,0 +1,6 @@ +local res_type = world.get_type_by_name("TestResourceWithVariousFields") +local res = world.get_resource(res_type) + +res.vec_usize:insert(2, 42) + +assert(res.vec_usize[2] == 42, "insert did not work") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/insert_children/adding_empty_list_does_nothing.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/insert_children/adding_empty_list_does_nothing.lua new file mode 100644 index 00000000..f6f0afac --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/insert_children/adding_empty_list_does_nothing.lua @@ -0,0 +1,5 @@ +local entity = world.spawn() + +world.insert_children(entity,1 , {}) + +assert(#world.get_children(entity) == 0) \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/insert_children/adds_children_at_correct_index.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/insert_children/adds_children_at_correct_index.lua new file mode 100644 index 00000000..e4cb914a --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/insert_children/adds_children_at_correct_index.lua @@ -0,0 +1,8 @@ +local entity = world.spawn() +local child = world.spawn() +local child2 = world.spawn() + +world.insert_children(entity, 1, {child}) +world.insert_children(entity, 1, {child2}) + +assert(world.get_children(entity)[1]:index() == child2:index()) \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/insert_children/adds_children_to_existing_enttity.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/insert_children/adds_children_to_existing_enttity.lua new file mode 100644 index 00000000..c90339fe --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/insert_children/adds_children_to_existing_enttity.lua @@ -0,0 +1,6 @@ +local entity = world.spawn() +local child = world.spawn() +local child2 = world.spawn() +world.insert_children(entity, 1, {child, child2}) + +assert(#world.get_children(entity) == 2) \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/insert_children/invalid_entity_errors.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/insert_children/invalid_entity_errors.lua new file mode 100644 index 00000000..2c5d51a2 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/insert_children/invalid_entity_errors.lua @@ -0,0 +1,10 @@ +local fake_entity = Entity.from_raw(9999) + +assert_throws(function() + world.insert_children(fake_entity, 1, {fake_entity}) +end, "Missing or invalid entity") + +local entity = world.spawn() +assert_throws(function() + world.insert_children(entity, 1, {fake_entity}) +end, "Missing or invalid entity") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/iter/vec.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/iter/vec.lua new file mode 100644 index 00000000..e1da679d --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/iter/vec.lua @@ -0,0 +1,13 @@ +local res_type = world.get_type_by_name("TestResourceWithVariousFields") +local res = world.get_resource(res_type) + +iterated_vals = {} +for v in pairs(res.vec_usize) do + iterated_vals[#iterated_vals + 1] = v +end +assert(#iterated_vals == 5, "Length is not 5") +assert(iterated_vals[1] == 1, "First value is not 1") +assert(iterated_vals[2] == 2, "Second value is not 2") +assert(iterated_vals[3] == 3, "Third value is not 3") +assert(iterated_vals[4] == 4, "Fourth value is not 4") +assert(iterated_vals[5] == 5, "Fifth value is not 5") diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/len/vec.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/len/vec.lua new file mode 100644 index 00000000..f1b17a8f --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/len/vec.lua @@ -0,0 +1,4 @@ +local res_type = world.get_type_by_name("TestResourceWithVariousFields") +local res = world.get_resource(res_type) + +assert(res.vec_usize:len() == 5, "Length is not 5") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/mod/vec3.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/mod/vec3.lua new file mode 100644 index 00000000..69dc8d96 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/mod/vec3.lua @@ -0,0 +1,10 @@ +local a = Vec3.new(2.0, 5.0, 6.0) +local b = Vec3.new(1.0, 2.0, 3.0) + +assert((a % 2).x == 0.0, "Modulus did not work") +assert((a % 2).y == 1.0, "Modulus did not work") +assert((a % 2).z == 0.0, "Modulus did not work") + +assert((a % b).x == 0.0, "Modulus did not work") +assert((a % b).y == 1.0, "Modulus did not work") +assert((a % b).z == 0.0, "Modulus did not work") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/mul/vec3.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/mul/vec3.lua new file mode 100644 index 00000000..f5b64fe1 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/mul/vec3.lua @@ -0,0 +1,10 @@ +local a = Vec3.new(1.0, 2.0, 3.0) +local b = Vec3.new(4.0, 5.0, 6.0) + +assert((a * 2).x == 2.0, "Multiplication did not work") +assert((a * 2).y == 4.0, "Multiplication did not work") +assert((a * 2).z == 6.0, "Multiplication did not work") + +assert((a * b).x == 4.0, "Multiplication did not work") +assert((a * b).y == 10.0, "Multiplication did not work") +assert((a * b).z == 18.0, "Multiplication did not work") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/pop/vec.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/pop/vec.lua new file mode 100644 index 00000000..4a4c2249 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/pop/vec.lua @@ -0,0 +1,6 @@ +local res_type = world.get_type_by_name("TestResourceWithVariousFields") +local res = world.get_resource(res_type) + +local popped = res.vec_usize:pop() + +assert(popped == 5, "Pop did not work") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/push/vec.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/push/vec.lua new file mode 100644 index 00000000..5795045f --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/push/vec.lua @@ -0,0 +1,6 @@ +local res_type = world.get_type_by_name("TestResourceWithVariousFields") +local res = world.get_resource(res_type) + +res.vec_usize:push(42) + +assert(res.vec_usize[6] == 42, "Push did not work") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/push_children/adding_empty_list_does_nothing.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/push_children/adding_empty_list_does_nothing.lua new file mode 100644 index 00000000..b6a58402 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/push_children/adding_empty_list_does_nothing.lua @@ -0,0 +1,5 @@ +local entity = world.spawn() + +world.push_children(entity, {}) + +assert(#world.get_children(entity) == 0) \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/push_children/adds_children_to_existing_enttity.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/push_children/adds_children_to_existing_enttity.lua new file mode 100644 index 00000000..e2c323cf --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/push_children/adds_children_to_existing_enttity.lua @@ -0,0 +1,7 @@ +local entity = world.spawn() +local child = world.spawn() +local child2 = world.spawn() + +world.push_children(entity, {child, child2}) + +assert(#world.get_children(entity) == 2) \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/push_children/invalid_entity_errors.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/push_children/invalid_entity_errors.lua new file mode 100644 index 00000000..cad01a84 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/push_children/invalid_entity_errors.lua @@ -0,0 +1,10 @@ +local fake_entity = Entity.from_raw(9999) + +assert_throws(function() + world.push_children(fake_entity, {fake_entity}) +end, "Missing or invalid entity") + +local entity = world.spawn() +assert_throws(function() + world.push_children(entity, {fake_entity}) +end, "Missing or invalid entity") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/query/empty_query_returns_nothing.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/query/empty_query_returns_nothing.lua new file mode 100644 index 00000000..3d4e3535 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/query/empty_query_returns_nothing.lua @@ -0,0 +1,5 @@ +local component_a = world.get_type_by_name("TestComponent") + +for i,result in pairs(world.query():component(component_a):without(component_a):build()) do + assert(false, "This should not be reached") +end \ 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 new file mode 100644 index 00000000..5a3e83b0 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/query/query_returns_all_entities_matching.lua @@ -0,0 +1,31 @@ +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 component_with = world.get_type_by_name("CompWithFromWorldAndComponentData") +local component_without = world.get_type_by_name("CompWithDefaultAndComponentData") + +world.add_default_component(entity_a, component_with) +world.add_default_component(entity_b, component_with) +world.add_default_component(entity_c, component_with) + +world.add_default_component(entity_b, component_without) + +local found_entities = {} +for i,result in pairs(world.query():component(component_with):without(component_without):build()) do + table.insert(found_entities, result:entity()) +end + +assert(#found_entities == 3, "Expected 3 entities, got " .. #found_entities) + +expected_entities = { + entity_c, + entity_d, + entity_a, +} + +for i, entity in ipairs(found_entities) do + assert(entity:index() == expected_entities[i]:index(), "Expected entity " .. expected_entities[i]:index() .. " but got " .. entity:index()) +end + diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/remove/vec.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/remove/vec.lua new file mode 100644 index 00000000..9974b001 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/remove/vec.lua @@ -0,0 +1,6 @@ +local res_type = world.get_type_by_name("TestResourceWithVariousFields") +local res = world.get_resource(res_type) + +local removed = res.vec_usize:remove(5) + +assert(removed == 5, "Remove did not work") diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/remove_component/empty_entity_does_nothing.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/remove_component/empty_entity_does_nothing.lua new file mode 100644 index 00000000..1f0ca7a4 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/remove_component/empty_entity_does_nothing.lua @@ -0,0 +1,5 @@ +local entity = world.spawn() +local type = world.get_type_by_name('TestComponent') + +world.remove_component(entity, type) +world.remove_component(entity, type) \ No newline at end of file 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 new file mode 100644 index 00000000..5a2cdb58 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/remove_component/no_component_data_errors.lua @@ -0,0 +1,7 @@ + +local entity = _get_entity_with_test_component("CompWithDefault") +local component = world.get_type_by_name("CompWithDefault") + +assert_throws(function () + world.remove_component(entity, component) +end, "Missing type data ReflectComponent for type: .*CompWithDefault.*") 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 new file mode 100644 index 00000000..43d6dfd7 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/remove_component/with_component_data_removes_component.lua @@ -0,0 +1,5 @@ + +local entity = _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/missing_resource_with_resource_data_does_nothing.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/remove_resource/missing_resource_with_resource_data_does_nothing.lua new file mode 100644 index 00000000..93fe8237 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/remove_resource/missing_resource_with_resource_data_does_nothing.lua @@ -0,0 +1,4 @@ +local type = world.get_type_by_name("TestResource") + +world.remove_resource(type) +world.remove_resource(type) \ No newline at end of file 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 new file mode 100644 index 00000000..2f7b85eb --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/remove_resource/no_resource_data_errors.lua @@ -0,0 +1,6 @@ + +local type = _get_mock_type() + +assert_throws(function () + world.remove_resource(type) +end, "Missing type data ReflectResource for type: Unregistered.TypeId.*") diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/remove_resource/with_resource_data_removes_resource.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/remove_resource/with_resource_data_removes_resource.lua new file mode 100644 index 00000000..1141a8fc --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/remove_resource/with_resource_data_removes_resource.lua @@ -0,0 +1,4 @@ + +local type = world.get_type_by_name("TestResource") +world.remove_resource(type) +assert(world.has_resource(type) == false, "Resource was not removed") diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/sub/vec3.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/sub/vec3.lua new file mode 100644 index 00000000..9c732987 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/sub/vec3.lua @@ -0,0 +1,13 @@ + + +local a = Vec3.new(1.0, 2.0, 3.0) +local b = Vec3.new(4.0, 5.0, 6.0) + + +assert((a - 1).x == 0.0, "Subtraction did not work") +assert((a - 1).y == 1.0, "Subtraction did not work") +assert((a - 1).z == 2.0, "Subtraction did not work") + +assert((a - b).x == -3.0, "Subtraction did not work") +assert((a - b).y == -3.0, "Subtraction did not work") +assert((a - b).z == -3.0, "Subtraction did not work") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/data/unm/vec3.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/unm/vec3.lua new file mode 100644 index 00000000..668d8fa6 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/unm/vec3.lua @@ -0,0 +1,5 @@ +local a = Vec3.new(2.0, -4.0, 6.0) + +assert(-a.x == -2.0, "Negation did not work") +assert(-a.y == 4.0, "Negation did not work") +assert(-a.z == -6.0, "Negation did not work") \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua/tests/lua_tests.rs b/crates/languages/bevy_mod_scripting_lua/tests/lua_tests.rs new file mode 100644 index 00000000..356c56ba --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/lua_tests.rs @@ -0,0 +1,275 @@ +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 libtest_mimic::{Arguments, Failed, Trial}; +use mlua::{Function, Lua}; +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, + path: PathBuf, +} + +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(), + 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/languages/bevy_mod_scripting_lua_derive/CHANGELOG.md b/crates/languages/bevy_mod_scripting_lua_derive/CHANGELOG.md deleted file mode 100644 index cb36e259..00000000 --- a/crates/languages/bevy_mod_scripting_lua_derive/CHANGELOG.md +++ /dev/null @@ -1,16 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -## [0.7.0](https://github.com/makspll/bevy_mod_scripting/compare/bevy_mod_scripting_lua_derive-v0.6.0...bevy_mod_scripting_lua_derive-v0.7.0) - 2024-11-03 - -### Other - -- Migrate to bevy 0.14 ([#127](https://github.com/makspll/bevy_mod_scripting/pull/127)) -- Fix cross-platform CI.yml ([#111](https://github.com/makspll/bevy_mod_scripting/pull/111)) -- update metadata diff --git a/crates/languages/bevy_mod_scripting_lua_derive/Cargo.toml b/crates/languages/bevy_mod_scripting_lua_derive/Cargo.toml deleted file mode 100644 index d98ff8f6..00000000 --- a/crates/languages/bevy_mod_scripting_lua_derive/Cargo.toml +++ /dev/null @@ -1,38 +0,0 @@ -[package] -name = "bevy_mod_scripting_lua_derive" -version = "0.8.0" -authors = ["Maksymilian Mozolewski "] -edition = "2021" -license = "MIT OR Apache-2.0" -description = "Necessary functionality for Lua support with bevy_mod_scripting" -repository = "https://github.com/makspll/bevy_mod_scripting" -homepage = "https://github.com/makspll/bevy_mod_scripting" -keywords = ["bevy", "gamedev", "scripting", "rhai"] -categories = ["game-development"] -readme = "readme.md" - -[package.metadata.release] -pre-release-replacements = [ - { file = "Cargo.toml", search = '^version\s*=\s*.*$', replace = "version = \"{{version}}\"", exactly = 1 }, - { file = "Cargo.toml", search = '^(?Pbevy_mod_scripting_common\s*=.*)version\s*=\s*".*"(?P.*)$', replace = "${h}version = \"{{version}}\"${t}", exactly = 1 }, -] - -[lib] -name = "bevy_mod_scripting_lua_derive" -path = "src/lib.rs" -proc-macro = true - -[dependencies] -bevy_mod_scripting_common = { path = "../../bevy_mod_scripting_common", version = "0.8.0" } -paste = "1.0.7" -darling = "0.20" -syn = { version = "2.0.38", features = ["full", "fold", "extra-traits"] } -quote = "1.0.8" -proc-macro2 = "1.0" -convert_case = "0.5.0" -rustdoc-types = "0.11.0" -serde = { version = "1.0", features = ["derive"] } -serde_derive = "1.0.137" -indexmap = { version = "1.9.1", features = ["serde"] } -strum = { version = "0.24.1", features = ["derive"] } -vec1 = "1.10.1" diff --git a/crates/languages/bevy_mod_scripting_lua_derive/readme.md b/crates/languages/bevy_mod_scripting_lua_derive/readme.md deleted file mode 100644 index e058ed4f..00000000 --- a/crates/languages/bevy_mod_scripting_lua_derive/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -# bevy_mod_scripting_lua_derive - -This crate is a part of the ["bevy_mod_scripting" workspace](https://github.com/makspll/bevy_mod_scripting). \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_lua_derive/src/arg.rs b/crates/languages/bevy_mod_scripting_lua_derive/src/arg.rs deleted file mode 100644 index ece327f3..00000000 --- a/crates/languages/bevy_mod_scripting_lua_derive/src/arg.rs +++ /dev/null @@ -1,119 +0,0 @@ -#![allow(clippy::manual_unwrap_or_default)] // from darling - -use std::collections::HashMap; - -use bevy_mod_scripting_common::input::{SimpleType, VisitSimpleType}; -use darling::FromAttributes; -use proc_macro2::{Ident, Span}; -use quote::{quote, quote_spanned}; -use syn::{parse_quote, token::Mut}; - -use crate::visitor::{LuaSimpleTypeArgumentUnwrapper, LuaTypeConstructorVisitor}; - -#[derive(Debug, FromAttributes)] -#[darling(attributes(proxy))] -pub struct ArgAttributes { - #[darling(default)] - pub map: HashMap, -} - -/// Struct for holding argument/output information in functions passed via `functions[..]` meta -#[derive(Debug)] -pub struct Arg { - // pub attrs: ArgAttributes, - pub mutability: Option, - /// the type of the argument, only suported patterns are allowed - pub name: Ident, - /// variant specific data enumeration - pub type_: SimpleType, - /// if an argument is raw, it's passed without any unwrapping to the handler function - /// if an argument isn't annotated with the `proxy` flag it is technically raw, but this is different for receiver and output arguments - pub is_raw: bool, - pub span: Span, -} - -impl Arg { - pub fn new( - // attrs: ArgAttributes, - name: Ident, - mutability: Option, - type_: SimpleType, - is_raw: bool, - ) -> Self { - Self { - // attrs, - mutability, - span: name.span(), - name, - type_, - is_raw, - } - } - - /// Unpacks non-reference proxy parameters (using the `inner` method) yielding expressions which correspond to the proxied type with conversion errors being - /// handled by the try `?` operator. - pub fn unpack_parameter(&self) -> syn::Result> { - let name = &self.name; - if self.is_raw { - // raw parameters DO NOT get unpacked, they get passed directly to the handling method as is - Ok(None) - } else { - // if a proxy parameter is to be passed by value we use inner (which requires Clone to be supported) - Ok(Some( - LuaSimpleTypeArgumentUnwrapper::new(name.clone(), name.span()) - .visit(&self.type_)?, - )) - } - } - - fn arg_signature_generic( - &self, - expecting_receiver: bool, - expecting_ctxt: bool, - ) -> (proc_macro2::TokenStream, proc_macro2::TokenStream) { - assert!(!(expecting_receiver && expecting_ctxt)); - - let _mut = &self.mutability; - let name = &self.name; - let type_ = if expecting_ctxt { - parse_quote!(&bevy_mod_scripting_lua::prelude::Lua) - } else { - LuaTypeConstructorVisitor::new(true, self.type_.contains_proxy_type()) - .visit(&self.type_) - }; - let forced_ref = expecting_receiver.then(|| { - Some(quote_spanned!(self.span=> - & #_mut - )) - }); - - let name_part = quote_spanned!(self.span=> - #_mut #name - ); - let type_part = quote_spanned!(self.span=> - #forced_ref #type_ - ); - (name_part, type_part) - } - - /// Generates the arg signature in an mlua `UserDataFields` or `UserDataMethods` closure for a receiver type argument. - /// generates using an additional outer reference. - pub fn arg_signature_receiver(&self) -> proc_macro2::TokenStream { - let (name, type_) = self.arg_signature_generic(true, false); - quote!(#name : #type_) - } - - /// Generates the arg signature in an mlua `UserDataFields` or `UserDataMethods` closure for a Lua context type argument. - /// generates using an additional outer reference. - pub fn arg_signature_context(&self) -> proc_macro2::TokenStream { - let (name, type_) = self.arg_signature_generic(false, true); - quote!(#name : #type_) - } - - /// Generates the arg signature in an mlua `UserDataFields` or `UserDataMethods` closure for a non-receiver non-context argument. - /// generates the type to match the argument received. - /// The output is split into the name and type parts - pub fn arg_signature(&self) -> (proc_macro2::TokenStream, proc_macro2::TokenStream) { - self.arg_signature_generic(false, false) - } -} diff --git a/crates/languages/bevy_mod_scripting_lua_derive/src/function.rs b/crates/languages/bevy_mod_scripting_lua_derive/src/function.rs deleted file mode 100644 index 29241a91..00000000 --- a/crates/languages/bevy_mod_scripting_lua_derive/src/function.rs +++ /dev/null @@ -1,602 +0,0 @@ -#![allow(clippy::manual_unwrap_or_default)] // from darling - -use bevy_mod_scripting_common::input::{ - DuoPath, IdentifierRenamingVisitor, Reference, SimpleType, VisitSimpleType, -}; -use darling::{util::Flag, FromAttributes, FromMeta}; -use proc_macro2::{Ident, Span}; -use quote::{format_ident, quote, quote_spanned, ToTokens}; -use strum::{Display, EnumIter, EnumString}; -use syn::{ - punctuated::Punctuated, spanned::Spanned, visit_mut::VisitMut, Block, LitInt, LitStr, Meta, - Path, Token, -}; -use vec1::Vec1; - -use crate::{ - arg::Arg, - signature::Signature, - visitor::{LuaSimpleTypeWrapper, LuaTypeConstructorVisitor}, - PROXY_OUT_ALIAS, RAW_OUT_ALIAS, SELF_ALIAS, -}; - -#[derive(Default, FromMeta, Display, EnumString, EnumIter, PartialEq, Eq, Clone, Copy, Debug)] -#[darling(rename_all = "PascalCase")] -pub enum FunctionKind { - Function, - MetaFunction, - #[default] - Method, - MetaMethod, - MutableFunction, - MutableMetaFunction, - MutatingMethod, - MutatingMetaMethod, - FieldGetterMethod, - FieldSetterMethod, -} - -impl FunctionKind { - pub fn expects_receiver(self) -> bool { - self == FunctionKind::Method - || self == FunctionKind::MetaMethod - || self == FunctionKind::MutatingMethod - || self == FunctionKind::MutatingMetaMethod - || self == FunctionKind::FieldGetterMethod - || self == FunctionKind::FieldSetterMethod - } - - pub fn is_field(self) -> bool { - self == FunctionKind::FieldGetterMethod || self == FunctionKind::FieldSetterMethod - } - - pub fn is_field_getter(self) -> bool { - self == FunctionKind::FieldGetterMethod - } - - /// Returns true if the mlua closure signature accepts a tuple for general 'Arguments' to the function - /// I.e. arguments freely passed to the function by the caller. - pub fn expects_arguments_tuple(self) -> bool { - self != FunctionKind::FieldGetterMethod - } - - pub fn get_tealr_function(self) -> &'static str { - match self { - FunctionKind::Function => "add_function", - FunctionKind::MetaFunction => "add_meta_function", - FunctionKind::Method => "add_method", - FunctionKind::MetaMethod => "add_meta_method", - FunctionKind::MutableFunction => "add_function_mut", - FunctionKind::MutableMetaFunction => "add_meta_function_mut", - FunctionKind::MutatingMethod => "add_method_mut", - FunctionKind::MutatingMetaMethod => "add_meta_method_mut", - FunctionKind::FieldGetterMethod => "add_field_method_get", - FunctionKind::FieldSetterMethod => "add_field_method_set", - } - } - - pub fn is_meta(self) -> bool { - self == FunctionKind::MetaMethod - || self == FunctionKind::MetaFunction - || self == FunctionKind::MutatingMetaMethod - || self == FunctionKind::MutableMetaFunction - } -} - -/// The attributes which can be applied to lua functions using the -/// `lua(..)` meta attribute -#[derive(Debug, FromAttributes)] -#[darling(attributes(lua))] -pub struct FunctionAttributes { - /// Marks the function to be treated as raw meaning a lot of the wrapping and unwrapping is skipped, - /// a 'Lua' ctxt argument is then expected - pub raw: Flag, - - /// Marks the function as a composite with the given ID, at least one another function with the same composite - /// ID must exist resulting in a combined function being generated. The actual function to dispatch to will be decided based on - /// the types of arguments. If the signature is invalid (i.e. doesn't allow us to dispatch) an error will be thrown - #[darling(default)] - pub composite: Option, - - /// If passed provides the name of the metamethod to use for metamethod based functions - /// the name of the function is used to decide what rust function to call in this case - #[darling(default)] - pub metamethod: Option, - - /// The kind of function to generate on the proxy - #[darling(default)] - pub kind: FunctionKind, - - /// Marks this to be ignored, only used for fields as functions are opt-in - pub skip: Flag, - - /// Meta to pass down to the output proxy or in case of fields - /// used as the argument meta for type being get/set - pub output: Option, - - /// If passed will generate statement before calling the method - /// on the type - pub as_trait: Option, - - #[darling(multiple)] - pub doc: Vec, -} - -/// A function which combines the signatures of multiple functions, -/// and dispatches to the one which matches the signature if any -/// Useful for binary operators which can accept many types on both sides -#[derive(Debug)] -pub struct CompositeFunction { - pub functions: Vec1, -} - -/// A struct corresponding to each function in the functions[...] meta list. -/// -#[derive(Debug)] -pub struct Function { - pub name: Ident, - pub attrs: FunctionAttributes, - pub sig: Signature, - pub default: Option, - pub span: Span, - pub is_unsafe: bool, -} - -impl Function { - pub fn new( - name: Ident, - attrs: FunctionAttributes, - default: Option, - sig: Signature, - span: Span, - is_unsafe: bool, - ) -> darling::Result { - Ok(Self { - name, - attrs, - sig, - default, - span, - is_unsafe, - }) - } - - /// Tries to retrieve the receiver argument from functions. - /// If not expected returns None and Some otherwise. - /// If the function is of the wrong kind or does not have the correct signature an error is thrown - pub fn self_arg(&self) -> syn::Result> { - if self.attrs.kind.expects_receiver() { - self.get_self_arg().map(Option::Some) - } else { - Ok(None) - } - } - - /// Returns an error if self arg is not there and returns it otherwise - pub fn get_self_arg(&self) -> syn::Result<&Arg> { - self.sig.inputs.first().ok_or_else(|| { - syn::Error::new( - self.sig.span, - "Expected receiver as first argument in the signature".to_string(), - ) - }) - } - - /// Tries to retrieve the context argument from raw functions. - /// If the function is not raw or doesn't have a correct signature an error is thrown - pub fn ctxt_arg(&self) -> syn::Result> { - if self.attrs.raw.is_present() { - self.get_ctxt_arg().map(Option::Some) - } else { - Ok(None) - } - } - - /// Returns an error if no context argument is found in the correct place or returns it otherwise - pub fn get_ctxt_arg(&self) -> syn::Result<&Arg> { - let ctxt_idx = if self.attrs.kind.expects_receiver() { - 1 - } else { - 0 - }; - self.sig.inputs.get(ctxt_idx).ok_or_else(|| { - syn::Error::new( - self.sig.span, - format!( - "Expected ctxt argument in the signature as argument number: `{}`", - ctxt_idx + 1 - ), - ) - }) - } - - /// Retrieves the rest of the arguments (after the receiver and context args) - /// If they are expected, otherwise returns None. - /// If arguments are expected but none are present Some(vec![]) is returned - /// If input vec is shorter than expected, i.e. if the receiver should be there but isn't returns an Err - pub fn other_arguments(&self) -> syn::Result>> { - if self.attrs.kind.expects_arguments_tuple() { - self.get_other_arguments().map(Option::Some) - } else { - Ok(None) - } - } - - pub fn get_other_arguments(&self) -> syn::Result> { - let other_args_idx = - self.attrs.kind.expects_receiver() as usize + self.attrs.raw.is_present() as usize; - - if self.sig.inputs.len() < other_args_idx { - return Err(syn::Error::new( - self.sig.span, - format!("Signature too short, expected {other_args_idx} arguments before this one"), - )); - } - - Ok(self.sig.inputs.iter().skip(other_args_idx)) - } - - /// Converts the function's arguments into closure arguments for use in the closures given to mlua calls - /// - /// # Example - /// ```rust,ignore - /// // the function: - /// fn foo(self, my_str : String){} - /// // would convert to - /// // | _, my_proxy: MyLua, (my_str): (String) | - /// // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <- these bits - /// ``` - pub fn generate_mlua_args(&self) -> syn::Result { - let self_arg = self.self_arg()?.map(Arg::arg_signature_receiver); - - let ctxt_arg = self - .ctxt_arg()? - .map(Arg::arg_signature_context) - .unwrap_or_else(|| quote!(_)); - - let other_args = self.other_arguments()?.map(|args| { - let (other_arg_names, other_arg_types) = - args.map(Arg::arg_signature).unzip::<_, _, Vec<_>, Vec<_>>(); - - quote_spanned!(self.sig.span=> - (#(mut #other_arg_names),*) : (#(#other_arg_types),*) - ) - }); - - Ok(vec![Some(ctxt_arg), self_arg, other_args] - .into_iter() - .filter(Option::is_some) - .collect::, Token![,]>>() - .to_token_stream()) - } - - /// Takes all the argument identifiers passed into the function, generates assignments which shadow the original - /// identifiers but modifies the parameter types if required by unpacking proxies. This is done via `.inner` calls on proxy wrappers - /// - /// For example for the type `MyType` - /// `fn my_fn(self, #[proxy] other_ref: &Self, #[proxy] other: Self)` - /// - /// will generate the following statements: - /// ```rust,ignore - /// let _self : MyType = self.inner(); - /// let other_ref : LuaMyType = other; // note this one is kept as a wrapper, and dealt in another process - /// let other : MyType = other_ref.inner(); - /// ``` - fn generate_mlua_body_unwrapped_parameter_assignments( - &self, - ) -> syn::Result { - Ok(self - .sig - .inputs - .iter() - .map(Arg::unpack_parameter) - .collect::>>()? - .iter() - .zip(self.sig.inputs.iter()) - .filter_map(|(unpacked_param, arg)| { - unpacked_param.as_ref().map(|unpacked_param| { - let name = &arg.name; - quote_spanned! {name.span()=>let mut #name = #unpacked_param;} - }) - }) - .collect::()) - } - - /// Similar to generate_mlua_body_output but for functions, makes some more assumptions and directly generates wrapped/unwrapped output depending on what's necessary - /// Does not require another wrapping step and can be directly put in a result as the final output of an mlua closure - fn generate_mlua_body_output_field( - &self, - raw_output_ident: &Ident, - ) -> syn::Result { - let field_type = if self.attrs.kind.is_field_getter() { - &self.sig.output - } else { - self.get_other_arguments()?.next() - .ok_or_else(|| syn::Error::new(self.sig.span, format!("Setter lua method with no arguments, expected at least one argument in function: `{}`", self.name)))? - }; - // we need to figure out which type of field access this is going to be - let self_name = &self.get_self_arg()?.name; - let ctxt_name = &self.get_ctxt_arg()?.name; - let world_ptr = quote!( - - ::get_world(#ctxt_name)? - ); - - let field_name = { - let str_name = self.name.to_string(); - - if str_name.starts_with('_') && str_name[1..].parse::().is_ok() { - syn::Lit::Int(LitInt::new(&str_name[1..], self.name.span())).to_token_stream() - } else { - self.name.clone().to_token_stream() - } - }; - let field_name_str = syn::Lit::Str(LitStr::new(&self.name.to_string(), self.name.span())); - let proxy_output_type = - LuaTypeConstructorVisitor::new(true, false).visit(&field_type.type_); - - Ok(match &field_type.type_ { - // proxy, need to index into it then wrap the result - // getter - t if t.contains_proxy_type() && self.attrs.kind.is_field_getter() => quote!( - let #raw_output_ident = #proxy_output_type::new_ref(bevy_script_api::script_ref::ValueIndex::index(& #self_name.reflect_ref(#world_ptr), std::borrow::Cow::Borrowed(#field_name_str))); - ), - // setter - t if t.contains_proxy_type() => { - let first_arg_name = &self - .get_other_arguments()? - .next() - .ok_or_else(|| { - syn::Error::new( - self.sig.span, - "Field setter requires a single argument which is missing", - ) - })? - .name; - quote!( - let #raw_output_ident = #first_arg_name.apply_self_to_base(&mut bevy_script_api::script_ref::ValueIndex::index(& #self_name.reflect_ref(#world_ptr), std::borrow::Cow::Borrowed(#field_name_str)))?; - ) - } - - // plain reflection, index into the ReflectReference with the field path - // getter - SimpleType::Type(syn::Type::Path(path)) - if path.path.is_ident("ReflectedValue") && self.attrs.kind.is_field_getter() => - { - quote!( - let #raw_output_ident = bevy_script_api::script_ref::ValueIndex::index(& #self_name.reflect_ref(#world_ptr), std::borrow::Cow::Borrowed(#field_name_str)); - ) - } - // setter - SimpleType::Type(syn::Type::Path(path)) if path.path.is_ident("ReflectedValue") => { - let first_arg_name = &self - .get_other_arguments()? - .next() - .ok_or_else(|| { - syn::Error::new( - self.sig.span, - "Field setter requires a single argument which is missing", - ) - })? - .name; - quote!( - let #raw_output_ident = bevy_script_api::script_ref::ValueIndex::index(& #self_name.reflect_ref(#world_ptr), std::borrow::Cow::Borrowed(#field_name_str)).apply(&#first_arg_name.ref_)?; - ) - } - - // primitive use clone on the value and return it without a wrapper - // getter - _ if self.attrs.kind.is_field_getter() => quote!( - let #raw_output_ident = #self_name.val(|#self_name| #self_name.#field_name.clone())?; - ), - // setter - _ => { - let first_arg_name = &self - .get_other_arguments()? - .next() - .ok_or_else(|| { - syn::Error::new( - self.sig.span, - "Field setter requires a single argument which is missing", - ) - })? - .name; - quote!( - let #raw_output_ident = #self_name.val_mut(|#self_name| #self_name.#field_name = #first_arg_name)?; - ) - } - }) - } - - /// Generates the statement which calls the proxied function with the same argument names as in the function declaration - /// and stores the output in a variable with the given identifier. Static methods, are called against the given `proxied_name` - /// - /// For example for the type `MyType` with proxied ident `__proxied_out` - /// `fn my_fn(self, #[proxy] other_ref: &Self, #[proxy] other: Self) -> Self` - /// - /// will generate the following statement: - /// ```rust,ignore - /// let __proxied_out : MyType = self.my_fn(other_ref, other); - /// ``` - fn generate_mlua_body_raw_output( - &self, - raw_output_ident: &Ident, - proxied_type_path: &Path, - ) -> syn::Result { - // generate function call on proxied type (operating over unwrapped parameters) - // output will be stored in raw_output_ident with the proxied_type_path - - // the type before we wrap it in a proxy - let raw_output_type = - LuaTypeConstructorVisitor::new(false, false).visit(&self.sig.output.type_); - - match &self.default { - Some(body) => { - let stmts = body.stmts.iter().cloned().map(|mut s| { - IdentifierRenamingVisitor { - target: "self", - replacement: SELF_ALIAS, - } - .visit_stmt_mut(&mut s); - s - }); - - Ok(quote_spanned! {body.span()=> - let #raw_output_ident : #raw_output_type = - (||{ - #(#stmts)* - })(); - }) - } - None => { - let function_name = &self.name; - let param_names = self - .sig - .inputs - .iter() - .map(|arg| &arg.name) - .collect::>(); - - // override this span, as otherwise spans propagate weird - let mut proxied_name = proxied_type_path.clone(); - - proxied_name - .segments - .iter_mut() - .for_each(|v| v.ident.set_span(self.sig.span)); - - let method_path = if let Some(trait_path) = &self.attrs.as_trait { - quote_spanned!(self.sig.span=> - #trait_path::#function_name - ) - } else { - quote_spanned!(self.sig.span=> - #proxied_name::#function_name - ) - }; - - Ok(quote_spanned! {self.sig.span=> - let #raw_output_ident : #raw_output_type = - #method_path(#(#param_names),*); - }) - } - } - } - - /// Generates a wrapping statement, which if the type present in the `proxied_output_ident` variable needs to be wrapped into a proxy constructor, will do so and assign - /// the output to the given `proxy_output_ident`. - /// - /// For example for the type: `MyType` with `__proxy_out output` identifier - /// the function: `fn my_fn(self, #[proxy] other_ref: &Self, #[proxy] other: Self) -> Self` - /// will generate the following statement: - /// ```rust,ignore - /// let __proxy_out : LuaMyType = LuaMyType::new(__proxied_out); - /// ``` - fn generate_mlua_body_proxy_output( - &self, - proxied_output_ident: &Ident, - proxy_output_ident: &Ident, - ) -> syn::Result { - if self.sig.output.is_raw { - return Ok(quote_spanned! {self.sig.span=> - let #proxy_output_ident = #proxied_output_ident; - }); - } - - // generate `new` calls as required to build proxy stored in out_ident - let constructor_wrapped_expression = - LuaSimpleTypeWrapper::new(proxied_output_ident.clone(), proxied_output_ident.span()) - .visit(&self.sig.output.type_)?; - - // the type of the wrapped type (if wrapped) - let proxy_output_type = - LuaTypeConstructorVisitor::new(true, false).visit(&self.sig.output.type_); - - // the statement assigning the proxy output to proxy_output_ident - Ok(quote_spanned! {self.sig.span=> - let #proxy_output_ident : #proxy_output_type = #constructor_wrapped_expression; - }) - } - - pub fn generate_mlua_body( - &self, - proxied_type_path: &Path, - ) -> syn::Result { - let unpacked_parameter_declarations = - self.generate_mlua_body_unwrapped_parameter_assignments()?; - - let raw_output_ident = format_ident!("{RAW_OUT_ALIAS}", span = self.sig.span); - let proxy_output_ident = format_ident!("{PROXY_OUT_ALIAS}", span = self.sig.span); - - let raw_output_stmt = if self.attrs.kind.is_field() { - self.generate_mlua_body_output_field(&raw_output_ident)? - } else { - self.generate_mlua_body_raw_output(&raw_output_ident, proxied_type_path)? - }; - - // for fields the output is expected to be raw anyway so this will just performa no-op - let proxy_output_stmt = - self.generate_mlua_body_proxy_output(&raw_output_ident, &proxy_output_ident)?; - - // determine if we need to wrap the output in an Ok() statement - let last_stm = match &self.sig.output.type_ { - SimpleType::DuoPath(DuoPath { ident, .. }) if *ident == "Result" => { - quote_spanned! {self.sig.span=>#proxy_output_ident} - } - _ => quote_spanned! {self.sig.span=>Ok(#proxy_output_ident)}, - }; - - let conversion_body_stms = quote!( - #raw_output_stmt - #proxy_output_stmt - #last_stm - ); - - // for every argument which is a reference, we need a separate sort of call, - // we cannot use `v.inner()` since this operates over values, we must use `val_mut` or `val` to get a reference to the wrapped - // structure for the duration of the call - let conversion_body_surrounded_with_dereferening_stms = - self.sig - .inputs - .iter() - .fold(conversion_body_stms, |acc, arg_meta| { - // only proxy types which are directly inside a reference are supported as references - if !matches!(arg_meta.type_, SimpleType::Reference(Reference{ ref inner, .. }) - if matches!(inner.as_ref(), SimpleType::ProxyType(_))) - { - return acc; - } - // raw arguments are passed directly to the handler function - if arg_meta.is_raw { - return acc; - } - - let method_call = if arg_meta.type_.has_outer_mut_ref() { - format_ident!("val_mut", span = arg_meta.span) - } else { - format_ident!("val", span = arg_meta.span) - }; - - let arg_name = &arg_meta.name; - - quote_spanned! {self.sig.span=>{ - #arg_name.#method_call(|mut #arg_name| {#acc})? - }} - }); - let out = quote!( - #unpacked_parameter_declarations - #conversion_body_surrounded_with_dereferening_stms - ); - - if self.is_unsafe { - Ok(quote_spanned! {self.sig.span=> - unsafe { - #out - } - }) - } else { - Ok(out) - } - } -} diff --git a/crates/languages/bevy_mod_scripting_lua_derive/src/lib.rs b/crates/languages/bevy_mod_scripting_lua_derive/src/lib.rs deleted file mode 100644 index 1b919e15..00000000 --- a/crates/languages/bevy_mod_scripting_lua_derive/src/lib.rs +++ /dev/null @@ -1,543 +0,0 @@ -use std::collections::HashMap; - -use arg::Arg; -use bevy_mod_scripting_common::{input::*, utils::doc_attribute_to_string_lit}; -use syn::{parse_macro_input, DeriveInput, Variant}; -use syn::{ - parse_quote, spanned::Spanned, AttrStyle, Attribute, Field, Meta, Path, Token, TraitItemFn, -}; - -use crate::function::*; -use crate::signature::*; -use darling::{FromAttributes, FromDeriveInput}; -use function::FunctionAttributes; -use proc_macro::TokenStream; -use proc_macro2::*; -use quote::*; -use vec1::{vec1, Vec1}; -pub(crate) mod arg; -pub(crate) mod function; -pub(crate) mod signature; -pub(crate) mod visitor; - -const SELF_ALIAS: &str = "_self"; -const RAW_OUT_ALIAS: &str = "__proxied_out"; -const PROXY_OUT_ALIAS: &str = "__proxy_out"; -const PROXY_PREFIX: &str = "Lua"; -const VALID_META_METHODS: [&str; 27] = [ - "Add", "Sub", "Mul", "Div", "Mod", "Pow", "Unm", "IDiv", "BAnd", "BOr", "BXor", "BNot", "Shl", - "Shr", "Concat", "Len", "Eq", "Lt", "Le", "Index", "NewIndex", "Call", "ToString", "Pairs", - "IPairs", "Iter", "Close", -]; - -/// Takes in field with all the required meta and converts it into a -/// TraitItemFn representation -fn convert_field_to_lua_accessor( - idx: usize, - field: &Field, - is_setter: bool, -) -> darling::Result { - let field_name = field - .ident - .clone() - .unwrap_or_else(|| format_ident!("_{}", idx)); - let field_type = &field.ty; - let attrs = &field.attrs; - let mut setter_args: Option = None; - if let Some(attr) = attrs.iter().find(|attr| attr.meta.path().is_ident("lua")) { - attr.parse_nested_meta(|nested| { - if nested.path.is_ident("output") { - nested.parse_nested_meta(|nested| { - setter_args = Some(nested.input.parse()?); - Ok(()) - })? - } - Ok(()) - })?; - } - let setter_arg_attrs = setter_args.map(|tokens| Attribute { - pound_token: Token![#](field.span()), - style: AttrStyle::Outer, - bracket_token: Default::default(), - meta: syn::Meta::List(syn::MetaList { - path: Ident::new("proxy", field.span()).into(), - delimiter: syn::MacroDelimiter::Paren(Default::default()), - tokens, - }), - }); - let trait_item_method: TraitItemFn = if is_setter { - parse_quote! { - #[lua(kind="FieldSetterMethod", raw)] - #(#attrs)* - fn #field_name (&mut self, lua: &Lua, #setter_arg_attrs other: #field_type); - } - } else { - parse_quote! { - #[lua(kind="FieldGetterMethod", raw)] - #(#attrs)* - fn #field_name (&self, lua: &Lua) -> #field_type; - } - }; - - Ok(trait_item_method) -} - -/// Removes functions from the list and matches them up based on composite ID's into a unified struct -fn extract_composite_functions(functions: &mut Vec) -> Vec { - let indices = functions - .iter() - .enumerate() - .filter_map(|(idx, elem)| { - if elem.attrs.composite.is_some() { - Some(idx) - } else { - None - } - }) - .rev() // reverse order to avoid double shifting things around - .collect::>(); - - let mut composites: HashMap> = HashMap::with_capacity(indices.len()); - for i in indices { - let f = functions.remove(i); - let name = &f.attrs.composite.as_ref().unwrap(); - if composites.contains_key(name.as_str()) { - composites.get_mut(name.as_str()).unwrap().push(f); - } else { - composites.entry((*name).to_owned()).or_insert(vec1![f]); - } - } - - composites - .into_values() - .map(|functions| CompositeFunction { functions }) - .collect() -} - -fn build_function( - proxied_type_path: &Path, - function_def: TraitItemFn, -) -> darling::Result> { - let attrs = FunctionAttributes::from_attributes(&function_def.attrs)?; - // if skipping return no-op - if attrs.skip.is_present() { - return Ok(None); - }; - - let span = function_def.span(); - - let function_name = function_def.sig.ident.clone(); - let output_attrs = attrs - .output - .clone() - .map(|meta| { - let meta = meta.require_list()?.parse_args::()?; - Ok::<_, syn::Error>(vec![Attribute { - pound_token: Token![#](meta.span()), - style: AttrStyle::Outer, - bracket_token: Default::default(), - meta, - }]) - }) - .transpose()? - .unwrap_or_default(); - - let is_unsafe = function_def.sig.unsafety.is_some(); - - let signature = Signature::new( - proxied_type_path.clone(), - function_def.sig, - attrs.raw.is_present(), - output_attrs, - )?; - Function::new( - function_name.clone(), - attrs, - function_def.default, - signature, - span, - is_unsafe, - ) - .map(Option::Some) -} - -/// generates either the string function name or the MetaMethod type path depending if it's a valid meta method -fn generate_mlua_function_name(function: &Function) -> syn::Result { - let function_name = &function.name; - let tealr = quote!(bevy_mod_scripting_lua::tealr::mlu::mlua); - if function.attrs.kind.is_meta() { - let metamethod = function.attrs.metamethod.as_ref().ok_or_else(|| { - syn::Error::new( - function.span, - "Missing `metamethod` lua proxy attribute, required for meta functions.", - ) - })?; - // check is valid meta method if not use custom name - if VALID_META_METHODS.contains(&metamethod.to_string().as_str()) { - Ok(quote!(#tealr::MetaMethod::#metamethod)) - } else { - let std_string = metamethod.to_string(); - Ok(quote!(#tealr::MetaMethod::Custom(#std_string.to_string()))) - } - } else { - Ok(function_name.to_string().to_token_stream()) - } -} - -/// Given a function with correct meta and the name of the proxied type will generate mlua statement -/// which will register the given function within an appropriate mlua container `UserDataMethods` or `UserDataFields` -/// i.e.: -/// ```rust,ignore -/// /// docs -/// fields.#tealr_function(#signature, #closure) -/// // or -/// -/// /// docs -/// methods.#tealr_function(#signature, #closure) -/// ``` -/// depending on if the function is a field accessor or a method/function -fn generate_mlua_registration_code( - container_ident: Ident, - proxied_type_path: &Path, - function: Function, -) -> darling::Result { - let method_documentation_calls = function - .attrs - .doc - .iter() - .map(|tkns| quote_spanned!(function.span=>#container_ident.document_type(#tkns))); - - let tealr_function = format_ident!( - "{}", - function.attrs.kind.get_tealr_function(), - span = function.span - ); - let signature = generate_mlua_function_name(&function)?; - - let args = function.generate_mlua_args()?; - let body = function.generate_mlua_body(proxied_type_path)?; - - Ok(quote_spanned! {body.span()=> - #(#method_documentation_calls);* - #container_ident.#tealr_function(#signature,|#args| { - #body - }); - }) -} - -/// Same as generate_mlua_registration_code but for composite functions -fn generate_mlua_registration_code_composite( - container_ident: Ident, - proxied_type_path: &Path, - functions: CompositeFunction, -) -> darling::Result { - let tealr = quote!(bevy_mod_scripting_lua::tealr::mlu); - let mut method_documentation_calls = Vec::default(); - let first = functions.functions.first(); - // take the first functions for function signature from the composite - let tealr_function = format_ident!( - "{}", - first.attrs.kind.get_tealr_function(), - span = first.span - ); - let signature = generate_mlua_function_name(first)?; - let (main_arg_names, main_arg_types) = first - .get_other_arguments()? - .map(|a| (a.name.clone(), quote!(#tealr::mlua::Value))) - .unzip::<_, _, Vec<_>, Vec<_>>(); - - let dispatchers = - functions - .functions - .iter() - .map(|function| { - // this is much easier, receivers need special treatment on mlua side - // function args are treated equally, we just need a union for lhs and rhs then to convert those args and - // pass dispatch them to the appropriate function - if function.attrs.kind.expects_receiver() || function.attrs.raw.is_present() { - return Err(syn::Error::new( - function.span, - "Composite functions with receivers are not supported, use a function instead", - )); - } - - method_documentation_calls.extend(function.attrs.doc.iter().map( - |tkns| quote_spanned!(function.span=>#container_ident.document_type(#tkns);), - )); - - let (arg_names, arg_types) = function - .sig - .inputs - .iter() - .map(Arg::arg_signature) - .unzip::<_, _, Vec<_>, Vec<_>>(); - let body = function.generate_mlua_body(proxied_type_path)?; - Ok(quote_spanned!(function.span=> - match (#(<#arg_types as #tealr::mlua::FromLua>::from_lua(#main_arg_names.clone(), ctxt)),*) { - (#(Ok(#arg_names)),*) => { - let out = { - #body - }; - return out.and_then(|out| #tealr::mlua::IntoLua::into_lua(out, ctxt)) - }, - _ => (), - }; - )) - }) - .collect::>>()?; - - // let (variant_idents, variant_types) = unique_types.iter().unzip(); - // let composite_id = Ident::new(&functions.id, first.span); - let composite = quote_spanned! {first.span=> - // bevy_script_api::impl_tealr_any_union!(#composite_id = #(#variant_idents: #variant_types),*) - #(#method_documentation_calls)* - #container_ident.#tealr_function(#signature,|ctxt, (#(#main_arg_names),*) : (#(#main_arg_types),*)| { - #(#dispatchers)* - Err(#tealr::mlua::Error::RuntimeError( - format!("Function `{}` has no overloaded version accepting argument types: `{}`", - #signature, - vec![#(#main_arg_names.type_name()),*].join(", ") - ) - ) - ) - }); - }; - Ok(composite) -} - -#[proc_macro_derive(LuaProxy, attributes(lua, proxy))] -pub fn impl_lua_proxy(input: TokenStream) -> TokenStream { - let derive_input = parse_macro_input!(input as DeriveInput); - - let meta: ProxyInput = match ProxyInput::from_derive_input(&derive_input) { - Ok(v) => v, - Err(e) => return darling::Error::write_errors(e).into(), - }; - if meta.proxy_name.is_some() { - // throw error - return syn::Error::new( - derive_input.span(), - "The `name` attribute is not supported for lua proxies", - ) - .to_compile_error() - .into(); - } - - let proxied_type_path: syn::Path = meta.remote.unwrap_or(meta.ident.clone().into()); - let proxied_type_str = proxied_type_path.segments.last().unwrap().ident.to_string(); - let proxy_type_ident = format_ident!("{PROXY_PREFIX}{}", &meta.ident); - let tealr = quote!(bevy_mod_scripting_lua::tealr::mlu); - - // optional clone extensions - let opt_with_clone = meta - .derive - .clone - .is_present() - .then_some(quote_spanned! {derive_input.span()=>with Clone}) - .unwrap_or_default(); - - let opt_from_lua_proxy = meta.derive.clone.is_present().then_some( - quote_spanned!{derive_input.span()=> - impl bevy_script_api::lua::FromLuaProxy<'_> for #proxied_type_path { - fn from_lua_proxy<'lua>(lua_value: #tealr::mlua::Value<'lua>, _: &'lua #tealr::mlua::Lua) -> #tealr::mlua::Result { - if let #tealr::mlua::Value::UserData(ud) = lua_value{ - let wrapper = ud.borrow::<#proxy_type_ident>()?; - Ok(std::ops::Deref::deref(&wrapper).inner()?) - } else { - Err(#tealr::mlua::Error::FromLuaConversionError{ - from: "Value", - to: #proxied_type_str, - message: None - }) - } - } - } - } - ).unwrap_or_default(); - - // generate type level tealr documentation calls - let type_level_document_calls = meta - .attrs - .iter() - .filter(|&a| a.meta.path().is_ident("doc")) - .map(doc_attribute_to_string_lit) - .map(|tkns| quote_spanned!(derive_input.span()=>methods.document_type(#tkns);)); - - // generate method equivalents for each field, i.e. unify fields and methods as both can be represented as functions - let field_methods: Vec = match meta.data { - darling::ast::Data::::Struct(fields) => { - let mut out: Vec<_> = Default::default(); - let mut errors = darling::Error::accumulator(); - - out.extend( - fields - .iter() - .enumerate() - .filter_map(|(idx, field)| { - errors.handle_in(|| convert_field_to_lua_accessor(idx, field, false)) - }) - .collect::>(), - ); - - out.extend( - fields - .iter() - .enumerate() - .filter_map(|(idx, field)| { - errors.handle_in(|| convert_field_to_lua_accessor(idx, field, true)) - }) - .collect::>(), - ); - - // short circuit if found any errors - if let Err(e) = errors.finish() { - return e.write_errors().into(); - } - - out - } - _ => panic!("Enums or Unions are not supported"), - }; - - let mut errors = darling::Error::accumulator(); - - // generate both tealr documentation and instantiations of functions and field getters/setters - let mut methods = meta - .functions - .0 - .into_iter() - .filter_map(|v| { - errors - .handle_in(|| build_function(&proxied_type_path, v)) - .flatten() - }) - .collect::>(); - - let composites = extract_composite_functions(&mut methods) - .into_iter() - .flat_map(|function| { - errors.handle_in(|| { - generate_mlua_registration_code_composite( - format_ident!("methods", span = function.functions.first().span), - &proxied_type_path, - function, - ) - }) - }) - .collect::>(); - - // for methods, allow composite functions with combined signatures and runtime dispatch based on type - - let fields = field_methods - .into_iter() - .flat_map(|v| { - errors - .handle_in(|| build_function(&proxied_type_path, v)) - .flatten() - }) - .collect::>(); - - let methods = methods - .into_iter() - .map(|function| { - errors.handle_in(|| { - generate_mlua_registration_code( - format_ident!("methods", span = function.span), - &proxied_type_path, - function, - ) - }) - }) - .collect::>(); - - let fields = fields - .into_iter() - .map(|function| { - errors.handle_in(|| { - generate_mlua_registration_code( - format_ident!("fields", span = function.span), - &proxied_type_path, - function, - ) - }) - }) - .collect::>(); - - // stop if any errors so far - if let Err(e) = errors.finish() { - return e.write_errors().into(); - } - - quote_spanned! {derive_input.span()=> - - bevy_script_api::make_script_wrapper!(#proxied_type_path as #proxy_type_ident #opt_with_clone); - bevy_script_api::impl_from_lua_with_clone!(#proxy_type_ident); - bevy_script_api::impl_tealr_type!(#proxy_type_ident); - - #opt_from_lua_proxy - - #[automatically_derived] - #[allow(unused_parens, unused_braces, unused_mut, unused_variables)] - #[allow(clippy::all)] - impl #tealr::TealData for #proxy_type_ident { - fn add_methods<'lua, T: #tealr::TealDataMethods<'lua, Self>>(methods: &mut T) { - #(#type_level_document_calls)* - #(#methods)* - #(#composites)* - } - - fn add_fields<'lua, T: #tealr::TealDataFields<'lua, Self>>(fields: &mut T) { - #(#fields)* - } - } - - #[allow(clippy::all, unused_variables)] - impl bevy_script_api::lua::LuaProxyable for #proxied_type_path { - fn ref_to_lua<'lua>(self_ : bevy_script_api::script_ref::ReflectReference, lua: &'lua #tealr::mlua::Lua) -> #tealr::mlua::Result<#tealr::mlua::Value<'lua>> { - <#proxy_type_ident as #tealr::mlua::IntoLua>::into_lua(#proxy_type_ident::new_ref(self_),lua) - } - - fn apply_lua<'lua>(self_ : &mut bevy_script_api::script_ref::ReflectReference, lua: &'lua #tealr::mlua::Lua, new_val: #tealr::mlua::Value<'lua>) -> #tealr::mlua::Result<()> { - if let #tealr::mlua::Value::UserData(v) = new_val { - let other = v.borrow::<#proxy_type_ident>()?; - let other = &other; - - other.apply_self_to_base(self_)?; - Ok(()) - } else { - Err(#tealr::mlua::Error::RuntimeError( - "Error in assigning to custom user data".to_owned(), - )) - } - } - } - - #[allow(clippy::all, unused_variables)] - impl bevy_script_api::lua::IntoLuaProxy<'_> for #proxied_type_path { - fn to_lua_proxy<'lua>(self, lua: &'lua #tealr::mlua::Lua) -> #tealr::mlua::Result<#tealr::mlua::Value<'lua>>{ - <#proxy_type_ident as #tealr::mlua::IntoLua>::into_lua(#proxy_type_ident::new(self),lua) - } - } - - } - .into() -} - -#[cfg(test)] -mod test { - - use crate::function::FunctionAttributes; - use darling::FromAttributes; - use syn::TraitItemFn; - - #[test] - fn test_parse_function_attributes_parses() { - let function = " - #[lua(output(proxy))] - fn asd(#[proxy] arg: String, #[proxy(Type=\"LuaType\")] arg2: (String, Type)) -> String; - "; - let trait_fn: TraitItemFn = syn::parse_str(function).unwrap(); - - FunctionAttributes::from_attributes(&trait_fn.attrs).unwrap(); - } -} diff --git a/crates/languages/bevy_mod_scripting_lua_derive/src/signature.rs b/crates/languages/bevy_mod_scripting_lua_derive/src/signature.rs deleted file mode 100644 index 05d48fb5..00000000 --- a/crates/languages/bevy_mod_scripting_lua_derive/src/signature.rs +++ /dev/null @@ -1,143 +0,0 @@ -use std::collections::HashMap; - -use bevy_mod_scripting_common::input::SimpleType; -use darling::FromAttributes; -use proc_macro2::{Ident, Span}; -use syn::{ - spanned::Spanned, token::Mut, Attribute, FnArg, Pat, PatIdent, PatType, Path, ReturnType, Type, - TypeTuple, -}; - -use crate::{ - arg::{Arg, ArgAttributes}, - PROXY_PREFIX, RAW_OUT_ALIAS, SELF_ALIAS, -}; - -/// Describes the functional signature of a function from the `functions[..]` list -#[derive(Debug)] -pub struct Signature { - pub inputs: Vec, - pub output: Arg, - pub span: Span, -} - -impl Signature { - /// Creates a new signature struct - /// if in_raw_function will set is_raw on all arguments and outputs to true - /// if is_field_setter, output_attrs will be applied to the third argument of the function if it exists (the first non self or ctxt arg) - pub fn new( - proxied_type_path: Path, - sig: syn::Signature, - in_raw_function: bool, - output_attrs: Vec, - ) -> darling::Result { - // convert output to FnArg - let output_arg_name = Ident::new(RAW_OUT_ALIAS, sig.output.span()); - let span = sig.span(); - // if no return type specified use `()` - let output_type = match sig.output { - ReturnType::Default => Type::Tuple(TypeTuple { - paren_token: Default::default(), - elems: Default::default(), - }), - ReturnType::Type(_, ty) => *ty, - }; - - let inputs = sig - .inputs - .into_iter() - .map(|arg| Self::convert_fn_arg(arg, &proxied_type_path, in_raw_function)) - .collect::>>()?; - - // convert to Arg structs - let output = Self::convert_type( - output_type, - &proxied_type_path, - in_raw_function, - output_attrs, - output_arg_name, - None, - )?; - - Ok(Self { - inputs, - output, - span, - }) - } - - /// Convert a function argument into custom Arg struct by converting the type to SimpleType and parsing attributes - fn convert_fn_arg( - arg: FnArg, - proxied_type_path: &Path, - in_raw_function: bool, - ) -> darling::Result { - let type_map = HashMap::from_iter([( - proxied_type_path.segments.last().unwrap().clone().ident, - None, - )]); - - Ok(match arg { - FnArg::Receiver(ref receiver) => { - let type_ = - SimpleType::new_from_fn_arg(PROXY_PREFIX, &arg, proxied_type_path, &type_map)?; - // let attrs = ArgAttributes::from_attributes(&receiver.attrs)?; - Arg::new( - // attrs, - Ident::new(SELF_ALIAS, receiver.span()), - receiver.mutability, - type_, - in_raw_function, - ) - } - FnArg::Typed(PatType { attrs, pat, ty, .. }) => { - let (mutability, arg_name) = match pat.as_ref() { - Pat::Ident(PatIdent { - mutability, ident, .. - }) => (mutability, ident), - _ => return Err(darling::Error::custom("Unsupported parameter pattern")), - }; - - Self::convert_type( - *ty, - proxied_type_path, - in_raw_function, - attrs, - arg_name.clone(), - *mutability, - )? - } - }) - } - - /// Convert a type corresponding to an argument into an Arg struct by converting it to a Simple type and parsing the given attributes - fn convert_type( - ty: Type, - proxied_type_path: &Path, - in_raw_function: bool, - attrs: Vec, - arg_name: Ident, - mutability: Option, - ) -> darling::Result { - let mut type_map = HashMap::from_iter([( - proxied_type_path.segments.last().unwrap().clone().ident, - None, - )]); - let is_proxy = attrs.iter().any(|a| a.path().is_ident("proxy")); - let attrs = ArgAttributes::from_attributes(&attrs)?; - let type_ = if is_proxy && attrs.map.is_empty() { - SimpleType::new_from_contextual_type_proxy_all(PROXY_PREFIX, &ty, proxied_type_path)? - } else { - type_map.extend(attrs.map.iter().map(|(a, b)| (a.clone(), Some(b.clone())))); - SimpleType::new_from_contextual_type(PROXY_PREFIX, &ty, proxied_type_path, &type_map)? - }; - - Ok(Arg::new( - // attrs, - arg_name, - mutability, - type_, - in_raw_function, - )) - } -} diff --git a/crates/languages/bevy_mod_scripting_lua_derive/src/visitor.rs b/crates/languages/bevy_mod_scripting_lua_derive/src/visitor.rs deleted file mode 100644 index 2dc8ec2b..00000000 --- a/crates/languages/bevy_mod_scripting_lua_derive/src/visitor.rs +++ /dev/null @@ -1,386 +0,0 @@ -/// This module contains both `SimpleType` and `syn::Type` visitors to help us with the code generation. -use bevy_mod_scripting_common::input::*; -use proc_macro2::Span; -use quote::*; -use syn::*; - -/// Generates an unwrapping expression which can be used to assign the unwrapped proxy to a variable. -/// the argument `#[proxy] arg: MyType` will generate the following expression: -/// ```rust,ignore -/// arg.inner()?; -/// ``` -pub(crate) struct LuaSimpleTypeArgumentUnwrapper { - arg_name: Ident, - span: Span, -} - -impl LuaSimpleTypeArgumentUnwrapper { - pub fn new(arg_name: Ident, span: Span) -> Self { - Self { arg_name, span } - } -} - -impl VisitSimpleType> for LuaSimpleTypeArgumentUnwrapper { - fn visit_unit(&mut self, _: bool) -> syn::Result { - Ok(quote_spanned!(self.span=> ())) - } - - fn visit_proxy_type( - &mut self, - _: &ProxyType, - is_child_of_reference: bool, - ) -> syn::Result { - let arg_name: &Ident = &self.arg_name; - - if is_child_of_reference { - Ok(quote_spanned!(self.span=> #arg_name)) - } else { - Ok(quote_spanned!(self.span=> #arg_name.inner()?)) - } - } - - fn visit_type(&mut self, _type: &Type, _: bool) -> syn::Result { - let arg_name: &Ident = &self.arg_name; - Ok(quote_spanned!(self.span=> #arg_name)) - } - - fn visit_unit_path( - &mut self, - unit_path: &UnitPath, - _: bool, - ) -> syn::Result { - match unit_path.std_type_ident { - Some(StdTypeIdent::Option) => { - let inner = self.visit_simple_type(&unit_path.inner, false)?; - let arg_name = &self.arg_name; - Ok(quote_spanned!(self.span=> - #arg_name.map(|#arg_name| Ok::<_,bevy_mod_scripting_lua::tealr::mlu::mlua::Error>(#inner)).transpose()? - )) - } - Some(StdTypeIdent::Vec) => { - let inner = self.visit_simple_type(&unit_path.inner, false)?; - let arg_name = &self.arg_name; - Ok(quote_spanned!(self.span=> - #arg_name.into_iter().map(|#arg_name| Ok(#inner)).collect::,bevy_mod_scripting_lua::tealr::mlu::mlua::Error>>()? - )) - } - Some(unsupported_std_type) => Err(syn::Error::new_spanned( - &unit_path.ident, - format!("`{}` is not yet supported", unsupported_std_type), - )), - _ => Err(syn::Error::new_spanned( - &unit_path.ident, - "Unsupported type", - )), - } - } -} - -/// `maps` a simple type recursively, expanding the type into a series of map/iter/etc calls where the leaf types are operating over -/// unwrapped proxied types (the inner types) and the output expression produces a wrapped proxy type. -/// -/// requires arg_name to be a valid identifier refering to the name of the variable containing a value with the SimpleType being mapped. -/// The returned token stream will be an expression. -pub(crate) struct LuaSimpleTypeWrapper { - arg_name: Ident, - span: Span, -} - -impl LuaSimpleTypeWrapper { - pub fn new(arg_name: Ident, span: Span) -> Self { - Self { arg_name, span } - } -} - -impl VisitSimpleType> for LuaSimpleTypeWrapper { - fn visit_unit_path( - &mut self, - unit_path: &UnitPath, - _: bool, - ) -> syn::Result { - match unit_path.std_type_ident { - Some(StdTypeIdent::Option) => { - let inner = self.visit_simple_type(&unit_path.inner, false)?; - let arg_name = &self.arg_name; - Ok(quote_spanned!(self.span=> - #arg_name.map(|mut #arg_name| #inner) - )) - } - Some(StdTypeIdent::Vec) => { - let inner = self.visit_simple_type(&unit_path.inner, false)?; - let arg_name = &self.arg_name; - - Ok(quote_spanned!(self.span=> - #arg_name.into_iter().map(|mut #arg_name| #inner).collect::>() - )) - } - Some(unsupported_std_type) => Err(syn::Error::new_spanned( - &unit_path.ident, - format!("`{}` is not yet supported", unsupported_std_type), - )), - _ => Err(syn::Error::new_spanned( - &unit_path.ident, - "Unsupported type", - )), - } - } - - fn visit_duo_path( - &mut self, - duo_path: &DuoPath, - _: bool, - ) -> syn::Result { - let tealr = quote!(bevy_mod_scripting_lua::tealr); - - match duo_path.std_type_ident { - Some(StdTypeIdent::Result) => { - let left = self.visit_simple_type(&duo_path.left, false)?; - let right = self.visit_simple_type(&duo_path.right, false)?; - let arg_name = &self.arg_name; - Ok(quote_spanned!(self.span=> - #arg_name.map(|mut #arg_name| #left).map_err(|#arg_name| #tealr::mlu::mlua::Error::external(#right)) - )) - } - Some(unsupported_std_type) => Err(syn::Error::new_spanned( - &duo_path.ident, - format!("`{}` is not yet supported", unsupported_std_type), - )), - _ => Err(syn::Error::new_spanned(&duo_path.ident, "Unsupported type")), - } - } - - fn visit_unit(&mut self, _: bool) -> syn::Result { - Ok(quote_spanned!(self.span=> - () - )) - } - - fn visit_proxy_type( - &mut self, - proxy_type: &ProxyType, - _: bool, - ) -> syn::Result { - let proxy_ident = &proxy_type.proxy_ident; - let arg_name = &self.arg_name; - Ok(quote_spanned! {self.span=> - #proxy_ident::new(#arg_name) - }) - } - - fn visit_type(&mut self, _type: &Type, _: bool) -> syn::Result { - Ok(self.arg_name.to_token_stream()) - } -} - -/// Wrapper around the `TypeConstructorVisitor` which generates a syn::Type from a `SimpleType`. -/// This is used to handle special cases such as when encountering an outer `Result` where E needs to specifically be converted to an `mlua::Error` on the proxy side -pub(crate) struct LuaTypeConstructorVisitor { - pub general_visitor: TypeConstructorVisitor, -} - -impl LuaTypeConstructorVisitor { - pub fn new(generate_proxy_type: bool, strip_outer_ref: bool) -> Self { - Self { - general_visitor: TypeConstructorVisitor::new(generate_proxy_type, strip_outer_ref), - } - } -} - -impl VisitSimpleType for LuaTypeConstructorVisitor { - fn visit_unit(&mut self, is_child_of_reference: bool) -> Type { - self.general_visitor.visit_unit(is_child_of_reference) - } - - fn visit_proxy_type(&mut self, proxy_type: &ProxyType, is_child_of_reference: bool) -> Type { - self.general_visitor - .visit_proxy_type(proxy_type, is_child_of_reference) - } - - fn visit_type(&mut self, _type: &Type, is_child_of_reference: bool) -> Type { - self.general_visitor - .visit_type(_type, is_child_of_reference) - } - - fn visit_unit_path(&mut self, unit_path: &UnitPath, is_child_of_reference: bool) -> Type { - self.general_visitor - .visit_unit_path(unit_path, is_child_of_reference) - } - - fn visit_duo_path(&mut self, duo_path: &DuoPath, is_child_of_reference: bool) -> Type { - // this will only trigger for top level types, the deeper nesting is handled by the general visitor - // outer Result needs to be converted to Result when converting to a proxy_type - let tealr = quote!(bevy_mod_scripting_lua::tealr); - - if duo_path - .std_type_ident - .is_some_and(|i| i == StdTypeIdent::Result) - && self.general_visitor.generate_proxy_type - { - let ident = &duo_path.ident; - let lt_token = duo_path.lt_token; - let gt_token = duo_path.gt_token; - let left = self.visit_simple_type(&duo_path.left, false); - parse_quote!(#ident #lt_token #left, #tealr::mlu::mlua::Error #gt_token) - } else { - self.general_visitor - .visit_duo_path(duo_path, is_child_of_reference) - } - } - - fn visit_reference( - &mut self, - reference: &bevy_mod_scripting_common::input::Reference, - is_child_of_reference: bool, - ) -> Type { - self.general_visitor - .visit_reference(reference, is_child_of_reference) - } -} - -#[cfg(test)] -mod test { - use std::collections::HashMap; - - use crate::visitor::LuaSimpleTypeArgumentUnwrapper; - - use super::LuaSimpleTypeWrapper; - use bevy_mod_scripting_common::input::{SimpleType, VisitSimpleType}; - use proc_macro2::Span; - use quote::*; - use syn::parse_quote; - - #[test] - pub fn test_lua_argument_wrapper_simple_proxy() { - let expected = quote_spanned!(Span::call_site()=> - LuaMyType::new(arg) - ); - - let mut visitor = LuaSimpleTypeWrapper::new(format_ident!("arg"), Span::call_site()); - - let output = visitor - .visit( - &SimpleType::new_from_fully_specified_type( - "Lua", - &parse_quote!(MyType), - &HashMap::from_iter([(format_ident!("MyType"), None)]), - ) - .unwrap(), - ) - .unwrap(); - - assert_eq!(output.to_string(), expected.to_string()) - } - - #[test] - pub fn test_lua_argument_wrapper_non_proxy() { - let expected = quote_spanned!(Span::call_site()=> - arg - ); - - let mut visitor = LuaSimpleTypeWrapper::new(format_ident!("arg"), Span::call_site()); - - let output = visitor - .visit( - &SimpleType::new_from_fully_specified_type( - "Lua", - &parse_quote!(MyType), - &HashMap::from_iter([]), - ) - .unwrap(), - ) - .unwrap(); - - assert_eq!(output.to_string(), expected.to_string()) - } - - #[test] - pub fn test_lua_argument_wrapper_vec() { - let expected = quote_spanned!(Span::call_site()=> - arg.into_iter().map(|mut arg| LuaMyType::new(arg)).collect::>() - ); - - let mut visitor = LuaSimpleTypeWrapper::new(format_ident!("arg"), Span::call_site()); - - let output = visitor - .visit( - &SimpleType::new_from_fully_specified_type( - "Lua", - &parse_quote!(Vec), - &HashMap::from_iter([(format_ident!("MyType"), None)]), - ) - .unwrap(), - ) - .unwrap(); - - assert_eq!(output.to_string(), expected.to_string()) - } - - #[test] - pub fn test_lua_argument_unwrapper_simple_proxy() { - let expected = quote_spanned!(Span::call_site()=> - arg.inner()? - ); - - let mut visitor = - LuaSimpleTypeArgumentUnwrapper::new(format_ident!("arg"), Span::call_site()); - - let output = visitor - .visit( - &SimpleType::new_from_fully_specified_type( - "Lua", - &parse_quote!(MyType), - &HashMap::from_iter([(format_ident!("MyType"), None)]), - ) - .unwrap(), - ) - .unwrap(); - - assert_eq!(output.to_string(), expected.to_string()) - } - - #[test] - pub fn test_lua_argument_unwrapper_non_proxy() { - let expected = quote_spanned!(Span::call_site()=> - arg - ); - - let mut visitor = - LuaSimpleTypeArgumentUnwrapper::new(format_ident!("arg"), Span::call_site()); - - let output = visitor - .visit( - &SimpleType::new_from_fully_specified_type( - "Lua", - &parse_quote!(MyType), - &HashMap::from_iter([]), - ) - .unwrap(), - ) - .unwrap(); - - assert_eq!(output.to_string(), expected.to_string()) - } - - #[test] - pub fn test_lua_argument_unwrapper_vec() { - let expected = quote_spanned!(Span::call_site()=> - arg.into_iter().map(|arg| Ok(arg.inner()?)).collect::, bevy_mod_scripting_lua::tealr::mlu::mlua::Error>>()? - ); - - let mut visitor = - LuaSimpleTypeArgumentUnwrapper::new(format_ident!("arg"), Span::call_site()); - - let output = visitor - .visit( - &SimpleType::new_from_fully_specified_type( - "Lua", - &parse_quote!(Vec), - &HashMap::from_iter([(format_ident!("MyType"), None)]), - ) - .unwrap(), - ) - .unwrap(); - - assert_eq!(output.to_string(), expected.to_string()) - } -} diff --git a/crates/languages/bevy_mod_scripting_rhai/Cargo.toml b/crates/languages/bevy_mod_scripting_rhai/Cargo.toml index c3965c97..f545257c 100644 --- a/crates/languages/bevy_mod_scripting_rhai/Cargo.toml +++ b/crates/languages/bevy_mod_scripting_rhai/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bevy_mod_scripting_rhai" -version = "0.8.0" +version = "0.9.0-alpha.1" authors = ["Maksymilian Mozolewski "] edition = "2021" license = "MIT OR Apache-2.0" @@ -17,6 +17,5 @@ path = "src/lib.rs" [dependencies] bevy = { workspace = true, default-features = false } -rhai = { version = "1.16", features = ["sync"] } -bevy_mod_scripting_core = { workspace = true } -anyhow = "1.0.75" +rhai = { workspace = true, features = ["sync"] } +bevy_mod_scripting_core = { workspace = true, features = ["rhai_impls"] } diff --git a/crates/languages/bevy_mod_scripting_rhai/src/assets.rs b/crates/languages/bevy_mod_scripting_rhai/src/assets.rs deleted file mode 100644 index 36b92498..00000000 --- a/crates/languages/bevy_mod_scripting_rhai/src/assets.rs +++ /dev/null @@ -1,42 +0,0 @@ -use bevy::{ - asset::{io::Reader, Asset, AssetLoader, LoadContext}, - reflect::TypePath, -}; - -use bevy_mod_scripting_core::prelude::*; - -#[derive(Asset, Debug, TypePath)] -/// A rhai code file in bytes -pub struct RhaiFile { - pub bytes: Vec, -} - -impl CodeAsset for RhaiFile { - fn bytes(&self) -> &[u8] { - self.bytes.as_slice() - } -} - -#[derive(Default)] -/// Asset loader for lua scripts -pub struct RhaiLoader; - -impl AssetLoader for RhaiLoader { - type Asset = RhaiFile; - type Settings = (); - type Error = anyhow::Error; - async fn load( - &self, - reader: &mut dyn Reader, - _: &Self::Settings, - _: &mut LoadContext<'_>, - ) -> Result { - let mut bytes = Vec::new(); - reader.read_to_end(&mut bytes).await?; - Ok(RhaiFile { bytes }) - } - - fn extensions(&self) -> &[&str] { - &["rhai"] - } -} diff --git a/crates/languages/bevy_mod_scripting_rhai/src/docs.rs b/crates/languages/bevy_mod_scripting_rhai/src/docs.rs deleted file mode 100644 index 6fd312fe..00000000 --- a/crates/languages/bevy_mod_scripting_rhai/src/docs.rs +++ /dev/null @@ -1,17 +0,0 @@ -use bevy_mod_scripting_core::prelude::*; - -pub struct RhaiDocFragment; - -impl DocFragment for RhaiDocFragment { - fn merge(self, _o: Self) -> Self { - todo!() - } - - fn gen_docs(self) -> Result<(), ScriptError> { - todo!() - } - - fn name(&self) -> &'static str { - todo!() - } -} diff --git a/crates/languages/bevy_mod_scripting_rhai/src/lib.rs b/crates/languages/bevy_mod_scripting_rhai/src/lib.rs index cbb0eb16..e507c4aa 100644 --- a/crates/languages/bevy_mod_scripting_rhai/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_rhai/src/lib.rs @@ -1,202 +1,156 @@ -use crate::{ - assets::{RhaiFile, RhaiLoader}, - docs::RhaiDocFragment, +use bevy::{ + app::Plugin, + ecs::{entity::Entity, world::World}, }; -use bevy::{ecs::schedule::ScheduleLabel, prelude::*}; -use bevy_mod_scripting_core::{prelude::*, systems::*, world::WorldPointerGuard}; -use rhai::*; -use std::marker::PhantomData; +use bevy_mod_scripting_core::{ + bindings::{script_value::ScriptValue, WorldCallbackAccess}, + context::{ContextBuilder, ContextInitializer, ContextPreHandlingInitializer}, + error::ScriptError, + event::CallbackLabel, + script::ScriptId, + IntoScriptPluginParams, ScriptingPlugin, +}; +use rhai::{CallFnOptions, Engine, FnPtr, Scope, AST}; -pub mod assets; -pub mod docs; pub use rhai; -pub mod prelude { - pub use crate::{ - assets::{RhaiFile, RhaiLoader}, - docs::RhaiDocFragment, - RhaiContext, RhaiEvent, RhaiScriptHost, - }; - pub use rhai; - pub use rhai::{Engine, FuncArgs}; + +pub type RhaiRuntime = Engine; + +pub struct RhaiScriptContext { + pub ast: AST, + pub scope: Scope<'static>, +} + +impl IntoScriptPluginParams for RhaiScriptingPlugin { + type C = RhaiScriptContext; + type R = RhaiRuntime; } -#[derive(Resource)] -pub struct RhaiScriptHost { - pub engine: Engine, - _ph: PhantomData, +pub struct RhaiScriptingPlugin { + pub scripting_plugin: ScriptingPlugin, } -#[allow(deprecated)] -impl Default for RhaiScriptHost { +impl Default for RhaiScriptingPlugin { fn default() -> Self { - let mut e = Engine::new(); - // prevent shadowing of `state`,`world` and `entity` in variable in scripts - e.on_def_var(|_, info, _| { - Ok(info.name() != "state" && info.name() != "world" && info.name() != "entity") - }); - - Self { - engine: e, - _ph: Default::default(), + RhaiScriptingPlugin { + scripting_plugin: ScriptingPlugin { + runtime_builder: RhaiRuntime::new, + runtime_settings: None, + callback_handler: Some(rhai_callback_handler), + context_assigner: None, + context_builder: Some(ContextBuilder { + load: rhai_context_load, + reload: rhai_context_reload, + }), + }, } } } -pub struct RhaiContext { - pub ast: AST, - pub scope: Scope<'static>, +impl Plugin for RhaiScriptingPlugin { + fn build(&self, app: &mut bevy::prelude::App) { + self.scripting_plugin.build(app); + } } -#[derive(Clone, Event)] -/// A Rhai Hook. The result of creating this event will be -/// a call to the lua script with the hook_name and the given arguments -pub struct RhaiEvent { - pub hook_name: String, - pub args: A, - pub recipients: Recipients, +pub fn rhai_context_load( + script: &ScriptId, + content: &[u8], + initializers: &[ContextInitializer], + pre_handling_initializers: &[ContextPreHandlingInitializer], + world: &mut World, + runtime: &mut RhaiRuntime, +) -> Result { + let mut ast = runtime.compile(std::str::from_utf8(content)?)?; + ast.set_source(script.to_string()); + + let mut context = RhaiScriptContext { + ast, + scope: Scope::new(), + }; + with_world(world, &mut context, |context| { + initializers + .iter() + .try_for_each(|init| init(script, context))?; + + pre_handling_initializers + .iter() + .try_for_each(|init| init(script, Entity::from_raw(0), context))?; + + runtime.eval_ast_with_scope(&mut context.scope, &context.ast)?; + // do not invoke top level statements after the first time we run the script + context.ast.clear_statements(); + + Ok(()) + })?; + Ok(context) } -impl ScriptEvent for RhaiEvent { - fn recipients(&self) -> &crate::Recipients { - &self.recipients - } +pub fn rhai_context_reload( + script: &ScriptId, + content: &[u8], + context: &mut RhaiScriptContext, + initializers: &[ContextInitializer], + pre_handling_initializers: &[ContextPreHandlingInitializer], + world: &mut World, + runtime: &mut RhaiRuntime, +) -> Result<(), ScriptError> { + *context = rhai_context_load( + script, + content, + initializers, + pre_handling_initializers, + world, + runtime, + )?; + Ok(()) } -impl ScriptHost for RhaiScriptHost { - type ScriptContext = RhaiContext; - type ScriptEvent = RhaiEvent; - type ScriptAsset = RhaiFile; - type APITarget = Engine; - type DocTarget = RhaiDocFragment; - - fn register_with_app_in_set( - app: &mut bevy::prelude::App, - schedule: impl ScheduleLabel, - set: impl SystemSet, - ) { - app.add_priority_event::() - .init_asset::() - .init_asset_loader::() - .init_resource::>() - .init_resource::>() - .init_resource::>() - .register_type::>() - .register_type::>() - .register_type::>() - .add_systems( - schedule, - ( - script_add_synchronizer::, - script_remove_synchronizer::, - script_hot_reload_handler::, - ) - .chain() - .in_set(set), - ) - // setup engine - .add_systems( - Startup, - |mut providers: ResMut>, mut host: ResMut| { - providers - .attach_all(&mut host.engine) - .expect("Error in adding api's for rhai"); - }, - ); - } - - fn setup_script( - &mut self, - script_data: &ScriptData, - ctx: &mut Self::ScriptContext, - providers: &mut APIProviders, - ) -> Result<(), ScriptError> { - providers.setup_all(script_data, ctx) - } - - fn load_script( - &mut self, - script: &[u8], - script_data: &ScriptData, - _: &mut APIProviders, - ) -> Result { - let mut scope = Scope::new(); - let mut ast = self - .engine - .compile( - std::str::from_utf8(script).map_err(|e| ScriptError::FailedToLoad { - script: script_data.name.to_owned(), - msg: e.to_string(), - })?, - ) - .map_err(|e| ScriptError::SyntaxError { - script: script_data.name.to_owned(), - msg: e.to_string(), - })?; - - ast.set_source(script_data.name); - - // persistent state for scripts - scope.push("state", Map::new()); - - Ok(RhaiContext { ast, scope }) - } +#[allow(clippy::too_many_arguments)] +pub fn rhai_callback_handler( + args: Vec, + entity: Entity, + script_id: &ScriptId, + callback: &CallbackLabel, + context: &mut RhaiScriptContext, + pre_handling_initializers: &[ContextPreHandlingInitializer], + runtime: &mut RhaiRuntime, + world: &mut World, +) -> Result<(), ScriptError> { + with_world(world, context, |context| { + pre_handling_initializers + .iter() + .try_for_each(|init| init(script_id, entity, context))?; + + if context + .scope + .get_value::(callback.as_ref()) + .is_none() + { + // not subscribed to this handler + return Ok(()); + }; + + // we want the call to be able to impact the scope + let options = CallFnOptions::new().rewind_scope(false); + runtime.call_fn_with_options( + options, + &mut context.scope, + &context.ast, + callback.as_ref(), + args, + )?; + Ok(()) + }) +} - fn handle_events<'a>( - &mut self, - world: &mut World, - events: &[Self::ScriptEvent], - ctxs: impl Iterator, &'a mut Self::ScriptContext)>, - providers: &mut APIProviders, - ) { - // safety: - // - we have &mut World access - // - we do not use the original reference again anywhere in this function - let world = unsafe { WorldPointerGuard::new(world) }; - - ctxs.for_each(|(fd, ctx)| { - providers - .setup_runtime_all(world.clone(), &fd, ctx) - .expect("Failed to setup script runtime"); - - for event in events.iter() { - // check if this script should handle this event - if !event.recipients().is_recipient(&fd) { - continue; - }; - - match self.engine.call_fn( - &mut ctx.scope, - &ctx.ast, - &event.hook_name, - event.args.clone(), - ) { - Ok(v) => v, - Err(e) => { - let mut world = world.write(); - let mut state: CachedScriptState = world.remove_resource().unwrap(); - - match *e { - EvalAltResult::ErrorFunctionNotFound(..) => {} - _ => { - let (_, mut error_wrt, _) = state.event_state.get_mut(&mut world); - - let error = ScriptError::RuntimeError { - script: fd.name.to_string(), - msg: e.to_string(), - }; - error!("{}", error); - error_wrt.send(ScriptErrorEvent { error }); - } - } - - world.insert_resource(state); - } - }; - } - - // executing this at the end here means we execute global statements exactly once - // all this method call does is set a variable on the AST to NONE so should not affect performance - ctx.ast.clear_statements(); - }); - } +pub fn with_world Result<(), ScriptError>>( + world: &mut World, + context: &mut RhaiScriptContext, + f: F, +) -> Result<(), ScriptError> { + WorldCallbackAccess::with_callback_access(world, |guard| { + context.scope.push("world", guard.clone()); + f(context) + }) } diff --git a/crates/languages/bevy_mod_scripting_rhai_derive/CHANGELOG.md b/crates/languages/bevy_mod_scripting_rhai_derive/CHANGELOG.md deleted file mode 100644 index 7efd6cc7..00000000 --- a/crates/languages/bevy_mod_scripting_rhai_derive/CHANGELOG.md +++ /dev/null @@ -1,14 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -## [0.7.0](https://github.com/makspll/bevy_mod_scripting/compare/bevy_mod_scripting_rhai_derive-v0.6.0...bevy_mod_scripting_rhai_derive-v0.7.0) - 2024-11-03 - -### Other - -- update metadata diff --git a/crates/languages/bevy_mod_scripting_rhai_derive/Cargo.toml b/crates/languages/bevy_mod_scripting_rhai_derive/Cargo.toml deleted file mode 100644 index 8ffd9d2d..00000000 --- a/crates/languages/bevy_mod_scripting_rhai_derive/Cargo.toml +++ /dev/null @@ -1,29 +0,0 @@ -[package] -name = "bevy_mod_scripting_rhai_derive" -version = "0.8.0" -authors = ["Maksymilian Mozolewski "] -edition = "2021" -license = "MIT OR Apache-2.0" -description = "Necessary functionality for Rhai support with bevy_mod_scripting" -repository = "https://github.com/makspll/bevy_mod_scripting" -homepage = "https://github.com/makspll/bevy_mod_scripting" -keywords = ["bevy", "gamedev", "scripting", "rhai"] -categories = ["game-development"] -readme = "readme.md" - -[lib] -name = "bevy_mod_scripting_rhai_derive" -path = "src/lib.rs" -proc-macro = true - -[dependencies] -bevy_mod_scripting_common = { path = "../../bevy_mod_scripting_common", version = "0.8.0" } -paste = "1.0.7" -syn = { version = "1.0.57", features = ["full", "fold", "extra-traits"] } -quote = "1.0.8" -proc-macro2 = "1.0" -convert_case = "0.5.0" -rustdoc-types = "0.11.0" -serde = { version = "1.0", features = ["derive"] } -serde_derive = "1.0.137" -indexmap = { version = "1.9.1", features = ["serde"] } diff --git a/crates/languages/bevy_mod_scripting_rhai_derive/readme.md b/crates/languages/bevy_mod_scripting_rhai_derive/readme.md deleted file mode 100644 index e058ed4f..00000000 --- a/crates/languages/bevy_mod_scripting_rhai_derive/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -# bevy_mod_scripting_lua_derive - -This crate is a part of the ["bevy_mod_scripting" workspace](https://github.com/makspll/bevy_mod_scripting). \ No newline at end of file diff --git a/crates/languages/bevy_mod_scripting_rhai_derive/src/lib.rs b/crates/languages/bevy_mod_scripting_rhai_derive/src/lib.rs deleted file mode 100644 index 4feb6fce..00000000 --- a/crates/languages/bevy_mod_scripting_rhai_derive/src/lib.rs +++ /dev/null @@ -1,13 +0,0 @@ -use proc_macro::TokenStream; - -#[proc_macro] -pub fn impl_lua_newtype(tokens: TokenStream) -> TokenStream { - // let newtype = parse_macro_input!(tokens as Newtype); - - // implementor - // .generate(newtype) - // .map_err(|e| e.to_compile_error()) - // .unwrap_or_else(core::convert::identity) - // .into() - tokens -} diff --git a/crates/languages/bevy_mod_scripting_rune/Cargo.toml b/crates/languages/bevy_mod_scripting_rune/Cargo.toml index b24a7c18..c929657b 100644 --- a/crates/languages/bevy_mod_scripting_rune/Cargo.toml +++ b/crates/languages/bevy_mod_scripting_rune/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bevy_mod_scripting_rune" -version = "0.8.0" +version = "0.9.0-alpha.1" edition = "2021" license = "MIT OR Apache-2.0" description = "Necessary functionality for Rune support with bevy_mod_scripting" diff --git a/crates/languages/bevy_mod_scripting_rune/src/lib.rs b/crates/languages/bevy_mod_scripting_rune/src/lib.rs index 4c7dc065..86030878 100644 --- a/crates/languages/bevy_mod_scripting_rune/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_rune/src/lib.rs @@ -1,271 +1,298 @@ -use std::{marker::PhantomData, sync::Arc}; +use std::sync::Arc; -use bevy::prelude::*; -use bevy_mod_scripting_core::{ - prelude::*, - systems::{self, CachedScriptState}, - world::{WorldPointer, WorldPointerGuard}, -}; -use prelude::{RuneDocFragment, RuneFile, RuneLoader}; +use bevy_mod_scripting_core::{IntoScriptPluginParams, ScriptingPlugin}; use rune::{ - runtime::{Args, RuntimeContext, VmError, VmResult}, - Context, Diagnostics, Source, Sources, Unit, Vm, + runtime::{Args, RuntimeContext}, + Unit, Vm, }; -mod assets; -mod docs; - -pub mod prelude { - pub use crate::{ - assets::{RuneFile, RuneLoader}, - docs::RuneDocFragment, - RuneArgs, RuneEvent, RuneScriptContext, RuneScriptHost, - }; - pub use rune::{self, runtime::Args, Context}; -} - -/// Super trait adding additional bounds to Rune's `Args` trait. -/// It's gets automatically implemented for any type that implments `Args`, -/// so you should never have to manually implement it. -pub trait RuneArgs: Args + Clone + Send + Sync + 'static {} - -impl RuneArgs for T {} - -/// A Rune script hook. -#[derive(Debug, Clone, Event)] -pub struct RuneEvent { - /// The name of the Rune function to call. - pub hook_name: String, - /// The arguments to supply the function being invoked. If you - /// don't need any arguments, `()` is a good default value. - pub args: A, - /// The target set of scripts that should handle this event. - pub recipients: Recipients, -} - -impl ScriptEvent for RuneEvent { - fn recipients(&self) -> &Recipients { - &self.recipients - } -} +pub trait RuneEventArg: Args + Clone + Send + Sync + 'static {} +impl RuneEventArg for T {} -/// A cached Rune Vm used to execute units. -struct RuneVm(Vm); - -impl Default for RuneVm { - fn default() -> Self { - Self(Vm::new( - Arc::new(RuntimeContext::default()), - Arc::new(Unit::default()), - )) - } -} - -/// Script context for a rune script. pub struct RuneScriptContext { pub unit: Arc, pub runtime_context: Arc, } -#[derive(Resource)] -/// Rune script host. Enables Rune scripting. -pub struct RuneScriptHost { - _ph: PhantomData, -} +pub type RuneRuntime = Vm; -impl Default for RuneScriptHost { - fn default() -> Self { - Self { - _ph: Default::default(), - } - } +impl IntoScriptPluginParams for RuneScriptingPlugin { + type C = RuneScriptContext; + type R = RuneRuntime; } -impl RuneScriptHost { - /// Helper function to handle errors from a Rune virtual machine. - /// - #[cold] - fn handle_rune_error(world: WorldPointer, error: VmError, script_data: &ScriptData<'_>) { - let mut world = world.write(); - let mut state: CachedScriptState = world.remove_resource().unwrap(); - - let (_, mut error_wrt, _) = state.event_state.get_mut(&mut world); - - let error = ScriptError::RuntimeError { - script: script_data.name.to_owned(), - msg: error.to_string(), - }; - - error!("{}", error); - - error_wrt.send(ScriptErrorEvent { error }); - world.insert_resource(state); - } +pub struct RuneScriptingPlugin { + pub scripting_plugin: ScriptingPlugin, } -impl ScriptHost for RuneScriptHost { - type ScriptContext = RuneScriptContext; - - type ScriptEvent = RuneEvent; - - type ScriptAsset = RuneFile; - - type APITarget = Context; - - type DocTarget = RuneDocFragment; - - fn register_with_app_in_set( - app: &mut App, - schedule: impl bevy::ecs::schedule::ScheduleLabel, - set: impl SystemSet, - ) { - app.add_priority_event::() - .init_asset::() - .init_asset_loader::() - .init_resource::>() - .init_resource::>() - .init_resource::>() - .register_type::>() - .register_type::>() - .register_type::>() - // Add a cached Vm as a non-send resource. - .insert_non_send_resource(RuneVm::default()) - // handle script insertions removal first - // then update their contexts later on script asset changes - .add_systems( - schedule, - ( - systems::script_add_synchronizer::, - systems::script_remove_synchronizer::, - systems::script_hot_reload_handler::, - ) - .chain() - .in_set(set), - ); - } - - fn load_script( - &mut self, - script: &[u8], - script_data: &ScriptData, - providers: &mut APIProviders, - ) -> Result { - let mut context = rune_modules::default_context().map_err(ScriptError::new_other)?; - - // Rune requires that we tell it what modules and types we'll be using before - // it compiles a file. - providers.attach_all(&mut context).unwrap(); - - let mut diagnostics = Diagnostics::new(); - - let mut sources = Sources::new(); - sources - .insert( - Source::new( - script_data.name, - std::str::from_utf8(script).expect("Slice is not UTF-8"), - ) - .map_err(|msg| ScriptError::FailedToLoad { - script: script_data.name.into(), - msg: msg.to_string(), - })?, - ) - .map_err(|msg| ScriptError::FailedToLoad { - script: script_data.name.into(), - msg: msg.to_string(), - })?; - - let result = rune::prepare(&mut sources) - .with_context(&context) - .with_diagnostics(&mut diagnostics) - .build(); - - if !diagnostics.is_empty() { - let mut writer = rune::termcolor::Buffer::no_color(); - - diagnostics - .emit(&mut writer, &sources) - .expect("Failed to write diagnostics to buffer"); - - return Err(ScriptError::SyntaxError { - script: script_data.name.into(), - msg: std::str::from_utf8(writer.as_slice()) - .expect("Slice was not UTF-8") - .to_owned(), - }); - } - - let unit = result.expect("Failed to build Rune unit."); - - let runtime_ctx = context - .runtime() - .expect("Failed to create Rune runtime context."); - - Ok(RuneScriptContext { - unit: Arc::new(unit), - runtime_context: Arc::new(runtime_ctx), - }) - } - - fn setup_script( - &mut self, - script_data: &ScriptData, - ctx: &mut Self::ScriptContext, - providers: &mut APIProviders, - ) -> Result<(), ScriptError> { - providers.setup_all(script_data, ctx) - } - - fn handle_events<'a>( - &mut self, - world: &mut World, - events: &[Self::ScriptEvent], - ctxs: impl Iterator, &'a mut Self::ScriptContext)>, - providers: &mut APIProviders, - ) { - // Grab the cached Vm. - let RuneVm(mut vm) = world.remove_non_send_resource::().unwrap(/* invariant */); - - { - // Safety: - // - we have &mut World access - // - we do not use the original reference again anywhere in this block. - // - the guard is dropped at the end of this block. - let world = unsafe { WorldPointerGuard::new(world) }; - - ctxs.for_each(|(script_data, ctx)| { - providers - .setup_runtime_all(world.clone(), &script_data, ctx) - .expect("Could not setup script runtime"); - - for event in events { - if !event.recipients().is_recipient(&script_data) { - continue; - } - - // Swap out the old context and old unit with the new ones. - *vm.context_mut() = Arc::clone(&ctx.runtime_context); - *vm.unit_mut() = Arc::clone(&ctx.unit); - - let mut exec = match vm.execute([event.hook_name.as_str()], event.args.clone()) - { - Ok(exec) => exec, - Err(error) => { - Self::handle_rune_error(world.clone(), error, &script_data); - continue; - } - }; - - if let VmResult::Err(error) = exec.complete() { - Self::handle_rune_error(world.clone(), error, &script_data); - } - } - }); - - // explictly release the pointer to world. - drop(world); - } - - world.insert_non_send_resource(RuneVm(vm)); +impl Default for RuneScriptingPlugin { + fn default() -> Self { + todo!() + // Self { + // scripting_plugin: ScriptingPlugin { + // runtime_builder: todo!(), + // runtime_settings: todo!(), + // callback_handler: todo!(), + // context_builder: todo!(), + // context_assigner: todo!(), + // }, + // } } } + +// use std::{marker::PhantomData, sync::Arc}; + +// use bevy::prelude::*; +// use bevy_mod_scripting_core::{ +// prelude::*, +// systems::{self, CachedScriptState}, +// }; +// use prelude::{RuneDocFragment, RuneFile, RuneLoader}; +// use rune::{ +// runtime::{Args, RuntimeContext, VmError, VmResult}, +// Context, Diagnostics, Source, Sources, Unit, Vm, +// }; + +// mod assets; +// mod docs; + +// pub mod prelude { +// pub use crate::{ +// assets::{RuneFile, RuneLoader}, +// docs::RuneDocFragment, +// RuneArgs, RuneEvent, RuneScriptContext, RuneScriptHost, +// }; +// pub use rune::{self, runtime::Args, Context}; +// } + +// /// Super trait adding additional bounds to Rune's `Args` trait. +// /// It's gets automatically implemented for any type that implments `Args`, +// /// so you should never have to manually implement it. +// pub trait RuneArgs: Args + Clone + Send + Sync + 'static {} + +// impl RuneArgs for T {} + +// /// A Rune script hook. +// #[derive(Debug, Clone, Event)] +// pub struct RuneEvent { +// /// The name of the Rune function to call. +// pub hook_name: String, +// /// The arguments to supply the function being invoked. If you +// /// don't need any arguments, `()` is a good default value. +// pub args: A, +// /// The target set of scripts that should handle this event. +// pub recipients: Recipients, +// } + +// impl ScriptEvent for RuneEvent { +// fn recipients(&self) -> &Recipients { +// &self.recipients +// } +// } + +// /// A cached Rune Vm used to execute units. +// struct RuneVm(Vm); + +// impl Default for RuneVm { +// fn default() -> Self { +// Self(Vm::new( +// Arc::new(RuntimeContext::default()), +// Arc::new(Unit::default()), +// )) +// } +// } + +// /// Script context for a rune script. +// pub struct RuneScriptContext { +// pub unit: Arc, +// pub runtime_context: Arc, +// } + +// #[derive(Resource)] +// /// Rune script host. Enables Rune scripting. +// pub struct RuneScriptHost { +// _ph: PhantomData, +// } + +// impl Default for RuneScriptHost { +// fn default() -> Self { +// Self { +// _ph: Default::default(), +// } +// } +// } + +// impl RuneScriptHost { +// /// Helper function to handle errors from a Rune virtual machine. +// /// +// #[cold] +// fn handle_rune_error(world: &mut World, error: VmError, script_data: &ScriptData<'_>) { +// let mut state: CachedScriptState = world.remove_resource().unwrap(); + +// let (_, mut error_wrt, _) = state.event_state.get_mut(world); + +// let error = ScriptError::RuntimeError { +// script: script_data.name.to_owned(), +// msg: error.to_string(), +// }; + +// error!("{}", error); + +// error_wrt.send(ScriptErrorEvent { error }); +// world.insert_resource(state); +// } +// } + +// impl ScriptHost for RuneScriptHost { +// type ScriptContext = RuneScriptContext; + +// type ScriptEvent = RuneEvent; + +// type ScriptAsset = RuneFile; + +// type APITarget = Context; + +// type DocTarget = RuneDocFragment; + +// fn register_with_app_in_set( +// app: &mut App, +// schedule: impl bevy::ecs::schedule::ScheduleLabel, +// set: impl SystemSet, +// ) { +// app.add_priority_event::() +// .init_asset::() +// .init_asset_loader::() +// .init_resource::>() +// .init_resource::>() +// .init_resource::>() +// .register_type::>() +// .register_type::>() +// .register_type::>() +// // Add a cached Vm as a non-send resource. +// .insert_non_send_resource(RuneVm::default()) +// // handle script insertions removal first +// // then update their contexts later on script asset changes +// .add_systems( +// schedule, +// ( +// systems::script_add_synchronizer::, +// systems::script_remove_synchronizer::, +// systems::script_hot_reload_handler::, +// ) +// .chain() +// .in_set(set), +// ); +// } + +// fn load_script( +// &mut self, +// script: &[u8], +// script_data: &ScriptData, +// providers: &mut APIProviders, +// ) -> Result { +// let mut context = rune_modules::default_context().map_err(ScriptError::new_other)?; + +// // Rune requires that we tell it what modules and types we'll be using before +// // it compiles a file. +// providers.attach_all(&mut context).unwrap(); + +// let mut diagnostics = Diagnostics::new(); + +// let mut sources = Sources::new(); +// sources +// .insert( +// Source::new( +// script_data.name, +// std::str::from_utf8(script).expect("Slice is not UTF-8"), +// ) +// .map_err(|msg| ScriptError::FailedToLoad { +// script: script_data.name.into(), +// msg: msg.to_string(), +// })?, +// ) +// .map_err(|msg| ScriptError::FailedToLoad { +// script: script_data.name.into(), +// msg: msg.to_string(), +// })?; + +// let result = rune::prepare(&mut sources) +// .with_context(&context) +// .with_diagnostics(&mut diagnostics) +// .build(); + +// if !diagnostics.is_empty() { +// let mut writer = rune::termcolor::Buffer::no_color(); + +// diagnostics +// .emit(&mut writer, &sources) +// .expect("Failed to write diagnostics to buffer"); + +// return Err(ScriptError::SyntaxError { +// script: script_data.name.into(), +// msg: std::str::from_utf8(writer.as_slice()) +// .expect("Slice was not UTF-8") +// .to_owned(), +// }); +// } + +// let unit = result.expect("Failed to build Rune unit."); + +// let runtime_ctx = context +// .runtime() +// .expect("Failed to create Rune runtime context."); + +// Ok(RuneScriptContext { +// unit: Arc::new(unit), +// runtime_context: Arc::new(runtime_ctx), +// }) +// } + +// fn setup_script( +// &mut self, +// script_data: &ScriptData, +// ctx: &mut Self::ScriptContext, +// providers: &mut APIProviders, +// ) -> Result<(), ScriptError> { +// providers.setup_all(script_data, ctx) +// } + +// fn handle_events<'a>( +// &mut self, +// world: &mut World, +// events: &[Self::ScriptEvent], +// ctxs: impl Iterator, &'a mut Self::ScriptContext)>, +// _providers: &mut APIProviders, +// ) { +// // Grab the cached Vm. +// let RuneVm(mut vm) = world.remove_non_send_resource::().unwrap(/* invariant */); + +// { +// ctxs.for_each(|(script_data, ctx)| { +// for event in events { +// if !event.recipients().is_recipient(&script_data) { +// continue; +// } + +// // Swap out the old context and old unit with the new ones. +// *vm.context_mut() = Arc::clone(&ctx.runtime_context); +// *vm.unit_mut() = Arc::clone(&ctx.unit); + +// let mut exec = match vm.execute([event.hook_name.as_str()], event.args.clone()) +// { +// Ok(exec) => exec, +// Err(error) => { +// Self::handle_rune_error(world, error, &script_data); +// continue; +// } +// }; + +// if let VmResult::Err(error) = exec.complete() { +// Self::handle_rune_error(world, error, &script_data); +// } +// } +// }); +// } + +// world.insert_non_send_resource(RuneVm(vm)); +// } +// } diff --git a/crates/macro_tests/Cargo.toml b/crates/macro_tests/Cargo.toml deleted file mode 100644 index d8b651d3..00000000 --- a/crates/macro_tests/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "macro_tests" -version = "0.1.0" -edition = "2021" -private = true - -[profile.ephemeral-build] -inherits = "dev" -opt-level = 2 -codegen-units = 8 -incremental = false -debug = false - -[dependencies] - -[dev-dependencies] -trybuild = "1.0" -bevy = { version = "0.15.0", default-features = false } -bevy_mod_scripting = { path = "../../", features = [ - "lua", - "lua_script_api", - "lua54", -] } -bevy_script_api = { path = "../bevy_script_api" } -bevy_mod_scripting_lua = { path = "../languages/bevy_mod_scripting_lua" } -bevy_mod_scripting_core = { path = "../bevy_mod_scripting_core" } diff --git a/crates/macro_tests/tests/fail/references/non-proxy-reference.rs b/crates/macro_tests/tests/fail/references/non-proxy-reference.rs deleted file mode 100644 index 1989c51e..00000000 --- a/crates/macro_tests/tests/fail/references/non-proxy-reference.rs +++ /dev/null @@ -1,21 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="Function")] - fn fn_returning_some_string(some_str: &str) -> String; - "#, -])] -pub struct MyStruct { - some_string: String, - me_vec: Vec, -} -impl MyStruct { - pub fn fn_returning_some_string(some_str: &str) -> String { - some_str.to_owned() - } -} - -pub fn main() {} diff --git a/crates/macro_tests/tests/fail/references/non-proxy-reference.stderr b/crates/macro_tests/tests/fail/references/non-proxy-reference.stderr deleted file mode 100644 index ecb3063b..00000000 --- a/crates/macro_tests/tests/fail/references/non-proxy-reference.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0277]: the trait bound `&str: FromLuaMulti<'lua>` is not satisfied - --> tests/fail/references/non-proxy-reference.rs:4:10 - | -4 | #[derive(LuaProxy, Reflect, Clone)] - | ^^^^^^^^ the trait `FromLua<'_>` is not implemented for `&str`, which is required by `&str: FromLuaMulti<'lua>` - | - = help: the trait `FromLua<'_>` is implemented for `std::string::String` - = help: for that trait implementation, expected `std::string::String`, found `&str` - = note: required for `&str` to implement `FromLuaMulti<'lua>` -note: required by a bound in `bevy_mod_scripting_lua::tealr::mlu::TealDataMethods::add_function` - --> $CARGO/tealr-0.9.1/src/mlu/teal_data_methods.rs - | - | fn add_function(&mut self, name: &S, function: F) - | ------------ required by a bound in this associated function -... - | A: FromLuaMulti<'lua> + TealMultiValue, - | ^^^^^^^^^^^^^^^^^^ required by this bound in `TealDataMethods::add_function` - = note: this error originates in the derive macro `LuaProxy` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/macro_tests/tests/fail/references/output-with-proxy-reference.rs b/crates/macro_tests/tests/fail/references/output-with-proxy-reference.rs deleted file mode 100644 index 8cb4cd7f..00000000 --- a/crates/macro_tests/tests/fail/references/output-with-proxy-reference.rs +++ /dev/null @@ -1,15 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="Function", output(proxy))] - fn fn_returning_some_string(ref_: &Self ) -> &Self { - ref_ - } - "#, -])] -pub struct MyStruct; - -pub fn main() {} diff --git a/crates/macro_tests/tests/fail/references/output-with-proxy-reference.stderr b/crates/macro_tests/tests/fail/references/output-with-proxy-reference.stderr deleted file mode 100644 index 7095c444..00000000 --- a/crates/macro_tests/tests/fail/references/output-with-proxy-reference.stderr +++ /dev/null @@ -1,63 +0,0 @@ -error[E0308]: mismatched types - --> tests/fail/references/output-with-proxy-reference.rs:4:10 - | -4 | #[derive(LuaProxy, Reflect, Clone)] - | ^^^^^^^^ - | | - | expected `MyStruct`, found `&MyStruct` - | arguments to this function are incorrect - | -note: associated function defined here - --> tests/fail/references/output-with-proxy-reference.rs:5:1 - | -5 | #[proxy(functions[ - | ^ - = note: this error originates in the derive macro `LuaProxy` which comes from the expansion of the macro `bevy_script_api::make_script_wrapper` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0308]: mismatched types - --> tests/fail/references/output-with-proxy-reference.rs:4:10 - | -4 | #[derive(LuaProxy, Reflect, Clone)] - | ^^^^^^^^ - | | - | expected `&LuaMyStruct`, found `LuaMyStruct` - | expected due to this - | - = note: this error originates in the derive macro `LuaProxy` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0277]: the trait bound `&LuaMyStruct: TealMultiValue` is not satisfied - --> tests/fail/references/output-with-proxy-reference.rs:4:10 - | -4 | #[derive(LuaProxy, Reflect, Clone)] - | ^^^^^^^^ the trait `ToTypename` is not implemented for `&LuaMyStruct`, which is required by `&LuaMyStruct: TealMultiValue` - | - = help: the trait `ToTypename` is implemented for `LuaMyStruct` - = note: required for `&LuaMyStruct` to implement `TealMultiValue` -note: required by a bound in `bevy_mod_scripting_lua::tealr::mlu::TealDataMethods::add_function` - --> $CARGO/tealr-0.9.1/src/mlu/teal_data_methods.rs - | - | fn add_function(&mut self, name: &S, function: F) - | ------------ required by a bound in this associated function -... - | R: ToLuaMulti<'lua> + TealMultiValue, - | ^^^^^^^^^^^^^^ required by this bound in `TealDataMethods::add_function` - = note: this error originates in the derive macro `LuaProxy` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0277]: the trait bound `&LuaMyStruct: IntoLuaMulti<'lua>` is not satisfied - --> tests/fail/references/output-with-proxy-reference.rs:4:10 - | -4 | #[derive(LuaProxy, Reflect, Clone)] - | ^^^^^^^^ the trait `LuaUserData` is not implemented for `&LuaMyStruct`, which is required by `&LuaMyStruct: IntoLuaMulti<'lua>` - | - = help: the trait `LuaUserData` is implemented for `LuaMyStruct` - = note: required for `&LuaMyStruct` to implement `IntoLua<'_>` - = note: required for `&LuaMyStruct` to implement `IntoLuaMulti<'lua>` -note: required by a bound in `bevy_mod_scripting_lua::tealr::mlu::TealDataMethods::add_function` - --> $CARGO/tealr-0.9.1/src/mlu/teal_data_methods.rs - | - | fn add_function(&mut self, name: &S, function: F) - | ------------ required by a bound in this associated function -... - | R: ToLuaMulti<'lua> + TealMultiValue, - | ^^^^^^^^^^^^^^^^ required by this bound in `TealDataMethods::add_function` - = note: this error originates in the derive macro `LuaProxy` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/macro_tests/tests/fail/simple/invalid-argument-count.rs b/crates/macro_tests/tests/fail/simple/invalid-argument-count.rs deleted file mode 100644 index 0f3e67c9..00000000 --- a/crates/macro_tests/tests/fail/simple/invalid-argument-count.rs +++ /dev/null @@ -1,17 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="Method")] - fn my_fn(&self); - "#, -])] -pub struct MyStruct; - -impl MyStruct { - pub fn my_fn(&self, _: usize) {} -} - -pub fn main() {} diff --git a/crates/macro_tests/tests/fail/simple/invalid-argument-count.stderr b/crates/macro_tests/tests/fail/simple/invalid-argument-count.stderr deleted file mode 100644 index edce984c..00000000 --- a/crates/macro_tests/tests/fail/simple/invalid-argument-count.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0061]: this function takes 2 arguments but 1 argument was supplied - --> tests/fail/simple/invalid-argument-count.rs:4:10 - | -4 | #[derive(LuaProxy, Reflect, Clone)] - | ^^^^^^^^ argument #2 of type `usize` is missing - | -note: method defined here - --> tests/fail/simple/invalid-argument-count.rs:14:12 - | -14 | pub fn my_fn(&self, _: usize) {} - | ^^^^^ ----- -------- - = note: this error originates in the derive macro `LuaProxy` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/macro_tests/tests/fail/simple/invalid-argument-type.rs b/crates/macro_tests/tests/fail/simple/invalid-argument-type.rs deleted file mode 100644 index a8987f9e..00000000 --- a/crates/macro_tests/tests/fail/simple/invalid-argument-type.rs +++ /dev/null @@ -1,17 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="Method")] - fn my_fn(&self, arg: String); - "#, -])] -pub struct MyStruct; - -impl MyStruct { - pub fn my_fn(&self, _: usize) {} -} - -pub fn main() {} diff --git a/crates/macro_tests/tests/fail/simple/invalid-argument-type.stderr b/crates/macro_tests/tests/fail/simple/invalid-argument-type.stderr deleted file mode 100644 index 0da85ca5..00000000 --- a/crates/macro_tests/tests/fail/simple/invalid-argument-type.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0308]: mismatched types - --> tests/fail/simple/invalid-argument-type.rs:4:10 - | -4 | #[derive(LuaProxy, Reflect, Clone)] - | ^^^^^^^^ - | | - | expected `usize`, found `String` - | arguments to this function are incorrect - | -note: method defined here - --> tests/fail/simple/invalid-argument-type.rs:14:12 - | -14 | pub fn my_fn(&self, _: usize) {} - | ^^^^^ -------- - = note: this error originates in the derive macro `LuaProxy` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/macro_tests/tests/fail/simple/invalid-function-type.rs b/crates/macro_tests/tests/fail/simple/invalid-function-type.rs deleted file mode 100644 index 17b854f5..00000000 --- a/crates/macro_tests/tests/fail/simple/invalid-function-type.rs +++ /dev/null @@ -1,15 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="AMASJDIASDKAW")] - fn fn_taking_nothing() { - - } - "#, -])] -pub struct MyStruct; - -pub fn main() {} diff --git a/crates/macro_tests/tests/fail/simple/invalid-function-type.stderr b/crates/macro_tests/tests/fail/simple/invalid-function-type.stderr deleted file mode 100644 index ac2fceec..00000000 --- a/crates/macro_tests/tests/fail/simple/invalid-function-type.stderr +++ /dev/null @@ -1,7 +0,0 @@ -error: Unknown literal value `AMASJDIASDKAW` - --> tests/fail/simple/invalid-function-type.rs:4:10 - | -4 | #[derive(LuaProxy, Reflect, Clone)] - | ^^^^^^^^ - | - = note: this error originates in the derive macro `LuaProxy` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/macro_tests/tests/fail/simple/invalid-output-type-custom-body.rs b/crates/macro_tests/tests/fail/simple/invalid-output-type-custom-body.rs deleted file mode 100644 index b10fe053..00000000 --- a/crates/macro_tests/tests/fail/simple/invalid-output-type-custom-body.rs +++ /dev/null @@ -1,14 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="Function", output(proxy))] - fn fn_returning_proxy() -> Self { - 2 - } - "#, -])] -pub struct MyStruct; -pub fn main() {} diff --git a/crates/macro_tests/tests/fail/simple/invalid-output-type-custom-body.stderr b/crates/macro_tests/tests/fail/simple/invalid-output-type-custom-body.stderr deleted file mode 100644 index 3c7899c0..00000000 --- a/crates/macro_tests/tests/fail/simple/invalid-output-type-custom-body.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error[E0308]: mismatched types - --> tests/fail/simple/invalid-output-type-custom-body.rs:4:10 - | -4 | #[derive(LuaProxy, Reflect, Clone)] - | ^^^^^^^^ expected `MyStruct`, found integer -... -13 | pub struct MyStruct; - | -------- expected due to this - | - = note: this error originates in the derive macro `LuaProxy` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/macro_tests/tests/fail/simple/invalid-output-type.rs b/crates/macro_tests/tests/fail/simple/invalid-output-type.rs deleted file mode 100644 index 09ee654d..00000000 --- a/crates/macro_tests/tests/fail/simple/invalid-output-type.rs +++ /dev/null @@ -1,17 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="Function")] - fn my_fn() -> usize; - "#, -])] -pub struct MyStruct; -impl MyStruct { - pub fn my_fn() -> Self { - MyStruct - } -} -pub fn main() {} diff --git a/crates/macro_tests/tests/fail/simple/invalid-output-type.stderr b/crates/macro_tests/tests/fail/simple/invalid-output-type.stderr deleted file mode 100644 index dfcd615b..00000000 --- a/crates/macro_tests/tests/fail/simple/invalid-output-type.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error[E0308]: mismatched types - --> tests/fail/simple/invalid-output-type.rs:4:10 - | -4 | #[derive(LuaProxy, Reflect, Clone)] - | ^^^^^^^^ - | | - | expected `usize`, found `MyStruct` - | expected due to this - | - = note: this error originates in the derive macro `LuaProxy` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/macro_tests/tests/fail/simple/method-without-receiver.rs b/crates/macro_tests/tests/fail/simple/method-without-receiver.rs deleted file mode 100644 index 69eaee3f..00000000 --- a/crates/macro_tests/tests/fail/simple/method-without-receiver.rs +++ /dev/null @@ -1,22 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="Method")] - fn fn_taking_nothing() { - - } - "#, - - r#" - #[lua(kind="Method")] - fn fn_taking_usize(arg: usize) { - - } - "#, -])] -pub struct MyStruct; - -pub fn main() {} diff --git a/crates/macro_tests/tests/fail/simple/method-without-receiver.stderr b/crates/macro_tests/tests/fail/simple/method-without-receiver.stderr deleted file mode 100644 index 44fbc6cd..00000000 --- a/crates/macro_tests/tests/fail/simple/method-without-receiver.stderr +++ /dev/null @@ -1,7 +0,0 @@ -error: Expected receiver as first argument in the signature - --> tests/fail/simple/method-without-receiver.rs:4:10 - | -4 | #[derive(LuaProxy, Reflect, Clone)] - | ^^^^^^^^ - | - = note: this error originates in the derive macro `LuaProxy` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/macro_tests/tests/macro_tests.rs b/crates/macro_tests/tests/macro_tests.rs deleted file mode 100644 index f009e7eb..00000000 --- a/crates/macro_tests/tests/macro_tests.rs +++ /dev/null @@ -1,11 +0,0 @@ -#[test] -fn success() { - let t = trybuild::TestCases::new(); - t.pass("tests/success/**/*.rs"); -} - -#[test] -fn fail() { - let t = trybuild::TestCases::new(); - t.compile_fail("tests/fail/**/*.rs"); -} diff --git a/crates/macro_tests/tests/success/containers/option-argument.rs b/crates/macro_tests/tests/success/containers/option-argument.rs deleted file mode 100644 index 2cc6223e..00000000 --- a/crates/macro_tests/tests/success/containers/option-argument.rs +++ /dev/null @@ -1,16 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(derive(clone), functions[ -r#" - #[lua(kind="Function")] - fn fn_returning_string_option(_opt: Option) {} -"#,r#" - #[lua(kind="Function")] - fn fn_returning_some_proxy(#[proxy] _opt: Option) {} -"# -])] -pub struct MyStruct; - -pub fn main() {} diff --git a/crates/macro_tests/tests/success/containers/option-output.rs b/crates/macro_tests/tests/success/containers/option-output.rs deleted file mode 100644 index c6f885ee..00000000 --- a/crates/macro_tests/tests/success/containers/option-output.rs +++ /dev/null @@ -1,36 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="Function")] - fn fn_returning_string_option() -> Option { - Some("hello".to_owned()) - } - "#, - - r#" - #[lua(kind="Function")] - fn fn_returning_string_option_none() -> Option { - None - } - "#, - - r#" - #[lua(kind="Function", output(proxy))] - fn fn_returning_some_proxy() -> Option { - Some(MyStruct) - } - "#, - - r#" - #[lua(kind="Function", output(proxy))] - fn fn_returning_none_proxy() -> Option { - None - } - "#, -])] -pub struct MyStruct; - -pub fn main() {} diff --git a/crates/macro_tests/tests/success/containers/vec-argument.rs b/crates/macro_tests/tests/success/containers/vec-argument.rs deleted file mode 100644 index 1c22bbd1..00000000 --- a/crates/macro_tests/tests/success/containers/vec-argument.rs +++ /dev/null @@ -1,21 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(derive(clone), functions[ - r#" - #[lua(kind="Function")] - fn fn_returning_string_vec(_vec: Vec) { - } - "#, - - r#" - #[lua(kind="Function", output(proxy))] - fn fn_returning_proxy_vec(_vec: Vec) { - - } - "#, -])] -pub struct MyStruct; - -pub fn main() {} diff --git a/crates/macro_tests/tests/success/containers/vec-output.rs b/crates/macro_tests/tests/success/containers/vec-output.rs deleted file mode 100644 index 42ac7cfc..00000000 --- a/crates/macro_tests/tests/success/containers/vec-output.rs +++ /dev/null @@ -1,29 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="Function")] - fn fn_returning_string_vec() -> Vec { - vec!["hello".to_owned()] - } - "#, - - r#" - #[lua(kind="Function", output(proxy))] - fn fn_returning_proxy_vec() -> Vec { - vec![MyStruct, MyStruct] - } - "#, - - r#" - #[lua(kind="Function", output(proxy))] - fn fn_returning_proxy_vec_empty() -> Vec { - Vec::default() - } - "#, -])] -pub struct MyStruct; - -pub fn main() {} diff --git a/crates/macro_tests/tests/success/references/proxy-non-receiver-reference.rs b/crates/macro_tests/tests/success/references/proxy-non-receiver-reference.rs deleted file mode 100644 index 2a0982c6..00000000 --- a/crates/macro_tests/tests/success/references/proxy-non-receiver-reference.rs +++ /dev/null @@ -1,22 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect)] -#[proxy(functions[ - r#" - #[lua(kind="Function")] - fn fn_returning_some_string(#[proxy] other: &Self) -> String; - "#, -])] -pub struct MyStruct { - some_string: String, - me_vec: Vec, -} - -impl MyStruct { - pub fn fn_returning_some_string(other: &Self) -> String { - other.some_string.clone() - } -} - -pub fn main() {} diff --git a/crates/macro_tests/tests/success/simple/function.rs b/crates/macro_tests/tests/success/simple/function.rs deleted file mode 100644 index 32a96bd0..00000000 --- a/crates/macro_tests/tests/success/simple/function.rs +++ /dev/null @@ -1,33 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="Function")] - fn fn_returning_some_string() -> String; - "#, - - r#" - #[lua(kind="Function", output(proxy))] - fn fn_returning_proxy() -> Self; - "#, -])] -pub struct MyStruct { - some_string: String, - me_vec: Vec, -} -impl MyStruct { - pub fn fn_returning_some_string() -> String { - "hello".to_owned() - } - - pub fn fn_returning_proxy() -> MyStruct { - MyStruct { - some_string: "hello".to_owned(), - me_vec: vec![1, 2, 3], - } - } -} - -pub fn main() {} diff --git a/crates/macro_tests/tests/success/simple/metafunction.rs b/crates/macro_tests/tests/success/simple/metafunction.rs deleted file mode 100644 index 97c2f698..00000000 --- a/crates/macro_tests/tests/success/simple/metafunction.rs +++ /dev/null @@ -1,25 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="MetaFunction", metamethod="ToString")] - fn ToString(#[proxy] my_struct: &Self) -> String { - my_struct.some_string.clone() - } - "#, - - r#" - #[lua(kind="MetaFunction", output(proxy), metamethod="Index")] - fn Index(#[proxy] my_struct: &Self, _i: usize) -> Self { - my_struct.clone() - } - "#, -])] -pub struct MyStruct { - some_string: String, - me_vec: Vec, -} - -pub fn main() {} diff --git a/crates/macro_tests/tests/success/simple/metamethod-owned-receiver.rs b/crates/macro_tests/tests/success/simple/metamethod-owned-receiver.rs deleted file mode 100644 index b9f476cd..00000000 --- a/crates/macro_tests/tests/success/simple/metamethod-owned-receiver.rs +++ /dev/null @@ -1,25 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="MetaMethod", metamethod="ToString")] - fn ToString(&self) -> String { - self.some_string.clone() - } - "#, - - r#" - #[lua(kind="MetaMethod", metamethod="Index", output(proxy))] - fn Index(&self, _idx: usize) -> Self { - self.clone() - } - "#, -])] -pub struct MyStruct { - some_string: String, - me_vec: Vec, -} - -pub fn main() {} diff --git a/crates/macro_tests/tests/success/simple/metamethod.rs b/crates/macro_tests/tests/success/simple/metamethod.rs deleted file mode 100644 index 7a0a13aa..00000000 --- a/crates/macro_tests/tests/success/simple/metamethod.rs +++ /dev/null @@ -1,24 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="MetaMethod", metamethod="ToString")] - fn ToString(&self) -> String { - self.some_string.clone() - } - "#, - - r#" - #[lua(kind="MetaMethod", metamethod="Index", output(proxy))] - fn Index(&self, _idx: usize) -> Self { - self.clone() - } - "#, -])] -pub struct MyStruct { - some_string: String, - me_vec: Vec, -} -pub fn main() {} diff --git a/crates/macro_tests/tests/success/simple/method-owned-receiver.rs b/crates/macro_tests/tests/success/simple/method-owned-receiver.rs deleted file mode 100644 index 955c623d..00000000 --- a/crates/macro_tests/tests/success/simple/method-owned-receiver.rs +++ /dev/null @@ -1,35 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(derive(clone), functions[ - r#" - #[lua(kind="Method")] - fn fn_returning_some_string(self) -> String { - self.some_string.clone() - } - "#, - - r#" - #[lua(kind="Method", output(proxy))] - fn fn_returning_proxy(self) -> Self { - self.clone() - } - "#, -])] -pub struct MyStruct { - some_string: String, - me_vec: Vec, -} - -impl MyStruct { - pub fn fn_returning_some_string(self) -> String { - self.some_string - } - - pub fn fn_returning_proxy(self) -> Self { - self.clone() - } -} - -pub fn main() {} diff --git a/crates/macro_tests/tests/success/simple/method.rs b/crates/macro_tests/tests/success/simple/method.rs deleted file mode 100644 index 3a04d4e4..00000000 --- a/crates/macro_tests/tests/success/simple/method.rs +++ /dev/null @@ -1,34 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="Method")] - fn fn_returning_some_string(&self) -> String { - self.some_string.clone() - } - "#, - - r#" - #[lua(kind="Method", output(proxy))] - fn fn_returning_proxy(&self) -> Self { - self.clone() - } - "#, -])] -pub struct MyStruct { - some_string: String, - me_vec: Vec, -} - -impl MyStruct { - pub fn fn_returning_some_string(&self) -> String { - self.some_string.clone() - } - - pub fn fn_returning_proxy(&self) -> Self { - self.clone() - } -} - -pub fn main() {} diff --git a/crates/macro_tests/tests/success/simple/mutable-function.rs b/crates/macro_tests/tests/success/simple/mutable-function.rs deleted file mode 100644 index 0b8ad7ea..00000000 --- a/crates/macro_tests/tests/success/simple/mutable-function.rs +++ /dev/null @@ -1,37 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="Function")] - fn fn_returning_some_string(#[proxy]arg: &mut MyStruct) -> String { - arg.some_string.clone() - } - "#, - - r#" - #[lua(kind="Function", output(proxy))] - fn fn_returning_proxy(#[proxy]arg: &mut MyStruct) -> Self { - arg.clone() - } - "#, -])] -pub struct MyStruct { - some_string: String, - me_vec: Vec, -} -impl MyStruct { - pub fn fn_returning_some_string() -> String { - "hello".to_owned() - } - - pub fn fn_returning_proxy() -> Self { - Self { - some_string: "hello".to_owned(), - me_vec: Default::default(), - } - } -} - -pub fn main() {} diff --git a/crates/macro_tests/tests/success/simple/mutable-metafunction.rs b/crates/macro_tests/tests/success/simple/mutable-metafunction.rs deleted file mode 100644 index 79b96ed2..00000000 --- a/crates/macro_tests/tests/success/simple/mutable-metafunction.rs +++ /dev/null @@ -1,24 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="MutableMetaFunction", metamethod="ToString")] - fn ToString(&self) -> String { - self.some_string.clone() - } - "#, - - r#" - #[lua(kind="MutableMetaFunction", metamethod="Index", output(proxy))] - fn Index(&self, _i: usize) -> Self { - self.clone() - } - "#, -])] -pub struct MyStruct { - some_string: String, - me_vec: Vec, -} -pub fn main() {} diff --git a/crates/macro_tests/tests/success/simple/mutating-metamethod-owned-receiver.rs b/crates/macro_tests/tests/success/simple/mutating-metamethod-owned-receiver.rs deleted file mode 100644 index 26c0f06a..00000000 --- a/crates/macro_tests/tests/success/simple/mutating-metamethod-owned-receiver.rs +++ /dev/null @@ -1,26 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="MutatingMetaMethod", metamethod="ToString")] - fn ToString(&mut self) -> String { - self.some_string = "lol".to_string(); - self.some_string.clone() - } - "#, - - r#" - #[lua(kind="MutatingMetaMethod", metamethod="Index", output(proxy))] - fn Index(&mut self, _i: usize) -> Self { - self.clone() - } - "#, -])] -pub struct MyStruct { - some_string: String, - me_vec: Vec, -} - -pub fn main() {} diff --git a/crates/macro_tests/tests/success/simple/mutating-metamethod.rs b/crates/macro_tests/tests/success/simple/mutating-metamethod.rs deleted file mode 100644 index 20b60302..00000000 --- a/crates/macro_tests/tests/success/simple/mutating-metamethod.rs +++ /dev/null @@ -1,25 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="MutatingMetaMethod", metamethod="ToString")] - fn ToString(&mut self) -> String { - self.some_string = "lol".to_string(); - self.some_string.clone() - } - "#, - - r#" - #[lua(kind="MutatingMetaMethod", metamethod="Index", output(proxy))] - fn Index(&mut self, _idx: usize) -> Self { - self.clone() - } - "#, -])] -pub struct MyStruct { - some_string: String, - me_vec: Vec, -} -pub fn main() {} diff --git a/crates/macro_tests/tests/success/simple/mutating-method-owned-receiver.rs b/crates/macro_tests/tests/success/simple/mutating-method-owned-receiver.rs deleted file mode 100644 index 49b91c02..00000000 --- a/crates/macro_tests/tests/success/simple/mutating-method-owned-receiver.rs +++ /dev/null @@ -1,35 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; - -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(derive(clone), functions[ - r#" - #[lua(kind="MutatingMethod")] - fn fn_returning_some_string(mut self) -> String { - self.some_string.clone() - } - "#, - - r#" - #[lua(kind="MutatingMethod", output(proxy))] - fn fn_returning_proxy(mut self) -> Self { - self.clone() - } - "#, -])] -pub struct MyStruct { - some_string: String, - me_vec: Vec, -} - -impl MyStruct { - pub fn fn_returning_some_string(self) -> String { - self.some_string - } - - pub fn fn_returning_proxy(self) -> Self { - self.clone() - } -} - -pub fn main() {} diff --git a/crates/macro_tests/tests/success/simple/mutating-method.rs b/crates/macro_tests/tests/success/simple/mutating-method.rs deleted file mode 100644 index 8b107a7a..00000000 --- a/crates/macro_tests/tests/success/simple/mutating-method.rs +++ /dev/null @@ -1,30 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::api::*; -#[derive(LuaProxy, Reflect, Clone)] -#[proxy(functions[ - r#" - #[lua(kind="MutatingMethod")] - fn fn_returning_some_string(&mut self) -> String; - "#, - - r#" - #[lua(kind="MutatingMethod", output(proxy))] - fn fn_returning_proxy(&mut self) -> Self; - "#, -])] -pub struct MyStruct { - some_string: String, - me_vec: Vec, -} - -impl MyStruct { - pub fn fn_returning_some_string(&mut self) -> String { - self.some_string.clone() - } - - pub fn fn_returning_proxy(&mut self) -> Self { - self.clone() - } -} - -pub fn main() {} diff --git a/crates/test_utils/Cargo.toml b/crates/test_utils/Cargo.toml new file mode 100644 index 00000000..9c3b96d8 --- /dev/null +++ b/crates/test_utils/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "test_utils" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] +bevy = { workspace = true } + +[lib] +path = "src/lib.rs" diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs new file mode 100644 index 00000000..363a59ff --- /dev/null +++ b/crates/test_utils/src/lib.rs @@ -0,0 +1 @@ +pub mod test_data; diff --git a/crates/test_utils/src/test_data.rs b/crates/test_utils/src/test_data.rs new file mode 100644 index 00000000..c052f095 --- /dev/null +++ b/crates/test_utils/src/test_data.rs @@ -0,0 +1,264 @@ +use std::alloc::Layout; +use std::sync::{Arc, RwLock}; + +use bevy::ecs::{component::*, world::World}; +use bevy::prelude::*; +use bevy::reflect::*; + +/// Test component with Reflect and ReflectComponent registered +#[derive(Component, Reflect, PartialEq, Eq, Debug)] +#[reflect(Component)] +pub struct TestComponent { + pub strings: Vec, +} + +impl TestComponent { + pub fn init() -> Self { + Self { + strings: vec!["Initial".to_string(), "Value".to_string()], + } + } +} + +/// Test Resource with Reflect and ReflectResource registered +#[derive(Resource, Reflect, Default, PartialEq, Eq, Debug)] +#[reflect(Resource)] +pub struct TestResource { + pub bytes: Vec, +} + +impl TestResource { + pub fn init() -> Self { + Self { + bytes: vec![0, 1, 2, 3, 4, 5], + } + } +} + +/// Resource with Reflect and ReflectDefault registered but no ReflectResource +#[derive(Resource, Reflect, PartialEq, Eq, Debug)] +#[reflect(Default)] +pub struct ResourceWithDefault(pub String); + +impl Default for ResourceWithDefault { + fn default() -> Self { + Self(String::from("Default")) + } +} + +impl ResourceWithDefault { + pub fn init() -> Self { + Self(String::from("Initial Value")) + } +} + +/// Component with Reflect and ReflectFromWorld registered but no ReflectComponent +#[derive(Reflect, Component, PartialEq, Debug)] +#[reflect(FromWorld)] +pub struct CompWithFromWorld(pub String); + +impl Default for CompWithFromWorld { + fn default() -> Self { + Self(String::from("Default")) + } +} + +impl CompWithFromWorld { + pub fn init() -> Self { + Self(String::from("Initial Value")) + } +} + +/// Component with Reflect and ReflectDefault but no ReflectComponent +#[derive(Component, Reflect, PartialEq, Eq, Debug)] +#[reflect(Default)] +pub struct CompWithDefault(pub String); + +impl CompWithDefault { + pub fn init() -> Self { + Self(String::from("Initial Value")) + } +} + +impl Default for CompWithDefault { + fn default() -> Self { + Self(String::from("Default")) + } +} + +#[derive(Component, Reflect, PartialEq, Eq, Debug)] +#[reflect(Component, Default)] +pub struct CompWithDefaultAndComponentData(pub String); +impl Default for CompWithDefaultAndComponentData { + fn default() -> Self { + Self(String::from("Default")) + } +} + +impl CompWithDefaultAndComponentData { + pub fn init() -> Self { + Self(String::from("Initial Value")) + } +} + +#[derive(Component, Reflect, PartialEq, Eq, Debug)] +#[reflect(Component, FromWorld)] +pub struct CompWithFromWorldAndComponentData(pub String); +impl Default for CompWithFromWorldAndComponentData { + fn default() -> Self { + Self(String::from("Default")) + } +} + +impl CompWithFromWorldAndComponentData { + pub fn init() -> Self { + Self(String::from("Initial Value")) + } +} + +#[derive(Resource, Reflect, PartialEq, Debug)] +pub struct TestResourceWithVariousFields { + pub string: String, + pub usize: usize, + pub int: i32, + pub float: f32, + pub bool: bool, + pub vec_usize: Vec, +} + +impl TestResourceWithVariousFields { + pub fn init() -> Self { + Self { + string: "Initial Value".to_string(), + usize: 22, + int: 42, + float: 69.0, + bool: true, + vec_usize: vec![1, 2, 3, 4, 5], + } + } +} + +pub(crate) const TEST_COMPONENT_ID_START: usize = 20; +pub(crate) const TEST_ENTITY_ID_START: u32 = 0; + +pub trait GetTestComponentId { + fn test_component_id() -> ComponentId; +} + +pub trait GetTestEntityId { + fn test_entity_id() -> Entity; +} + +pub trait EnumerateTestComponents { + fn enumerate_test_components() -> Vec<(&'static str, ComponentId, Option)>; +} + +macro_rules! impl_test_component_ids { + ([$($comp_type:ty => $comp_id:expr),* $(,)?], [$($res_type:ty => $res_id:expr),* $(,)?]) => { + $( + impl GetTestComponentId for $comp_type { + fn test_component_id() -> ComponentId { + ComponentId::new(TEST_COMPONENT_ID_START + $comp_id) + } + } + + impl GetTestEntityId for $comp_type { + fn test_entity_id() -> Entity { + Entity::from_raw(TEST_ENTITY_ID_START + $comp_id) + } + } + )* + $( + impl GetTestComponentId for $res_type { + fn test_component_id() -> ComponentId { + ComponentId::new(TEST_COMPONENT_ID_START + $res_id) + } + } + )* + + pub(crate) fn init_all_components(world: &mut World, registry: &mut TypeRegistry) { + $( + world.register_component::<$comp_type>(); + registry.register::<$comp_type>(); + let registered_id = world.component_id::<$comp_type>().unwrap().index(); + assert_eq!(registered_id, TEST_COMPONENT_ID_START + $comp_id, "Test setup failed. Did you register components before running setup_world?"); + let entity = world.spawn(<$comp_type>::init()).id(); + assert_eq!(entity.index(), TEST_ENTITY_ID_START + $comp_id, "Test setup failed. Did you spawn entities before running setup_world?"); + assert_eq!(entity.generation(), 1, "Test setup failed. Did you spawn entities before running setup_world?"); + )* + $( + world.insert_resource::<$res_type>(<$res_type>::init()); + registry.register::<$res_type>(); + let registered_id = world.resource_id::<$res_type>().unwrap().index(); + assert_eq!(registered_id, TEST_COMPONENT_ID_START + $res_id, "Test setup failed. Did you register components before running setup_world?"); + )* + } + + impl EnumerateTestComponents for World { + fn enumerate_test_components() -> Vec<(&'static str, ComponentId, Option)> { + vec![ + $( + (std::any::type_name::<$comp_type>(), <$comp_type as GetTestComponentId>::test_component_id(), Some(<$comp_type as GetTestEntityId>::test_entity_id())) + ),* + $( + ,(std::any::type_name::<$res_type>(), <$res_type as GetTestComponentId>::test_component_id(), None) + )* + + ] + } + } + }; +} + +impl_test_component_ids!( + [ TestComponent => 0, + CompWithFromWorld => 1, + CompWithDefault => 2, + CompWithDefaultAndComponentData => 3, + CompWithFromWorldAndComponentData => 4 + ], + [ + TestResource => 5, + ResourceWithDefault => 6, + TestResourceWithVariousFields => 7, + ] +); + +/// 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 + while world.components().len() < TEST_COMPONENT_ID_START { + unsafe { + world.register_component_with_descriptor(ComponentDescriptor::new_with_layout( + format!("Filler{}", world.components().len()), + StorageType::Table, + Layout::new::(), + None, + )) + }; + } + + let mut type_registry = TypeRegistry::new(); + init_all_components(&mut world, &mut type_registry); + + init(&mut world, &mut type_registry); + + world.insert_resource(AppTypeRegistry(TypeRegistryArc { + internal: Arc::new(RwLock::new(type_registry)), + })); + + world +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn setup_works() { + setup_world(|_, _| {}); + } +} diff --git a/crates/xtask/Cargo.toml b/crates/xtask/Cargo.toml new file mode 100644 index 00000000..07c4edff --- /dev/null +++ b/crates/xtask/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "xtask" +version = "0.1.0" +edition = "2021" +publish = false + + +[[bin]] +name = "xtask" +path = "src/main.rs" + +[dependencies] +clap = { version = "4", features = ["derive", "string"] } +strum = { version = "0.26", features = ["derive"] } +anyhow = "1" +pretty_env_logger = "0.5" +log = "0.4" +itertools = "0.14" +cargo_metadata = "*" diff --git a/crates/xtask/readme.md b/crates/xtask/readme.md new file mode 100644 index 00000000..e95f8ae1 --- /dev/null +++ b/crates/xtask/readme.md @@ -0,0 +1,3 @@ +# 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 diff --git a/crates/xtask/src/main.rs b/crates/xtask/src/main.rs new file mode 100644 index 00000000..101d86cf --- /dev/null +++ b/crates/xtask/src/main.rs @@ -0,0 +1,626 @@ +use anyhow::*; +use clap::Parser; +use itertools::Itertools; +use log::*; +use std::{collections::HashMap, ffi::OsStr, path::Path, process::Command, str::FromStr}; +use strum::VariantNames; + +#[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + strum::EnumString, + strum::EnumIter, + strum::Display, + strum::VariantNames, + strum::VariantArray, +)] +#[strum(serialize_all = "snake_case")] +enum Feature { + // Lua + Lua51, + Lua52, + Lua53, + Lua54, + Luajit, + Luajit52, + Luau, + BevyBindings, + CoreFunctions, + UnsafeLuaModules, + MluaSerialize, + MluaMacros, + MluaAsync, + + // Rhai + Rhai, + + // Rune + Rune, +} + +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] +enum FeatureGroup { + LuaExclusive, + RhaiExclusive, + RuneExclusive, + ForExternalCrate, + BMSFeature, +} + +impl FeatureGroup { + fn default_feature(self) -> Feature { + match self { + FeatureGroup::LuaExclusive => Feature::Lua54, + FeatureGroup::RhaiExclusive => Feature::Rhai, + FeatureGroup::RuneExclusive => Feature::Rune, + _ => panic!("No default feature for non-exclusive group"), + } + } + + fn is_exclusive(self) -> bool { + matches!( + self, + FeatureGroup::LuaExclusive | FeatureGroup::RhaiExclusive | FeatureGroup::RuneExclusive + ) + } +} + +trait IntoFeatureGroup { + fn to_feature_group(self) -> FeatureGroup; +} + +impl IntoFeatureGroup for Feature { + fn to_feature_group(self) -> FeatureGroup { + match self { + Feature::Lua51 + | Feature::Lua52 + | Feature::Lua53 + | Feature::Lua54 + | Feature::Luajit + | Feature::Luajit52 + | Feature::Luau => FeatureGroup::LuaExclusive, + Feature::Rhai => FeatureGroup::RhaiExclusive, + Feature::Rune => FeatureGroup::RuneExclusive, + Feature::MluaAsync + | Feature::MluaMacros + | Feature::MluaSerialize + | Feature::UnsafeLuaModules => FeatureGroup::ForExternalCrate, + _ => FeatureGroup::BMSFeature, + } + } +} + +#[derive(Debug, Clone)] +struct Features(Vec); + +impl Features { + /// Returns all features except the exclusive ones which are not the default + fn all_features() -> Self { + // remove exclusive features which are not the default + Self( + ::VARIANTS + .iter() + .filter(|f| { + let group = f.to_feature_group(); + (!group.is_exclusive()) || (**f == group.default_feature()) + }) + .cloned() + .collect(), + ) + } + + fn to_cargo_args(&self) -> Vec { + if self.0.is_empty() { + vec![] + } else { + vec!["--features".to_owned(), self.to_string()] + } + } + + fn to_placeholder() -> clap::builder::Str { + format!("[{}]", Feature::VARIANTS.join("|")).into() + } + + fn split_by_group(&self) -> HashMap> { + let mut groups = HashMap::new(); + for feature in &self.0 { + let group = feature.to_feature_group(); + groups.entry(group).or_insert_with(Vec::new).push(*feature); + } + groups + } +} + +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 i > 0 { + write!(f, ",")?; + } + write!(f, "{}", feature)?; + } + std::result::Result::Ok(()) + } +} + +impl From for Features { + fn from(s: String) -> Self { + if s.is_empty() { + return Self(vec![]); + } + + let features = s + .trim() + .split(',') + .map(|f| { + Feature::from_str(f).unwrap_or_else(|_| { + eprintln!("Unknown feature: '{}'", f); + std::process::exit(1); + }) + }) + .collect(); + Self(features) + } +} + +#[derive(Debug, 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(subcommand)] + subcmd: Xtasks, +} + +#[derive(Debug, clap::Subcommand)] +#[clap( + name = "xtask", + bin_name = "cargo xtask", + about = "A set of xtasks for managing the project. Run 'cargo xtask init' to get started." +)] +enum Xtasks { + /// Performs first time local-development environment setup + Init, + /// Build the main workspace only + Build, + /// Build the main workspace, apply all prefferred lints + Check, + /// Build the rust crates.io docs as well as any other docs + Docs { + /// Open in browser + /// This will open the generated docs in the default browser + #[clap(long, short)] + open: bool, + + /// Skip building rust docs + #[clap(long, short)] + no_rust_docs: bool, + }, + /// Build the main workspace, and then run all tests + Test, + /// Perform a full check as it would be done in CI + CiCheck, +} + +impl Xtasks { + fn run(self, features: Features) -> Result<()> { + match self { + Xtasks::Build => Self::build(features), + Xtasks::Check => Self::check(features), + Xtasks::Docs { open, no_rust_docs } => Self::docs(open, no_rust_docs), + Xtasks::Test => Self::test(features), + Xtasks::CiCheck => Self::cicd(), + Xtasks::Init => Self::init(), + } + } + + // TODO: have a global args struct instead of this + fn set_cargo_profile(profile: &str) { + std::env::set_var("BMS_CARGO_PROFILE", profile); + } + + fn get_cargo_profile() -> Option { + Some(std::env::var("BMS_CARGO_PROFILE").unwrap_or_default()) + } + + fn cargo_metadata() -> Result { + let cargo_manifest_path = std::env::var("CARGO_MANIFEST_PATH").unwrap(); + + let mut cmd = cargo_metadata::MetadataCommand::new(); + cmd.manifest_path(cargo_manifest_path); + let out = cmd.exec()?; + Ok(out) + } + + fn workspace_dir() -> Result { + let metadata = Self::cargo_metadata()?; + let workspace_root = metadata.workspace_root; + Ok(workspace_root.into()) + } + + fn relative_workspace_dir>(dir: P) -> Result { + let workspace_dir = Self::workspace_dir()?; + Ok(workspace_dir.join(dir)) + } + + fn append_rustflags(flag: &str) { + let rustflags = std::env::var("RUSTFLAGS").unwrap_or_default(); + let mut flags = rustflags.split(' ').collect::>(); + flags.push(flag); + let flags = flags.join(" "); + std::env::set_var("RUSTFLAGS", flags); + } + + fn run_system_command>>( + command: &str, + context: &str, + add_args: I, + dir: Option<&Path>, + ) -> Result<()> { + info!("Running system command: {}", command); + + let working_dir = match dir { + Some(d) => Self::relative_workspace_dir(d)?, + None => Self::workspace_dir()?, + }; + + let mut cmd = Command::new(command); + cmd.args(add_args) + .stdout(std::process::Stdio::inherit()) + .stderr(std::process::Stdio::inherit()) + .current_dir(working_dir); + + info!("Using command: {:?}", cmd); + + let output = cmd.output(); + info!("Command output: {:?}", output); + let output = output.with_context(|| context.to_owned())?; + match output.status.code() { + Some(0) => Ok(()), + _ => bail!( + "{} failed with exit code: {}", + context, + output.status.code().unwrap_or(-1) + ), + } + } + + fn run_workspace_command>>( + command: &str, + context: &str, + features: Features, + add_args: I, + dir: Option<&Path>, + ) -> Result<()> { + info!("Running workspace command: {}", command); + + 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 { + args.push("--profile".to_owned()); + args.push(profile); + } + + args.extend(features.to_cargo_args()); + args.extend(add_args.into_iter().map(|s| { + s.as_ref() + .to_str() + .expect("invalid command argument") + .to_owned() + })); + + let working_dir = match dir { + Some(d) => Self::relative_workspace_dir(d)?, + None => Self::workspace_dir()?, + }; + + let mut cmd = Command::new("cargo"); + cmd.args(args) + .stdout(std::process::Stdio::inherit()) + .stderr(std::process::Stdio::inherit()) + .current_dir(working_dir); + + info!("Using command: {:?}", cmd); + + let output = cmd.output().with_context(|| context.to_owned())?; + match output.status.code() { + Some(0) => Ok(()), + _ => bail!( + "{} failed with exit code: {}. Features: {features}", + context, + output.status.code().unwrap_or(-1) + ), + } + } + + fn build(features: Features) -> Result<()> { + // build workspace using the given features + Self::run_workspace_command( + "build", + "Failed to build workspace", + features, + vec!["--all-targets"], + None, + )?; + Ok(()) + } + + fn check(features: Features) -> Result<()> { + // start with cargo clippy + Self::run_workspace_command( + "clippy", + "Failed to run clippy", + features, + vec!["--all-targets", "--", "-D", "warnings"], + None, + )?; + + // run cargo fmt checks + Self::run_system_command( + "cargo", + "Failed to run cargo fmt", + vec!["fmt", "--all", "--", "--check"], + None, + )?; + + Ok(()) + } + + fn docs(open: bool, no_rust_docs: bool) -> Result<()> { + // find [package.metadata."docs.rs"] key in Cargo.toml + if !no_rust_docs { + info!("Building rust docs"); + let metadata = Self::cargo_metadata()?; + + let package = metadata + .packages + .iter() + .find(|p| p.name == "bevy_mod_scripting") + .expect("Could not find bevy_mod_scripting package in metadata"); + + info!("Building with root package: {}", package.name); + + let docs_rs = package + .metadata + .get("docs.rs") + .expect("no docs.rs metadata"); + + let features = docs_rs + .as_object() + .expect("docs.rs metadata is not an object") + .get("features") + .expect("no 'features' in docs.rs metadata"); + + info!("Using docs.rs metadata: {:?}", docs_rs); + let string_list = features + .as_array() + .expect("docs.rs metadata is not an array") + .iter() + .map(|v| v.as_str().expect("docs.rs metadata is not a string")) + .map(|s| Feature::from_str(s).expect("invalid feature")) + .collect::>(); + + let features = Features(string_list); + + let mut args = Vec::default(); + args.push("--all"); + if open { + args.push("--open"); + } + Self::run_workspace_command( + "doc", + "Failed to build crates.io docs", + features.clone(), + args, + None, + )?; + } + + // build mdbook + info!("Building mdbook docs"); + let args = if !open { vec!["build"] } else { vec!["serve"] }; + + Self::run_system_command( + "mdbook", + "Failed to build or serve mdbook docs", + args, + Some(Path::new("docs")), + )?; + + Ok(()) + } + + fn test(features: Features) -> 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"); + + // 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); + + Self::run_workspace_command( + "test", + "Failed to run tests", + features, + vec!["--exclude", "xtask"], + None, + )?; + + // 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, + )?; + + 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, + ) + } + + fn cicd() -> Result<()> { + // set profile + Self::set_cargo_profile("ephemeral-build"); + + // setup the CI environment + Self::init()?; + + // 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()); + + let grouped = all_features.split_by_group(); + + let features_to_combine = grouped + .get(&FeatureGroup::BMSFeature) + .expect("no bms features were found at all, bms definitely has feature flags"); + + // run powerset with all language features enabled without mutually exclusive + let mut powersets = features_to_combine + .iter() + .cloned() + .powerset() + .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 + ); + + // choose language features + for category in [ + FeatureGroup::LuaExclusive, + FeatureGroup::RhaiExclusive, + FeatureGroup::RuneExclusive, + ] { + feature_set.0.push(category.default_feature()); + } + + // include all non-bms features + if let Some(f) = grouped.get(&FeatureGroup::ForExternalCrate) { + feature_set.0.extend(f.iter().cloned()); + } + + Self::build(feature_set)?; + } + + // run lints + let all_features = Features::all_features(); + Self::check(all_features.clone())?; + + // run docs + Self::docs(false, false)?; + + info!("All checks passed, running tests"); + + // run tests + Self::test(all_features)?; + + Ok(()) + } + + fn init() -> Result<()> { + // install cargo mdbook + Self::run_system_command( + "cargo", + "Failed to install mdbook", + vec!["install", "mdbook"], + None, + )?; + + // install grcov + Self::run_system_command( + "cargo", + "Failed to install grcov", + vec!["install", "grcov"], + None, + )?; + + // install llvm-tools and clippy + Self::run_system_command( + "rustup", + "Failed to install rust components", + vec![ + "component", + "add", + "rust-src", + "rustc-dev", + "clippy", + "llvm-tools-preview", + ], + None, + )?; + + Ok(()) + } +} + +fn try_main() -> Result<()> { + pretty_env_logger::formatted_builder() + .filter_level(LevelFilter::Info) + .init(); + let args = App::try_parse()?; + args.subcmd.run(args.features) +} + +fn main() { + if let Err(e) = try_main() { + eprintln!("{}", e); + std::process::exit(1); + } +} diff --git a/crates/xtask/templates/settings.json.tera b/crates/xtask/templates/settings.json.tera new file mode 100644 index 00000000..2d90818a --- /dev/null +++ b/crates/xtask/templates/settings.json.tera @@ -0,0 +1,31 @@ +{ + "lldb.displayFormat": "auto", + "lldb.showDisassembly": "never", + "lldb.dereferencePointers": true, + "lldb.consoleMode": "commands", + "[rust]": { + "editor.formatOnSave": true, + "editor.formatOnSaveMode": "file", + "editor.defaultFormatter": "rust-lang.rust-analyzer" + }, + "rust-analyzer.rustc.source": "discover", + "rust-analyzer.linkedProjects": [ + "./crates/bevy_api_gen/Cargo.toml", + "Cargo.toml" + ], + "rust-analyzer.check.invocationStrategy": "per_workspace", + "rust-analyzer.check.invocationLocation": "workspace", + "rust-analyzer.check.overrideCommand": [ + "cargo xtask check" + ], + "rust-analyzer.cargo.buildScripts.overrideCommand": [ + "cargo xtask check" + ], + "rust-analyzer.showUnlinkedFileNotification": false, + "rust-analyzer.runnables.extraTestBinaryArgs": [ + "--show-output" + ], + "rust-analyzer.runnables.extraArgs": [ + "--profile=release-with-debug" + ] +} \ No newline at end of file diff --git a/docs/book.toml b/docs/book.toml index dafeadc1..60a51257 100644 --- a/docs/book.toml +++ b/docs/book.toml @@ -1,6 +1,11 @@ [book] -authors = ["makspll"] +authors = ["Maksymilian Mozolewski"] language = "en" multilingual = false src = "src" title = "Bevy Scripting" +description = "Documentation for the Bevy Scripting library" + +[output.html] +additional-js = ["multi-code-block.js"] +git-repository-url = "https://github.com/makspll/bevy_mod_scripting" diff --git a/docs/multi-code-block.js b/docs/multi-code-block.js new file mode 100644 index 00000000..9ec0c067 --- /dev/null +++ b/docs/multi-code-block.js @@ -0,0 +1,3 @@ +document.addEventListener("DOMContentLoaded", function() { + console.log("Hello, world!"); +}); \ No newline at end of file diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 7390c828..6e3b7122 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -1,3 +1,20 @@ # Summary -- [Chapter 1](./chapter_1.md) +[Installation](./Summary/installation.md) + +# Quick Start + +- [Managing Scripts](./Summary/managing-scripts.md) +- [Running Scripts](./Summary/running-scripts.md) +- [Controlling Script Bindings](./Summary/controlling-script-bindings.md) + +# Scripting Reference + +- [Introduction](./ScriptingReference/introduction.md) +- [Core Bindings](./ScriptingReference/core-api.md) + - [World](./ScriptingReference/world.md) + - [ReflectReference](./ScriptingReference/reflect-reference.md) + - [ScriptTypeRegistration](./ScriptingReference/script-type-registration.md) + - [ScriptQueryBuilder](./ScriptingReference/script-query-builder.md) + - [ScriptQueryResult](./ScriptingReference/script-query-result.md) +- [Core Callbacks](./ScriptingReference/core-callbacks.md) diff --git a/docs/src/ScriptingReference/core-api.md b/docs/src/ScriptingReference/core-api.md new file mode 100644 index 00000000..6d0bcf04 --- /dev/null +++ b/docs/src/ScriptingReference/core-api.md @@ -0,0 +1,5 @@ +# Core Bindings + +The core bindings are manually written utilities for interacting with the `Bevy` world and everything contained within it. These bindings are used to create and manipulate entities, components, resources, and systems. + +Every language BMS supports will support these. \ No newline at end of file diff --git a/docs/src/ScriptingReference/core-callbacks.md b/docs/src/ScriptingReference/core-callbacks.md new file mode 100644 index 00000000..14af4dfd --- /dev/null +++ b/docs/src/ScriptingReference/core-callbacks.md @@ -0,0 +1,28 @@ +# Core Callbacks + +On top of callbacks which are registered by your application, BMS provides a set of core callbacks which are always available. + +The two core callbacks are: +- `on_script_loaded` +- `on_script_unloaded` + +## `on_script_loaded` + +This will be called right after a script has been loaded or reloaded. This is a good place to initialize your script. You should avoid placing a lot of logic into the global body of your script, and instead put it into this callback. Otherwise errors in the initialization will fail the loading of the script. + +```lua +print("you can also use this space, but it's not recommended") +function on_script_loaded() + print("Hello world") +end +``` + +## `on_script_unloaded` + +This will be called right before a script is unloaded. This is a good place to clean up any resources that your script has allocated. Note this is not called when a script is reloaded, only when it is being removed from the system. + +```lua +function on_script_unloaded() + print("Goodbye world") +end +``` \ No newline at end of file diff --git a/docs/src/ScriptingReference/introduction.md b/docs/src/ScriptingReference/introduction.md new file mode 100644 index 00000000..ea1e0826 --- /dev/null +++ b/docs/src/ScriptingReference/introduction.md @@ -0,0 +1,5 @@ +# Scripting Reference + +This part of the book covers the user-facing API of the scripting languages supported by BMS. This will be where you will want to forward your script users to get started with scripting in BMS. + +If you are a modder, welcome! 👋, apologies for the rust-centricity of this guide, we are working on it! \ No newline at end of file diff --git a/docs/src/ScriptingReference/reflect-reference.md b/docs/src/ScriptingReference/reflect-reference.md new file mode 100644 index 00000000..052192a4 --- /dev/null +++ b/docs/src/ScriptingReference/reflect-reference.md @@ -0,0 +1,222 @@ +# ReflectReference + +ReflectReferences are simply references to date living either: +- In a component +- In a resource +- In the allocator + +Reflect references contain a standard interface which operates over the reflection layer exposed by `Bevy` and also provides a way to call various dynamic functions registered on the underlying pointed to data. + +## display_ref + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `s` | `ReflectReference` | The reference to display | + +Returns: + +| Return | Description | +| --- | --- | +| `String` | The reference in string format | + +```lua +print(ref:display_ref()) +print(ref) +``` + +## display_value + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `s` | `ReflectReference` | The reference to display | + +Returns: + +| Return | Description | +| --- | --- | +| `String` | The value in string format | + +```lua +print(ref:display_value()) +``` + +## get +The index function, allows you to index into the reflect reference. + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `key` | `ScriptValue` | The key to get the value for | + +Returns: + +| Return | Description | +| --- | --- | +| `ScriptValue` | The value | + +```lua +local value = ref:get(key) +-- same as +local value = ref.key +local value = ref[key] +local value = ref["key"] +-- for tuple structs +local valye = ref._1 +``` + +## set + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `key` | `ScriptValue` | The key to set the value for | +| `value` | `ScriptValue` | The value to set | + +Returns: + +| Return | Description | +| --- | --- | +| `ScriptValue` | The result | + +```lua +ref:set(key, value) +-- same as +ref.key = value +ref[key] = value +ref["key"] = value +-- for tuple structs +ref._1 = value +``` + +## push +Generic push method, if the underlying type supports it, will push the value into the end of the reference. + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `value` | `ScriptValue` | The value to push | + +```lua +ref:push(value) +``` + +## pop +Generic pop method, if the underlying type supports it, will pop the value from the end of the reference. + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `s` | `ReflectReference` | The reference to pop from | + +Returns: + +| Return | Description | +| --- | --- | +| `ScriptValue` | The popped value | + +```lua +local value = ref:pop() +``` + +## insert +Generic insert method, if the underlying type supports it, will insert the value at the key. + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `key` | `ScriptValue` | The key to insert the value for | +| `value` | `ScriptValue` | The value to insert | + +```lua +ref:insert(key, value) +``` + +## clear +Generic clear method, if the underlying type supports it, will clear the referenced container type. + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `s` | `ReflectReference` | The reference to clear | + + +```lua +ref:clear() +``` + +## len +Generic length method, if the underlying type supports it, will return the length of the referenced container or length relevant to the type itself (number of fields etc.). + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `s` | `ReflectReference` | The reference to get the length of | + +Returns: + +| Return | Description | +| --- | --- | +| `usize` | The length | + +```lua +length = ref:len() +``` + +## remove +Generic remove method, if the underlying type supports it, will remove the value at the key. + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `key` | `ScriptValue` | The key to remove the value for | + +Returns: + +| Return | Description | +| --- | --- | +| `ScriptValue` | The removed value | + +```lua +local value = ref:remove(key) +``` + +## iter +The iterator function, returns a function which can be called to iterate over the reference. + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `s` | `ReflectReference` | The reference to iterate over | + +Returns: + +| Return | Description | +| --- | --- | +| `ScriptFunctionMut` | The iterator function | + +```lua +local iter = ref:iter() +local val = iter() +while val do + print(val) + next = iter() +end + +-- same as +for val in pairs(ref) do + print(val) +end +``` diff --git a/docs/src/ScriptingReference/script-query-builder.md b/docs/src/ScriptingReference/script-query-builder.md new file mode 100644 index 00000000..3f0654b1 --- /dev/null +++ b/docs/src/ScriptingReference/script-query-builder.md @@ -0,0 +1,83 @@ +# ScriptQueryBuilder + +The query builder is used to build queries for entities with specific components. Can be used to interact with arbitrary entities in the world. + +## component + +Adds a component to the query, this will be accessible in the query results under the index corresponding to the index of this component in the query. + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `s` | `ScriptQueryBuilder` | The query builder | +| `component` | `ScriptTypeRegistration` | The component to query for | + +Returns: + +| Return | Description | +| --- | --- | +| `ScriptQueryBuilder` | The updated query builder | + +```lua +query:component(MyType):component(MyOtherType) +``` + +## with + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `s` | `ScriptQueryBuilder` | The query builder | +| `with` | `ScriptTypeRegistration` | The component to include in the query | + +Returns: + +| Return | Description | +| --- | --- | +| `ScriptQueryBuilder` | The updated query builder | + +```lua +query:with(MyType):with(MyOtherType) +``` + +## without + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `s` | `ScriptQueryBuilder` | The query builder | +| `without` | `ScriptTypeRegistration` | The component to exclude from the query | + +Returns: + +| Return | Description | +| --- | --- | +| `ScriptQueryBuilder` | The updated query builder | + +```lua +query:without(MyType):without(MyOtherType) +``` + +## build + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `s` | `ScriptQueryBuilder` | The query builder | + +Returns: + +| Return | Description | +| --- | --- | +| `Vec` | The query results | + +```lua +local results = query:build() +for _, result in pairs(results) do + print(result) +end +``` diff --git a/docs/src/ScriptingReference/script-query-result.md b/docs/src/ScriptingReference/script-query-result.md new file mode 100644 index 00000000..f25e5d1c --- /dev/null +++ b/docs/src/ScriptingReference/script-query-result.md @@ -0,0 +1,41 @@ +# ScriptQueryResult + +The result of a query, built by the query builder. + +## entity + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `s` | `ScriptQueryResult` | The query result | + +Returns: + +| Return | Description | +| --- | --- | +| `Entity` | The entity | + +```lua +local entity = result:entity() +``` + +## components + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `s` | `ScriptQueryResult` | The query result | + +Returns: + +| Return | Description | +| --- | --- | +| `Vec` | The components | + +```lua +for _, component in pairs(result:components()) do + print(component) +end +``` \ No newline at end of file diff --git a/docs/src/ScriptingReference/script-type-registration.md b/docs/src/ScriptingReference/script-type-registration.md new file mode 100644 index 00000000..1eb45d62 --- /dev/null +++ b/docs/src/ScriptingReference/script-type-registration.md @@ -0,0 +1,79 @@ +# ScriptTypeRegistration + +A reference to a type registration, in general think of this as a handle to a type. + +## type_name + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `s` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` | + +Returns: + +| Return | Description | +| --- | --- | +| `String` | The type name | + +```lua +local name = MyType:type_name() +``` + +## short_name + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `s` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` | + +Returns: + +| Return | Description | +| --- | --- | +| `String` | The short name | + +```lua +local name = MyType:short_name() +``` + +## is_resource + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `s` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` | + +Returns: + +| Return | Description | +| --- | --- | +| `bool` | `true` if the type is a resource, otherwise `false` | + +```lua +if MyType:is_resource() then + print("MyType is a resource") +end +``` + +## is_component + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `s` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` | + +Returns: + +| Return | Description | +| --- | --- | +| `bool` | `true` if the type is a component, otherwise `false` | + +```lua +if MyType:is_component() then + print("MyType is a component") +end +``` diff --git a/docs/src/ScriptingReference/world.md b/docs/src/ScriptingReference/world.md new file mode 100644 index 00000000..387b4023 --- /dev/null +++ b/docs/src/ScriptingReference/world.md @@ -0,0 +1,302 @@ +## World + +The `World` is the entry point for interacting with `Bevy`. It is provided to scripts under either the `world` or `World` static variable. + +### get_type_by_name + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `type_name` | `String` | The name of the type to get, this can be either the short type name, i.e. `my_type` or the long name i.e. `my_crate::my_module::my_type` | + +Returns: + +| Return | Description | +| --- | --- | +| `Option` | The type if it exists, otherwise `None` | + +```lua +MyType = world.get_type_by_name("MyType") +if MyType == nil then + print("MyType not found") +end +``` + +### get_component + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `entity` | `Entity` | The entity to get the component from | +| `registration` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` of the component | + +Returns: + +| Return | Description | +| --- | --- | +| `Option` | The reference to the component if it exists, otherwise `None` | + +```lua +local component = world.get_component(entity, MyType) +if component ~= nil then + print("found component:" .. component) +end +``` + +### has_component + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `entity` | `Entity` | The entity to check the component for | +| `registration` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` of the component | + +Returns: + +| Return | Description | +| --- | --- | +| `bool` | `true` if the entity has the component, otherwise `false` | + +```lua +if world.has_component(entity, MyType) then + print("Entity has MyType") +end +``` + +### remove_component + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `entity` | `Entity` | The entity to remove the component from | +| `registration` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` of the component | + +```lua +world.remove_component(entity, MyType) +``` + +### get_resource + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `registration` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` of the resource | + +Returns: + +| Return | Description | +| --- | --- | +| `Option` | The resource if it exists, otherwise `None` | + +```lua +local resource = world.get_resource(MyType) +if resource ~= nil then + print("found resource:" .. resource) +end +``` + +### has_resource + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `registration` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` of the resource | + +Returns: + +| Return | Description | +| --- | --- | +| `bool` | `true` if the resource exists, otherwise `false` | + +```lua +local hasResource = world.has_resource(MyType) +``` + +### remove_resource + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `registration` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` of the resource | + +```lua +world.remove_resource(MyType) +``` + +### add_default_component + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `entity` | `Entity` | The entity to add the component to | +| `registration` | `ScriptTypeRegistration` | The type registration as returned by `get_type_by_name` of the component | + +```lua +world.add_default_component(entity, MyType) +``` + +### spawn + +Returns: + +| Return | Description | +| --- | --- | +| `Entity` | The spawned entity | + +```lua +local entity = world.spawn() +``` + +### insert_children + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `entity` | `Entity` | The parent entity | +| `index` | `usize` | The index to insert the children at | +| `children` | `Vec` | The children entities to insert | + +```lua +world.insert_children(parent, 1, {child1, child2}) +``` + +### push_children + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `entity` | `Entity` | The parent entity | +| `children` | `Vec` | The children entities to push | + + +```lua +world.push_children(parent, {child1, child2}) +``` + +### get_children + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `entity` | `Entity` | The parent entity | + +Returns: + +| Return | Description | +| --- | --- | +| `Vec` | The children entities | + +```lua +local children = world.get_children(parent) +for _, child in pairs(children) do + print("child: " .. child) +end +``` + +### get_parent + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `entity` | `Entity` | The child entity | + +Returns: + +| Return | Description | +| --- | --- | +| `Option` | The parent entity if it exists, otherwise `None` | + +```lua +local parent = world.get_parent(child) +if parent ~= nil then + print("parent: " .. parent) +end +``` + +### despawn + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `entity` | `Entity` | The entity to despawn | + +```lua +world.despawn(entity) +``` + +### despawn_descendants + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `entity` | `Entity` | The entity to despawn descendants of | + +```lua +world.despawn_descendants(entity) +``` + +### despawn_recursive + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `entity` | `Entity` | The entity to despawn recursively | + +```lua +world.despawn_recursive(entity) +``` + +### has_entity + +Arguments: + +| Argument | Type | Description | +| --- | --- | --- | +| `entity` | `Entity` | The entity to check | + +Returns: + +| Return | Description | +| --- | --- | +| `bool` | `true` if the entity exists, otherwise `false` | + +```lua +local exists = world.has_entity(entity) +if exists then + print("entity exists") +end +``` + +### query + +Returns: + +| Return | Description | +| --- | --- | +| `ScriptQueryBuilder` | The query builder | + +```lua +local queryBuilder = world.query() +``` + +### exit +Send the exit signal to the application, will gracefully shutdown the application. + +```lua +world.exit() +``` diff --git a/docs/src/Summary/controlling-script-bindings.md b/docs/src/Summary/controlling-script-bindings.md new file mode 100644 index 00000000..fd5f5de3 --- /dev/null +++ b/docs/src/Summary/controlling-script-bindings.md @@ -0,0 +1,81 @@ +# Controlling Script Bindings + +In this book we reffer to anything accessible by a script, which allows it to communicate with your Rust code a `binding` (which in previous versions was more generically referred to as a script API). + +The "binding" here being used as in: binding `script` code to `rust` code. + +## Dynamic Functions + +Everything callable by scripts must first be registered in the dynamic function registry. Notably we do not make use of the normal bevy function registry to improve performance and usability. This means you cannot call just any function. + +In order for a function to be callable by a script it must adhere to a few requirements: +- Each argument must implement `FromScript`. +- Each return type must implement `IntoScript`. +- Each argument must also implement `GetInnerTypeDependencies` +- Each return type must also implement `GetInnerTypeDependencies` + +The into/from requirements allow us to convert these types to `ScriptValue`'s, and each supported scripting language can then marshall these into the script. + +Note these types are implemented for primitives, but if you want to interact with one of your `Reflect` implementing types, you will need to use one of `Ref`, `Mut` or `Val` wrappers in place of `&T`, `&mut T` and `T` respectively. + +These wrappers enable us to safely interact with bevy, and claim any necessary mutex'es on `Resources`, `Components` or `Allocations`. + +The `GetInnerTypeDependencies`, trait is simply a local trait alias for `GetTypeRegistration` with less strict type requirements. It allows us to register all the types necessary for the function calls, so that you don't have to register anything manually. If your type implements `GetTypeRegistration` you should not face any issues on this front. + +## Registering Script Functions + +Registering functions can be done via the `NamespaceBuilder` like below: + +```rust,ignore + NamespaceBuilder::::new(&mut world) + .register( + "hello_world", + |s: String| { + println!(s) + }, + ); +``` + +This will allow you to call this function within lua like so: + +```lua +hello_world("hi from lua!") +``` + +## Context Arguments + +Each script function call always receives 2 context arguments, namely: +- `CallerContext` +- `WorldCallbackAccess` + +The first one is configured by the caller, and contains requests from the caller to your function, such as "I am calling you from a 1-indexed array system, please convert the index first", This argument is only relevant if you're targeting multiple languages. + +The second argument gives you access to the world from your function. + +You can opt-in to receive these arguments by adding them to your closure arguments in the above order (either both or just one) + +## Generic Arguments + +Sometimes you might want to be generic over the type of argument you're accepting, you can do so by accepting `ScriptValue` arguments like so: + +```rust,ignore + NamespaceBuilder::::new(&mut world) + .register( + "is_integer", + |s: ScriptValue| { + match s { + ScriptValue::Integer(i) => true, + _ => false + } + }, + ); +``` + +You can treat return values similarly. + +## Fallible functions + +Your script functions can return errors either by: +- Returning `Result` +- Returning `ScriptValue` and manually creating the `ScriptValue::Error(into_interop_erorr.into())` variant. + diff --git a/docs/src/Summary/installation.md b/docs/src/Summary/installation.md new file mode 100644 index 00000000..0d134682 --- /dev/null +++ b/docs/src/Summary/installation.md @@ -0,0 +1,56 @@ +# Installation + +## Cargo + +First you need to install the crate by adding this entry to your `Cargo.toml` dependencies list: + +```toml +bevy_mod_scripting = { version = "0.9.0", features = ["lua54"]} +``` + +Choose the language features you wish enabled and add them to the features block. + + +## Bevy Plugin + +The next step is to add the BMS plugin to your application, on top of any other extras you want included in your app: + +```rust,ignore +app.add_plugins(LuaScriptingPlugin::default()); +``` + +The above is how you'd setup BMS for Lua, if you want to use another language, simply use a corresponding plugin from the integration crate. + + +## Language Features + +Each language supported by BMS can be switched-on via feature flag as below: + +| Language | Feature Flag | +| ---- | ---- | +| Lua51 | lua51 | +| Lua52 | lua54 | +| Lua53 | lua53 | +| Lua54 | lua54 | +| Luajit | luajit | +| Luajit52 | luajit52 | +| Luau | luau | +| Rhai | rhai | +| Rune | rune | + +## Extra Features + +In order to fit as many use cases as possible, BMS allows you to disable a lot of its functionality. + +By default all of the useful features are enabled, but you may disable them if you wish if you are only needing BMS for script lifecycle management, and want to populate the bindings yourself. + +| Feature | Description | +| ---- | ---- | +| core_functions | If enabled, will enable all core functions, i.e. bevy integrations which let you interact with Bevy via reflection | +| bevy_bindings | If enabled, populates the function registry with additiona automatically generated bevy bindings. This includes functions on `glam` and `bevy::ecs` types. These are useful but will slow down compilation considerably. | +| mlua_async | Enables `mlua/async`| +| mlua_serialize | Enables `mlua/serialize` | +| mlua_macros | Enables `mlua/macros` | +| unsafe_lua_modules | Allows loading unsafe modules via `require` in lua | + + diff --git a/docs/src/Summary/managing-scripts.md b/docs/src/Summary/managing-scripts.md new file mode 100644 index 00000000..05596684 --- /dev/null +++ b/docs/src/Summary/managing-scripts.md @@ -0,0 +1,52 @@ +# Managing Scripts + +Scripts live in the standard bevy `assets` directory. Loading a script means: +- Parsing the script body +- Creating or updating the resources which store script state +- Assigning a name/id to the script so it can be referred to by the rest of the application. + +## Loading +BMS listens to `ScriptAsset` events and reacts accordingly. In order to load a script, all you need to do is request a handle to it via the asset server and store it somewhere. + +Below is an example system which loads a script called `assets/my_script.lua` and stores the handle in a local system parameter: + +```rust,ignore +fn load_script(server: Res, mut handle: Local>) { + let handle_ = server.load::("my_script.lua"); + *handle = handle_; +} +``` + +In practice you will likely store this handle in a resource or component, when your load all the scripts necessary for your application. + +## Unloading +Scripts are automatically unloaded when the asset is dropped. This means that if you have a handle to a script and it goes out of scope, the script will be unloaded. + + +This will delete references to the script and remove any internal handles to the asset. You will also need to clean up any handles to the asset you hold in your application in order for the asset to be unloaded. + +## Hot-loading scripts +To enable hot-loading of assets, you need to enable the necessary bevy features as normal [see the bevy cheatbook for instructions](https://bevy-cheatbook.github.io/assets/hot-reload.html). + +Assuming that hot-reloading is enabled for your app, any changes to script assets will automatically be picked up and the scripts re-loaded. + +## Manually (re)loading scripts +In order to manually re-load or load a script you can issue the `CreateOrUpdateScript` command: + +```rust,ignore +CreateOrUpdateScript::::new("my_script.lua".into(), "print(\"hello world from new script body\")".into(), asset_handle) +``` + +replace `LuaScriptingPlugin` with the scripting plugin you are using. + +## Manually Deleting scripts +In order to delete a previously loaded script, you will need to issue a `DeleteScript` command like so: + +```rust,ignore +DeleteScript::::new("my_script.lua".into()) +``` + +replace `LuaScriptingPlugin` with the scripting plugin you are using. + +## Loading/Unloading timeframe +Scripts are processed via commands, so any asset events will be processed at the next command execution point running after BMS internal asset systems. \ No newline at end of file diff --git a/docs/src/Summary/running-scripts.md b/docs/src/Summary/running-scripts.md new file mode 100644 index 00000000..3d072515 --- /dev/null +++ b/docs/src/Summary/running-scripts.md @@ -0,0 +1,50 @@ +# Attaching Scripts + +Once you have scripts discovered and loaded, you'll want to run them. At the moment BMS supports one method of triggering scripts, and that is by attaching them to entities via `ScriptComponent`'s and then sending script event's which trigger callbacks on the scripts. + +In order to attach a script and make it runnable simply add a `ScriptComponent` to an entity +```rust,ignore + commands.entity(my_entity).insert(ScriptComponent::new(vec!["my_script.lua", "my_other_script.lua"])); +``` + +# Running Scripts + +Scripts can run logic either when loaded or when triggered by an event. For example the script: + +```lua +print("hello from load time") +function on_event() + print("hello from event time") +end +``` + +Will print "hello from load time" when the script is loaded, and "hello from event time" when the script receives an event targeting the `on_event` callback with a receiver list including this script or entity. + +In order to trigger `on_event` you need to first define a label, then send an event containing the label: +```rust,ignore +// define the label, you can define as many as you like here +callback_labels!(OnEvent => "on_event"); + +// trigger the event +fn send_event(mut writer: EventWriter) { + writer.send(ScriptCallbackEvent::new_for_all( + OnEvent, + vec![ScriptValue::Unit], + )); +} +``` + +Note the second argument is the payload we are sending with the event, in this case we are sending an empty payload. + + +# Event Handlers + +In order for the events you send to actually be picked up, you need to inject special systems into your application. These systems will listen for the events and trigger the appropriate callbacks on the scripts: + +```rust,ignore +app.add_systems(Update, event_handler::); +``` + +Note the system is parameterized by the label we defined earlier, and the scripting plugin we are using. You can add as many of these systems as you like. + +The event handler will catch all events with the label `OnEvent` and trigger the `on_event` callback on all targeted scripts which have that callback defined. \ No newline at end of file diff --git a/docs/src/chapter_1.md b/docs/src/chapter_1.md deleted file mode 100644 index 1259c54e..00000000 --- a/docs/src/chapter_1.md +++ /dev/null @@ -1,6 +0,0 @@ -# Chapter 1 - - -## Introduction - -Welcome to the greatest documentation of all time WIP \ No newline at end of file diff --git a/examples/lua/bevy_api.rs b/examples/lua/bevy_api.rs deleted file mode 100644 index 493bec50..00000000 --- a/examples/lua/bevy_api.rs +++ /dev/null @@ -1,207 +0,0 @@ -use bevy::app::AppExit; - -use bevy::prelude::*; -use bevy_mod_scripting::prelude::*; - -use bevy_script_api::lua::RegisterForeignLuaType; - -#[derive(Component, Default, Reflect)] -#[reflect(Component)] -pub struct MyComponent { - quat: Quat, - vec2: Vec2, - usize: usize, - f32: f32, - mat3: Mat3, - option_vec3: Option, - vec_of_option_bools: Vec>, - option_vec_of_bools: Option>, -} - -fn main() -> std::io::Result<()> { - let mut app = App::new(); - - app.add_plugins(DefaultPlugins) - .add_plugins(ScriptingPlugin) - .register_type::() - // note the implementation for Option is there, but we must register `LuaProxyable` for it - .register_foreign_lua_type::>() - .register_foreign_lua_type::>>() - .register_foreign_lua_type::>() - .register_foreign_lua_type::>>() - .add_script_host::>(PostUpdate) - .add_api_provider::>(Box::new(LuaBevyAPIProvider)) - .add_api_provider::>(Box::new(LuaCoreBevyAPIProvider)) - .add_systems(Startup, - |world: &mut World| { - - let entity = world.spawn(()) - .insert(MyComponent { - usize: 5, - vec2: Vec2::new(1.0, 2.0), - f32: 6.7, - mat3: Mat3::from_cols( - Vec3::new(1.0, 2.0, 3.0), - Vec3::new(4.0, 5.0, 6.0), - Vec3::new(7.0, 8.0, 9.0), - ), - quat: Quat::from_xyzw(1.0, 2.0, 3.0, 4.0), - option_vec3: None, - vec_of_option_bools: vec![Some(true), None, Some(false)], - option_vec_of_bools: Some(vec![true, true, true]), - }).id(); - - // run script - world.resource_scope(|world, mut host: Mut>| { - host.run_one_shot( - r#" - function table_to_string(t) - local result = "[" - for k,v in pairs(t) do - result = result .. string.format("%s:%s,",k,v) - end - return result .. "]" - end - - function once() - - -- the api provides us with 3 globals - print(entity) - print(script) - print(world) - - -- we first retrieve ID's for our component and resource by their short name (long name/full path also work) - local my_component_type = world:get_type_by_name("MyComponent") - - -- then ask the world to give us a reference to `MyComponent` on the entity we just spawned - -- resources work the same way, but we use `get_resource` instead of `get_component` - -- the comp object is resolved to a `bevy_script_api::script_ref::ReflectValue` which implements UserData. - -- we can use a custom proxy instead (by implementing LuaProxyable), but this is the simplest way to get started. - local comp = world:get_component(entity, my_component_type) - print("Before script: ", comp) - - print("============") - - -- the index metamethod on ReflectValue's uses bevy's reflection mechanism on top of some custom sub-reflection logic to - -- allow reflecting inside Options, Vectors etc. - -- when we index into ReflectValue's we either get back a custom proxy or another ReflectValue - - -- the LuaBevyAPIProvider provides us custom proxies for many bevy types as well as std types. - -- all of these implementations can be overridden via the bevy TypeRegistry - comp.usize = 2 - print("comp.usize after assigning to 2: ", comp.usize) - - -- vec's and matrices have custom __index and __newindex overrides - print("comp.vec2 before: ", comp.vec2) - comp.vec2[1] = 69 - print("comp.vec2 after: ", comp.vec2) - - -- Option's get converted to nil or the value inside - print("comp.option_vec3 before: ", comp.option_vec3) - comp.option_vec3 = Vec3.new(2,1,3) - print("comp.option_vec3 after: ", comp.option_vec3) - - -- reflection via index is indexed starting at 1, unlike in Rust to match Lua's indexing - print("comp.option_vec3[1] before: ", comp.option_vec3[1]) - comp.option_vec3[1] = 5 - print("comp.option_vec3[1] after: ", comp.option_vec3[1]) - - print("============") - - -- Vec references get converted to a custom proxy `LuaVec` which is - -- also assignable via lua tables - - print("comp.vec_of_option_bools before: ", table_to_string(comp.vec_of_option_bools)) - comp.vec_of_option_bools = {true,false,true} - print("comp.vec_of_option_bools after assignment: ", table_to_string(comp.vec_of_option_bools)) - - print("comp.vec_of_option_bools[1] before: ", comp.vec_of_option_bools[1]) - comp.vec_of_option_bools[1] = false - print("comp.vec_of_option_bools[1] after: ", comp.vec_of_option_bools[1]) - - -- there are some additional methods available on LuaVec proxies imitating the Vec api - print("comp.vec_of_option_bools before insert: ", table_to_string(comp.vec_of_option_bools)) - comp.vec_of_option_bools:insert(1,nil) - print("comp.vec_of_option_bools after insert: ", table_to_string(comp.vec_of_option_bools)) - - print("comp.vec_of_option_bools before push: ", table_to_string(comp.vec_of_option_bools)) - comp.vec_of_option_bools:push(false) - print("comp.vec_of_option_bools after push: ", table_to_string(comp.vec_of_option_bools)) - - print("comp.vec_of_option_bools len after push: ", #comp.vec_of_option_bools) - - print("comp.vec_of_option_bools before pop: ", table_to_string(comp.vec_of_option_bools)) - print(comp.vec_of_option_bools:pop()) - print("comp.vec_of_option_bools after pop: ", table_to_string(comp.vec_of_option_bools)) - - print("the pairs inside comp.vec_of_option_bools: ") - for k,v in pairs(comp.vec_of_option_bools) do - print(string.format(" - %s:%s",k,v)) - end - - comp.vec_of_option_bools:clear() - print("comp.vec_of_option_bools after clear: ", table_to_string(comp.vec_of_option_bools)) - - print("comp.vec_of_option_bools len after clear: ", #comp.vec_of_option_bools) - print("============") - - print("comp.option_vec_of_bools before: ", table_to_string(comp.option_vec_of_bools)) - print(comp.option_vec_of_bools:pop()) - print("comp.option_vec_of_bools after pop: ", table_to_string(comp.option_vec_of_bools)) - - - print("comp.option_vec_of_bools len after pop: ", #comp.option_vec_of_bools) - - print("the pairs inside comp.option_vec_of_bools: ") - for k,v in pairs(comp.option_vec_of_bools) do - print(string.format(" - %s:%s",k,v)) - end - - print("============") - - local complex_vec_op = Vec3.new(0,1,0):any_orthonormal_vector() + comp.mat3.x_axis - print("(0,1,0).any_orthonormal_vector() + mat3.x_axis is: ", complex_vec_op) - - local new_mat3 = Mat3.from_cols(Vec3.new(1,0,0),Vec3.new(0,1,0),Vec3.new(0,0,-1)) - print("new_mat3 is:", new_mat3) - - comp.vec2 = comp.vec2 + comp.vec2 - comp.usize = comp.vec2:min_element() - comp.f32 = comp.f32 + comp.f32 + comp.vec2:min_element() - comp.vec2 = Vec2.new(2,1) - comp.quat = Quat.from_xyzw(3,2,1,4) - comp.mat3.x_axis = Vec3.new(69,69,69) - - print("============") - - -- this is an example of something impossible to achieve with plain bevy reflection under the hood - comp.mat3[1][1] = 42 - - -- now let's retrieve these again to see if we actually changed their values permanently - comp = world:get_component(entity,my_component_type) - - print("After script:") - print(comp) - end - "# - .as_bytes(), - "script.lua", - entity, - world, - LuaEvent { - hook_name: "once".to_owned(), - args: (), - recipients: Recipients::All, - }, - ) - .expect("Something went wrong in the script!"); - }); - - world.send_event(AppExit::Success); - }, - ); - - app.run(); - - Ok(()) -} diff --git a/examples/lua/complex_game_loop.rs b/examples/lua/complex_game_loop.rs deleted file mode 100644 index 55efa657..00000000 --- a/examples/lua/complex_game_loop.rs +++ /dev/null @@ -1,193 +0,0 @@ -use bevy::core::FrameCount; -use bevy::ecs::schedule::ScheduleLabel; -use bevy::prelude::*; -use bevy_mod_scripting::prelude::*; -use rand::prelude::SliceRandom; -use std::sync::atomic::AtomicU32; -use std::sync::atomic::Ordering::Relaxed; - -#[derive(Clone)] -/// The type we will be using to send data to Lua -pub struct MyLuaArg(usize); - -impl<'lua> IntoLua<'lua> for MyLuaArg { - fn into_lua(self, lua: &'lua Lua) -> mlua::Result> { - self.0.into_lua(lua) - } -} - -/// Used to assign events unique ids -static COUNTER: AtomicU32 = AtomicU32::new(0); - -/// The event firing logic we will use at the each stage of the game loop -/// Fires a random event from the pool of all events i.e. one of: -/// - on_pre_physics, priority: 0 -/// - on_post_physics, priority: 11 -/// - on_pre_physics, priority: 21 -fn fire_random_event(w: &mut PriorityEventWriter>>) { - let mut rng = rand::thread_rng(); - let id = COUNTER.fetch_add(1, Relaxed); - let arg = MyLuaArg(id as usize); - let (event, prio) = [ - ("on_pre_physics", 0), - ("on_post_physics", 11), - ("on_post_update", 21), - ] - .choose(&mut rng) - .map(|v| { - let mut args = mlua::Variadic::new(); - args.push(arg); - ( - LuaEvent { - hook_name: v.0.to_string(), - args, - recipients: Recipients::All, - }, - v.1, - ) - }) - .unwrap(); - - info!( - "\t - event: {},\t prio: {},\t id: {}", - event.hook_name, prio, id - ); - w.send(event, prio); -} - -/// physics stage logic, represents a bunch of systems sending events of various types and priorities -fn do_physics(mut w: PriorityEventWriter>>) { - info!("Physics, firing:"); - - for _ in 0..5 { - fire_random_event(&mut w); - } -} - -/// update stage logic, fired each frame, represents a bunch of systems sending events of various types and priorities -/// we fire just one since we want to keep the output clean -fn do_update(mut w: PriorityEventWriter>>) { - info!("Update, firing:"); - - fire_random_event(&mut w); -} - -/// We will run this system at the end of each update to make the output easier to read -fn print_frame_count(frame: Res) { - info!("================ Frame no {} End ================", frame.0); -} - -fn load_our_script(server: Res, mut commands: Commands) { - let path = "scripts/complex_game_loop.lua"; - let handle = server.load::(path); - - commands.spawn(()).insert(ScriptCollection:: { - scripts: vec![Script::::new(path.to_string(), handle)], - }); -} - -#[derive(ScheduleLabel, Debug, Clone, PartialEq, Eq, Hash, SystemSet)] -enum ComplexGameLoopSet { - Physics, - PrePhysicsScripts, - PostPhysicsScripts, - PostUpdateScripts, - EndFrame, -} - -fn main() -> std::io::Result<()> { - const TIMESTEP_2_PER_SECOND: f64 = 30.0 / 60.0; - - let mut app = App::new(); - - // first let's configure the set orders: - // we run the pre-physics scripts before physics (duh) - // we run the post-physics scripts after physics - // we run the post-update scripts after post-update - // pretty straightforward, note we use FixedUpdate for physics, which means it runs less often than Update - app.add_plugins(DefaultPlugins) - .insert_resource(Time::::from_seconds(TIMESTEP_2_PER_SECOND)) - .add_plugins(ScriptingPlugin) - .add_systems(Startup, load_our_script) - .configure_sets( - FixedUpdate, - ComplexGameLoopSet::PrePhysicsScripts.before(ComplexGameLoopSet::Physics), - ) - .configure_sets( - FixedUpdate, - ComplexGameLoopSet::PostPhysicsScripts.after(ComplexGameLoopSet::Physics), - ) - .configure_sets( - PostUpdate, - ComplexGameLoopSet::EndFrame.after(ComplexGameLoopSet::PostUpdateScripts), - ); - - // Now let's configure our game's main logic/engine systems - app.add_systems(FixedUpdate, do_physics.in_set(ComplexGameLoopSet::Physics)) - // main update logic system set (every frame) - .add_systems(Update, do_update) - .add_systems( - PostUpdate, - print_frame_count.in_set(ComplexGameLoopSet::EndFrame), - ); - - // Finally let's configure the scripting systems. - // Think of the priority value of events as their "order" - // Events with priority "1" go before events of priority "2" - app - // --- script handler system sets - // pre_physics, event priority: [0,10] inclusive - // handlers always ignore the events of lower priority than their range - // meaning this one will only handle pre_physics events - .add_script_handler_to_set::>, 0, 10>( - FixedUpdate, - ComplexGameLoopSet::PrePhysicsScripts, - ) - // post_physics, event priority: [11,20] inclusive - // This handler one will only ever handle post_physics events, - // events of higher priority [0-11] are discarded completely - // (the logic being: if we are at a point in time where we are handling post_physics events, we don't care about pre_physics events) - .add_script_handler_to_set::>, 11, 20>( - FixedUpdate, - ComplexGameLoopSet::PostPhysicsScripts, - ) - // post_update, priority: [21,30] inclusive - // similar to before, only post_update events are handled - .add_script_handler_to_set::>, 21, 30>( - PostUpdate, - ComplexGameLoopSet::PostUpdateScripts, - ) - // finally we add core script host systems to PostUpdate - // these handle the scripts themselves i.e. add/remove/modify them when necessary - .add_script_host_to_set::>>( - PostUpdate, - ComplexGameLoopSet::PostUpdateScripts, - ); - // We have 2 core systems - - // Physics (twice per second), fires 5 random events - // Update (every frame), fires 1 random event - - // and 3 event handlers - - // pre_physics (twice per second) - // post_physics (twice per second) - // post_update (every frame) - - // each of those spawns a single random event from the pool of all events - // when a handler encounters an event of higher priority outside its range, that event is discarded - // when a handler encounters an event of lower priority outside its range, it's left in the queue - // therefore - // in our case, Physics systems can generate events which can be handled by post_update, - // but Update cannot send events which are handled by anything other than post_update - - // note that regardless of the order in which the events were spawned - // priority decides the order in which they are executed - // in case of identical priority, order is the tie-breaker (earlier events launch first) - - // interestingly, because the Main bevy scheduler runs FixedUpdate systems *before* any Update systems, in this case - // on_pre_physics events will *never* be handled! (they are discarded by the post_physics handler, and the update system never runs before physics) - app.run(); - - Ok(()) -} diff --git a/examples/lua/console_integration.rs b/examples/lua/console_integration.rs deleted file mode 100644 index ca1711d2..00000000 --- a/examples/lua/console_integration.rs +++ /dev/null @@ -1,180 +0,0 @@ -use bevy::{ecs::event::Events, prelude::*}; -use bevy_console::{AddConsoleCommand, ConsoleCommand, ConsolePlugin, PrintConsoleLine}; -use bevy_mod_scripting::prelude::*; -use clap::Parser; - -use std::sync::Mutex; - -#[derive(Default)] -pub struct LuaAPIProvider; - -/// the custom Lua api, world is provided via a global pointer, -/// and callbacks are defined only once at script creation -impl APIProvider for LuaAPIProvider { - type APITarget = Mutex; - type DocTarget = LuaDocFragment; - type ScriptContext = Mutex; - - fn attach_api(&mut self, ctx: &mut Self::APITarget) -> Result<(), ScriptError> { - // callbacks can receive any `ToLuaMulti` arguments, here '()' and - // return any `FromLuaMulti` arguments, here a `usize` - // check the Rlua documentation for more details - - let ctx = ctx.get_mut().unwrap(); - - ctx.globals() - .set( - "print_to_console", - ctx.create_function(|ctx, msg: String| { - // retrieve the world pointer - let world = ctx.get_world()?; - let mut world = world.write(); - - let mut events: Mut> = - world.get_resource_mut().unwrap(); - events.send(PrintConsoleLine { line: msg }); - - // return something - Ok(()) - }) - .map_err(ScriptError::new_other)?, - ) - .map_err(ScriptError::new_other)?; - - Ok(()) - } - - fn setup_script( - &mut self, - _: &ScriptData, - _: &mut Self::ScriptContext, - ) -> Result<(), ScriptError> { - Ok(()) - } -} - -/// sends updates to script host which are then handled by the scripts -/// in their designated system sets -pub fn trigger_on_update_lua(mut w: PriorityEventWriter>) { - let event = LuaEvent { - hook_name: "on_update".to_string(), - args: (), - recipients: Recipients::All, - }; - - w.send(event, 0); -} - -pub fn forward_script_err_to_console( - mut r: EventReader, - mut w: EventWriter, -) { - for e in r.read() { - w.send(PrintConsoleLine { - line: format!("ERROR:{}", e.error), - }); - } -} - -// we use bevy-debug-console to demonstrate how this can fit in in the runtime of a game -// note that using just the entity id instead of the full Entity has issues, -// but since we aren't despawning/spawning entities this works in our case -#[derive(Parser, ConsoleCommand)] -#[command(name = "run_script")] -///Runs a Lua script from the `assets/scripts` directory -pub struct RunScriptCmd { - /// the relative path to the script, e.g.: `/hello.lua` for a script located in `assets/scripts/hello.lua` - pub path: String, - - /// the entity id to attach this script to - pub entity: Option, -} - -pub fn run_script_cmd( - mut log: ConsoleCommand, - server: Res, - mut commands: Commands, - mut existing_scripts: Query<&mut ScriptCollection>, -) { - if let Some(Ok(RunScriptCmd { path, entity })) = log.take() { - let handle = server.load::(&format!("scripts/{}", &path)); - - match entity { - Some(e) => { - if let Ok(mut scripts) = existing_scripts.get_mut(Entity::from_raw(e)) { - info!("Creating script: scripts/{} {:?}", &path, e); - scripts.scripts.push(Script::::new(path, handle)); - } else { - log.reply_failed("Something went wrong".to_string()); - }; - } - None => { - info!("Creating script: scripts/{}", &path); - - commands.spawn(()).insert(ScriptCollection:: { - scripts: vec![Script::::new(path, handle)], - }); - } - }; - } -} - -pub fn delete_script_cmd( - mut log: ConsoleCommand, - mut scripts: Query<(Entity, &mut ScriptCollection)>, -) { - if let Some(Ok(DeleteScriptCmd { name, entity_id })) = log.take() { - for (e, mut s) in scripts.iter_mut() { - if e.index() == entity_id { - let old_len = s.scripts.len(); - s.scripts.retain(|s| s.name() != name); - - if old_len > s.scripts.len() { - log.reply_ok(format!("Deleted script {}, on entity: {}", name, entity_id)); - } else { - log.reply_failed(format!( - "Entity {} did own a script named: {}", - entity_id, name - )) - }; - return; - } - } - - log.reply_failed("Could not find given entity ID with a script") - } -} - -#[derive(Parser, ConsoleCommand)] -#[command(name = "delete_script")] -///Runs a Lua script from the `assets/scripts` directory -pub struct DeleteScriptCmd { - /// the name of the script - pub name: String, - - /// the entity the script is attached to - pub entity_id: u32, -} - -fn main() -> std::io::Result<()> { - let mut app = App::new(); - app.add_plugins(DefaultPlugins) - .add_plugins(ScriptingPlugin) - .add_plugins(ConsolePlugin) - // register bevy_console commands - .add_console_command::(run_script_cmd) - .add_console_command::(delete_script_cmd) - // choose and register the script hosts you want to use - .add_script_host::>(PostUpdate) - .add_api_provider::>(Box::new(LuaAPIProvider)) - .add_api_provider::>(Box::new(LuaCoreBevyAPIProvider)) - .add_script_handler::, 0, 0>(PostUpdate) - // add your systems - .add_systems(Update, trigger_on_update_lua) - .add_systems(Update, forward_script_err_to_console); - - info!("press '~' to open the console. Type in `run_script \"console_integration.lua\"` to run example script!"); - app.run(); - - Ok(()) -} diff --git a/examples/lua/coroutines.rs b/examples/lua/coroutines.rs deleted file mode 100644 index 2285984a..00000000 --- a/examples/lua/coroutines.rs +++ /dev/null @@ -1,40 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::prelude::*; - -/// fire on_update -fn do_update(mut w: PriorityEventWriter>) { - let event = LuaEvent { - hook_name: "on_update".to_owned(), - args: (), - recipients: Recipients::All, - }; - - w.send(event, 0); -} - -fn load_our_scripts(server: Res, mut commands: Commands) { - let path = "scripts/coroutines.lua"; - let handle = server.load::(path); - let script = Script::::new(path.to_string(), handle); - - commands.spawn(()).insert(ScriptCollection:: { - scripts: vec![script], - }); -} - -fn main() -> std::io::Result<()> { - let mut app = App::new(); - - app.add_plugins(DefaultPlugins) - .add_plugins(ScriptingPlugin) - .add_systems(Startup, load_our_scripts) - // randomly fire events for either all scripts, - // the script with id 0 - // or the script with id 1 - .add_systems(Update, do_update) - .add_script_handler::, 0, 0>(PostUpdate) - .add_script_host::>(PostUpdate); - app.run(); - - Ok(()) -} diff --git a/examples/lua/documentation_gen.rs b/examples/lua/documentation_gen.rs deleted file mode 100644 index 12e8e59e..00000000 --- a/examples/lua/documentation_gen.rs +++ /dev/null @@ -1,99 +0,0 @@ -use bevy::prelude::*; - -use bevy_mod_scripting::{api::impl_tealr_type, prelude::*}; - -use std::sync::Mutex; - -#[derive(Clone)] -pub struct MyLuaArg; - -impl<'lua> IntoLua<'lua> for MyLuaArg { - fn into_lua(self, _lua: &'lua Lua) -> mlua::Result> { - Ok(Value::Nil) - } -} - -#[derive(Clone)] -/// This is acts as a documentation and function holder -/// We can add some general documentation about what it holds -/// but also specific function level documenation -pub struct APIModule; - -impl_tealr_type!(APIModule); - -impl TealData for APIModule { - fn add_methods<'lua, T: tealr::mlu::TealDataMethods<'lua, Self>>(methods: &mut T) { - methods - .document_type("This is type level documentation for our api, it will be shown first"); - methods.document_type(""); - - methods.document("Here we document the next function"); - methods.document("## Markdown!:"); - methods.document( - "```lua - local hello = \"string\" - \n```", - ); - methods.add_function("my_function", |_, ()| Ok("hello world!")); - methods.generate_help(); - } -} - -/// This is tealr's way to export global items -/// Here `my_api` will be available globally in the lua script - -#[derive(Default)] -struct Export; -impl tealr::mlu::ExportInstances for Export { - fn add_instances<'lua, T: tealr::mlu::InstanceCollector<'lua>>( - self, - instance_collector: &mut T, - ) -> mlua::Result<()> { - instance_collector.document_instance("Documentation for the exposed global variable"); - instance_collector.add_instance("my_api", |_| Ok(APIModule))?; - - Ok(()) - } -} - -#[derive(Default)] -pub struct LuaAPIProvider; - -impl APIProvider for LuaAPIProvider { - type APITarget = Mutex; - type DocTarget = LuaDocFragment; - type ScriptContext = Mutex; - - fn attach_api(&mut self, _ctx: &mut Self::APITarget) -> Result<(), ScriptError> { - Ok(()) - } - - fn get_doc_fragment(&self) -> Option { - Some(LuaDocFragment::new("MyAPI", |tw| - // we must select items we want included in the documentation - tw.process_type::() - .document_global_instance::().unwrap())) - } - - fn register_with_app(&self, _app: &mut App) {} -} - -fn main() -> std::io::Result<()> { - let mut app = App::new(); - - app.add_plugins(DefaultPlugins) - .add_plugins(ScriptingPlugin) - // add the providers and script host - .add_script_host::>(PostUpdate) - .add_api_provider::>(Box::new(LuaAPIProvider)) - .add_api_provider::>(Box::new(LuaCoreBevyAPIProvider)) - .add_api_provider::>(Box::new(LuaBevyAPIProvider)) - // this needs to be placed after any `add_api_provider` and `add_script_host` calls - // it will generate `doc` and `types` folders under `assets/scripts` containing the documentation and teal declaration files - // respectively. See example asset folder to see how they look like. The `teal_file.tl` script in example assets shows the usage of one of those - // declaration files, use the teal vscode extension to explore the type hints! - // Note: This is a noop in optimized builds unless the `doc_always` feature is enabled! - .update_documentation::>() - .add_script_handler::, 0, 0>(PostUpdate); - Ok(()) -} diff --git a/examples/lua/dynamic_queries.rs b/examples/lua/dynamic_queries.rs deleted file mode 100644 index 9a07eb64..00000000 --- a/examples/lua/dynamic_queries.rs +++ /dev/null @@ -1,64 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::prelude::*; - -#[derive(Component, Reflect)] -#[reflect(Component)] -pub struct ComponentA; - -#[derive(Component, Reflect)] -#[reflect(Component)] -pub struct ComponentB; - -#[derive(Component, Reflect)] -#[reflect(Component)] -pub struct ComponentC; - -fn main() { - let mut app = App::new(); - - app.add_plugins((DefaultPlugins, ScriptingPlugin)) - .register_type::() - .register_type::() - .register_type::() - .add_script_host::>(PostUpdate) - .add_script_handler::, 0, 0>(PostUpdate) - .add_api_provider::>(Box::new(LuaBevyAPIProvider)) - .add_api_provider::>(Box::new(LuaCoreBevyAPIProvider)) - .add_systems(Startup, (setup, apply_deferred, run).chain()) - .run(); -} - -fn setup(mut commands: Commands, asset_server: Res) { - commands.spawn((ComponentA,)); - commands.spawn((ComponentA, ComponentB)); - commands.spawn((ComponentA, ComponentC)); - commands.spawn((ComponentA, ComponentB, ComponentC)); - - commands.spawn((ComponentB,)); - commands.spawn((ComponentB, ComponentC)); - commands.spawn((ComponentB, ComponentA)); - commands.spawn((ComponentB, ComponentA, ComponentC)); - - commands.spawn((ComponentC,)); - commands.spawn((ComponentC, ComponentA)); - commands.spawn((ComponentC, ComponentB)); - commands.spawn((ComponentC, ComponentA, ComponentB)); - - let path = "scripts/dynamic_queries.lua"; - let handle = asset_server.load(path); - - commands.spawn(ScriptCollection:: { - scripts: vec![Script::new(path.into(), handle)], - }); -} - -fn run(mut events: PriorityEventWriter>) { - events.send( - LuaEvent { - hook_name: "on_event".into(), - args: (), - recipients: Recipients::All, - }, - 0, - ); -} diff --git a/examples/lua/event_recipients.rs b/examples/lua/event_recipients.rs deleted file mode 100644 index 3a8a75e1..00000000 --- a/examples/lua/event_recipients.rs +++ /dev/null @@ -1,134 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::prelude::*; -use rand::prelude::SliceRandom; -use std::sync::atomic::Ordering::Relaxed; -use std::sync::{atomic::AtomicU32, Mutex}; - -#[derive(Clone)] -pub struct MyLuaArg(usize); - -impl<'lua> IntoLua<'lua> for MyLuaArg { - fn into_lua(self, lua: &'lua Lua) -> mlua::Result> { - self.0.into_lua(lua) - } -} - -#[derive(Default)] -pub struct LuaAPIProvider; - -/// the custom Lua api, world is provided via a global pointer, -/// and callbacks are defined only once at script creation -impl APIProvider for LuaAPIProvider { - type APITarget = Mutex; - type DocTarget = LuaDocFragment; - type ScriptContext = Mutex; - - fn attach_api(&mut self, ctx: &mut Self::APITarget) -> Result<(), ScriptError> { - // callbacks can receive any `ToLuaMulti` arguments, here '()' and - // return any `FromLuaMulti` arguments, here a `usize` - // check the Rlua documentation for more details - - let ctx = ctx.get_mut().unwrap(); - - ctx.globals() - .set( - "print", - ctx.create_function(|_ctx, msg: String| { - info!("{}", msg); - Ok(()) - }) - .map_err(ScriptError::new_other)?, - ) - .map_err(ScriptError::new_other)?; - - Ok(()) - } - - fn setup_script( - &mut self, - script_data: &ScriptData, - ctx: &mut Self::ScriptContext, - ) -> Result<(), ScriptError> { - let ctx = ctx.get_mut().unwrap(); - let globals = ctx.globals(); - globals - .set("script_id", script_data.sid) - .map_err(ScriptError::new_other)?; - Ok(()) - } -} - -static COUNTER: AtomicU32 = AtomicU32::new(0); - -/// utility for generating random events from a list -fn fire_random_event(w: &mut PriorityEventWriter>, events: &[ScriptEventData]) { - let mut rng = rand::thread_rng(); - let id = COUNTER.fetch_add(1, Relaxed); - let arg = MyLuaArg(id as usize); - let event = events - .choose(&mut rng) - .map(|v| LuaEvent { - hook_name: v.0.to_string(), - args: arg, - recipients: v.1.clone(), - }) - .unwrap(); - - info!( - "\t - event: {},\t recipients: {:?},\t id: {}", - event.hook_name, event.recipients, id - ); - w.send(event, 0); -} - -fn do_update(mut w: PriorityEventWriter>) { - info!("Update, firing:"); - - let all_events = [ - ScriptEventData("on_event", Recipients::All), - ScriptEventData("on_event", Recipients::ScriptID(0)), - ScriptEventData("on_event", Recipients::ScriptID(1)), - ScriptEventData( - "on_event", - Recipients::ScriptName("scripts/event_recipients.lua".to_owned()), - ), - ]; - - // fire random event, for any of the system sets - fire_random_event(&mut w, &all_events); -} - -#[derive(Clone)] -pub struct ScriptEventData(&'static str, Recipients); - -fn load_our_scripts(server: Res, mut commands: Commands) { - // spawn two identical scripts - // id's will be 0 and 1 - let path = "scripts/event_recipients.lua"; - let handle = server.load::(path); - let scripts = (0..2) - .map(|_| Script::::new(path.to_string(), handle.clone())) - .collect(); - - commands - .spawn(()) - .insert(ScriptCollection:: { scripts }); -} - -fn main() -> std::io::Result<()> { - let mut app = App::new(); - - app.add_plugins(DefaultPlugins) - .add_plugins(ScriptingPlugin) - .add_systems(Startup, load_our_scripts) - // randomly fire events for either all scripts, - // the script with id 0 - // or the script with id 1 - .add_systems(Update, do_update) - .add_script_handler::, 0, 0>(PostUpdate) - .add_script_host::>(PostUpdate) - .add_api_provider::>(Box::new(LuaAPIProvider)); - app.run(); - - Ok(()) -} diff --git a/examples/lua/game_of_life.rs b/examples/lua/game_of_life.rs index 994d80d9..0487a48a 100644 --- a/examples/lua/game_of_life.rs +++ b/examples/lua/game_of_life.rs @@ -1,9 +1,8 @@ #![allow(deprecated)] -use std::sync::Mutex; use bevy::{ - diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, image::ImageSampler, + log::LogPlugin, prelude::*, reflect::Reflect, render::{ @@ -12,36 +11,114 @@ use bevy::{ }, window::{PrimaryWindow, WindowResized}, }; +use bevy_console::{make_layer, AddConsoleCommand, ConsoleCommand, ConsoleOpen, ConsolePlugin}; +use bevy_mod_scripting::{NamespaceBuilder, ScriptFunctionsPlugin}; +use bevy_mod_scripting_core::{ + asset::ScriptAsset, bindings::script_value::ScriptValue, callback_labels, + event::ScriptCallbackEvent, script::ScriptComponent, systems::event_handler, +}; +use bevy_mod_scripting_lua::LuaScriptingPlugin; +use clap::Parser; -use bevy_mod_scripting::prelude::*; +// CONSOLE SETUP -#[derive(Debug, Default, Clone, Reflect, Component, LuaProxy)] -#[reflect(Component, LuaProxyable)] -pub struct LifeState { - pub cells: Vec, +fn console_app(app: &mut App) -> &mut App { + // forward logs to the console + app.add_plugins(( + DefaultPlugins.set(LogPlugin { + level: bevy::log::Level::INFO, + filter: "error,game_of_life=info".to_owned(), + custom_layer: make_layer, + }), + ConsolePlugin, + )) + .add_console_command::(run_script_cmd) + .add_systems(Startup, |mut open: ResMut| { + open.open = true; + }) } -#[derive(Default)] -pub struct LifeAPI; +fn run_script_cmd( + mut log: ConsoleCommand, + mut commands: Commands, + mut loaded_scripts: ResMut, +) { + if let Some(Ok(command)) = log.take() { + match command { + GameOfLifeCommand::Start => { + // 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()], + )); + } + 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"); -impl APIProvider for LifeAPI { - type APITarget = Mutex; - type ScriptContext = Mutex; - type DocTarget = LuaDocFragment; + // I am not mapping the handles to the script names, so I'll just clear the entire list + loaded_scripts.0.clear(); - fn attach_api(&mut self, _: &mut Self::APITarget) -> Result<(), ScriptError> { - // we don't actually provide anything global - Ok(()) + // you could also do + // commands.queue(DeleteScript::::new( + // "scripts/game_of_life.lua".into(), + // )); + // as this will retain your script asset and handle + } + } } +} - fn register_with_app(&self, app: &mut App) { - // this will register the `LuaProxyable` typedata since we derived it - // this will resolve retrievals of this component to our custom lua object - app.register_type::(); - app.register_type::(); - } +#[derive(Parser, ConsoleCommand)] +#[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 + Stop, +} + +// ------------- GAME OF LIFE +fn game_of_life_app(app: &mut App) -> &mut App { + app.insert_resource(Time::::from_seconds(UPDATE_FREQUENCY.into())) + .add_plugins(( + // for scripting + LuaScriptingPlugin::default(), + ScriptFunctionsPlugin, + )) + .register_type::() + .register_type::() + .init_resource::() + .init_resource::() + .add_systems(Startup, (init_game_of_life_state, load_script_assets)) + .add_systems(Update, (sync_window_size, send_on_click)) + .add_systems( + FixedUpdate, + ( + update_rendered_state.after(sync_window_size), + send_on_update.after(update_rendered_state), + ( + event_handler::, + event_handler::, + ) + .after(send_on_update), + ), + ); + register_script_functions(app) } +#[derive(Debug, Default, Clone, Reflect, Component)] +#[reflect(Component)] +pub struct LifeState { + pub cells: Vec, +} + +#[derive(Debug, Resource, Default)] +pub struct LoadedScripts(pub Vec>); + #[derive(Reflect, Resource)] #[reflect(Resource)] pub struct Settings { @@ -64,10 +141,27 @@ impl Default for Settings { } } -pub fn setup( +/// Prepares any scripts by loading them and storing the handles. +pub fn load_script_assets( + asset_server: Res, + mut loaded_scripts: ResMut, +) { + loaded_scripts + .0 + .push(asset_server.load("scripts/game_of_life.lua")); +} + +pub fn register_script_functions(app: &mut App) -> &mut App { + let world = app.world_mut(); + NamespaceBuilder::::new_unregistered(world).register("info", |s: String| { + bevy::log::info!(s); + }); + app +} + +pub fn init_game_of_life_state( mut commands: Commands, mut assets: ResMut>, - asset_server: Res, settings: Res, ) { let mut image = Image::new_fill( @@ -84,8 +178,6 @@ pub fn setup( image.sampler = ImageSampler::nearest(); - let script_path = bevy_mod_scripting_lua::lua_path!("game_of_life"); - commands.spawn(Camera2d); commands .spawn(Sprite { @@ -103,13 +195,10 @@ pub fn setup( (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), - )], }); + + bevy::log::info!("Game of life was initialized. use `gol start` to start the game!"); + bevy::log::info!("Type `help gol` for more commands."); } pub fn sync_window_size( @@ -159,55 +248,52 @@ pub fn update_rendered_state( 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(); } } +callback_labels!( + OnUpdate => "on_update", + OnClick => "on_click" +); + /// Sends events allowing scripts to drive update logic -pub fn send_on_update(mut events: PriorityEventWriter>) { - events.send( - LuaEvent { - hook_name: "on_update".to_owned(), - args: (), - recipients: Recipients::All, - }, - 1, - ) +pub fn send_on_update(mut events: EventWriter) { + events.send(ScriptCallbackEvent::new_for_all( + OnUpdate, + vec![ScriptValue::Unit], + )); } -/// Sends initialization event -pub fn send_init(mut events: PriorityEventWriter>) { - events.send( - LuaEvent { - hook_name: "init".to_owned(), - args: (), - recipients: Recipients::All, - }, - 0, - ) +pub fn send_on_click( + buttons: Res>, + q_windows: Query<&Window, With>, + mut events: EventWriter, +) { + if buttons.just_pressed(MouseButton::Left) { + let window = q_windows.single(); + let pos = window.cursor_position().unwrap_or_default(); + let x = pos.x as u32; + let y = pos.y as u32; + events.send(ScriptCallbackEvent::new_for_all( + OnClick, + vec![ + ScriptValue::Integer(x as i64), + ScriptValue::Integer(y as i64), + ], + )); + } } const UPDATE_FREQUENCY: f32 = 1.0 / 60.0; +// MAIN + fn main() -> std::io::Result<()> { let mut app = App::new(); - app.add_plugins(DefaultPlugins) - .insert_resource(Time::::from_seconds(UPDATE_FREQUENCY.into())) - .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.after(sync_window_size)) - .add_systems(FixedUpdate, send_on_update.after(update_rendered_state)) - .add_systems(FixedUpdate, script_event_handler::, 0, 1>) - .add_script_host::>(PostUpdate) - .add_api_provider::>(Box::new(LuaCoreBevyAPIProvider)) - .add_api_provider::>(Box::new(LifeAPI)); + console_app(&mut app); + game_of_life_app(&mut app); app.run(); diff --git a/examples/rhai/bevy_api.rs b/examples/rhai/bevy_api.rs deleted file mode 100644 index 88dcc65c..00000000 --- a/examples/rhai/bevy_api.rs +++ /dev/null @@ -1,180 +0,0 @@ -use bevy::app::AppExit; - -use bevy::prelude::*; -use bevy_mod_scripting::{api::rhai::bevy::RhaiBevyAPIProvider, prelude::*}; -use bevy_mod_scripting_rhai::rhai::Engine; -use bevy_script_api::rhai::{std::RegisterVecType, RegisterForeignRhaiType}; - -#[derive(Component, Default, Reflect)] -#[reflect(Component)] -pub struct MyComponent { - quat: Quat, - vec2: Vec2, - usize: usize, - f32: f32, - mat3: Mat3, - option_vec3: Option, - vec_of_option_bools: Vec>, - option_vec_of_bools: Option>, -} - -pub struct MyAPIProvider; -// unlike mlua, rhai does not have the concept of generic types, all functionality is based around -// registering monomorphized functions, therefore we must register functions of generic types for every type we want -// to use them with, it's less convenient and is what the compiler would do anyway but hey it works! -impl APIProvider for MyAPIProvider { - type APITarget = Engine; - - type ScriptContext = RhaiContext; - - type DocTarget = RhaiDocFragment; - - fn attach_api(&mut self, api: &mut Self::APITarget) -> Result<(), ScriptError> { - api.set_max_expr_depths(999, 999); - api.register_vec_functions::>(); - api.register_vec_functions::(); - Ok(()) - } -} - -fn main() -> std::io::Result<()> { - let mut app = App::new(); - - app.add_plugins(DefaultPlugins) - .add_plugins(ScriptingPlugin) - .register_type::() - .register_foreign_rhai_type::>() - .register_foreign_rhai_type::>>() - .register_foreign_rhai_type::>>() - // note the implementation for Option is there, but we must register `LuaProxyable` for it - // this system set handles addition and removal of script contexts, we can safely use `CoreSet::PostUpdate` - .add_script_host::>(PostUpdate) - .add_api_provider::>(Box::new(RhaiBevyAPIProvider)) - .add_api_provider::>(Box::new(MyAPIProvider)) - .add_systems(Update, |world: &mut World| { - let entity = world - .spawn(()) - .insert(MyComponent { - usize: 5, - vec2: Vec2::new(1.0, 2.0), - f32: 6.7, - mat3: Mat3::from_cols( - Vec3::new(1.0, 2.0, 3.0), - Vec3::new(4.0, 5.0, 6.0), - Vec3::new(7.0, 8.0, 9.0), - ), - quat: Quat::from_xyzw(1.0, 2.0, 3.0, 4.0), - option_vec3: Some(Vec3::new(1.0, 2.0, 3.0)), - vec_of_option_bools: vec![Some(true), None, Some(false)], - option_vec_of_bools: Some(vec![true, true, true]), - }) - .id(); - - // run script - world.resource_scope(|world, mut host: Mut>| { - host.run_one_shot( - r#" - fn once() { - print(world); - debug(world.get_children(entity)); - - // we first retrieve ID's for our component and resource by their short name (long name/full path also work) - let my_component_type = world.get_type_by_name("MyComponent"); - - // then ask the world to give us a reference to `MyComponent` on the entity we just spawned - // resources work the same way, but we use `get_resource` instead of `get_component` - // the comp object is resolved to a `bevy_script_api::script_ref::ReflectValue`. - // we can use a custom proxy instead (by implementing RhaiProxyable), but this is the simplest way to get started. - let comp = world.get_component(entity,my_component_type); - - print("Before script: " + comp); - - print("============="); - - comp.usize = 2; - print("comp.usize: after assigning to 2: " + comp.usize); - - // not supported yet (no Bevy proxies yet) - // print("comp.option_vec3 before: " + comp.option_vec3); - // comp.option_vec3 = Vec3::new(2,1,3); - // print("comp.option_vec3 after: " + comp.option_vec3); - - // print("comp.option_vec3[0] before: " + comp.option_vec3[0]); - // comp.option_vec3[1] = 5; - // print("comp.option_vec3[0] after: " + comp.option_vec3[0]); - - print("============="); - - print("comp.vec_of_option_bools before: " + comp.vec_of_option_bools); - comp.vec_of_option_bools = [true,false,true]; - print("comp.vec_of_option_bools after: " + comp.vec_of_option_bools); - - print("comp.vec_of_option_bools[0] before: " + comp.vec_of_option_bools[0]); - comp.vec_of_option_bools[0] = false; - print("comp.vec_of_option_bools[0] after: " + comp.vec_of_option_bools[0]); - - print("comp.vec_of_option_bools before insert: " + comp.vec_of_option_bools); - comp.vec_of_option_bools.insert(1,()); - print("comp.vec_of_option_bools after insert: " + comp.vec_of_option_bools); - - print("comp.vec_of_option_bools before push: " + comp.vec_of_option_bools); - comp.vec_of_option_bools.push(false); - print("comp.vec_of_option_bools after push: " + comp.vec_of_option_bools); - - print("comp.vec_of_option_bools len after push: " + comp.vec_of_option_bools.len()); - - print("comp.vec_of_option_bools before pop: " + comp.vec_of_option_bools); - print(comp.vec_of_option_bools.pop()); - print("comp.vec_of_option_bools after pop: " + comp.vec_of_option_bools); - - print("the elements inside comp.vec_of_option_bools: "); - for e in comp.vec_of_option_bools { - print(`elem: ${e}`); - } - - comp.vec_of_option_bools.clear(); - print("comp.vec_of_option_bools after clear: " + comp.vec_of_option_bools); - print("comp.vec_of_option_bools len after clear: " + comp.vec_of_option_bools.len()); - - print("============="); - - print("comp.option_vec_of_bools before: " + comp.option_vec_of_bools); - print(comp.option_vec_of_bools.pop()); - print("comp.option_vec_of_bools after pop: " + comp.option_vec_of_bools); - - print("comp.option_vec_of_bools len after pop: " + comp.option_vec_of_bools.len()); - - print("the elements inside comp.option_vec_of_bools: "); - for e in comp.option_vec_of_bools { - print(`elem: ${e}`); - } - - print("============="); - - - let comp_after = world.get_component(entity, my_component_type); - print("after script:"); - print(comp_after); - - } - "# - .as_bytes(), - "script.rhai", - entity, - world, - RhaiEvent { - hook_name: "once".to_owned(), - args: (), - recipients: Recipients::All, - }, - ) - .expect("Something went wrong in the script!"); - }); - - world.send_event(AppExit::Success); - }); - - app.run(); - - Ok(()) -} diff --git a/examples/rhai/console_integration.rs b/examples/rhai/console_integration.rs deleted file mode 100644 index caeef239..00000000 --- a/examples/rhai/console_integration.rs +++ /dev/null @@ -1,174 +0,0 @@ -use bevy::{ecs::event::Events, prelude::*}; -use bevy_console::{AddConsoleCommand, ConsoleCommand, ConsolePlugin, PrintConsoleLine}; -use bevy_mod_scripting::prelude::*; -use bevy_script_api::common::bevy::ScriptWorld; -use clap::Parser; -/// custom Rhai API, world is provided as a usize (by the script this time), since -/// Rhai does not allow global/local variable access from a callback -#[derive(Default)] -pub struct RhaiAPI; - -impl APIProvider for RhaiAPI { - type APITarget = Engine; - type DocTarget = RhaiDocFragment; - type ScriptContext = RhaiContext; - - fn attach_api(&mut self, engine: &mut Self::APITarget) -> Result<(), ScriptError> { - // rhai allows us to decouple the api from the script context, - // so here we do not have access to the script scope, but the advantage is that - // this single engine is shared with all of our scripts. - // we can also set script wide settings here like this one for all our scripts. - - engine.set_max_expr_depths(0, 0); - - engine.register_fn( - "print_to_console", - |world: &mut ScriptWorld, msg: String| { - let mut world = world.write(); - - let mut events: Mut> = world.get_resource_mut().unwrap(); - events.send(PrintConsoleLine { line: msg }); - }, - ); - - engine.register_fn("entity_id", |entity: Entity| entity.index()); - - Ok(()) - } - - fn setup_script( - &mut self, - _: &ScriptData, - _: &mut Self::ScriptContext, - ) -> Result<(), ScriptError> { - Ok(()) - } -} - -// sends updates to script host which are then handled by the scripts -// in the designated system sets -pub fn trigger_on_update_rhai(mut w: PriorityEventWriter>) { - let event = RhaiEvent { - hook_name: "on_update".to_string(), - args: (), - recipients: Recipients::All, - }; - - w.send(event, 0); -} - -pub fn forward_script_err_to_console( - mut r: EventReader, - mut w: EventWriter, -) { - for e in r.read() { - w.send(PrintConsoleLine { - line: format!("ERROR:{}", e.error), - }); - } -} - -// we use bevy-debug-console to demonstrate how this can fit in in the runtime of a game -// note that using just the entity id instead of the full Entity has issues, -// but since we aren't despawning/spawning entities this works in our case -#[derive(Parser, ConsoleCommand)] -#[command(name = "run_script")] -///Runs a Lua script from the `assets/scripts` directory -pub struct RunScriptCmd { - /// the relative path to the script, e.g.: `/hello.lua` for a script located in `assets/scripts/hello.lua` - pub path: String, - - /// the entity id to attach this script to - pub entity: Option, -} - -pub fn run_script_cmd( - mut log: ConsoleCommand, - server: Res, - mut commands: Commands, - mut existing_scripts: Query<&mut ScriptCollection>, -) { - if let Some(Ok(RunScriptCmd { path, entity })) = log.take() { - let handle = server.load::(&format!("scripts/{}", &path)); - - match entity { - Some(e) => { - if let Ok(mut scripts) = existing_scripts.get_mut(Entity::from_raw(e)) { - info!("Creating script: scripts/{} {:?}", &path, e); - - scripts.scripts.push(Script::::new(path, handle)); - } else { - log.reply_failed("Something went wrong".to_string()); - }; - } - None => { - info!("Creating script: scripts/{}", &path); - - commands.spawn(()).insert(ScriptCollection:: { - scripts: vec![Script::::new(path, handle)], - }); - } - }; - } -} - -pub fn delete_script_cmd( - mut log: ConsoleCommand, - mut scripts: Query<(Entity, &mut ScriptCollection)>, -) { - if let Some(Ok(DeleteScriptCmd { name, entity_id })) = log.take() { - for (e, mut s) in scripts.iter_mut() { - if e.index() == entity_id { - let old_len = s.scripts.len(); - s.scripts.retain(|s| s.name() != name); - - if old_len > s.scripts.len() { - log.reply_ok(format!("Deleted script {}, on entity: {}", name, entity_id)); - } else { - log.reply_failed(format!( - "Entity {} did own a script named: {}", - entity_id, name - )) - }; - return; - } - } - - log.reply_failed("Could not find given entity ID with a script") - } -} - -#[derive(Parser, ConsoleCommand)] -#[command(name = "delete_script")] -///Runs a Lua script from the `assets/scripts` directory -pub struct DeleteScriptCmd { - ///the name of the script - pub name: String, - - ///the entity the script is attached to - pub entity_id: u32, -} - -fn main() -> std::io::Result<()> { - let mut app = App::new(); - app.add_plugins(DefaultPlugins) - .add_plugins(ScriptingPlugin) - .add_plugins(ConsolePlugin) - // register bevy_console commands - .add_console_command::(run_script_cmd) - .add_console_command::(delete_script_cmd) - // choose and register the script hosts you want to use - .add_script_host::>(PostUpdate) - .add_api_provider::>(Box::new(RhaiAPI)) - .add_api_provider::>(Box::new(RhaiBevyAPIProvider)) - .add_script_handler::, 0, 0>(PostUpdate) - // add your systems - .add_systems(Update, trigger_on_update_rhai) - .add_systems(Update, forward_script_err_to_console); - - info!("press '~' to open the console. Type in `run_script \"console_integration.rhai\"` to run example script!"); - - app.run(); - - Ok(()) -} diff --git a/examples/rhai/dynamic_queries.rs b/examples/rhai/dynamic_queries.rs deleted file mode 100644 index 887215d4..00000000 --- a/examples/rhai/dynamic_queries.rs +++ /dev/null @@ -1,63 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::prelude::*; - -#[derive(Component, Reflect)] -#[reflect(Component)] -pub struct ComponentA; - -#[derive(Component, Reflect)] -#[reflect(Component)] -pub struct ComponentB; - -#[derive(Component, Reflect)] -#[reflect(Component)] -pub struct ComponentC; - -fn main() { - let mut app = App::new(); - - app.add_plugins((DefaultPlugins, ScriptingPlugin)) - .register_type::() - .register_type::() - .register_type::() - .add_script_host::>(PostUpdate) - .add_script_handler::, 0, 0>(PostUpdate) - .add_api_provider::>(Box::new(RhaiBevyAPIProvider)) - .add_systems(Startup, (setup, apply_deferred, run).chain()) - .run(); -} - -fn setup(mut commands: Commands, asset_server: Res) { - commands.spawn((ComponentA,)); - commands.spawn((ComponentA, ComponentB)); - commands.spawn((ComponentA, ComponentC)); - commands.spawn((ComponentA, ComponentB, ComponentC)); - - commands.spawn((ComponentB,)); - commands.spawn((ComponentB, ComponentC)); - commands.spawn((ComponentB, ComponentA)); - commands.spawn((ComponentB, ComponentA, ComponentC)); - - commands.spawn((ComponentC,)); - commands.spawn((ComponentC, ComponentA)); - commands.spawn((ComponentC, ComponentB)); - commands.spawn((ComponentC, ComponentA, ComponentB)); - - let path = "scripts/dynamic_queries.rhai"; - let handle = asset_server.load(path); - - commands.spawn(ScriptCollection:: { - scripts: vec![Script::new(path.into(), handle)], - }); -} - -fn run(mut events: PriorityEventWriter>) { - events.send( - RhaiEvent { - hook_name: "on_event".into(), - args: (), - recipients: Recipients::All, - }, - 0, - ); -} diff --git a/examples/rune/event_recipients.rs b/examples/rune/event_recipients.rs deleted file mode 100644 index 8b469edf..00000000 --- a/examples/rune/event_recipients.rs +++ /dev/null @@ -1,119 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::prelude::*; -use rand::prelude::SliceRandom; -use std::sync::atomic::AtomicU32; -use std::sync::atomic::Ordering::Relaxed; - -#[derive(Clone)] -pub struct MyRuneArg(usize); - -impl Args for MyRuneArg { - fn into_stack(self, stack: &mut rune::runtime::Stack) -> rune::runtime::VmResult<()> { - (self.0,).into_stack(stack) - } - - fn try_into_vec(self) -> rune::runtime::VmResult> { - (self.0,).try_into_vec() - } - - fn count(&self) -> usize { - 1 - } -} - -/// A custom Rune API. -#[derive(Default)] -pub struct RuneAPIProvider; - -impl APIProvider for RuneAPIProvider { - type APITarget = Context; - type DocTarget = RuneDocFragment; - type ScriptContext = RuneScriptContext; - - fn attach_api(&mut self, ctx: &mut Self::APITarget) -> Result<(), ScriptError> { - let mut module = rune::Module::new(); - - module - .function("info", |msg: String| info!("{msg}")) - .build() - .map_err(ScriptError::new_other)?; - - ctx.install(module).map_err(ScriptError::new_other)?; - - Ok(()) - } -} - -static COUNTER: AtomicU32 = AtomicU32::new(0); - -/// Utility for generating random events from a list. -fn fire_random_event( - w: &mut PriorityEventWriter>, - events: &[ScriptEventData], -) { - let mut rng = rand::thread_rng(); - let id = COUNTER.fetch_add(1, Relaxed); - let arg = MyRuneArg(id as usize); - let event = events - .choose(&mut rng) - .map(|v| RuneEvent { - hook_name: v.0.to_string(), - args: arg, - recipients: v.1.clone(), - }) - .unwrap(); - - info!( - "\t - event: {},\t recipients: {:?},\t id: {}", - event.hook_name, event.recipients, id - ); - w.send(event, 0); -} - -fn do_update(mut w: PriorityEventWriter>) { - info!("Update, firing:"); - - let all_events = [ - ScriptEventData("on_event", Recipients::All), - ScriptEventData("on_event", Recipients::ScriptID(0)), - ScriptEventData("on_event", Recipients::ScriptID(1)), - ScriptEventData( - "on_event", - Recipients::ScriptName("scripts/event_recipients.rune".to_owned()), - ), - ]; - - // fire random event, for any of the system sets - fire_random_event(&mut w, &all_events); -} - -#[derive(Clone)] -pub struct ScriptEventData(&'static str, Recipients); - -fn load_scripts(server: Res, mut commands: Commands) { - // Spawn two identical scripts. - // Their id's will be 0 and 1. - let path = "scripts/event_recipients.rune"; - let handle = server.load::(path); - let scripts = (0..2) - .map(|_| Script::::new(path.to_string(), handle.clone())) - .collect(); - - commands - .spawn(()) - .insert(ScriptCollection:: { scripts }); -} - -fn main() { - App::new() - .add_plugins(DefaultPlugins) - .add_plugins(ScriptingPlugin) - .add_systems(Startup, load_scripts) - // Randomly fire events for either all scripts, the script with an id of `0`, - // or the script with an id of `1`. - .add_systems(Update, do_update) - .add_script_handler::, 0, 0>(PostUpdate) - .add_script_host::>(PostUpdate) - .add_api_provider::>(Box::new(RuneAPIProvider)) - .run(); -} diff --git a/examples/rune/minimal.rs b/examples/rune/minimal.rs deleted file mode 100644 index ff75fbc5..00000000 --- a/examples/rune/minimal.rs +++ /dev/null @@ -1,57 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::prelude::*; - -fn main() { - App::new() - .add_plugins(DefaultPlugins) - .add_plugins(ScriptingPlugin) - .add_systems(Startup, setup) - .add_systems(Update, update) - .add_script_host::>(PostUpdate) - .add_script_handler::, 0, 1>(PostUpdate) - .add_api_provider::>(Box::new(MyAPIProvider)) - .run(); -} - -struct MyAPIProvider; - -impl APIProvider for MyAPIProvider { - type APITarget = Context; - type ScriptContext = RuneScriptContext; - type DocTarget = RuneDocFragment; - - fn attach_api(&mut self, api: &mut Self::APITarget) -> Result<(), ScriptError> { - let mut module = rune::Module::new(); - - module - .function("print_fancy", |msg: &str| println!("✨ {msg} ✨")) - .build() - .map_err(ScriptError::new_other)?; - - api.install(module).map_err(ScriptError::new_other)?; - - Ok(()) - } -} - -fn setup(mut commands: Commands, asset_server: Res) { - let script_path = "scripts/minimal.rune"; - - commands.spawn(ScriptCollection:: { - scripts: vec![Script::new( - script_path.to_owned(), - asset_server.load(script_path), - )], - }); -} - -fn update(mut events: PriorityEventWriter>) { - events.send( - RuneEvent { - hook_name: "on_event".into(), - args: (), - recipients: Recipients::All, - }, - 0, - ); -} diff --git a/examples/wrappers.rs b/examples/wrappers.rs deleted file mode 100644 index fb085ea5..00000000 --- a/examples/wrappers.rs +++ /dev/null @@ -1,120 +0,0 @@ -use bevy::{app::AppExit, prelude::*}; -use bevy_mod_scripting::prelude::*; - -#[derive(LuaProxy, Reflect, Resource, Default, Debug, Clone)] -#[reflect(Resource, LuaProxyable)] -#[proxy( - derive(clone), - functions[ - r#" - #[lua(kind="MutatingMethod")] - fn set_my_string(&mut self, another_string: Option); - "#, - r#" - #[lua(kind="MutatingMethod")] - fn set_with_another(&mut self, #[proxy] another: Self); - "#, - r#" - #[lua(kind="Method")] - fn get_my_string(&self) -> String; - "#, - r#" - #[lua(kind="Method",raw)] - fn raw_method(&self, ctx : &Lua) -> Result { - let a = ctx.globals().get::<_,String>("world").unwrap(); - let a = self.inner()?; - Ok("".to_owned()) - } - "#, - r#" - #[lua(kind="MetaMethod", metamethod="ToString")] - fn to_string(&self) -> String { - format!("{:#?}", _self) - } - "# - ]) - ] -pub struct MyProxiedStruct { - my_string: String, -} - -impl MyProxiedStruct { - fn set_with_another(&mut self, another: MyProxiedStruct) { - self.my_string = another.my_string; - } - - fn set_my_string(&mut self, another_string: Option) { - if let Some(s) = another_string { - self.my_string = s; - } else { - self.my_string = "".to_owned(); - } - } - - fn get_my_string(&self) -> String { - self.my_string.clone() - } -} - -fn main() -> std::io::Result<()> { - let mut app = App::new(); - - app.add_plugins(DefaultPlugins) - .add_plugins(ScriptingPlugin) - .add_script_host::>(PostUpdate) - .register_type::() - .init_resource::() - .add_api_provider::>(Box::new(LuaCoreBevyAPIProvider)) - .add_systems(Startup, |world: &mut World| { - world.insert_resource(MyProxiedStruct { - my_string: "I was retrieved from the world".to_owned(), - }); - - // run script - world.resource_scope(|world, mut host: Mut>| { - host.run_one_shot( - r#" - function once() - local type = world:get_type_by_name("MyProxiedStruct") - local resource = world:get_resource(type) - - print("The initial value is:", resource) - print("The string value is:", resource:get_my_string()) - - resource:set_my_string(nil) - print("The string value after calling 'set_my_string(nil)' is:", resource:get_my_string()) - - resource:set_my_string("I was changed by the script") - print("The string value after calling 'set_my_string(\"I was changed by the script\")' is:", resource:get_my_string()) - - resource:set_with_another(resource) - print("The string value after calling 'set_with_another(resource)' is:", resource:get_my_string()) - - end - "# - .as_bytes(), - "script.lua", - Entity::from_raw(0), - world, - LuaEvent { - hook_name: "once".to_owned(), - args: (), - recipients: Recipients::All, - }, - ) - .expect("Something went wrong in the script!"); - }); - - // print current state of MyThing - let my_thing = world - .get_resource::() - .expect("Could not find MyProxiedStruct Resource"); - println!("After the script MyProxiedStruct resource is now: {my_thing:#?}"); - // exit app - world.send_event(AppExit::Success); - }); - - app.run(); - - Ok(()) -} diff --git a/log.out b/log.out new file mode 100644 index 00000000..f16c4b42 --- /dev/null +++ b/log.out @@ -0,0 +1,841 @@ +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) diff --git a/makefile b/makefile index 5fc3883b..3cb3fd83 100644 --- a/makefile +++ b/makefile @@ -21,20 +21,22 @@ PACKAGE=bevy_mod_scripting TEST_NAME= # # valgrind outputs a callgrind.out.. We can analyze this with kcachegrind # kcachegrind -NIGHTLY_VERSION=nightly-2024-11-05 +NIGHTLY_VERSION=nightly-2024-12-15 BEVY_VERSION=0.15.0 GLAM_VERSION=0.29.0 CODEGEN_PATH=${PWD}/target/codegen BEVY_PATH=${CODEGEN_PATH}/bevy GLAM_PATH=${CODEGEN_PATH}/glam OUTPUT_PATH=${CODEGEN_PATH}/output -GENERATED_SRC_PATH=./crates/bevy_script_api/src/providers +GENERATED_SRC_PATH=./crates/bevy_mod_scripting_functions/src/bevy/ GEN_BEVY_FEATURES=bevy_asset,bevy_animation,bevy_core_pipeline,bevy_ui,bevy_pbr,bevy_render,bevy_text,bevy_sprite,file_watcher,multi_threaded build_test_in_package: - @cargo test --no-run --lib --workspace $(TEST_NAME) - @export OUTPUT=$$(find ./target/debug/deps/ -regex ".*${PACKAGE}[^.]*" -printf "%T@\t%Tc %6k KiB %p\n" | sort -n -r | awk '{print $$NF}' | head -1); \ - mv $${OUTPUT} ./target/debug/test_binary && echo "Using: $${OUTPUT}" && ls -v ./target/debug/ | grep "test_binary" + @RUSTFLAGS=-g cargo test --no-run --all-targets --features ${TEST_FEATURES} --package ${PACKAGE} $(TEST_NAME) --message-format=json | jq -r 'first(select(.executable != null and .target.kind == ["test"])) | .executable' | xargs -I@ ln -fs @ ./target/debug/test_binary + +run_lua_tests: + cargo test --features=lua54 --package bevy_mod_scripting_lua --test lua_tests -- $(TEST_NAME) + comp_benches: RUSTFLAGS="-g" cargo bench --no-run @@ -61,10 +63,10 @@ clean_bevy: cd ${BEVY_PATH} && cargo clean generate_bevy: - cd ${BEVY_PATH} && cargo +${NIGHTLY_VERSION} bevy-api-gen generate --output ${OUTPUT_PATH} --template-args '{ "self_is_bevy_script_api": true}' --features ${GEN_BEVY_FEATURES} -vv + cd ${BEVY_PATH} && cargo +${NIGHTLY_VERSION} bevy-api-gen generate --output ${OUTPUT_PATH} --template-args '{ "self_is_bms_lua": true}' --features ${GEN_BEVY_FEATURES} -vv collect_bevy: - cd ${BEVY_PATH} && cargo +${NIGHTLY_VERSION} bevy-api-gen collect --output ${OUTPUT_PATH} --template-args '{ "self_is_bevy_script_api": true}' -vv + cd ${BEVY_PATH} && cargo +${NIGHTLY_VERSION} bevy-api-gen collect --output ${OUTPUT_PATH} --template-args '{ "self_is_bms_lua": true}' deletion_confirmation: @echo -n "This action will delete ALL files in directories: '${GENERATED_SRC_PATH}' amd ${OUTPUT_PATH} (y/N) " diff --git a/readme.md b/readme.md index 8ac489b4..8ad2ac88 100644 --- a/readme.md +++ b/readme.md @@ -6,284 +6,38 @@ Although Bevy doesn't directly support scripting, efforts are underway to incorporate it. This crate represents an initial attempt to enable scripting within Bevy's existing framework. It's important to note that this is a work in progress and not yet optimized or complete. As Bevy evolves, significant changes to this API are anticipated. -For a detailed look at how this crate works see [architecture.md](architecture.md) - ## Why Use Scripts? -- Refresh your game mechanics without the need for full crate recompilation +- Update your game mechanics without the need for re-compiling - Encapsulating game logic in scripts paves way for modders to create custom content easilly - Scripting game logic/UI in a simpler language broadens development accessibility to non-programmers on your team ## Features -- Hot re-loading scripts -- Lua, Teal, Rhai and Rune integrations -- Automatically generated Bevy bindings for Lua -- CLI rustc extensions for generating your own Lua bindings -- Event based hooks (i.e. `on_update`) -- Flexible event scheduling (i.e. allow handling events at handling stages based on the event) -- Multiple scripts per entity -- Multiple instances of the same script on one entity -- Extensive callback argument type support -- Utilities for generating script native documentation -- Loading external lua libraries via `require` (enabled with `unsafe_lua_modules` cargo feature due to potential unsafety) +- Script management via commands +- Hot loading +- Support for multiple scripting languages +- 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 ## Support -Support for languages is expressed in three levels: - -1. `ScriptHost` implementation, scripts can be loaded, scheduled and run in this language with support for custom `APIProvider` -2. A Bevy API Providedr is implemented which enables access to `entity`,`world` etc and provides support for at least basic operations such as `get_component`, `add_component`, `spawn` etc -3. Macros for generating proxy wrapper structures exist and can be used for custom types with the ability to add script-side functionality -4. Macros instantiations are automatically generated for native Bevy structures - The languages currently supported are as follows: -|Language| Support Level | Documentation Generation | -|----|----|----| -|Lua|4|[Yes](https://makspll.github.io/bevy_mod_scripting_lua/latest/)| -|Lua51|4|[Yes](https://makspll.github.io/bevy_mod_scripting_lua/latest/)| -|Lua52|4|[Yes](https://makspll.github.io/bevy_mod_scripting_lua/latest/)| -|Lua53|4|[Yes](https://makspll.github.io/bevy_mod_scripting_lua/latest/)| -|Lua54|4|[Yes](https://makspll.github.io/bevy_mod_scripting_lua/latest/)| -|Luajit|4|[Yes](https://makspll.github.io/bevy_mod_scripting_lua/latest/)| -|Luajit52|4|[Yes](https://makspll.github.io/bevy_mod_scripting_lua/latest/)| -|Luau|4|[Yes](https://makspll.github.io/bevy_mod_scripting_lua/latest/)| -|Teal|4|[Yes](https://makspll.github.io/bevy_mod_scripting_lua/latest/)| -|Rhai|2|No| -|Rune|1|No| - -## Usage - -### Installation - -To install: - -- Add this crate to your Cargo.toml file dependencies - - The crate is still in development so I recommended pinning to a git commit -- Add ScriptingPlugin to your app -- Add the ScriptHosts you plan on using (`add_script_host`, `add_script_host_to_set`) - - Make sure to attach it to a system set running AFTER any systems which may generate modify/create/remove script components -- Add script handlers to capture events in the priority range you're expecting (`add_script_handler_to_set`,`add_script_handler`) -- Add systems which generate ScriptEvents corresponding to your script host -- Add systems which add ScriptCollection components to your entities and fill them with scripts - -An example can be seen below - -```rust, ignore - -fn main() -> std::io::Result<()> { - let mut app = App::new(); - app.add_plugins(ScriptingPlugin) - .add_plugins(DefaultPlugins) - // pick and register only the hosts you want to use - // use any system set AFTER any systems which add/remove/modify script components - // in order for your script updates to propagate in a single frame - .add_script_host::>(PostUpdate) - .add_script_host::>(PostUpdate) - - // the handlers should be ran after any systems which produce script events. - // The PostUpdate set is okay only if your API doesn't require the core Bevy systems' commands - // to run beforehand. - // Note, this setup assumes a single script handler system set with all events having identical - // priority of zero (see examples for more complex scenarios) - .add_script_handler::, 0, 0>( - CoreSet::PostUpdate, - ) - .add_script_handler::, 0, 0>( - CoreSet::PostUpdate, - ) - - // generate events for scripts to pickup - .add_system(trigger_on_update_lua) - .add_system(trigger_on_update_rhai) - - // attach script components to entities - .add_startup_system(load_a_script); - app.run(); - - Ok(()) -} -``` - -### Firing Script Callbacks - -Scripts are activated by dispatching `ScriptEvents`. This crate employs custom priority event writers and readers, which means events are transmitted with an associated priority. This priority, in conjunction with your event pipeline, influences the sequence in which your events are processed. A priority of 0 is considered the highest. - -This mechanism can be utilized to construct game loops similar to those found in Unity or other game engines. - -An example event dispatching system can be seen below: - -```rust -use bevy::prelude::*; -use bevy_mod_scripting::prelude::*; - - -// event callback generator for lua -#[cfg(feature = "lua")] -pub fn trigger_on_update_lua(mut w: PriorityEventWriter>) { - let event = LuaEvent::<()> { - hook_name: "on_update".to_string(), - args: (), - recipients: Recipients::All - }; - - w.send(event,0); -} -``` - -### Adding scripts - -A script is composed of: - -- A reference to its code file, represented as an asset handle -- A name, typically the path relative to the assets folder - -Scripts are associated with entities through `bevy_mod_scripting::ScriptCollection` components, as illustrated below: - -```rust -use std::sync::Mutex; -use bevy::prelude::*; -use bevy_mod_scripting::prelude::*; - -// An example of a startup system which loads the lua script "console_integration.lua" -// placed in "assets/scripts/" and attaches it to a new entity -#[cfg(feature = "lua")] -pub fn load_a_script( - server: Res, - mut commands: Commands, -) { - // this handle is kept by the script so it will not be unloaded - let path = "scripts/console_integration.lua".to_string(); - let handle = server.load::(&path); - - - commands.spawn(()).insert(ScriptCollection:: { - scripts: vec![Script::::new( - path, handle, - )], - }); -} -``` - -### Defining an API - -To make an API accessible to your scripts, you need to implement the `APIProvider` trait. This can be registered with your script host using the `add_api_provider` method of `App`. `APIProviders` function similarly to plugins: - -```rust -use ::std::sync::Mutex; -use bevy_mod_scripting::prelude::*; - -#[cfg(feature = "lua")] -#[derive(Default)] -pub struct LuaAPI; - -#[cfg(feature = "lua")] -impl APIProvider for LuaAPI { - type APITarget = Mutex; - type DocTarget = LuaDocFragment; - type ScriptContext = Mutex; - - fn attach_api(&mut self, ctx: &mut Self::APITarget) -> Result<(),ScriptError> { - // ... access the lua context here when the script loads - Ok(()) - } -} -``` - -Register your API providers like so: - -```rust, ignore - app.add_plugins(DefaultPlugins) - .add_plugins(ScriptingPlugin) - .add_script_host::>(PostUpdate) - .add_api_provider::>(Box::new(LuaAPI)) - //... -``` -The `APIProvider` interface also includes `setup_script` and `get_doc_fragment` methods. By default, these methods do not perform any operation. However, they can be utilized for specific purposes. For instance, `get_doc_fragment` can be used to generate documentation (refer to examples), and `setup_script` can ensure a one-time setup per script, like setting up a Lua package path. - -### Documentation Generation - -Documentation features are exposed at runtime via the `update_documentation` builder trait method for `App`: - -```rust, no_run -use bevy::prelude::*; -use bevy_mod_scripting::prelude::*; - -fn main() -> std::io::Result<()> { - let mut app = App::new(); - - app.add_plugins(DefaultPlugins) - .add_plugins(ScriptingPlugin); - #[cfg(feature = "lua")] - { - app.add_script_host::>(PostUpdate) - // Note: This is a noop in optimized builds unless the `doc_always` feature is enabled! - // this will pickup any API providers added *BEFOREHAND* like this one - .add_api_provider::>(Box::new(LuaBevyAPIProvider)) - .add_api_provider::>(Box::new(LuaCoreBevyAPIProvider)) - .update_documentation::>() - .add_script_handler::, 0, 0>(PostUpdate); - } - - Ok(()) -} - -``` -#### Lua - -`tealr`, a wrapper around the `mlua` crate, provides mechanisms for Lua documentation generation. It can generate `d.tl` files for static typing in Lua via the `teal` project, but using `teal` isn't necessary for documentation generation. - -See [this example](examples/lua/documentation_gen.rs) for a demonstration. - -The Bevy API documentation for this crate is auto-generated with each release and can be found [here](https://github.com/makspll/bevy_mod_scripting_lua) and [here](https://makspll.github.io/bevy_mod_scripting_lua/v0.3.0/). You may need to adjust the `page_root` in the auto-generated `assets/doc/tealr_doc_gen_config.json` file to a path like `assets/doc/YourAPI`. - -##### Teal - Lua static typing - -Teal is the recommended way of introducing lua to your bevy game. This functionality is locked behind the `teal` cargo feature however, since it's quite opinionanted when it comes to your asset structure (`script` and `scripts/build`, folders under `assets`), and also requires `lua` + `teal` + `tealr_doc_gen` (`cargo install --git https://github.com/lenscas/tealr_doc_gen --rev 91afd4a528e7f5b746ac3a6b299c422b42c05db6`) to be installed (see https://github.com/teal-language/tl and `tealr`). - -Once enabled, `.tl` files can be loaded as lua scripts in addition to `.lua` files and compiled on the fly. With full hot-reloading support. When you're ready to release your game, you just need to run `tl build` from the `assets/scripts` directory to compile your teal files. This will generate `.lua` files under `assets/scripts/build`. You can manage loading scripts using the [`bevy_mod_scripting::lua_path`] macro. - -If `teal` is enabled and you've added the `update_documentation` step to your app, every time you run/build your app in development the following will be generated/synced: - a `scripts/doc` directory containing documentation for your lua exposed API - a `scripts/types` directory containing `.d.tl` files for your lua IDE - a `scripts/tlconfig.lua` file will be generated _once_ if it does not yet exist - any scripts with a `.tl` extension will be compiled to lua code and type checked -On optimized release builds none of this happens (no debug_asserts). - -The recommended workflow is to use vscode and the official teal extension with an additional `tlconfig.lua` file at the **root** of your workspace with the -following content: - -```lua -return { - include_dir = { - "path_to_your_lib/", - } -} -``` - -## Configuration - -- `SCRIPT_DOC_DIR` - documentation is generated in `assets/scripts/docs` or to the path in this ENV variable if it's set. - -## Examples - -To see more complex applications of this library have a look at the examples: - -- [lua - complex game loop](examples/lua/complex_game_loop.rs) -- [lua - event recipients](examples/lua/event_recipients.rs) -- [lua - bevy API](examples/lua/bevy_api.rs) -- [rhai - bevy API](examples/rhai/bevy_api.rs) -- [generating statically typed lua wrappers + ReflectReference system](examples/wrappers.rs) -- [lua - documentation generation + lua static typing](examples/lua/documentation_gen.rs) -- [lua - bevy console integration](examples/lua/console_integration.rs) -- [lua - dynamic queryies](examples/lua/dynamic_queries.rs) -- [rhai - bevy console integration](examples/rhai/console_integration.rs) -- [lua - game of life with teal](examples/lua/game_of_life.rs) -- [rhai - game of life](examples/rhai/game_of_life.rs) - -Below is a video showcasing the game_of_life example: -[![Watch the video](https://img.youtube.com/vi/Mo9gh2g3ZHw/maxresdefault.jpg)](https://www.youtube.com/watch?v=Mo9gh2g3ZHw) - -# Compatibility - -| bevy_mod_scripting | bevy | -|---------------------|--------| -| 0.8 | 0.15 | -| 0.7 | 0.14 | -| 0.6 | 0.13.1 | +|Language | +|----| +|Lua| +|Lua51| +|Lua52| +|Lua53| +|Lua54| +|Luajit| +|Luajit52| +|Luau| +|Rhai| +|Rune| + +## Documentation + +For examples, installation and usage instructions see our shiny new [book](https://makspll.github.io/bevy_mod_scripting) diff --git a/release-plz.toml b/release-plz.toml index 3a224167..4e81f25e 100644 --- a/release-plz.toml +++ b/release-plz.toml @@ -23,14 +23,10 @@ git_release_body = """ """ changelog_include = [ "bevy_mod_scripting_lua", - "bevy_mod_scripting_common", "bevy_mod_scripting_core", "bevy_mod_scripting_rhai", "bevy_mod_scripting_rune", - "bevy_script_api", - "bevy_event_priority", - "bevy_mod_scripting_lua_derive", - "bevy_mod_scripting_rhai_derive", + "bevy_mod_scripting_functions", ] [[package]] @@ -38,10 +34,6 @@ name = "bevy_mod_scripting_lua" publish_features = ["lua54"] version_group = "main" -[[package]] -name = "bevy_mod_scripting_common" -version_group = "main" - [[package]] name = "bevy_mod_scripting_core" version_group = "main" @@ -55,17 +47,5 @@ name = "bevy_mod_scripting_rune" version_group = "main" [[package]] -name = "bevy_script_api" -version_group = "main" - -[[package]] -name = "bevy_event_priority" -version_group = "main" - -[[package]] -name = "bevy_mod_scripting_lua_derive" -version_group = "main" - -[[package]] -name = "bevy_mod_scripting_rhai_derive" +name = "bevy_mod_scripting_functions" version_group = "main" diff --git a/src/documentation/main.rs b/src/documentation/main.rs deleted file mode 100644 index d7802bea..00000000 --- a/src/documentation/main.rs +++ /dev/null @@ -1,32 +0,0 @@ -use bevy::prelude::*; -use bevy_mod_scripting::prelude::*; -use std::env; - -fn main() { - let args: Vec = env::args().collect(); - let mut app = App::new(); - app.add_plugins(MinimalPlugins) - .add_plugins(ScriptingPlugin) - .add_plugins(AssetPlugin::default()); - - static INVALID_ARGUMENT_WARNING: &str = "Expected one of: 'lua','rhai' as arguments"; - - let lang = args.get(1).expect(INVALID_ARGUMENT_WARNING); - - match lang.as_str() { - "lua" => { - #[cfg(all(feature = "lua", feature = "lua_script_api"))] - app.add_script_host::>(PostUpdate) - .add_api_provider::>(Box::new(LuaCoreBevyAPIProvider)) - .add_api_provider::>(Box::new(LuaBevyAPIProvider)) - .update_documentation::>(); - - #[cfg(any(not(feature = "lua"), not(feature = "lua_script_api")))] - println!("Re-run with the following features enabled: `lua`,`lua_script_api`") - } - "rhai" => { - println!("Rhai documentation generation is not supported yet"); - } - _ => println!("{}", INVALID_ARGUMENT_WARNING), - } -} diff --git a/src/lib.rs b/src/lib.rs index 82d53079..6a00b7ed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,21 +7,11 @@ pub mod core { #[cfg(feature = "lua")] pub mod lua { pub use bevy_mod_scripting_lua::*; - - #[cfg(feature = "lua_script_api")] - pub mod api { - pub use bevy_script_api::lua::*; - } } #[cfg(feature = "rhai")] pub mod rhai { pub use bevy_mod_scripting_rhai::*; - - #[cfg(feature = "rhai_script_api")] - pub mod api { - pub use bevy_script_api::rhai::*; - } } #[cfg(feature = "rune")] @@ -29,23 +19,4 @@ pub mod rune { pub use bevy_mod_scripting_rune::*; } -#[cfg(any(feature = "lua_script_api", feature = "rhai_script_api"))] -pub mod api { - pub use bevy_script_api::*; -} - -pub mod prelude { - pub use bevy_mod_scripting_core::prelude::*; - - #[cfg(feature = "lua")] - pub use bevy_mod_scripting_lua::prelude::*; - - #[cfg(feature = "rhai")] - pub use bevy_mod_scripting_rhai::prelude::*; - - #[cfg(feature = "rune")] - pub use bevy_mod_scripting_rune::prelude::*; - - #[cfg(any(feature = "lua_script_api", feature = "rhai_script_api"))] - pub use bevy_script_api::prelude::*; -} +pub use bevy_mod_scripting_functions::*;