diff --git a/.github/workflows/bevy_mod_scripting.yml b/.github/workflows/bevy_mod_scripting.yml index 92497dee1d..2e1eb32795 100644 --- a/.github/workflows/bevy_mod_scripting.yml +++ b/.github/workflows/bevy_mod_scripting.yml @@ -27,17 +27,16 @@ jobs: 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 - All Features, os: windows-latest, features: "lua54,rhai,teal,rune", cross: x86_64-pc-windows-msvc }, + {label: MacOS - All Features, os: macOS-latest, features: "lua54,rhai,teal,rune", cross: x86_64-apple-darwin }, + {label: Ubuntu - All Features, os: ubuntu-latest, features: "lua54,rhai,teal,rune", cross: x86_64-unknown-linux-gnu }, + {label: Ubuntu Aarch64 - All Features, os: ubuntu-latest, features: "lua54,rhai,teal,rune", cross: aarch64-unknown-linux-gnu }, + {label: Ubuntu - Lua51, os: ubuntu-latest, features: "lua51", cross: x86_64-unknown-linux-gnu }, + {label: Ubuntu - Lua52, os: ubuntu-latest, features: "lua52", cross: x86_64-unknown-linux-gnu }, + {label: Ubuntu - Lua53, os: ubuntu-latest, features: "lua53", cross: x86_64-unknown-linux-gnu }, + {label: Ubuntu - Luajit, os: ubuntu-latest, features: "luajit", cross: x86_64-unknown-linux-gnu }, + {label: Ubuntu - Luajit52, os: ubuntu-latest, features: "luajit52", cross: x86_64-unknown-linux-gnu }, + {label: Ubuntu - Luau, os: ubuntu-latest, features: "luau", cross: x86_64-unknown-linux-gnu } ] steps: - if: runner.os == 'linux' @@ -97,7 +96,7 @@ jobs: - 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 + args: --features=lua54,rhai,teal,rune --profile=ephemeral-build -- -D warnings tests: name: Tests runs-on: ubuntu-latest @@ -117,7 +116,7 @@ jobs: - uses: actions-rs/cargo@v1 with: command: test - args: --workspace --features=lua54,rhai,teal,lua_script_api,rhai_script_api,rune --profile=ephemeral-build + args: --workspace --features=lua54,rhai,teal,rune --profile=ephemeral-build docs: name: Docs runs-on: ubuntu-latest diff --git a/.github/workflows/doc_gen.yml b/.github/workflows/doc_gen.yml index 0d8a75a703..ed7055970e 100644 --- a/.github/workflows/doc_gen.yml +++ b/.github/workflows/doc_gen.yml @@ -32,7 +32,7 @@ jobs: - uses: actions-rs/cargo@v1 with: command: run - args: --features=lua54,lua_script_api lua + args: --features=lua54 lua - run: cat ./assets/scripts/doc/tealr_doc_gen_config.json - name: Push to pages uses: cpina/github-action-push-to-another-repository@main diff --git a/.rustfmt.toml b/.rustfmt.toml index 6e65172c8d..9a5f6e52a8 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 a6483eca38..67b227bd90 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 3c966b296b..980f809761 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -24,4 +24,4 @@ ], "rust-analyzer.showUnlinkedFileNotification": false, // "rust-analyzer.semanticHighlighting.operator.enable": false -} +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 14262c18e9..ddfbb877a8 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/Cargo.toml b/Cargo.toml index c119d32866..5f7b601e69 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,15 +21,7 @@ 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 = ["lua", "lua54", "rhai", "teal", "rune"] [features] ## core @@ -47,7 +39,6 @@ luajit52 = ["bevy_mod_scripting_lua/luajit52", "lua"] luau = ["bevy_mod_scripting_lua/luau", "lua"] # 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"] @@ -56,7 +47,6 @@ 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"] @@ -67,13 +57,13 @@ bevy_mod_scripting_core = { workspace = true } bevy_mod_scripting_lua = { path = "crates/languages/bevy_mod_scripting_lua", version = "0.8.0-alpha.2", optional = true } bevy_mod_scripting_rhai = { path = "crates/languages/bevy_mod_scripting_rhai", version = "0.8.0-alpha.2", optional = true } bevy_mod_scripting_rune = { path = "crates/languages/bevy_mod_scripting_rune", version = "0.8.0-alpha.2", optional = true } -bevy_script_api = { path = "crates/bevy_script_api", version = "0.8.0-alpha.2", optional = 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-alpha.2" } bevy_mod_scripting_common = { path = "crates/bevy_mod_scripting_common", version = "0.8.0-alpha.2" } +test_utils = { path = "crates/test_utils" } [dev-dependencies] bevy = { workspace = true, default-features = true } @@ -86,13 +76,14 @@ rhai-rand = "0.1" 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/bevy_mod_scripting_derive", + "crates/test_utils", ] resolver = "2" exclude = ["crates/bevy_api_gen", "crates/macro_tests"] @@ -117,7 +108,6 @@ name = "console_integration_lua" path = "examples/lua/console_integration.rs" required-features = [ "lua54", - "lua_script_api", "bevy/file_watcher", "bevy/multi_threaded", ] @@ -127,7 +117,6 @@ name = "console_integration_rhai" path = "examples/rhai/console_integration.rs" required-features = [ "rhai", - "rhai_script_api", "bevy/file_watcher", "bevy/multi_threaded", ] @@ -140,32 +129,22 @@ required-features = ["lua54"] [[example]] name = "dynamic_queries_lua" path = "examples/lua/dynamic_queries.rs" -required-features = ["lua54", "lua_script_api"] +required-features = ["lua54"] [[example]] name = "dynamic_queries_rhai" path = "examples/rhai/dynamic_queries.rs" -required-features = ["rhai", "rhai_script_api"] +required-features = ["rhai"] [[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", -] +required-features = ["lua54", "bevy/file_watcher", "bevy/multi_threaded"] [[example]] +required-features = ["rhai", "bevy/file_watcher", "bevy/multi_threaded"] name = "game_of_life_rhai" path = "examples/rhai/game_of_life.rs" -required-features = [ - "rhai", - "rhai_script_api", - "bevy/file_watcher", - "bevy/multi_threaded", -] [[example]] name = "event_recipients_lua" @@ -180,22 +159,22 @@ required-features = ["lua54"] [[example]] name = "documentation_gen_lua" path = "examples/lua/documentation_gen.rs" -required-features = ["lua54", "teal", "lua_script_api"] +required-features = ["lua54", "teal"] [[example]] name = "bevy_api_lua" path = "examples/lua/bevy_api.rs" -required-features = ["lua54", "lua_script_api"] +required-features = ["lua54"] [[example]] name = "bevy_api_rhai" path = "examples/rhai/bevy_api.rs" -required-features = ["rhai", "rhai_script_api"] +required-features = ["rhai"] [[example]] name = "wrappers" path = "examples/wrappers.rs" -required-features = ["lua54", "lua_script_api"] +required-features = ["lua54"] [[example]] name = "minimal_rune" diff --git a/assets/scripts/bevy_api.lua b/assets/scripts/bevy_api.lua new file mode 100644 index 0000000000..c8748f0026 --- /dev/null +++ b/assets/scripts/bevy_api.lua @@ -0,0 +1,138 @@ +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() + + print(entity) + print(script) + print(world) + + + local my_component_type = world:get_type_by_name("MyComponent") + + local comp = world:get_component(entity, my_component_type) + print("Before script: ", comp) + + print("\noption") + 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} + 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)) + + + 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("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) + + world:exit() +end \ No newline at end of file diff --git a/assets/scripts/coroutines.lua b/assets/scripts/coroutines.lua index 8fec50daca..941e25cab9 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 8128df28f8..92b217d110 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 2aa50e2528..b846a742ae 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/check.sh b/check.sh index eb7a8f5488..18d7f7c1c4 100755 --- a/check.sh +++ b/check.sh @@ -6,5 +6,5 @@ CURRENT_DIR=$(basename "$PWD") if [[ "$CURRENT_DIR" == "bevy_api_gen" ]]; then cargo +nightly-2024-11-05 clippy --all-targets --message-format=json else - cargo clippy --workspace --all-targets --message-format=json --features="lua54 lua_script_api rhai rhai_script_api teal rune bevy/file_watcher bevy/multi_threaded" + cargo clippy --workspace --all-targets --message-format=json --features="lua54 rhai teal rune bevy/file_watcher bevy/multi_threaded" fi diff --git a/crates/bevy_api_gen/Cargo.bootstrap.toml b/crates/bevy_api_gen/Cargo.bootstrap.toml index 74afa48681..b7557099fc 100644 --- a/crates/bevy_api_gen/Cargo.bootstrap.toml +++ b/crates/bevy_api_gen/Cargo.bootstrap.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] mlua = { version = "0.9.2", features = ["lua54", "vendored", "send", "macros"] } -bevy_reflect = { version = "0.14", features = [ +bevy_reflect = { version = "0.15.0-rc.3", features = [ "bevy", "glam", "petgraph", diff --git a/crates/bevy_api_gen/Cargo.toml b/crates/bevy_api_gen/Cargo.toml index 501fca03d5..9e4ecd7c98 100644 --- a/crates/bevy_api_gen/Cargo.toml +++ b/crates/bevy_api_gen/Cargo.toml @@ -36,15 +36,12 @@ source = "discover" [package.metadata.rust-analyzer] rustc_private = true -[rust-analyzer.check] -overrideCommand = ["cargo", "+nightly-2024-11-05", "a", "--message-format=json"] - [dependencies] -log = "0.4" -env_logger = "0.11" rustc_plugin = { git = "https://github.com/makspll/rustc_plugin", branch = "feature/rust-1.82.0" } indexmap = "2" +log = "0.4" +env_logger = "0.11" tempdir = "0.3" cargo_metadata = "0.18" serde_json = "1" diff --git a/crates/bevy_api_gen/readme.md b/crates/bevy_api_gen/readme.md index 93f556bb94..0831b6fc9b 100644 --- a/crates/bevy_api_gen/readme.md +++ b/crates/bevy_api_gen/readme.md @@ -8,7 +8,7 @@ bevy_api_gen is a Cargo plugin that generates reflection-powered wrappers for Be To install bevy_api_gen, use the following command: ```bash -cargo +nightly-2024-11-05 install bevy_api_gen +cargo +nightly-2024-01-24 install bevy_api_gen ``` # Usage @@ -18,17 +18,17 @@ cargo +nightly-2024-11-05 install bevy_api_gen To run the main codegen process, use the following command: ```bash -cargo +nightly-2024-11-05 bevy-api-gen generate +cargo +nightly-2024-01-24 bevy-api-gen generate ``` -This will perform all parts of the process and generate meta as well as .rs files for each crate in your workspace in your `/target/plugin-nightly-2024-11-05/bevy_api_gen` directory +This will perform all parts of the process and generate meta as well as .rs files for each crate in your workspace in your `/target/plugin-nightly-2024-01-24/bevy_api_gen` directory ## Collect After generating all the files, you can 'collect' them in a mod.rs file like so: ```bash -cargo +nightly-2024-11-05 bevy-api-gen collect +cargo +nightly-2024-01-24 bevy-api-gen collect ``` ## List Types @@ -36,7 +36,7 @@ cargo +nightly-2024-11-05 bevy-api-gen collect To see a list of all `Reflect` implementing types in your workspace run: ```bash -cargo +nightly-2024-11-05 bevy-api-gen list-types > all_types.txt +cargo +nightly-2024-01-24 bevy-api-gen list-types > all_types.txt ``` ## List Templates @@ -44,7 +44,7 @@ cargo +nightly-2024-11-05 bevy-api-gen list-types > all_types.txt To see the list of all templates which you can override use: ```bash -cargo +nightly-2024-11-05 bevy-api-gen list-templates +cargo +nightly-2024-01-24 bevy-api-gen list-templates ``` ## Print Template @@ -52,5 +52,5 @@ cargo +nightly-2024-11-05 bevy-api-gen list-templates You can also print any of the templates to stdout: ```bash -cargo +nightly-2024-11-05 bevy-api-gen print item.tera +cargo +nightly-2024-01-24 bevy-api-gen print item.tera ``` \ No newline at end of file diff --git a/crates/bevy_api_gen/src/args.rs b/crates/bevy_api_gen/src/args.rs index 848d0a9335..69ff5294fe 100644 --- a/crates/bevy_api_gen/src/args.rs +++ b/crates/bevy_api_gen/src/args.rs @@ -112,6 +112,7 @@ fn default_ignored_types() -> 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 658afed6a0..56ced9d33e 100644 --- a/crates/bevy_api_gen/src/bin/main.rs +++ b/crates/bevy_api_gen/src/bin/main.rs @@ -1,4 +1,5 @@ #![feature(rustc_private)] + use std::{ collections::HashMap, env, diff --git a/crates/bevy_api_gen/src/callback.rs b/crates/bevy_api_gen/src/callback.rs index a762ed766d..71f0a9f91a 100644 --- a/crates/bevy_api_gen/src/callback.rs +++ b/crates/bevy_api_gen/src/callback.rs @@ -87,6 +87,7 @@ impl rustc_driver::Callbacks for BevyAnalyzerCallbacks { 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 498a958c42..baa33448a1 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", @@ -138,13 +139,13 @@ impl CachedTraits { .all(|t| self.std_source_traits.contains_key(*t)) } - // pub(crate) fn missing_std_source_traits(&self) -> Vec { - // STD_SOURCE_TRAITS - // .iter() - // .filter(|t| !self.std_source_traits.contains_key(**t)) - // .map(|s| (*s).to_owned()) - // .collect() - // } + pub(crate) fn missing_std_source_traits(&self) -> Vec { + STD_SOURCE_TRAITS + .iter() + .filter(|t| !self.std_source_traits.contains_key(**t)) + .map(|s| (*s).to_owned()) + .collect() + } } #[derive(Clone, Debug)] @@ -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 2f26fd1276..c8f5522685 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 23d294032e..3388d68b0b 100644 --- a/crates/bevy_api_gen/src/lib.rs +++ b/crates/bevy_api_gen/src/lib.rs @@ -1,13 +1,16 @@ #![feature(rustc_private, let_chains)] #![deny(rustc::internal)] - extern crate rustc_ast; +extern crate rustc_const_eval; extern crate rustc_driver; extern crate rustc_errors; extern crate rustc_hir; +extern crate rustc_hir_analysis; extern crate rustc_infer; extern crate rustc_interface; +extern crate rustc_lint; extern crate rustc_middle; +extern crate rustc_session; extern crate rustc_span; extern crate rustc_trait_selection; diff --git a/crates/bevy_api_gen/src/meta.rs b/crates/bevy_api_gen/src/meta.rs index a9861da384..029c438cb3 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 @@ -94,7 +116,7 @@ impl MetaLoader { let cache = self.cache.borrow(); if cache.contains_key(crate_name) { trace!("Loading meta from cache for: {}", crate_name); - cache.get(crate_name).cloned() + return cache.get(crate_name).cloned(); } else { trace!("Loading meta from filesystem for: {}", crate_name); drop(cache); diff --git a/crates/bevy_api_gen/src/modifying_file_loader.rs b/crates/bevy_api_gen/src/modifying_file_loader.rs index 7fab22dd3b..5458080dd1 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 12e2972bfe..c0c36b058b 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 6a2a1a6812..cd2e9ccdc5 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 8034681a41..170744c7a1 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 @@ -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, }) }) @@ -332,6 +332,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 +345,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 }) } @@ -391,7 +386,7 @@ fn type_is_supported_as_non_proxy_return_val<'tcx>( ) -> bool { trace!("Checkign type is supported as non proxy return val: '{ty:?}' with param_env: '{param_env:?}'"); if let TyKind::Ref(region, _, _) = ty.kind() { - if region.get_name().is_none_or(|rn| rn.as_str() != "'static") { + if !region.get_name().is_some_and(|rn| rn.as_str() == "'static") { return false; } } 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 f808922c94..22096759ef 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 9541869012..ba542ab9e4 100644 --- a/crates/bevy_api_gen/src/passes/find_trait_impls.rs +++ b/crates/bevy_api_gen/src/passes/find_trait_impls.rs @@ -136,6 +136,7 @@ fn impl_matches<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>, impl_def_id: DefId) let ocx = ObligationCtxt::new(infcx); let param_env = tcx.param_env_reveal_all_normalized(impl_def_id); 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 e5aff8e684..0254ee73b7 100644 --- a/crates/bevy_api_gen/src/passes/populate_template_data.rs +++ b/crates/bevy_api_gen/src/passes/populate_template_data.rs @@ -1,9 +1,12 @@ -use std::fmt::Write; +use std::{any::Any, 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::{ + print::Print, AdtDef, FieldDef, GenericArg, GenericParamDefKind, ParamTy, TraitRef, Ty, TyKind, + TypeFoldable, +}; use rustc_span::Symbol; use crate::{ @@ -126,7 +129,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 +148,25 @@ 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(ctxt.tcx.param_env(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(ctxt.tcx.param_env(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 +179,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 +214,271 @@ 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) } -struct TyPrinter { +/// 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(", ")) + } +} + +#[derive(Clone, Copy)] +pub(crate) enum ProxyType { + Ref, + RefMut, + Val, + NonReflectVal, +} + +impl ProxyType { + pub fn to_ident_str(self) -> &'static str { + match self { + ProxyType::Ref => "LuaReflectRefProxy", + ProxyType::RefMut => "LuaReflectRefMutProxy", + ProxyType::Val => "LuaReflectValProxy", + ProxyType::NonReflectVal => "LuaValProxy", + } + } +} +/// 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.print_ty(*ty); + } + } + 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('>'); } + 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()) } - _ => 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 b365458ee9..1e0d73a245 100644 --- a/crates/bevy_api_gen/src/plugin.rs +++ b/crates/bevy_api_gen/src/plugin.rs @@ -53,7 +53,9 @@ impl RustcPlugin for BevyAnalyzer { 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() + let out = compiler.run(); + log::trace!("Finished compiling with plugin"); + out } 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 e9219d0013..ddb9d02960 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, } @@ -195,8 +199,9 @@ pub(crate) fn configure_tera_env(tera: &mut Tera, crate_name: &str) { let file = syn::parse_file(&str) .map_err(|e| tera::Error::msg(e.to_string())) - .inspect_err(|_| { + .map_err(|e| { log::error!("prettyplease error on input: ```\n{}\n```", str); + e })?; let out = prettyplease::unparse(&file); diff --git a/crates/bevy_api_gen/templates/field.tera b/crates/bevy_api_gen/templates/field.tera index bf9baae508..ea5fb1450a 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 b14a4794a1..0009ff8855 100644 --- a/crates/bevy_api_gen/templates/footer.tera +++ b/crates/bevy_api_gen/templates/footer.tera @@ -1,70 +1,53 @@ +{% if args.self_is_bms_lua %} +{% set bms_lua_path="crate" %} +{% else %} +{% set bms_lua_path="bevy_mod_scripting::lua"%} +{% endif %} + #[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>>( +impl {{bms_lua_path}}::tealr::mlu::ExportInstances for Globals { + fn add_instances<'lua, T: {{bms_lua_path}}::tealr::mlu::InstanceCollector<'lua>>( self, instances: &mut T, - ) -> bevy_mod_scripting_lua::tealr::mlu::mlua::Result<()> { + ) -> {{bms_lua_path}}::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)?; + {{bms_lua_path}}::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 %} - } - )) - } - 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 {{ "ContextInitializer" | prefix_cratename | convert_case(case="snake") }} (_: &bevy_mod_scripting_core::script::ScriptId, ctx: &mut {{bms_lua_path}}::prelude::Lua) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { + {{bms_lua_path}}::tealr::mlu::set_global_env(Globals, ctx)?; + 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(()) - } +pub struct {{ "ScriptingPlugin" | prefix_cratename | convert_case(case="upper_camel")}}; - fn register_with_app(&self, app: &mut bevy::app::App) { +impl bevy::app::Plugin for {{ "ScriptingPlugin" | prefix_cratename | convert_case(case="upper_camel")}} { + fn build(&self, app: &mut bevy::prelude::App) { {% for item in items %} - app.register_foreign_lua_type::<{{ item.import_path }}>(); + app.register_lua_proxy::<{{ item.import_path }}>(); {% endfor %} + app.add_context_initializer::<()>({{ "ContextInitializer" | prefix_cratename | convert_case(case="snake") }}); + app.add_documentation_fragment( + {{bms_lua_path}}::docs::LuaDocumentationFragment::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::<{{bms_lua_path}}::tealr::mlu::UserDataProxy<{{ item.ident | prefix_lua }}>>() + {% endif %} + {% 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 a525af9bd4..970eebdfcc 100644 --- a/crates/bevy_api_gen/templates/function.tera +++ b/crates/bevy_api_gen/templates/function.tera @@ -13,6 +13,11 @@ r#" as_trait="{{ function.from_trait_path }}", {%- endif -%} +{% if is_op %} +composite="{{ function.ident }}", +{% 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 %} @@ -25,9 +30,7 @@ kind="Function", output(proxy), {%- endif -%} -{% if is_op %} -composite="{{ function.ident }}", -{% endif %} + {% if function.from_trait_path == "std::ops::Neg" %} metamethod="Unm", @@ -44,23 +47,22 @@ metamethod="Mod", {% elif function.from_trait_path == "std::cmp::PartialEq" %} metamethod="Eq", {% 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 e40a725a12..02f0fa1b81 100644 --- a/crates/bevy_api_gen/templates/header.tera +++ b/crates/bevy_api_gen/templates/header.tera @@ -8,8 +8,11 @@ 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}; + +{% if args.self_is_bms_lua %} +use crate::{bindings::proxy::{LuaReflectRefProxy,LuaReflectRefMutProxy,LuaReflectValProxy,LuaValProxy,LuaIdentityProxy},type_data::RegisterLua, tealr::mlu::mlua::IntoLua}; +{% else %} +use bevy_mod_scripting::{lua::bindings::proxy::{LuaReflectRefProxy,LuaReflectRefMutProxy,LuaReflectValProxy,LuaValProxy,LuaIdentityProxy}, type_data::RegisterLua, tealr::mlu::mlua::IntoLua}; +{% 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 3a8a8bfacb..969b932438 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 4e75fc50bd..ec421a0605 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")] +fn index(_self: LuaIdentityProxy, idx: usize) -> LuaIdentityProxy<{{ col_type | prefix_lua }}> { + let mut curr_ref = _self.0.clone(); + let def_ref = {{bms_core_path}}::bindings::DeferredReflection{ + get: std::sync::Arc::new(|ref_| Err(bevy::reflect::ReflectPathError::InvalidDowncast)), + get_mut: std::sync::Arc::new(move |ref_| { + if let Some(ret) = ref_.try_as_reflect_mut().map(|ret| ret.downcast_mut::()).flatten(){ + Ok(ret.col_mut(idx - 1)) + } else { + Err(bevy::reflect::ReflectPathError::InvalidDowncast) + } + }) + }; + curr_ref.reflect_path.push({{bms_core_path}}::bindings::ReflectionPathElem::new_deferred(def_ref)); + {{ col_type | prefix_lua }}(curr_ref) } {% 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 186b98ace2..4032b344d9 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_mod_scripting_core/Cargo.toml b/crates/bevy_mod_scripting_core/Cargo.toml index e1448c42a5..f11e517759 100644 --- a/crates/bevy_mod_scripting_core/Cargo.toml +++ b/crates/bevy_mod_scripting_core/Cargo.toml @@ -19,20 +19,18 @@ 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"] [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", -] } -bevy_event_priority = { path = "../bevy_event_priority", version = "0.8.0-alpha.2" } +mlua = { version = "0.9", optional = true } +bevy = { workspace = true, default-features = false, features = ["bevy_asset"] } thiserror = "1.0.31" paste = "1.0.7" parking_lot = "0.12.1" -anyhow = "1.0.75" +lockable = "0.0.8" +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 1dc86bb292..0833c413db 100644 --- a/crates/bevy_mod_scripting_core/src/asset.rs +++ b/crates/bevy_mod_scripting_core/src/asset.rs @@ -1,8 +1,85 @@ -use bevy::asset::Asset; +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]; +use bevy::{ + asset::{Asset, AssetLoader, AsyncReadExt}, + ecs::system::Resource, + reflect::TypePath, + utils::BoxedFuture, +}; + +use crate::{prelude::ScriptError, script::ScriptId}; + +/// 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_lifecycle_error(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, } 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 0000000000..b338950ec2 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/allocator.rs @@ -0,0 +1,125 @@ +use bevy::ecs::system::Resource; +use bevy::reflect::{PartialReflect, Reflect}; +use std::any::{Any, TypeId}; +use std::cell::UnsafeCell; +use std::collections::HashMap; +use std::fmt::{Display, Formatter}; +use std::sync::Arc; + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub struct ReflectAllocationId(pub(crate) usize); +impl ReflectAllocationId { + pub fn id(&self) -> usize { + self.0 + } +} + +#[derive(Clone, Debug)] +pub struct ReflectAllocation(pub(self) Arc>); + +unsafe impl Send for ReflectAllocation {} +unsafe impl Sync for ReflectAllocation {} + +impl ReflectAllocation { + pub fn get_ptr(&self) -> *mut dyn PartialReflect { + self.0.get() + } + pub fn new(value: Arc>) -> Self { + Self(value) + } +} + +impl Display for ReflectAllocationId { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +/// 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(Resource, Default)] +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, ReflectAllocation) { + let type_id = value.get_represented_type_info().map(|i| i.type_id()); + + let id = ReflectAllocationId(self.allocations.len()); + let value = ReflectAllocation::new(Arc::new(UnsafeCell::new(value))); + self.allocations.insert(id, value.clone()); + if let Some(type_id) = type_id { + self.types.insert(id, type_id); + } + (id, value) + } + + // /// Moves the given boxed [`PartialReflect`] value into the allocator, returning an [`AllocationId`] which can be used to access it later + // pub fn allocate_boxed( + // &mut self, + // existing: Box, + // ) -> (ReflectAllocationId, ReflectAllocation) { + // let type_id = existing.get_represented_type_info().map(|i| i.type_id()); + // let id = ReflectAllocationId(self.allocations.len()); + + // let raw_ptr = Box::into_raw(existing); + // // Safety: + // // - we are the only ones to have access to this value since we have the Box + // // - UnsafeCell is repr(transparent), meaning we can safely transmute between it and the trait object + // // TODO: I don't think we can use this, because from_raw has a pre-condition that requires the pointer to have been an arc before + // let arc: Arc> = + // unsafe { Arc::from_raw(raw_ptr as *const _) }; + // let allocation = ReflectAllocation::new(arc); + // self.allocations.insert(id, allocation.clone()); + // if let Some(type_id) = type_id { + // self.types.insert(id, type_id); + // } + // (id, allocation) + // } + + pub fn get(&self, id: ReflectAllocationId) -> Option { + self.allocations.get(&id).cloned() + } + + pub fn get_type_id(&self, id: ReflectAllocationId) -> Option { + self.types.get(&id).cloned() + } + + pub fn get_mut(&self, id: ReflectAllocationId) -> Option { + self.allocations.get(&id).cloned() + } + + /// 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) { + self.allocations.retain(|_, v| Arc::strong_count(&v.0) > 1); + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_reflect_allocator() { + let mut allocator = ReflectAllocator::default(); + let (id, val) = allocator.allocate(0); + assert_eq!(allocator.allocations.len(), 1); + drop(val); + allocator.clean_garbage_allocations(); + assert_eq!(allocator.allocations.len(), 0); + } +} 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 0000000000..24f8ddf453 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/mod.rs @@ -0,0 +1,7 @@ +pub mod allocator; +pub mod proxy; +pub mod query; +pub mod reference; +pub mod world; + +pub use {allocator::*, proxy::*, query::*, reference::*, world::*}; diff --git a/crates/bevy_mod_scripting_core/src/bindings/proxy.rs b/crates/bevy_mod_scripting_core/src/bindings/proxy.rs new file mode 100644 index 0000000000..ce1002b537 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/proxy.rs @@ -0,0 +1,1096 @@ +//! Set of traits used to define how types are turned into and from proxies in Lua. +//! Proxies can either be logical "copies" or owned "direct representations" of the instance, or references to one via the [`bevy_mod_scripting_core::bindings::ReflectReference`] construct. +use std::{ + cell::UnsafeCell, + marker::PhantomData, + num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize}, + sync::Arc, +}; + +use bevy::reflect::{FromReflect, Reflect, TypeRegistry}; +use smallvec::SmallVec; + +use crate::{ + bindings::ReflectAllocation, + error::ScriptResult, + prelude::{ReflectAllocator, ScriptError}, +}; + +use super::{ + world::{WorldAccessGuard, WorldAccessUnit, WorldAccessWrite}, + ReflectReference, DEFAULT_INTERVAL, DEFAULT_TIMEOUT, +}; + +/// Inverse to [`Unproxy`], packages up a type into a proxy type. +pub trait Proxy: Sized { + type Input<'a>; + + /// Proxies a type without access to the allocator, types which require access to the allocator will throw an error here + fn proxy<'a>(input: Self::Input<'a>) -> ScriptResult { + Err(ScriptError::new_reflection_error(format!( + "Cannot unproxy type: `{}` without allocator access. Use proxy_with_allocator instead.", + std::any::type_name::(), + ))) + } + + /// Proxies a type with access to the allocator + fn proxy_with_allocator<'a>( + input: Self::Input<'a>, + _allocator: &mut ReflectAllocator, + ) -> ScriptResult { + Self::proxy(input) + } +} + +/// A mechanism for converting proxy types into their represented types. +/// Note this can be implemented by 'meta-proxy' types which themselves aren't proxies, but wrap other proxies and provide a specific unproxying mechanism. +/// `RefProxy` and `RefMutProxy` are such 'meta-proxy' types. +/// +/// the [`Unproxy::Output`] type parameter is the type that this `proxy` will be converted to after unwrapping. +/// +pub trait Unproxy { + type Output<'o> + where + Self: 'o; + + fn collect_accesses<'w>( + &self, + _guard: &WorldAccessGuard<'w>, + _accesses: &mut SmallVec<[WorldAccessWrite<'w>; 1]>, + ) -> ScriptResult<()> { + Ok(()) + } + + fn accesses_len(&self) -> usize { + 0 + } + + /// Unproxies a proxy type into the represented type without world access + /// This will fail on proxies which require world access to unproxy (for example those whose proxies are glorified [`ReflectReference`]'s ) + fn unproxy<'o>(&'o mut self) -> ScriptResult> { + Err(ScriptError::new_reflection_error(format!( + "Cannot unproxy type: `{}` without world access. Use unproxy_with_world instead", + std::any::type_name::(), + ))) + } + + /// Unproxies a proxy type into the represented type with world access + /// # Safety + /// - The caller must not use the accesses in the accesses list after the unproxy call at all, as implementors assume they have unique access to the accesses. + unsafe fn unproxy_with_world<'w, 'o>( + &'o mut self, + _guard: &WorldAccessGuard<'w>, + _accesses: &'o [WorldAccessUnit<'w>], + _type_registry: &TypeRegistry, + _allocator: &ReflectAllocator, + ) -> ScriptResult> { + self.unproxy() + } +} + +/// A wrapper type which when unproxied will return a `T` value. +/// Requires the type to be constructible from a reference to the proxy type. +#[derive(Debug, PartialEq, Eq)] +pub struct ValProxy(pub P, PhantomData); + +impl ValProxy { + pub fn new(v: P) -> Self { + Self(v, PhantomData) + } +} + +/// A wrapper type which when unproxied will return a `T` value. +/// Assumes that the proxy type contains a [`ReflectReference`] via [`AsRef`] +#[derive(PartialEq, Eq, Debug)] +pub struct ReflectValProxy(pub P, PhantomData); + +impl ReflectValProxy { + pub fn new(v: P) -> Self { + Self(v, PhantomData) + } +} + +/// A proxy type which when unproxied will return a reference to a `T` value. +/// Assumes that the proxy type contains a [`ReflectReference`] via [`AsRef`] +pub struct ReflectRefProxy(pub P, PhantomData); + +impl ReflectRefProxy { + pub fn new(v: P) -> Self { + Self(v, PhantomData) + } +} + +/// A proxy type which when unproxied will return a mutable reference to a `T` value. +/// Assumes that the proxy type contains a [`ReflectReference`] via [`AsRef`] +#[derive(Debug)] +pub struct ReflectRefMutProxy(pub P, PhantomData); + +impl ReflectRefMutProxy { + pub fn new(v: P) -> Self { + Self(v, PhantomData) + } +} + +impl Unproxy for ValProxy +where + T: for<'l> From<&'l P>, +{ + type Output<'o> = T where Self: 'o; + + fn unproxy<'o>(&'o mut self) -> ScriptResult> { + Ok(T::from(&self.0)) + } +} + +impl Proxy for ValProxy +where + T: Into

, +{ + type Input<'a> = T; + + fn proxy<'a>(input: Self::Input<'a>) -> ScriptResult { + Ok(ValProxy::new(input.into())) + } +} + +impl Proxy for ReflectValProxy +where + T: Reflect, + P: From, +{ + type Input<'a> = T; + + fn proxy_with_allocator<'a>( + input: Self::Input<'a>, + allocator: &mut ReflectAllocator, + ) -> ScriptResult { + Ok(Self::new( + ReflectReference::new_allocated(input, allocator).into(), + )) + } +} + +impl Unproxy for ReflectValProxy +where + P: AsRef, + T: FromReflect, +{ + type Output<'o> = T where Self: 'o; + + unsafe fn unproxy_with_world<'w, 'o>( + &'o mut self, + guard: &WorldAccessGuard<'w>, + _accesses: &'o [WorldAccessUnit<'w>], + type_registry: &TypeRegistry, + allocator: &'o ReflectAllocator, + ) -> ScriptResult> { + let reflect_ref: &ReflectReference = self.0.as_ref(); + let access = reflect_ref.base.base_id.get_reflect_access_id(); + let access = guard.get_access_timeout(access, DEFAULT_TIMEOUT, DEFAULT_INTERVAL); + let out = reflect_ref.reflect( + guard.as_unsafe_world_cell(), + &access, + type_registry, + Some(allocator), + )?; + let out = T::from_reflect(out).ok_or_else(|| { + ScriptError::new_reflection_error(format!( + "FromReflect failed for `{}`.", + std::any::type_name::() + )) + })?; + guard.release_access(access); + Ok(out) + } +} + +impl Proxy for ReflectRefProxy +where + T: FromReflect, + P: From, +{ + type Input<'a> = &'a T; + + fn proxy_with_allocator<'a>( + input: Self::Input<'a>, + allocator: &mut ReflectAllocator, + ) -> ScriptResult { + let inner = T::from_reflect(input).ok_or_else(|| { + ScriptError::new_reflection_error(format!( + "FromReflect failed for `{}`.", + std::any::type_name::() + )) + })?; + Ok(Self::new( + ReflectReference::new_allocated(inner, allocator).into(), + )) + } +} + +impl Unproxy for ReflectRefProxy +where + P: AsRef, + T: Reflect, +{ + type Output<'o> = &'o T where Self: 'o; + + fn collect_accesses<'w>( + &self, + guard: &WorldAccessGuard<'w>, + accesses: &mut SmallVec<[WorldAccessUnit<'w>; 1]>, + ) -> ScriptResult<()> { + let reflect_ref: &ReflectReference = self.0.as_ref(); + let access = reflect_ref.base.base_id.get_reflect_access_id(); + let access = guard.get_access_timeout(access, DEFAULT_TIMEOUT, DEFAULT_INTERVAL); + accesses.push(access); + Ok(()) + } + + unsafe fn unproxy_with_world<'w, 'o>( + &'o mut self, + guard: &WorldAccessGuard<'w>, + accesses: &'o [WorldAccessUnit<'w>], + type_registry: &TypeRegistry, + allocator: &ReflectAllocator, + ) -> ScriptResult> { + let reflect_ref: &ReflectReference = self.0.as_ref(); + let access = accesses.last().ok_or_else(|| { + ScriptError::new_reflection_error(format!( + "No required access collected when unproxying type: `{}`.", + std::any::type_name::() + )) + })?; + + let out = reflect_ref.reflect( + guard.as_unsafe_world_cell(), + access, + type_registry, + Some(allocator), + )?; + let out = out.try_downcast_ref().ok_or_else(|| { + ScriptError::new_reflection_error(format!( + "Could not downcast value from reflect reference to type: `{}`.", + std::any::type_name::() + )) + })?; + Ok(out) + } + + fn accesses_len(&self) -> usize { + 1 + } +} + +impl Unproxy for ReflectRefMutProxy +where + P: AsRef, + T: Reflect, +{ + type Output<'o> = &'o mut T where Self: 'o; + + fn collect_accesses<'w>( + &self, + guard: &WorldAccessGuard<'w>, + accesses: &mut SmallVec<[WorldAccessUnit<'w>; 1]>, + ) -> ScriptResult<()> { + let reflect_ref: &ReflectReference = self.0.as_ref(); + let access = reflect_ref.base.base_id.get_reflect_access_id(); + let access = guard.get_access_timeout(access, DEFAULT_TIMEOUT, DEFAULT_INTERVAL); + accesses.push(access); + Ok(()) + } + + unsafe fn unproxy_with_world<'w, 'o>( + &'o mut self, + guard: &WorldAccessGuard<'w>, + accesses: &'o [WorldAccessUnit<'w>], + type_registry: &TypeRegistry, + allocator: &ReflectAllocator, + ) -> ScriptResult> { + let reflect_ref: &ReflectReference = self.0.as_ref(); + accesses + .last() + .ok_or_else(|| { + ScriptError::new_reflection_error(format!( + "No required access collected when unproxying type: `{}`.", + std::any::type_name::() + )) + }) + .and_then(|access| { + reflect_ref.expect_write_access( + access, + type_registry, + Some(allocator), + guard.as_unsafe_world_cell(), + ) + })?; + + // Safety: + // - we verified and we have the right access + // - the caller promises not to alias it from the root access + let out = unsafe { + reflect_ref.reflect_mut_unsafe( + guard.as_unsafe_world_cell(), + type_registry, + Some(allocator), + )? + }; + let out = out.try_downcast_mut().ok_or_else(|| { + ScriptError::new_reflection_error(format!( + "Could not downcast value from reflect reference to type: `{}`.", + std::any::type_name::() + )) + })?; + Ok(out) + } + + fn accesses_len(&self) -> usize { + 1 + } +} + +macro_rules! impl_unproxy_via_vec { + ($type:ty, $out_type:ty, ($($generics:tt)*)) => { + impl<'c, $($generics)*> Unproxy for $type { + type Output<'o> = $out_type where Self: 'o; + + fn collect_accesses<'w>( + &self, + guard: &WorldAccessGuard<'w>, + accesses: &mut SmallVec<[WorldAccessUnit<'w>; 1]>, + ) -> ScriptResult<()> { + for item in self { + item.collect_accesses(guard, accesses)?; + } + Ok(()) + } + + fn accesses_len(&self) -> usize { + self.iter().map(|item| item.accesses_len()).sum() + } + + fn unproxy(&mut self) -> ScriptResult> { + let mut out = Vec::with_capacity(self.len()); + for item in self { + let unproxied = item.unproxy()?; + out.push(unproxied); + } + Ok(out.try_into().map_err(|_| "something went wrong").unwrap()) + } + + unsafe fn unproxy_with_world<'w, 'o>( + &'o mut self, + guard: &WorldAccessGuard<'w>, + accesses: &'o [WorldAccessUnit<'w>], + type_registry: &TypeRegistry, + allocator: &ReflectAllocator, + ) -> ScriptResult> { + let mut out = Vec::with_capacity(self.len()); + let mut offset = 0; + for item in self.iter_mut() { + let width = item.accesses_len(); + let unproxied = item.unproxy_with_world( + guard, + &accesses[offset..offset + width], + type_registry, + allocator, + )?; + out.push(unproxied); + offset += width; + } + Ok(out.try_into().map_err(|_| "something went wrong").unwrap()) + } + } + }; +} + +macro_rules! impl_proxy_via_vec { + ($type:ty, $item_type:ty, $in_type:ty, ($($generics:tt)*)) => { + impl<$($generics)*> Proxy for $type { + type Input<'i> = $in_type; + + fn proxy(input: Self::Input<'_>) -> ScriptResult { + let mut out = Vec::with_capacity(input.len()); + for item in input { + out.push(<$item_type as Proxy>::proxy(item)?); + } + Ok(out.try_into().map_err(|_| "something went wrong").unwrap()) + } + + fn proxy_with_allocator( + input: Self::Input<'_>, + _allocator: &mut ReflectAllocator, + ) -> ScriptResult { + let mut out = Vec::with_capacity(input.len()); + for item in input { + out.push(<$item_type as Proxy>::proxy_with_allocator(item, _allocator)?); + } + Ok(out.try_into().map_err(|_| "something went wrong").unwrap()) + } + } + }; +} + +impl_unproxy_via_vec!(Vec, Vec>, (T: Unproxy)); +impl_proxy_via_vec!(Vec, T, Vec>, (T: Proxy)); +impl_unproxy_via_vec!([T; C], [T::Output<'o>; C], (T: Unproxy, const C: usize)); +impl_proxy_via_vec!([T; C],T,[T::Input<'i>; C], (T: Proxy, const C: usize)); +impl_unproxy_via_vec!(SmallVec<[T; C]>, SmallVec<[T::Output<'o>; C]>, (T: Unproxy, const C: usize)); +impl_proxy_via_vec!(SmallVec<[T; C]>, T, SmallVec<[T::Input<'i>; C]>, (T: Proxy, const C: usize)); + +// impl_proxy_unproxy_via_vec!(T, SmallVec, SmallVec<[T; C]>); +// impl<'c, T: 'c> Unproxy for &'c T { +// type Output<'o> = &'c T where Self: 'o; + +// fn unproxy(&mut self) -> ScriptResult> { +// Ok(self) +// } +// } + +// impl<'s, T> Proxy for &'s T { +// type Input<'b> = &'s T; + +// fn proxy(input: Self::Input<'_>) -> ScriptResult { +// Ok(input) +// } + +// fn proxy_with_allocator( +// input: Self::Input<'_>, +// _allocator: &mut ReflectAllocator, +// ) -> ScriptResult { +// Ok(input) +// } +// } + +// impl Unproxy for &mut T { +// type Output<'o> = &'o mut T where Self: 'o; + +// fn unproxy(&mut self) -> ScriptResult> { +// Ok(self) +// } +// } + +// impl<'s, T> Proxy for &'s mut T { +// type Input<'a> = &'s mut T; + +// fn proxy(input: Self::Input<'_>) -> ScriptResult { +// Ok(input) +// } + +// fn proxy_with_allocator( +// input: Self::Input<'_>, +// _allocator: &mut ReflectAllocator, +// ) -> ScriptResult { +// Ok(input) +// } +// } + +impl Unproxy for Option { + type Output<'o> = Option> where Self: 'o; + + fn unproxy(&mut self) -> ScriptResult> { + if let Some(s) = self { + let inner = s.unproxy()?; + Ok(Some(inner)) + } else { + Ok(None) + } + } + + unsafe fn unproxy_with_world<'w, 'o>( + &'o mut self, + guard: &WorldAccessGuard<'w>, + accesses: &'o [WorldAccessUnit<'w>], + type_registry: &TypeRegistry, + allocator: &ReflectAllocator, + ) -> ScriptResult> { + if let Some(s) = self { + let inner = s.unproxy_with_world(guard, accesses, type_registry, allocator)?; + Ok(Some(inner)) + } else { + Ok(None) + } + } + + fn collect_accesses<'w>( + &self, + guard: &WorldAccessGuard<'w>, + accesses: &mut SmallVec<[WorldAccessWrite<'w>; 1]>, + ) -> ScriptResult<()> { + self.as_ref() + .map(|s| s.collect_accesses(guard, accesses)) + .unwrap_or_else(|| Ok(())) + } + + fn accesses_len(&self) -> usize { + self.as_ref().map_or(0, |s| s.accesses_len()) + } +} + +impl Proxy for Option { + type Input<'a> = Option>; + + fn proxy(input: Self::Input<'_>) -> ScriptResult { + input.map(T::proxy).transpose() + } + + fn proxy_with_allocator( + input: Self::Input<'_>, + _allocator: &mut ReflectAllocator, + ) -> ScriptResult { + input + .map(|i| T::proxy_with_allocator(i, _allocator)) + .transpose() + } +} + +impl Proxy for Result { + type Input<'a> = Result, E::Input<'a>>; + + fn proxy(input: Self::Input<'_>) -> ScriptResult { + match input { + Ok(i) => Ok(Ok(T::proxy(i)?)), + Err(e) => Ok(Err(E::proxy(e)?)), + } + } + + fn proxy_with_allocator( + input: Self::Input<'_>, + _allocator: &mut ReflectAllocator, + ) -> ScriptResult { + match input { + Ok(i) => Ok(Ok(T::proxy_with_allocator(i, _allocator)?)), + Err(e) => Ok(Err(E::proxy_with_allocator(e, _allocator)?)), + } + } +} + +impl Unproxy for Result { + type Output<'o> = Result, E::Output<'o>> where Self: 'o; + + fn unproxy(&mut self) -> ScriptResult> { + match self { + Ok(s) => Ok(Ok(s.unproxy()?)), + Err(e) => Ok(Err(e.unproxy()?)), + } + } + + unsafe fn unproxy_with_world<'w, 'o>( + &'o mut self, + guard: &WorldAccessGuard<'w>, + accesses: &'o [WorldAccessUnit<'w>], + type_registry: &TypeRegistry, + allocator: &ReflectAllocator, + ) -> ScriptResult> { + match self { + Ok(s) => Ok(Ok(s.unproxy_with_world( + guard, + accesses, + type_registry, + allocator, + )?)), + Err(e) => Ok(Err(e.unproxy()?)), + } + } + + fn collect_accesses<'w>( + &self, + guard: &WorldAccessGuard<'w>, + accesses: &mut SmallVec<[WorldAccessWrite<'w>; 1]>, + ) -> ScriptResult<()> { + match self { + Ok(s) => s.collect_accesses(guard, accesses), + Err(_) => Ok(()), + } + } + + fn accesses_len(&self) -> usize { + match self { + Ok(s) => s.accesses_len(), + Err(_) => 0, + } + } +} + +macro_rules! impl_unproxy_by_move { + ($($ty:ty),*) => { + $( + impl Unproxy for $ty { + type Output<'o> = $ty; + + fn unproxy( + &mut self + ) -> ScriptResult> { + Ok(*self) + } + } + + impl Unproxy for &$ty { + type Output<'o> = &'o $ty where Self : 'o; + + fn unproxy( + &mut self + ) -> ScriptResult> { + Ok(self) + } + } + + impl Unproxy for &mut $ty { + type Output<'o> = &'o mut $ty where Self : 'o; + + fn unproxy( + &mut self + ) -> ScriptResult> { + Ok(self) + } + } + )* + }; +} + +macro_rules! impl_proxy_by_move { + ($($ty:ident),*) => { + $( + impl Proxy for $ty { + type Input<'a> = Self; + + fn proxy(input: Self::Input<'_>) -> ScriptResult { + Ok(input) + } + } + + impl <'l>Proxy for &'l $ty { + type Input<'a> = Self; + + fn proxy(input: Self::Input<'_>) -> ScriptResult { + Ok(input) + } + } + + impl <'l>Proxy for &'l mut $ty { + type Input<'a> = Self; + + fn proxy(input: Self::Input<'_>) -> ScriptResult { + Ok(input) + } + } + )* + } +} + +impl_proxy_by_move!( + usize, + u8, + u16, + u32, + u64, + u128, + isize, + i8, + i16, + i32, + i64, + i128, + f32, + f64, + bool, + NonZeroUsize, + NonZeroU8, + NonZeroU16, + NonZeroU32, + NonZeroU64, + NonZeroU128 +); + +impl_unproxy_by_move!( + usize, + u8, + u16, + u32, + u64, + u128, + isize, + i8, + i16, + i32, + i64, + i128, + f32, + f64, + bool, + NonZeroUsize, + NonZeroU8, + NonZeroU16, + NonZeroU32, + NonZeroU64, + NonZeroU128 +); + +macro_rules! impl_unproxy_by_clone { + ($($ty:ty),*) => { + $(impl Unproxy for $ty { + type Output<'o> = $ty; + + fn unproxy(&mut self) -> ScriptResult> { + Ok(self.clone()) + } + })* + }; +} + +impl_unproxy_by_clone!(String); +impl_proxy_by_move!(String); + +macro_rules! impl_tuple_unproxy_proxy { + ($(($ty:ident, $idx:tt)),*) => { + impl <$($ty : Proxy,)*> Proxy for ($($ty,)*) + { + type Input<'a> = ($($ty::Input<'a>,)*); + + #[allow(clippy::unused_unit)] + fn proxy(_input: Self::Input<'_>) -> ScriptResult { + Ok(($($ty::proxy(_input.$idx)?,)*)) + } + + fn proxy_with_allocator(_input: Self::Input<'_>, _allocator: &mut ReflectAllocator) -> ScriptResult { + Ok(($($ty::proxy_with_allocator(_input.$idx, _allocator)?,)*)) + } + } + + impl<$($ty: Unproxy),*> Unproxy for ($($ty,)*) { + type Output<'o> = ($($ty::Output<'o>,)*) where Self: 'o; + + fn collect_accesses<'w>( + &self, + _guard: &WorldAccessGuard<'w>, + _accesses: &mut SmallVec<[WorldAccessWrite<'w>; 1]>, + ) -> ScriptResult<()> { + $(self.$idx.collect_accesses(_guard, _accesses)?;)* + Ok(()) + } + + fn accesses_len(&self) -> usize { + let mut _len = 0; + $(_len += self.$idx.accesses_len();)* + _len + } + + fn unproxy(&mut self) -> ScriptResult> { + Ok(($( + self.$idx.unproxy()? + ,)*)) + } + + #[allow(unused_assignments)] + unsafe fn unproxy_with_world<'w,'o>( + &'o mut self, + _guard: &WorldAccessGuard<'w>, + _accesses: &'o [WorldAccessUnit<'w>], + _type_registry: &TypeRegistry, + _allocator: &ReflectAllocator, + ) -> ScriptResult> { + let mut _offset = 0; + + Ok(($( + { + let width = self.$idx.accesses_len(); + let elem = self.$idx.unproxy_with_world(_guard, &_accesses[_offset.._offset+width], _type_registry, _allocator)?; + + _offset += width; + elem + } + ,)*)) + + } + } + }; +} + +impl_tuple_unproxy_proxy!(); +#[rustfmt::skip] +impl_tuple_unproxy_proxy!((A, 0)); +#[rustfmt::skip] +impl_tuple_unproxy_proxy!((A, 0), (B, 1)); +#[rustfmt::skip] +impl_tuple_unproxy_proxy!((A, 0), (B, 1), (C, 2)); +#[rustfmt::skip] +impl_tuple_unproxy_proxy!((A, 0), (B, 1), (C, 2), (D, 3)); +#[rustfmt::skip] +impl_tuple_unproxy_proxy!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4)); +#[rustfmt::skip] +impl_tuple_unproxy_proxy!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5)); +#[rustfmt::skip] +impl_tuple_unproxy_proxy!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6)); +#[rustfmt::skip] +impl_tuple_unproxy_proxy!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7)); +#[rustfmt::skip] +impl_tuple_unproxy_proxy!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7), (I, 8)); +#[rustfmt::skip] +impl_tuple_unproxy_proxy!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7), (I, 8), (J, 9)); +#[rustfmt::skip] +impl_tuple_unproxy_proxy!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7), (I, 8), (J, 9), (K, 10)); +#[rustfmt::skip] +impl_tuple_unproxy_proxy!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7), (I, 8), (J, 9), (K, 10), (L, 11)); +#[rustfmt::skip] +impl_tuple_unproxy_proxy!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7), (I, 8), (J, 9), (K, 10), (L, 11), (M, 12)); +#[rustfmt::skip] +impl_tuple_unproxy_proxy!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7), (I, 8), (J, 9), (K, 10), (L, 11), (M, 12), (N, 13)); +#[rustfmt::skip] +impl_tuple_unproxy_proxy!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7), (I, 8), (J, 9), (K, 10), (L, 11), (M, 12), (N, 13), (O, 14)); +#[rustfmt::skip] +impl_tuple_unproxy_proxy!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7), (I, 8), (J, 9), (K, 10), (L, 11), (M, 12), (N, 13), (O, 14), (P, 15)); +#[rustfmt::skip] +impl_tuple_unproxy_proxy!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7), (I, 8), (J, 9), (K, 10), (L, 11), (M, 12), (N, 13), (O, 14), (P, 15), (Q, 16)); + +#[cfg(test)] +mod test { + + use bevy::ecs::{component::Component, world::World}; + + use crate::bindings::{ReflectBase, ReflectBaseType}; + + use super::*; + + #[derive(Reflect, Component, PartialEq, Eq, Debug, Clone)] + struct Test(pub &'static str); + + #[derive(Debug, Clone, PartialEq, Eq)] + struct ValTestProxy(Test); + + impl From for ValTestProxy { + fn from(value: Test) -> Self { + Self(value) + } + } + + impl<'a> From<&'a ValTestProxy> for Test { + fn from(value: &'a ValTestProxy) -> Self { + value.0.clone() + } + } + + #[derive(Debug, Clone, PartialEq, Eq)] + struct TestProxy(ReflectReference); + + impl From for TestProxy { + fn from(value: ReflectReference) -> Self { + TestProxy(value) + } + } + + impl AsRef for TestProxy { + fn as_ref(&self) -> &ReflectReference { + &self.0 + } + } + + macro_rules! assert_proxy_invertible { + ($original:expr, $($proxy_ty:tt)*) => { + let mut world = World::new(); + let mut accesses = SmallVec::new(); + let world = WorldAccessGuard::new(&mut world); + let type_registry = TypeRegistry::default(); + let mut allocator = ReflectAllocator::default(); + + // test with world version + let mut proxy = <$($proxy_ty)* as Proxy>::proxy_with_allocator($original, &mut allocator).unwrap(); + proxy.collect_accesses(&world, &mut accesses).unwrap(); + + let unproxied = unsafe { + proxy + .unproxy_with_world(&world, &mut accesses, &type_registry, &allocator) + .unwrap() + }; + assert_eq!( + unproxied, $original, + "Proxy and unproxy does not yield original type, expected {:?}, got {:?}", + $original, unproxied + ); + + let mut proxy = <$($proxy_ty)* as Proxy>::proxy($original).unwrap(); + + let unproxied_without_world = proxy.unproxy().unwrap(); + assert_eq!( + unproxied_without_world, $original, + "Proxy and unproxy does not yield original type, expected {:?}, got {:?}", + $original, unproxied_without_world + ); + + }; + } + + #[test] + pub fn test_non_reflect_val_proxy() { + assert_proxy_invertible!(Test("test"), ValProxy::); + } + + #[test] + pub fn test_complex_types_proxy_is_inverse_of_unproxy() { + assert_proxy_invertible!([32; 4], [usize; 4]); + assert_proxy_invertible!( + core::array::from_fn::<_, 4, _>(|_| vec![Test("test")]), + [Vec::>; 4] + ); + assert_proxy_invertible!(Vec::::default(), Vec::); + assert_proxy_invertible!(Some(Test("test")), Option::>); + assert_proxy_invertible!(None::, Option::>); + assert_proxy_invertible!( + Some(Some(Test("test"))), + Option::>> + ); + assert_proxy_invertible!( + vec![Some(Test("test")), None, Some(Test("test"))], + Vec::>> + ); + assert_proxy_invertible!(vec![&1, &2, &3], Vec::<&usize>); + // assert_proxy_invertible!(vec![&(1, 2)], Vec::<&(usize, usize)>); + assert_proxy_invertible!(vec![vec![1, 2], vec![1, 2, 3]], Vec::>); + assert_proxy_invertible!( + vec![vec![(1, 2), (3, 4)], vec![(1, 2), (3, 4)]], + Vec::> + ); + assert_proxy_invertible!(Some(1), Option::); + assert_proxy_invertible!(Some(Some(1)), Option::>); + assert_proxy_invertible!(None::, Option::); + assert_proxy_invertible!(None::>, Option::>); + assert_proxy_invertible!(vec![Some(1), None, Some(2)], Vec::>); + assert_proxy_invertible!( + vec![Some(vec![1, 2, 3]), None, Some(vec![1, 4])], + Vec::>> + ); + } + + #[test] + pub fn test_val_proxy() { + let mut allocator = ReflectAllocator::default(); + let (alloc_id, _) = allocator.allocate(Test("test")); + + let mut proxy = ReflectValProxy::::new(TestProxy(ReflectReference { + base: ReflectBaseType { + type_id: std::any::TypeId::of::(), + base_id: ReflectBase::Owned(alloc_id), + }, + reflect_path: vec![], + })); + let mut world = World::new(); + let mut accesses = SmallVec::new(); + let world = WorldAccessGuard::new(&mut world); + let type_registry = TypeRegistry::default(); + + proxy.collect_accesses(&world, &mut accesses).unwrap(); + let unproxied = unsafe { + proxy + .unproxy_with_world(&world, &accesses, &type_registry, &allocator) + .unwrap() + }; + assert_eq!(unproxied.0, "test"); + } + + #[test] + pub fn test_proxy_ref() { + let mut allocator = ReflectAllocator::default(); + let (alloc_id, _) = allocator.allocate(Test("test")); + + let mut proxy = ReflectRefProxy::::new(TestProxy(ReflectReference { + base: ReflectBaseType { + type_id: std::any::TypeId::of::(), + base_id: ReflectBase::Owned(alloc_id), + }, + reflect_path: vec![], + })); + let mut world = World::new(); + let mut accesses = SmallVec::new(); + let world = WorldAccessGuard::new(&mut world); + let type_registry = TypeRegistry::default(); + + proxy.collect_accesses(&world, &mut accesses).unwrap(); + let unproxied = unsafe { + proxy + .unproxy_with_world(&world, &accesses, &type_registry, &allocator) + .unwrap() + }; + assert_eq!(unproxied.0, "test"); + } + + #[test] + pub fn test_proxy_ref_mut() { + let mut allocator = ReflectAllocator::default(); + let (alloc_id, _) = allocator.allocate(Test("test")); + + let mut proxy = ReflectRefMutProxy::::new(TestProxy(ReflectReference { + base: ReflectBaseType { + type_id: std::any::TypeId::of::(), + base_id: ReflectBase::Owned(alloc_id), + }, + reflect_path: vec![], + })); + let mut world = World::new(); + let mut accesses = SmallVec::new(); + let world = WorldAccessGuard::new(&mut world); + let type_registry = TypeRegistry::default(); + + proxy.collect_accesses(&world, &mut accesses).unwrap(); + let unproxied = unsafe { + proxy + .unproxy_with_world(&world, &accesses, &type_registry, &allocator) + .unwrap() + }; + assert_eq!(unproxied.0, "test"); + } + + #[test] + pub fn test_vec_proxy_ref_mut() { + let mut allocator = ReflectAllocator::default(); + let (alloc_id, _) = allocator.allocate(Test("test")); + + let mut proxy = vec![Some(ReflectRefMutProxy::::new(TestProxy( + ReflectReference { + base: ReflectBaseType { + type_id: std::any::TypeId::of::(), + base_id: ReflectBase::Owned(alloc_id), + }, + reflect_path: vec![], + }, + )))]; + let mut world = World::new(); + let mut accesses = SmallVec::new(); + let world = WorldAccessGuard::new(&mut world); + let type_registry = TypeRegistry::default(); + + proxy.collect_accesses(&world, &mut accesses).unwrap(); + let unproxied = unsafe { + proxy + .unproxy_with_world(&world, &accesses, &type_registry, &allocator) + .unwrap() + }; + assert_eq!(unproxied[0].as_ref().unwrap().0, "test"); + } + + #[test] + pub fn test_invalid_access() { + let mut allocator = ReflectAllocator::default(); + + let (allocation_id, _) = allocator.allocate(Test("test")); + + let reflect_ref = ReflectReference { + base: ReflectBaseType { + type_id: std::any::TypeId::of::(), + base_id: ReflectBase::Owned(allocation_id), + }, + reflect_path: vec![], + }; + + // mutable access to the same allocation + let proxy = vec![ + ReflectRefMutProxy::::new(TestProxy(reflect_ref.clone())), + ReflectRefMutProxy::::new(TestProxy(reflect_ref)), + ]; + + let mut world = World::new(); + let mut accesses = SmallVec::new(); + let world = WorldAccessGuard::new(&mut world); + + let result = proxy.collect_accesses(&world, &mut accesses); + assert!(matches!(result, Err(..))); + } +} 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 0000000000..cf2a4dfdf7 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/query.rs @@ -0,0 +1,166 @@ +use super::{ReflectReference, WorldAccessGuard, WorldCallbackAccess}; +use crate::{ + bindings::{CONCURRENT_WORLD_ACCESS_MSG, STALE_WORLD_MSG}, + prelude::ScriptResult, +}; +use bevy::{ + ecs::{component::ComponentId, entity::Entity}, + prelude::{EntityRef, QueryBuilder}, + 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)] +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) -> &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 or a resource. + #[inline(always)] + pub fn component_id(&self) -> Option { + self.component_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)] +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 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 + } +} + +#[derive(Clone)] +pub struct ScriptQueryResult(pub Entity, pub Vec); + +impl WorldCallbackAccess { + pub fn query(&self, query: ScriptQueryBuilder) -> ScriptResult> { + // find the set of components + self.read() + .unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")) + .query(query) + } +} + +impl<'w> WorldAccessGuard<'w> { + pub fn query(&self, query: ScriptQueryBuilder) -> ScriptResult> { + let world = self + .get_whole_world_access() + .unwrap_or_else(|| panic!("{CONCURRENT_WORLD_ACCESS_MSG}")); + + 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().unwrap()); + } + + for w in query.with { + dynamic_query.with_id(w.component_id.unwrap()); + } + + for without_id in query.without { + dynamic_query.without_id(without_id.component_id.unwrap()); + } + + 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: vec![], + }) + .collect(); + ScriptQueryResult(r.id(), references) + }) + .collect()) + } +} + +#[cfg(test)] +mod test { + use test_utils::test_data::setup_world; + + use super::*; + + // #[test] + // fn test_simple_query() { + // let world = setup_world(|w,r|{ + // w.spawn(TestComponent::init()) + // w.spawn(Te) + // }) + // } +} 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 0000000000..13305542ae --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/reference.rs @@ -0,0 +1,664 @@ +//! # 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 lockable::LockableHashMap; + +use std::{ + any::TypeId, + cell::UnsafeCell, + error::Error, + fmt::Debug, + marker::PhantomData, + ops::Index, + sync::{Arc, Weak}, + time::Duration, +}; + +use bevy::{ + ecs::{ + change_detection::MutUntyped, + component::{Component, ComponentId}, + entity::Entity, + reflect::AppTypeRegistry, + system::Resource, + world::{unsafe_world_cell::UnsafeWorldCell, Mut, World}, + }, + ptr::Ptr, + reflect::{ + Access, DynamicEnum, DynamicTuple, ParsedPath, PartialReflect, Reflect, ReflectFromPtr, ReflectPath, ReflectPathError, TypeInfo, TypeRegistry + }, +}; +use smallvec::SmallVec; + +use crate::{ + bindings::{ReflectAllocation, ReflectAllocationId}, + prelude::{ReflectAllocator, ScriptError, ScriptResult}, reflection_extensions::{PartialReflectExt, TypeIdExtensions}, +}; + +use super::{ + proxy::{Proxy, Unproxy}, + ReflectAccessId, ReflectAccessKind, WorldAccessGuard, WorldAccessWrite, DEFAULT_INTERVAL, + DEFAULT_TIMEOUT, +}; + +/// 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)] +pub struct ReflectReference { + 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 + pub reflect_path: Vec, +} + + +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) + } + + /// Attempts to insert into the reflected value, if the underlying supports inserting at usize indices + pub fn insert_at(&mut self, world: &WorldAccessGuard, index: usize, elem: ReflectReference) -> ScriptResult<()> { + self.with_reflect_mut(world, |target, type_registry, allocator| { + elem.with_reflect_only(world, type_registry, allocator, |other,_,_| { + target.insert_at(index, other.clone_value()) + })? + })??; + Ok(()) + } + + /// Prints the reference using the world to resolve type names. + pub fn print_with_world(&self, world: &WorldAccessGuard) -> String { + world.with_resource(|_, type_registry: Mut| { + let type_registry = type_registry.read(); + self.print_with_type_registry(&type_registry) + }) + } + + /// Prints the reference using the type registry to resolve type names. Prefer this over [`Self::print_with_world`] if you have a type registry available. + pub fn print_with_type_registry(&self, type_registry: &TypeRegistry) -> String { + let base = self.base.display_with_type_name(type_registry); + format!("Reference(base: {}, path: {:?})", base, self.reflect_path) + } + + /// If this is a reference to something with a length accessible via reflection, returns that length. + pub fn len(&self, world: &WorldAccessGuard) -> ScriptResult> { + 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()), + bevy::reflect::ReflectRef::Opaque(_) => 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: 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.push(index.into()); + } + + /// A form of [`Self::reflect`] which does the access checks for you. + #[track_caller] + pub fn with_reflect O>( + &self, + world: &WorldAccessGuard, + f: F, + ) -> ScriptResult { + world.with_allocator_and_type_registry(|world, type_registry, mut allocator| { + let type_registry = type_registry.write(); + self.with_reflect_only(world, &type_registry, &mut allocator, f) + }) + } + + pub fn with_reflect_only O>( + &self, + world: &WorldAccessGuard, + type_registry: &TypeRegistry, + allocator: &mut ReflectAllocator, + f: F, + ) -> ScriptResult { + let access = world + .get_access_timeout( + self.base.base_id.get_reflect_access_id(), + DEFAULT_TIMEOUT, + DEFAULT_INTERVAL, + ); + + let reflect = self + .reflect( + world.as_unsafe_world_cell(), + &access, + type_registry, + Some(allocator), + ).map(|r| f(r, type_registry, allocator)); + + world.release_access(access); + reflect + } + + #[track_caller] + pub fn with_reflect_mut O>( + &self, + world: &WorldAccessGuard, + f: F, + ) -> ScriptResult { + world.with_allocator_and_type_registry(|_, type_registry, mut allocator| { + let type_registry = type_registry.read(); + self.with_reflect_mut_only(world, &type_registry, &mut allocator, f) + }) + } + + pub fn with_reflect_mut_only O>( + &self, + world: &WorldAccessGuard, + type_registry: &TypeRegistry, + allocator: &mut ReflectAllocator, + f: F, + ) -> ScriptResult { + let mut access = world + .get_access_timeout( + self.base.base_id.get_reflect_access_id(), + DEFAULT_TIMEOUT, + DEFAULT_INTERVAL, + ); + + let reflect = self + .reflect_mut( + world.as_unsafe_world_cell(), + &mut access, + type_registry, + Some(allocator), + ).map(|r| f(r, type_registry, allocator)); + + world.release_access(access); + reflect + } + + /// Returns `Ok(())` if the given access is sufficient to read the value or an appropriate error otherwise + pub fn expect_read_access<'w>( + &self, + access: &WorldAccessWrite<'w>, + type_registry: &TypeRegistry, + allocator: Option<&ReflectAllocator>, + world: UnsafeWorldCell<'w>, + ) -> ScriptResult<()> { + if !access.can_read(self.base.base_id.get_reflect_access_id()) { + Err(ScriptError::new_reflection_error(format!( + "Invalid access when trying to read: `{}`, instead got access to `{}`", + self.base.display_with_type_name(type_registry), + access.to_enriched_str(type_registry, allocator, world) + ))) + } else { + Ok(()) + } + } + + /// Returns `Ok(())` if the given access is sufficient to write to the value or an appropriate error otherwise + /// Note that this is not sufficient for write access, you also need to ensure the [`WorldAccessWrite`] won't be used to access the same value mutably elsewhere, + /// if you have a `&mut WorldAccessWrite` you can guarantee this statically. This function just checks that the access itself is for the right base with write access + pub fn expect_write_access<'w>( + &self, + access: &WorldAccessWrite<'w>, + type_registry: &TypeRegistry, + allocator: Option<&ReflectAllocator>, + world: UnsafeWorldCell<'w>, + ) -> ScriptResult<()> { + if !access.can_read(self.base.base_id.get_reflect_access_id()) { + Err(ScriptError::new_reflection_error(format!( + "Invalid access when trying to write: `{}`, instead got access to `{}`", + self.base.display_with_type_name(type_registry), + access.to_enriched_str(type_registry, allocator, world) + ))) + } else { + Ok(()) + } + } + + /// Retrieves a reference to the underlying `dyn PartialReflect` type valid for the 'w lifetime of the world cell. + /// If the underlying componentId is not the same as the one we have access to, an error is returned. + pub fn reflect<'w, 'c>( + &self, + world: UnsafeWorldCell<'w>, + access: &'c WorldAccessWrite<'w>, + type_registry: &TypeRegistry, + allocator: Option<&ReflectAllocator>, + ) -> ScriptResult<&'c dyn PartialReflect> { + self.expect_read_access(access, type_registry, allocator, world)?; + // Safety: since we have read access to the underlying componentId we can safely access the component + // and we can return a reference tied to its lifetime, which will prevent invalid aliasing + return unsafe { self.reflect_unsafe(world, type_registry, allocator) }; + } + + /// Retrieves a reference to the underlying `dyn PartialReflect` type valid for the 'w lifetime of the world cell. + /// If the underlying componentId is not the same as the one we have access to, an error is returned. + /// + /// If we are accessing a component or resource, it's marked as changed + pub fn reflect_mut<'w, 'c>( + &self, + world: UnsafeWorldCell<'w>, + access: &'c mut WorldAccessWrite<'w>, + type_registry: &TypeRegistry, + allocator: Option<&ReflectAllocator>, + ) -> ScriptResult<&'c mut dyn PartialReflect> { + self.expect_write_access(access, type_registry, allocator, world)?; + // Safety: since we have write access to the underlying reflect access id we can safely access the component + // and we can return a reference tied to its lifetime, which will prevent invalid aliasing + return unsafe { self.reflect_mut_unsafe(world, type_registry, allocator) }; + } + + /// 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 mut references to the same value exist at all at the same time + pub unsafe fn reflect_unsafe<'w>( + &self, + world: UnsafeWorldCell<'w>, + type_registry: &TypeRegistry, + allocator: Option<&ReflectAllocator>, + ) -> ScriptResult<&'w dyn PartialReflect> { + if let ReflectBase::Owned(id) = &self.base.base_id { + let allocator = + allocator.ok_or_else(|| ScriptError::new_reflection_error("Allocator missing"))?; + let arc = allocator + .get(*id) + .ok_or_else(|| ScriptError::new_reflection_error("Missing allocation"))?; + + // safety: caller promises it's fine :) + return self.walk_path(unsafe { &*arc.get_ptr() }); + }; + // all Reflect types should have this derived + let from_ptr_data: &ReflectFromPtr = type_registry + .get_type_data(self.base.type_id) + .expect("FromPtr is not registered for this type, cannot retrieve reflect reference"); + + let ptr = self + .base + .base_id + .clone() + .into_ptr(world) + .ok_or_else(|| + ScriptError::new_reflection_error( + format!("Base reference is invalid, is the component/resource initialized? does the entity exist?. When accessing: `{}`", self.base.display_with_type_name(type_registry))))?; + + // (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(ptr) }; + 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) + pub unsafe fn reflect_mut_unsafe<'w>( + &self, + world: UnsafeWorldCell<'w>, + type_registry: &TypeRegistry, + allocator: Option<&ReflectAllocator>, + ) -> ScriptResult<&'w mut dyn PartialReflect> { + if let ReflectBase::Owned(id) = &self.base.base_id { + let allocator = + allocator.ok_or_else(|| ScriptError::new_reflection_error("Allocator missing"))?; + + let arc = allocator + .get_mut(*id) + .ok_or_else(|| ScriptError::new_reflection_error("Missing allocation"))?; + + // Safety: caller promises this is fine :) + return self.walk_path_mut(unsafe { &mut *arc.get_ptr() }); + }; + + // all Reflect types should have this derived + let from_ptr_data: &ReflectFromPtr = type_registry + .get_type_data(self.base.type_id) + .expect("FromPtr is not registered for this type, cannot retrieve reflect reference"); + + let ptr = self + .base + .base_id + .clone() + .into_ptr_mut(world) + .ok_or_else(|| + ScriptError::new_reflection_error( + format!("Base reference is invalid, is the component/resource initialized? does the entity exist?. When accessing: `{}`", self.base.display_with_type_name(type_registry))))? + .into_inner(); + + // (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) }; + self.walk_path_mut(base.as_partial_reflect_mut()) + } + + fn walk_path<'a>(&self, root: &'a dyn PartialReflect) -> ScriptResult<&'a dyn PartialReflect> { + let mut current = root; + for elem in self.reflect_path.iter() { + current = elem + .reflect_element(current) + .map_err(|e| ScriptError::new_reflection_error(e.to_string()))?; + } + Ok(current) + } + + fn walk_path_mut<'a>( + &self, + root: &'a mut dyn PartialReflect, + ) -> ScriptResult<&'a mut dyn PartialReflect> { + let mut current = root; + for elem in self.reflect_path.iter() { + current = elem + .reflect_element_mut(current) + .map_err(|e| ScriptError::new_reflection_error(e.to_string()))?; + } + Ok(current) + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ReflectBaseType { + pub type_id: TypeId, + pub base_id: ReflectBase, +} + +impl ReflectBaseType { + pub fn type_name(type_id: TypeId, type_registry: &TypeRegistry) -> &'static str { + type_registry + .get_type_info(type_id) + .map(TypeInfo::type_path) + .unwrap_or("") + } + + pub fn display_with_type_name(&self, type_registry: &TypeRegistry) -> String { + let type_name = Self::type_name(self.type_id, type_registry); + + let kind = match self.base_id { + ReflectBase::Component(entity, _) => "Component", + ReflectBase::Resource(_) => "Resource", + ReflectBase::Owned(id) => "Allocation", + }; + + format!("{}({})", kind, type_name) + } +} + +/// The Id of the kind of reflection base being pointed to +#[derive(Clone, Debug, PartialEq, Eq)] +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 fn get_reflect_access_id(&self) -> ReflectAccessId { + match self { + ReflectBase::Component(_, cid) | ReflectBase::Resource(cid) => (*cid).into(), + ReflectBase::Owned(id) => (*id).into(), + } + } +} + +/// An element in the reflection path, the base reference included +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum ReflectionPathElem { + /// A standard reflection path, i.e. `.field_name[vec_index]`, pre-parsed since we construct once potentially use many times + Reflection(ParsedPath), + /// a deferred reflection + DeferredReflection(DeferredReflection), + /// a no-op reflection, i.e. a reference to the base object, useful identity to have + Identity +} + +impl ReflectionPathElem { + pub fn new_reflection>(path: I) -> Self { + Self::Reflection(path.into()) + } + + pub fn new_deferred>(defref: I) -> Self { + Self::DeferredReflection(defref.into()) + } +} + +impl From<(A, B)> for DeferredReflection +where + A: Fn(&dyn PartialReflect) -> Result<&dyn PartialReflect, ReflectPathError<'static>> + + Send + + Sync, + B: Fn(&mut dyn PartialReflect) -> Result<&mut dyn PartialReflect, ReflectPathError<'static>> + + Send + + Sync, +{ + fn from((get, get_mut): (A, B)) -> Self { + Self { + get: Arc::new(get), + get_mut: Arc::new(get_mut), + } + } +} + +impl> From for ReflectionPathElem { + fn from(value: T) -> Self { + Self::DeferredReflection(value.into()) + } +} + +impl From for ReflectionPathElem { + fn from(value: ParsedPath) -> Self { + Self::Reflection(value) + } +} + +impl<'a> ReflectPath<'a> for &'a ReflectionPathElem { + fn reflect_element<'r>( + self, + root: &'r dyn PartialReflect, + ) -> Result<&'r dyn PartialReflect, ReflectPathError<'a>> { + match self { + ReflectionPathElem::Reflection(path) => path.reflect_element(root), + ReflectionPathElem::DeferredReflection(f) => (f.get)(root), + ReflectionPathElem::Identity => Ok(root), + } + } + + fn reflect_element_mut<'r>( + self, + root: &'r mut dyn PartialReflect, + ) -> Result<&'r mut dyn PartialReflect, ReflectPathError<'a>> { + match self { + ReflectionPathElem::Reflection(path) => path.reflect_element_mut(root), + ReflectionPathElem::DeferredReflection(defref) => (defref.get_mut)(root), + ReflectionPathElem::Identity => Ok(root) + } + } +} + +/// A ReflectPath which can perform arbitrary operations on the root object to produce a sub-reference +#[derive(Clone)] +pub struct DeferredReflection { + pub get: Arc< + dyn Fn(&dyn PartialReflect) -> Result<&dyn PartialReflect, ReflectPathError<'static>> + + Send + + Sync, + >, + pub get_mut: Arc< + dyn Fn( + &mut dyn PartialReflect, + ) -> Result<&mut dyn PartialReflect, ReflectPathError<'static>> + + Send + + Sync, + >, +} + +/// Given a function, repeats it with a mutable reference for the get_mut deferred variant +#[macro_export] +macro_rules! new_deferred_reflection { + (|$root:ident| {$($get:tt)*}) => { + DeferredReflection::from(( + |$root: &dyn PartialReflect| -> Result<&dyn PartialReflect, ReflectPathError<'static>> { + $($get)* + }, + |$root: &mut dyn PartialReflect| -> Result<&mut dyn PartialReflect, ReflectPathError<'static>> { + $($get)* + }, + )) + }; +} + + +impl Debug for DeferredReflection { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("DeferredReflection") + } +} + +impl PartialEq for DeferredReflection { + fn eq(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.get, &other.get) && Arc::ptr_eq(&self.get_mut, &other.get_mut) + } +} + +impl Eq for DeferredReflection {} + + +/// 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(ReflectionPathElem::Reflection(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(ReflectionPathElem::Reflection(parsed_path)); + *i += 1; + Ok(next) + } + } + }; + + Some(result) + } +} \ No newline at end of file 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 0000000000..02e7f8f212 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/bindings/world.rs @@ -0,0 +1,2050 @@ +//! # 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 lockable::{LockableHashMap, SyncLimit}; + +use std::{ + any::TypeId, + fmt::Debug, + marker::PhantomData, + mem, + sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, Weak, + }, + time::Duration, +}; + +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, TypeRegistry}, +}; + +use smallvec::SmallVec; + +use crate::{ + bindings::ReflectAllocationId, + prelude::{ReflectAllocator, ScriptError, ScriptResult}, +}; + +use super::{ + proxy::{Proxy, Unproxy}, + ReflectBase, ReflectBaseType, ReflectReference, ScriptTypeRegistration, +}; + +/// 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: usize, +} + +impl From for ReflectAccessId { + fn from(value: ComponentId) -> Self { + Self { + kind: ReflectAccessKind::ComponentOrResource, + id: value.index(), + } + } +} + +impl From for ReflectAccessId { + fn from(value: ReflectAllocationId) -> Self { + Self { + kind: ReflectAccessKind::Allocation, + id: value.id(), + } + } +} + +/// 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)] +pub struct WorldCallbackAccess(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::new(WorldAccessGuard::new(world)); + let world_guard = unsafe { WorldCallbackAccess::new(Arc::downgrade(&world_guard)) }; + + callback(&world_guard) + } + + /// Creates a new [`WorldCallbackAccess`] with an erased lifetime. + /// + /// # Safety + /// - The caller must ensure the [`WorldAccessGuard`] must 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) + } + + /// Attempts to read the world access guard, if it still exists + pub fn read(&self) -> Option>> { + self.0.upgrade() + } +} + +pub(crate) const STALE_WORLD_MSG: &str = "Tried to access world via stale reference"; +pub(crate) const CONCURRENT_WORLD_ACCESS_MSG: &str = + "Something else is accessing the world right now!"; +pub(crate) const CONCURRENT_ACCESS_MSG: &str = + "Something else is accessing the resource/component/allocation right now!"; + +/// common world methods, see: +/// - [`crate::bindings::query`] for query related functionality +impl WorldCallbackAccess { + pub fn spawn(&self) -> Entity { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + 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) -> Option { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + world.get_type_by_name(type_name) + } + + pub fn add_default_component( + &self, + entity: Entity, + registration: ScriptTypeRegistration, + ) -> ScriptResult<()> { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + world.add_default_component(entity, registration) + } + + pub fn get_component( + &self, + entity: Entity, + component_id: ComponentId, + ) -> ScriptResult> { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + world.get_component(entity, component_id) + } + + pub fn has_component(&self, entity: Entity, component_id: ComponentId) -> ScriptResult { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + world.has_component(entity, component_id) + } + + pub fn remove_component( + &self, + entity: Entity, + registration: ScriptTypeRegistration, + ) -> ScriptResult<()> { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + world.remove_component(entity, registration) + } + + pub fn get_resource(&self, resource_id: ComponentId) -> ScriptResult> { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + world.get_resource(resource_id) + } + + pub fn remove_resource(&self, registration: ScriptTypeRegistration) -> ScriptResult<()> { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + world.remove_resource(registration) + } + + pub fn has_resource(&self, resource_id: ComponentId) -> bool { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + world.has_resource(resource_id) + } + + pub fn has_entity(&self, entity: Entity) -> bool { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + world.has_entity(entity) + } + + pub fn get_children(&self, entity: Entity) -> ScriptResult> { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + world.get_children(entity) + } + + pub fn get_parent(&self, entity: Entity) -> ScriptResult> { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + world.get_parent(entity) + } + + pub fn push_children(&self, parent: Entity, children: &[Entity]) -> ScriptResult<()> { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + world.push_children(parent, children) + } + + pub fn remove_children(&self, parent: Entity, children: &[Entity]) -> ScriptResult<()> { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + world.remove_children(parent, children) + } + + pub fn insert_children( + &self, + parent: Entity, + index: usize, + children: &[Entity], + ) -> ScriptResult<()> { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + world.insert_children(parent, index, children) + } + + pub fn despawn_recursive(&self, entity: Entity) -> ScriptResult<()> { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + world.despawn_recursive(entity) + } + + pub fn despawn(&self, entity: Entity) -> ScriptResult<()> { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + world.despawn(entity) + } + + pub fn despawn_descendants(&self, entity: Entity) -> ScriptResult<()> { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + world.despawn_descendants(entity) + } + + pub fn exit(&self) { + let world = self.read().unwrap_or_else(|| panic!("{STALE_WORLD_MSG}")); + world.exit() + } +} + +/// Unit of world access +pub type WorldAccessUnit<'w> = WorldAccessWrite<'w>; + +pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(5); +pub const DEFAULT_INTERVAL: Duration = Duration::from_millis(10); + +enum WorldAccessValue<'w> { + Free(WorldAccessWrite<'w>), + Locked(std::panic::Location<'static>), +} + +impl<'w> WorldAccessValue<'w> { + fn is_locked(&self) -> bool { + matches!(self, WorldAccessValue::Locked(_)) + } + + fn as_location(&self) -> Option> { + match self { + WorldAccessValue::Free(_) => None, + WorldAccessValue::Locked(location) => Some(*location), + } + } + + fn into_access(self) -> Option> { + match self { + WorldAccessValue::Free(access) => Some(access), + WorldAccessValue::Locked(_) => None, + } + } + + #[track_caller] + fn take(&mut self) -> Option> { + mem::replace( + self, + WorldAccessValue::Locked(*std::panic::Location::caller()), + ) + .into_access() + } +} + +impl<'w> From> for WorldAccessValue<'w> { + fn from(value: WorldAccessWrite<'w>) -> Self { + WorldAccessValue::Free(value) + } +} + +/// 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 cell: UnsafeWorldCell<'w>, + // TODO: this is fairly hefty, explore other ways to hand out locks on WorldAccess + accesses: Arc>>, + /// true if anybody has any access to the world + pub accesses_count: Arc, + // TODO can we track code/stack locations of things holding onto theese locks for debugging? +} + +impl<'w> WorldAccessGuard<'w> { + /// Creates a new [`WorldAccessGuard`] for the given mutable borrow of the world + pub fn new(world: &'w mut World) -> Self { + Self { + cell: world.as_unsafe_world_cell(), + accesses: Default::default(), + accesses_count: Arc::new(AtomicUsize::new(0)), + } + } + + /// Purely debugging utility to list all accesses currently held. + pub fn list_accesses(&self) -> Vec { + let keys = self.accesses.keys_with_entries_or_locked(); + + // return only those which have no value + keys.into_iter() + .filter(|k| { + let val = self + .accesses + .blocking_lock(*k, SyncLimit::no_limit()) + .unwrap(); + let val = val.value().unwrap(); + + val.is_locked() + }) + .collect() + } + + /// 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.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.cell + } + + /// Gets the component id of the given component or resource + pub fn get_component_id(&self, id: TypeId) -> Option { + self.cell.components().get_id(id) + } + + pub fn get_resource_id(&self, id: TypeId) -> Option { + self.cell.components().get_resource_id(id) + } + + #[track_caller] + /// Checks nobody else is currently accessing the world, and if so locks access to it until + /// [`release_whole_world_access`] is called. + pub fn get_whole_world_access(&self) -> Option<&mut World> { + if self.accesses_count.load(Ordering::Relaxed) == 0 { + Some(unsafe { self.cell.world_mut() }) + } else { + None + } + } + + /// Releases whole world access. Allowing others to access it. + pub fn release_whole_world_access(&self, _world: &mut World) { + // we do not need ot use the world reference, it's there as proof that the caller has claimed access before + assert_eq!(self.accesses_count.load(Ordering::Relaxed), 1); + self.accesses_count.fetch_sub(1, Ordering::Relaxed); + } + + pub fn get_access_location(&self, raid: ReflectAccessId) -> Option> { + let guard = self + .accesses + .blocking_lock(raid, lockable::SyncLimit::no_limit()) + .unwrap(); + let guard = guard.value().unwrap(); + + guard.as_location() + } + + #[track_caller] + /// Tries to get access to the given reflect access id, if it's already given out returns `None`. If you want to wait for access, use [`WorldAccessGuard::get_access_timeout`] instead. + /// Remember to release this access once done with [`WorldAccessGuard::release_access`] or nobody else will be able to access this id!. + /// + /// Although forgetting to release access is safe, it's frankly quite rude and can lead to deadlocks. + pub fn get_access(&self, raid: ReflectAccessId) -> Option> { + let mut guard = self + .accesses + .blocking_lock(raid, lockable::SyncLimit::no_limit()) + .unwrap(); + let guard = guard.value_or_insert_with(|| { + WorldAccessWrite { + raid, + _ph: PhantomData, + } + .into() + }); + + if !guard.is_locked() { + self.accesses_count.fetch_add(1, Ordering::Relaxed); + guard.take() + } else { + // somebody has access to this already, we cannot access at the moment + None + } + } + + /// Blocking version of [`WorldAccessGuard::get_access`], waits for access to the given reflect access id. Will busy wait at the given intervals, untill the timeout is reached. + /// If interval is zero this is equivalent to busy waiting. + /// + /// # Panic + /// Will panic once access was not available after the timeout was reached + #[track_caller] + pub fn get_access_timeout( + &self, + raid: ReflectAccessId, + timeout: Duration, + interval: Duration, + ) -> WorldAccessUnit<'w> { + let mut access = self.get_access(raid); + let start = std::time::Instant::now(); + + while access.is_none() { + std::thread::sleep(interval); + access = self.get_access(raid); + if start.elapsed() > timeout { + panic!( + "Timed out while waiting for access to {:?}. This is likely a deadlock. The access is being held by: {:?}", + raid, + self.get_access_location(raid) + ); + } + } + access.expect("invariant") + } + + /// Releases access to the given reflect access id + pub fn release_access(&self, access: WorldAccessUnit<'w>) { + let mut guard = self + .accesses + .blocking_lock(access.raid, lockable::SyncLimit::no_limit()) + .unwrap(); + + let guard = guard + .value_mut() + .expect("Invariant violated, access should exist"); + + // should not be possible, we are the only ones who can instantiate WorldAccessUnit + assert!( + guard.is_locked(), + "Invariant violated, an access has been released by someone else already who shouldn't have been able to do so" + ); + + self.accesses_count.fetch_sub(1, Ordering::Relaxed); + *guard = WorldAccessValue::Free(access); + } + + #[track_caller] + /// Get access to the given component_id, this is the only way to access a component/resource safely (in the context of the world access guard) + /// since you can only access this component_id through a RwLock, there is no way to break aliasing rules. + /// Additionally the 'w lifetime prevents you from storing this access outside the lifetime of the underlying cell + pub fn get_component_access(&self, cid: ComponentId) -> Option> { + let access_id = ReflectAccessId { + kind: ReflectAccessKind::ComponentOrResource, + id: cid.index(), + }; + self.get_access(access_id) + } + + #[track_caller] + /// Similar to [`Self::get_component_access`] but typed, additionally panics if the component is not registered + pub fn get_component_access_typed(&self) -> Option> { + self.get_component_access( + self.cell + .components() + .component_id::() + .unwrap_or_else(|| { + panic!("Component not registered: `{}`", std::any::type_name::()) + }), + ) + } + + #[track_caller] + /// Get access to the given component_id, this is the only way to access a component/resource safely (in the context of the world access guard) + /// since you can only access this component_id through a RwLock, there is no way to break aliasing rules. + /// Additionally the 'w lifetime prevents you from storing this access outside the lifetime of the underlying cell + pub fn get_resource_access(&self, cid: ComponentId) -> Option> { + self.get_component_access(cid) + } + + #[track_caller] + /// Similar to [`Self::get_resource_access`] but typed, additionally panics if the resource is not registered + pub fn get_resource_access_typed(&self) -> Option> { + self.get_resource_access( + self.cell + .components() + .resource_id::() + .unwrap_or_else(|| { + panic!("Resource not registered: `{}`", std::any::type_name::()) + }), + ) + } + + #[track_caller] + /// Get access to the given allocation_id, this is the only way to access a script owned value safely (in the context of the world access guard) + pub fn get_allocation_access(&self, id: ReflectAllocationId) -> Option> { + let access_id = ReflectAccessId { + kind: ReflectAccessKind::Allocation, + id: id.id(), + }; + self.get_access(access_id) + } + + #[track_caller] + /// Provides access to a resource via callback. Panics if the resource does not exist or if waiting for access times out. + pub fn with_resource) -> O>(&self, f: F) -> O { + let cid = self + .cell + .components() + .resource_id::() + .unwrap_or_else(|| panic!("Resource not registered: `{}`", std::any::type_name::())); + + let mut access = self.get_access_timeout(cid.into(), DEFAULT_TIMEOUT, DEFAULT_INTERVAL); + + let resource = self + .get_resource_with_access_mut::(&mut access) + .expect("invariant") + .expect("invariant"); + let out = f(self, resource); + self.release_access(access); + out + } + + #[track_caller] + /// Convenience to get commonly used resources at the same time. Internally identical to [`Self::with_resource`] + pub fn with_allocator_and_type_registry< + O, + F: FnOnce(&Self, Mut, Mut) -> O, + >( + &self, + f: F, + ) -> O { + self.with_resource(|world, registry: Mut| { + world.with_resource(|world, allocator: Mut| { + f(world, registry, allocator) + }) + }) + } + + #[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, + mut proxied_input: T, + f: F, + ) -> ScriptResult { + let type_registry = + self.with_resource(|_, type_registry: Mut| type_registry.clone()); + + let type_registry = type_registry.read(); + let mut world_acceses = SmallVec::default(); + + let unproxied_input = self.with_resource(|_, allocator: Mut| { + proxied_input.collect_accesses(self, &mut world_acceses)?; + unsafe { + proxied_input.unproxy_with_world(self, &world_acceses, &type_registry, &allocator) + } + })?; + + let out = f(unproxied_input); + + let proxied_output = self.with_resource(|_, mut allocator: Mut| { + O::proxy_with_allocator(out, &mut allocator) + })?; + + // make sure to release all accesses + world_acceses.drain(..).for_each(|a| { + self.release_access(a); + }); + + Ok(proxied_output) + } + + #[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: &WorldAccessWrite, + entity: Entity, + ) -> ScriptResult> { + let component_id = match self.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 + return unsafe { Ok(self.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 WorldAccessWrite, + entity: Entity, + ) -> ScriptResult>> { + let component_id = match self.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 + return unsafe { Ok(self.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: &WorldAccessWrite, + ) -> ScriptResult> { + let resource_id = match self.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 + return unsafe { Ok(self.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 WorldAccessWrite, + ) -> ScriptResult>> { + let resource_id = match self.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 + return unsafe { Ok(self.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.cell.get_entity(entity).is_some() + } +} + +/// Impl block for higher level world methods +impl<'w> WorldAccessGuard<'w> { + pub fn spawn(&self) -> Entity { + if let Some(world) = self.get_whole_world_access() { + world.spawn_empty().id() + } else { + panic!("{CONCURRENT_WORLD_ACCESS_MSG}") + } + } + + pub fn get_type_by_name(&self, type_name: String) -> Option { + self.with_resource(|world, registry: Mut| { + 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()), + world.get_component_id(registration.type_id()), + world.get_resource_id(registration.type_id()), + ) + }) + }) + } + + pub fn add_default_component( + &self, + entity: Entity, + registration: ScriptTypeRegistration, + ) -> ScriptResult<()> { + let component_data = registration.registration.data::().ok_or_else(|| ScriptError::new_runtime_error(format!( + "Cannot add default component since type: `{}`, Does not have ReflectComponent data registered.", + registration.registration.type_info().type_path() + )))?; + + // 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::() { + if let Some(world) = self.get_whole_world_access() { + from_world_td.from_world(world) + } else { + panic!("{CONCURRENT_WORLD_ACCESS_MSG}") + } + } else { + return Err(ScriptError::new_runtime_error(format!( + "Cannot add default component since type: `{}`, Does not have ReflectDefault or ReflectFromWorld data registered.", + registration.registration.type_info().type_path() + ))); + }; + + // TODO: this shouldn't need entire world access it feels + if let Some(world) = self.get_whole_world_access() { + let app_registry = world + .remove_resource::() + .unwrap_or_else(|| panic!("Missing type registry")); + + let mut entity = world.get_entity_mut(entity).map_err(|e| { + ScriptError::new_runtime_error(format!( + "Could not retrieve entity: {:?}. {e}", + entity + )) + })?; + { + let registry = app_registry.read(); + component_data.insert(&mut entity, instance.as_partial_reflect(), ®istry); + } + world.insert_resource(app_registry); + } else { + panic!("{CONCURRENT_WORLD_ACCESS_MSG}") + } + + Ok(()) + } + pub fn get_component( + &self, + entity: Entity, + component_id: ComponentId, + ) -> ScriptResult> { + let entity = self.cell.get_entity(entity).ok_or_else(|| { + ScriptError::new_runtime_error(format!("Entity does not exist: {:?}", entity)) + })?; + + let component_info = self + .cell + .components() + .get_info(component_id) + .ok_or_else(|| { + ScriptError::new_runtime_error(format!( + "Component does not exist: {:?}", + 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: Default::default(), + })) + } else { + Ok(None) + } + } + + pub fn has_component(&self, entity: Entity, component_id: ComponentId) -> ScriptResult { + let entity = self.cell.get_entity(entity).ok_or_else(|| { + ScriptError::new_runtime_error(format!("Entity does not exist: {:?}", entity)) + })?; + + Ok(entity.contains_id(component_id)) + } + + pub fn remove_component( + &self, + entity: Entity, + registration: ScriptTypeRegistration, + ) -> ScriptResult<()> { + let component_data = registration.registration.data::().ok_or_else(|| ScriptError::new_runtime_error(format!( + "Cannot remove component since type: `{}`, Does not have ReflectComponent data registered.", + registration.registration.type_info().type_path() + )))?; + + // TODO: this shouldn't need entire world access it feels + if let Some(world) = self.get_whole_world_access() { + let mut entity = world.get_entity_mut(entity).map_err(|e| { + ScriptError::new_runtime_error(format!( + "Could not retrieve entity: {:?}. {e}", + entity + )) + })?; + + component_data.remove(&mut entity); + } else { + panic!("{CONCURRENT_WORLD_ACCESS_MSG}") + } + Ok(()) + } + + pub fn get_resource(&self, resource_id: ComponentId) -> ScriptResult> { + let component_info = match self.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: Default::default(), + })) + } + + pub fn remove_resource(&self, registration: ScriptTypeRegistration) -> ScriptResult<()> { + let component_data = registration.registration.data::().ok_or_else(|| ScriptError::new_runtime_error(format!( + "Cannot remove resource since type: `{}`, Does not have ReflectResource data registered.", + registration.registration.type_info().type_path() + )))?; + + // TODO: this shouldn't need entire world access it feels + if let Some(world) = self.get_whole_world_access() { + component_data.remove(world); + } else { + panic!("{CONCURRENT_WORLD_ACCESS_MSG}") + } + Ok(()) + } + + pub fn has_resource(&self, resource_id: ComponentId) -> bool { + // Safety: we are not reading the value at all + let res_ptr = unsafe { self.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) -> ScriptResult> { + if !self.is_valid_entity(entity) { + return Err(ScriptError::new_runtime_error(format!( + "Entity does not exist or is not valid: {:?}", + entity + ))); + } + + let access = self + .get_component_access_typed::() + .unwrap_or_else(|| panic!("{CONCURRENT_ACCESS_MSG}")); + + Ok(self + .get_component_with_access::(&access, entity)? + .map(|c| c.to_vec()) + .unwrap_or_default()) + } + + pub fn get_parent(&self, entity: Entity) -> ScriptResult> { + if !self.is_valid_entity(entity) { + return Err(ScriptError::new_runtime_error(format!( + "Entity does not exist or is not valid: {:?}", + entity + ))); + } + + let access = self + .get_component_access_typed::() + .unwrap_or_else(|| panic!("{CONCURRENT_ACCESS_MSG}")); + + Ok(self + .get_component_with_access::(&access, entity)? + .map(|c| c.get())) + } + + pub fn push_children(&self, parent: Entity, children: &[Entity]) -> ScriptResult<()> { + // verify entities exist + if !self.is_valid_entity(parent) { + return Err(ScriptError::new_runtime_error(format!( + "The parent Entity does not exist or is not valid: {:?}", + parent + ))); + } + for c in children { + if !self.is_valid_entity(*c) { + return Err(ScriptError::new_runtime_error(format!( + "the Entity does not exist or is not valid: {:?}", + c + ))); + } + } + + if let Some(world) = self.get_whole_world_access() { + let mut queue = CommandQueue::default(); + let mut commands = Commands::new(&mut queue, world); + commands.entity(parent).add_children(children); + queue.apply(world); + } else { + panic!("{CONCURRENT_WORLD_ACCESS_MSG}") + } + + Ok(()) + } + + pub fn remove_children(&self, parent: Entity, children: &[Entity]) -> ScriptResult<()> { + if !self.is_valid_entity(parent) { + return Err(ScriptError::new_runtime_error(format!( + "The parent Entity does not exist or is not valid: {:?}", + parent + ))); + } + + for c in children { + if !self.is_valid_entity(*c) { + return Err(ScriptError::new_runtime_error(format!( + "the Entity does not exist or is not valid: {:?}", + c + ))); + } + } + + if let Some(world) = self.get_whole_world_access() { + let mut queue = CommandQueue::default(); + let mut commands = Commands::new(&mut queue, world); + commands.entity(parent).remove_children(children); + queue.apply(world); + } else { + panic!("{CONCURRENT_WORLD_ACCESS_MSG}") + } + + Ok(()) + } + + pub fn insert_children( + &self, + parent: Entity, + index: usize, + children: &[Entity], + ) -> ScriptResult<()> { + if !self.is_valid_entity(parent) { + return Err(ScriptError::new_runtime_error(format!( + "parent Entity does not exist or is not valid: {:?}", + parent + ))); + } + + for c in children { + if !self.is_valid_entity(*c) { + return Err(ScriptError::new_runtime_error(format!( + "the Entity does not exist or is not valid: {:?}", + c + ))); + } + } + + if let Some(world) = self.get_whole_world_access() { + let mut queue = CommandQueue::default(); + let mut commands = Commands::new(&mut queue, world); + commands.entity(parent).insert_children(index, children); + queue.apply(world); + } else { + panic!("{CONCURRENT_WORLD_ACCESS_MSG}") + } + + Ok(()) + } + + pub fn despawn_recursive(&self, parent: Entity) -> ScriptResult<()> { + if !self.is_valid_entity(parent) { + return Err(ScriptError::new_runtime_error(format!( + "parent Entity does not exist or is not valid: {:?}", + parent + ))); + } + + if let Some(world) = self.get_whole_world_access() { + let mut queue = CommandQueue::default(); + let mut commands = Commands::new(&mut queue, world); + commands.entity(parent).despawn_recursive(); + queue.apply(world); + } else { + panic!("{CONCURRENT_WORLD_ACCESS_MSG}") + } + + Ok(()) + } + + pub fn despawn(&self, entity: Entity) -> ScriptResult<()> { + if !self.is_valid_entity(entity) { + return Err(ScriptError::new_runtime_error(format!( + "Entity does not exist or is not valid: {:?}", + entity + ))); + } + + if let Some(world) = self.get_whole_world_access() { + let mut queue = CommandQueue::default(); + let mut commands = Commands::new(&mut queue, world); + commands.entity(entity).despawn(); + queue.apply(world); + } else { + panic!("{CONCURRENT_WORLD_ACCESS_MSG}") + } + + Ok(()) + } + + pub fn despawn_descendants(&self, parent: Entity) -> ScriptResult<()> { + if !self.is_valid_entity(parent) { + return Err(ScriptError::new_runtime_error(format!( + "parent Entity does not exist or is not valid: {:?}", + parent + ))); + } + + if let Some(world) = self.get_whole_world_access() { + let mut queue = CommandQueue::default(); + let mut commands = Commands::new(&mut queue, world); + commands.entity(parent).despawn_descendants(); + queue.apply(world); + } else { + panic!("{CONCURRENT_WORLD_ACCESS_MSG}") + } + + Ok(()) + } + + /// Sends AppExit event to the world with success status + pub fn exit(&self) { + if let Some(world) = self.get_whole_world_access() { + world.send_event(AppExit::Success); + } else { + panic!("{CONCURRENT_WORLD_ACCESS_MSG}") + } + } +} + +/// Having this is permission to access the contained [`ReflectAccessId`], there is no way to access anything safely through a [`WorldAccessGuard`] +/// without having a [`WorldAccess`] instance for that particular [`ReflectAccessId`]. +/// +/// If you do own a [`WorldAccess`] for some [`ReflectAccessId`], you can read and write to it safely. +/// If you only have an immutable borrow of [`WorldAccess`] you can only read it safely. +/// If you have a mutable borrow of [`WorldAccess`] you can read and write to it safely. +#[derive(Debug)] +pub struct WorldAccessWrite<'a> { + pub raid: ReflectAccessId, + pub(self) _ph: PhantomData<&'a usize>, +} + +impl<'w> WorldAccessWrite<'w> { + pub fn can_read(&self, raid: ReflectAccessId) -> bool { + self.raid == raid + } + + #[inline] + pub fn can_write(&self, raid: ReflectAccessId) -> bool { + self.can_read(raid) + } + + /// Prints the type of access this [`WorldAccessWrite`] entails, enriched with type information from the registry + pub fn to_enriched_str( + &self, + registry: &TypeRegistry, + allocator: Option<&ReflectAllocator>, + cell: UnsafeWorldCell, + ) -> String { + let (base_type, type_id) = match self.raid.kind { + ReflectAccessKind::ComponentOrResource => { + let type_id = cell + .components() + .get_info(ComponentId::new(self.raid.id)) + .and_then(|info| info.type_id()); + + ("Component/Resource", type_id) + } + ReflectAccessKind::Allocation => { + let type_id = allocator + .and_then(|allocator| allocator.get_type_id(ReflectAllocationId(self.raid.id))); + ("Allocation", type_id) + } + }; + + type_id + .and_then(|type_id| registry.get_type_info(type_id)) + .map(|info| format!("{base_type}<{}>", info.type_path())) + .unwrap_or(format!("{:?}", self.raid)) + } +} + +// pub struct + +#[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()) + .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); + } + + #[test] + #[should_panic] + fn test_double_release_panics() { + let mut world = World::new(); + let world = WorldAccessGuard::new(&mut world); + let access = world.get_component_access(ComponentId::new(0)).unwrap(); + world.release_access(access); + // This won't be possible in client code + world.release_access(WorldAccessWrite { + raid: ReflectAccessId { + kind: ReflectAccessKind::ComponentOrResource, + id: 0, + }, + _ph: PhantomData, + }); + } + + #[test] + fn test_count_updated_correctly() { + let mut world = World::new(); + let guard = WorldAccessGuard::new(&mut world); + let access = guard.get_access(ComponentId::new(0).into()).unwrap(); + assert_eq!(1, guard.accesses_count.load(Ordering::Relaxed)); + guard.release_access(access); + assert_eq!(0, guard.accesses_count.load(Ordering::Relaxed)); + } + + 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 0000000000..2c5367b403 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/commands.rs @@ -0,0 +1,151 @@ +use std::{any::type_name, marker::PhantomData}; + +use bevy::{asset::Handle, ecs::world::Mut, log::debug, prelude::Command}; + +use crate::{ + asset::ScriptAsset, + context::{Context, ContextLoadingSettings, ScriptContexts}, + prelude::{Runtime, RuntimeContainer}, + script::{Script, ScriptId, Scripts}, + systems::handle_script_errors, +}; + +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(); + + world.resource_scope(|world, mut scripts: Mut| { + if let Some(script) = scripts.scripts.remove(&self.id) { + debug!("Deleting script with id: {}", self.id); + let mut ctxts = world.get_non_send_resource_mut::>(); + let ctxts = ctxts.as_deref_mut().unwrap(); + 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, ctxts) + } else { + bevy::log::error!( + "Attempted to delete script with id: {} but it does not exist, doing nothing!", + self.id + ); + } + }); + + world.insert_resource(settings); + } +} + +/// 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) { + 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(); + // assign context + let assigner = settings.assigner.clone().expect("No context assigner set"); + let builder = settings.loader.clone().expect("No context loader 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 { + 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, &format!("Failed to load context for script with id: {}. With runtime type: {} and context type: {}", self.id, type_name::(), type_name::()), [e]); + 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); + } + } + + + // 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, + }, + ); + }); + 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 0000000000..fcd5087cd5 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/context.rs @@ -0,0 +1,152 @@ +use std::{collections::HashMap, sync::atomic::AtomicU32}; + +use bevy::ecs::{entity::Entity, system::Resource, world::World}; + +use crate::{ + prelude::{Runtime, ScriptError}, + script::{Script, ScriptId}, +}; + +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: T) -> 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) + } +} + +/// Initializer run once after creating a context but before executing it for the first time +pub type ContextInitializer = fn(&ScriptId, &mut C) -> Result<(), ScriptError>; +/// Initializer run every time before executing or loading a script +pub type ContextPreHandlingInitializer = + fn(&ScriptId, 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], + &[ContextInitializer], + &[ContextPreHandlingInitializer], + &mut World, + runtime: &mut R, + ) -> Result, + pub reload: fn( + script: &ScriptId, + new_content: &[u8], + context: &mut C, + &[ContextInitializer], + &[ContextPreHandlingInitializer], + &mut World, + &mut 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 8a2a2dfd3d..d186bcfe96 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 3f0dd2be2b..e3a62864b8 100644 --- a/crates/bevy_mod_scripting_core/src/error.rs +++ b/crates/bevy_mod_scripting_core/src/error.rs @@ -1,30 +1,152 @@ +use std::{ + ops::{Deref, DerefMut}, + sync::Arc, +}; + +use bevy::reflect::{ApplyError, Reflect}; 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::ReflectAllocationId, bindings::ReflectReference}; + +pub type ScriptResult = Result; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum ScriptErrorKind { + /// Any other error, default for script errors generated via Into conversions + Other, + /// Errors specifically to do with reflecting & reading/writing stuff from the world + ReflectionError, + /// Erorrs to do with invalid script API usage, invalid arguments etc. + RuntimeError, + /// Errors to do with the script lifecycle, loading, unloading etc. + Lifecycle, +} + +impl std::fmt::Display for ScriptErrorKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ScriptErrorKind::ReflectionError => f.write_str("Reflection Error"), + ScriptErrorKind::Lifecycle => f.write_str("Script Lifecycle Error"), + ScriptErrorKind::Other => f.write_str("Error"), + ScriptErrorKind::RuntimeError => f.write_str("Runtime Error"), + }; + Ok(()) + } +} + +#[derive(Error, Debug)] +pub struct ScriptErrorWrapper(ScriptError); + +impl std::fmt::Display for ScriptErrorWrapper { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +impl From for Box { + fn from(val: ScriptError) -> Self { + ScriptErrorWrapper(val).into() + } +} +/// An error with an optional script Context +#[derive(Debug, Clone)] +pub struct ScriptError(pub Arc); + +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 kind: ScriptErrorKind, + pub context: String, + pub reason: Arc, } impl ScriptError { - /// Create new `ScriptError::Other` from another error - pub fn new_other(other: T) -> Self { - Self::Other(other.to_string()) + pub fn new_reflection_error>>( + reason: E, + ) -> Self { + Self(Arc::new(ScriptErrorInner { + script: None, + kind: ScriptErrorKind::ReflectionError, + reason: Arc::from(reason.into()), + context: Default::default(), + })) + } + + pub fn new_generic_error>>(reason: E) -> Self { + Self(Arc::new(ScriptErrorInner { + script: None, + kind: ScriptErrorKind::Other, + reason: Arc::from(reason.into()), + context: Default::default(), + })) + } + + pub fn new_lifecycle_error>>( + reason: E, + ) -> Self { + Self(Arc::new(ScriptErrorInner { + script: None, + kind: ScriptErrorKind::Lifecycle, + reason: Arc::from(reason.into()), + context: Default::default(), + })) + } + + pub fn new_runtime_error>>(reason: E) -> Self { + Self(Arc::new(ScriptErrorInner { + script: None, + kind: ScriptErrorKind::RuntimeError, + reason: Arc::from(reason.into()), + context: Default::default(), + })) + } + + pub fn with_context(self, context: S) -> Self { + Self(Arc::new(ScriptErrorInner { + script: self.0.script.clone(), + kind: self.0.kind, + context: context.to_string(), + reason: self.0.reason.clone(), + })) + } +} + +impl From for ScriptError { + fn from(value: T) -> Self { + Self::new_generic_error(value) + } +} + +impl std::fmt::Display for ScriptError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(script) = &self.0.script { + write!( + f, + "Encountered {} error in script `{}`: {}", + self.0.kind, script, self.0.reason + ) + } else { + write!( + f, + "Encountered {} error in a script: {}", + self.0.kind, self.0.reason + ) + } + } +} + +#[cfg(feature = "mlua_impls")] +impl From for mlua::Error { + fn from(value: ScriptError) -> Self { + mlua::Error::external(value) } } diff --git a/crates/bevy_mod_scripting_core/src/event.rs b/crates/bevy_mod_scripting_core/src/event.rs index 7ba3470709..2921d19c58 100644 --- a/crates/bevy_mod_scripting_core/src/event.rs +++ b/crates/bevy_mod_scripting_core/src/event.rs @@ -1,6 +1,6 @@ -use bevy::prelude::Event; +use bevy::{ecs::entity::Entity, prelude::Event}; -use crate::{error::ScriptError, hosts::Recipients}; +use crate::{error::ScriptError, handler::Args, script::ScriptId}; /// An error coming from a script #[derive(Debug, Event)] @@ -8,15 +8,235 @@ 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) + } + } +} + +pub trait IntoCallbackLabel { + fn into_callback_label() -> CallbackLabel; +} + +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()) + } +} + +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()) + } } -/// 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; +/// 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: A, +} + +impl ScriptCallbackEvent { + pub fn new>(label: L, args: A, recipients: Recipients) -> Self { + Self { + label: label.into(), + args, + recipients, + } + } + + pub fn new_for_all>(label: L, args: A) -> 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 0000000000..63bc1e0819 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/handler.rs @@ -0,0 +1,37 @@ +use bevy::ecs::{entity::Entity, system::Resource, world::World}; + +use crate::{ + context::{Context, ContextPreHandlingInitializer}, + event::CallbackLabel, + prelude::ScriptError, + runtime::Runtime, + script::ScriptId, +}; + +pub trait Args: Clone + Send + Sync + 'static {} +impl Args for T {} + +pub type HandlerFn = fn( + args: A, + 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 1225782a42..0000000000 --- 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 2022dad31b..67a1ce74d0 100644 --- a/crates/bevy_mod_scripting_core/src/lib.rs +++ b/crates/bevy_mod_scripting_core/src/lib.rs @@ -1,211 +1,226 @@ -use crate::{ - event::ScriptErrorEvent, - hosts::{APIProvider, APIProviders, ScriptHost}, +#![allow(clippy::arc_with_non_send_sync)] + +use crate::event::ScriptErrorEvent; +use asset::{ScriptAsset, ScriptAssetLoader, ScriptAssetSettings}; +use bevy::prelude::*; +use bindings::ReflectAllocator; +use context::{ + Context, ContextAssigner, ContextBuilder, ContextInitializer, ContextLoadingSettings, + ContextPreHandlingInitializer, ScriptContexts, }; -use bevy::{ecs::schedule::ScheduleLabel, prelude::*}; -use event::ScriptLoaded; -use systems::script_event_handler; +use handler::{Args, CallbackSettings, HandlerFn}; +use prelude::{ + initialize_runtime, + runtime::{RuntimeInitializer, RuntimeSettings}, + sync_script_data, Documentation, DocumentationFragment, ScriptCallbackEvent, +}; +use runtime::{Runtime, RuntimeContainer}; +use script::Scripts; +use systems::garbage_collector; 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 {crate::docs::*, crate::error::*, crate::event::*, crate::systems::*, crate::*}; +} + +/// Bevy plugin enabling scripting within the bevy mod scripting framework +pub struct ScriptingPlugin { + /// Callback for initiating the runtime + pub runtime_builder: fn() -> 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>, } -pub use bevy_event_priority as events; -#[derive(Default)] -/// Bevy plugin enabling run-time scripting -pub struct ScriptingPlugin; +impl Default for ScriptingPlugin { + fn default() -> Self { + Self { + runtime_builder: R::default, + runtime_settings: Default::default(), + callback_handler: Default::default(), + context_builder: Default::default(), + context_assigner: Default::default(), + } + } +} -impl Plugin for ScriptingPlugin { +impl Plugin for ScriptingPlugin { fn build(&self, app: &mut bevy::prelude::App) { - app.add_event::(); + app.add_event::() + .add_event::>() + .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()) + .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::); } } -pub trait GenDocumentation { - fn update_documentation(&mut self) -> &mut Self; +pub trait AddRuntimeInitializer { + fn add_runtime_initializer(&mut self, initializer: RuntimeInitializer) -> &mut Self; } -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 AddRuntimeInitializer for App { + fn add_runtime_initializer(&mut self, 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 } } -/// 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( +pub trait AddContextInitializer { + fn add_context_initializer( &mut self, - schedule: impl ScheduleLabel, - set: impl SystemSet, + initializer: ContextInitializer, ) -> &mut Self; } -impl AddScriptHost for App { - fn add_script_host_to_set( +impl AddContextInitializer for App { + fn add_context_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: ContextInitializer, + ) -> &mut Self { + self.world_mut() + .init_resource::>(); + self.world_mut() + .resource_mut::>() + .as_mut() + .context_initializers + .push(initializer); self } } -pub trait AddScriptApiProvider { - fn add_api_provider( +pub trait AddContextPreHandlingInitializer { + fn add_context_pre_handling_initializer( &mut self, - provider: Box< - dyn APIProvider< - APITarget = T::APITarget, - DocTarget = T::DocTarget, - ScriptContext = T::ScriptContext, - >, - >, + initializer: ContextPreHandlingInitializer, ) -> &mut Self; } -impl AddScriptApiProvider for App { - fn add_api_provider( +impl AddContextPreHandlingInitializer for App { + fn add_context_pre_handling_initializer( &mut self, - provider: Box< - dyn APIProvider< - APITarget = T::APITarget, - DocTarget = T::DocTarget, - ScriptContext = T::ScriptContext, - >, - >, + initializer: ContextPreHandlingInitializer, ) -> &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() + .resource_mut::>() + .as_mut() + .context_pre_handling_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( - &mut self, - schedule: impl ScheduleLabel, - set: impl SystemSet, - ) -> &mut Self; +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 AddScriptHostHandler for App { - fn add_script_handler_to_set( - &mut self, - schedule: impl ScheduleLabel, - set: impl SystemSet, - ) -> &mut Self { - self.add_systems(schedule, script_event_handler::.in_set(set)); +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 add_script_handler( - &mut self, - schedule: impl ScheduleLabel, - ) -> &mut Self { - self.add_systems(schedule, script_event_handler::); - 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 super::*; + + #[test] + fn test_default_scripting_plugin_initializes_all_resources_correctly() { + let mut app = App::new(); + #[derive(Default, Clone)] + struct A; + #[derive(Default, Clone)] + struct C; + #[derive(Default, Clone)] + struct 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::>()); } } 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 0000000000..ad2ec4dd1f --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/reflection_extensions.rs @@ -0,0 +1,366 @@ +use std::{any::TypeId, cmp::max}; + +use bevy::reflect::{List, PartialReflect}; +use itertools::Itertools; + +use crate::error::ScriptError; + +/// Extension trait for [`PartialReflect`] providing additional functionality for working with specific types. +pub trait PartialReflectExt { + /// 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<(), ScriptError>; + + /// 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, ScriptError>; + + /// Similar to [`PartialReflectExt::as_option`] but for mutable references. + fn as_option_mut(&mut self) -> Result, ScriptError>; + + /// If the type is an iterable list-like type, returns an iterator over the elements. + fn as_list(&self) -> Result, ScriptError>; + + /// 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<(), ScriptError>, + >( + &mut self, + other: Box, + apply: F, + ) -> Result<(), ScriptError>; + + + /// Inserts into the type at the given key, if the type supports inserting with the given key + fn insert_at(&mut self, index: usize, value: Box) -> Result<(), ScriptError>; +} +pub trait TypeIdExtensions { + fn type_id_or_dummy(&self) -> TypeId; +} + +impl TypeIdExtensions for Option { + fn type_id_or_dummy(&self) -> TypeId { + struct UknownType; + 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<(), ScriptError> { + if !self.is_type(crate_name, type_ident) { + return Err(ScriptError::new_runtime_error(format!( + "Expected type {type_ident}{}, but got {}", + crate_name + .map(|s| format!(" from crate {s}")) + .unwrap_or_default(), + self.get_represented_type_info() + .map(|ti| ti.type_path()) + .unwrap_or_else(|| "dynamic type with no type information") + ))); + } + Ok(()) + } + + fn as_option(&self) -> Result, ScriptError> { + 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(ScriptError::new_runtime_error(format!( + "Expected enum type, but got type which is not an enum: {}", + self.get_represented_type_info() + .map(|ti| ti.type_path()) + .unwrap_or_else(|| "dynamic type with no type information") + ))) + } + + fn as_option_mut(&mut self) -> Result, ScriptError> { + 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(ScriptError::new_runtime_error(format!( + "Expected enum type, but got type which is not an enum: {}", + type_info.unwrap_or("dynamic type with no type information") + ))), + } + } + + fn as_list(&self) -> Result, ScriptError> { + if let bevy::reflect::ReflectRef::List(l) = self.reflect_ref() { + Ok(l.iter()) + } else { + Err(ScriptError::new_runtime_error(format!( + "Expected list-like type from crate core, but got {}", + self.get_represented_type_info() + .map(|ti| ti.type_path()) + .unwrap_or_else(|| "dynamic type with no type information") + ))) + } + } + + fn set_as_list< + F: Fn(&mut dyn PartialReflect, &dyn PartialReflect) -> Result<(), ScriptError>, + >( + &mut self, + mut other: Box, + apply: F, + ) -> Result<(), ScriptError> { + match (self.reflect_mut(), other.reflect_mut()) { + (bevy::reflect::ReflectMut::List(l), bevy::reflect::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(()) + } + _ => Err(ScriptError::new_reflection_error(format!( + "Could not set {} with {}. Both need to reflect as list types, but at least one does not.", + self.reflect_type_path(), + other.reflect_type_path() + ))), + } + } + + fn insert_at(&mut self, index: usize, value: Box) -> Result<(), ScriptError> { + match self.reflect_mut() { + bevy::reflect::ReflectMut::List(l) => { + l.insert(index, value); + Ok(()) + }, + bevy::reflect::ReflectMut::Map(m) => { + m.insert_boxed(Box::new(index), value); + Ok(()) + }, + bevy::reflect::ReflectMut::Set(s) => { + s.insert_boxed(value); + Ok(()) + }, + _ => Err(ScriptError::new_reflection_error(format!( + "Could not insert into {}. The type does not support insertion at a key.", + self.reflect_type_path() + ))), + } + } + +} + + + + +#[cfg(test)] +mod test { + use super::*; + + #[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")); + assert_eq!( + "Encountered Runtime Error error in a script: Expected type Option from crate std, but got core::option::Option", + Some(42) + .expect_type(Some("std"), "Option") + .unwrap_err() + .to_string() + ); + } + + #[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_option_error() { + assert_eq!( + "Encountered Runtime Error error in a script: Expected type Option from crate core, but got i32", + 42.as_option().unwrap_err().to_string() + ); + } + + #[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_insert_at_vec() { + let mut list = vec![1, 2, 3]; + let value = 4; + let value_ref: Box = Box::new(value); + list.insert_at(&1, value_ref).unwrap(); + assert_eq!(vec![1, 4, 2, 3], list); + } + + #[test] + fn test_insert_at_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.insert_at(&1, value_ref).unwrap(); + assert_eq!(4, map[&1]); + } + + #[test] + fn test_insert_at_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.insert_at(&1, value_ref).unwrap(); + assert!(set.contains(&4)); + } +} 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 0000000000..6b9fe7fb67 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/runtime.rs @@ -0,0 +1,36 @@ +//! "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 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: 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 0000000000..9817eb8bd1 --- /dev/null +++ b/crates/bevy_mod_scripting_core/src/script.rs @@ -0,0 +1,42 @@ +//! Everything to do with the way scripts and their contexts are stored and handled. + +use std::{borrow::Cow, collections::HashMap, ops::Deref}; + +use bevy::{asset::Handle, ecs::system::Resource, reflect::Reflect}; + +use crate::{asset::ScriptAsset, context::ContextId}; + +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 d7512a4174..b5c6fafefc 100644 --- a/crates/bevy_mod_scripting_core/src/systems.rs +++ b/crates/bevy_mod_scripting_core/src/systems.rs @@ -1,233 +1,449 @@ -use std::collections::HashSet; - use bevy::{ecs::system::SystemState, prelude::*}; -use bevy_event_priority::PriorityEventReader; +use std::any::type_name; use crate::{ - event::ScriptLoaded, - prelude::{APIProviders, Script, ScriptCollection, ScriptContexts, ScriptData, ScriptHost}, - ScriptErrorEvent, + asset::{ScriptAsset, ScriptAssetSettings}, + bindings::ReflectAllocator, + commands::{CreateOrUpdateScript, DeleteScript}, + context::{Context, ContextLoadingSettings, ScriptContexts}, + error::{ScriptError, ScriptResult}, + event::{IntoCallbackLabel, ScriptCallbackEvent, ScriptErrorEvent}, + handler::{Args, CallbackSettings}, + prelude::RuntimeSettings, + runtime::{Runtime, RuntimeContainer}, + script::{ScriptComponent, Scripts}, }; -/// 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(mut allocator: ResMut) { + 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 commands: Commands, +) { + for event in events.read() { + debug!("Responding to 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 } | AssetEvent::Unused { id } => (id, true), + _ => continue, + }; + // get the path + let asset = script_assets.get(*id); + let asset = match asset.as_ref() { + Some(a) => a, + None => { + if remove { + debug!( + "Script presumably failed to load, no need to remove anything, ignoring." + ); + continue; + } else { + panic!("Asset was expected to be loaded!"); + } + } + }; - let removed_scripts = context_ids.difference(&script_ids); - let added_scripts = script_ids.difference(&context_ids); + let path = &asset.asset_path; + // convert it to script id + let converter = asset_settings.script_id_mapper.map; + let script_id = converter(path); - for r in removed_scripts { - contexts.remove_context(*r); - } + if !remove { + commands.queue(CreateOrUpdateScript::::new( + script_id, + asset.content.clone(), + Some(script_assets.reserve_handle()), + )); + } else { + commands.queue(DeleteScript::::new(script_id)); + } + } +} - 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, - ) +macro_rules! push_err_and_continue { + ($errors:ident, $expr:expr) => { + match $expr { + Ok(v) => v, + Err(e) => { + $errors.push(e); + continue; } } - }) + }; } -/// Handles the removal of script components and their contexts -pub fn script_remove_synchronizer( - mut query: RemovedComponents>, - mut contexts: ResMut>, +/// 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 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); + debug!("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::())); + + 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: {}, Args: {}", + type_name::(), + 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 => { + info!( + "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, + ); + + 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, + &format!( + "Encountered error in event handling for: Runtime {}, Context: {}, Args: {}", + type_name::(), + type_name::(), + type_name::() + ), + errors, + ); } -/// 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, +/// Handles errors caused by script execution and sends them to the error event channel +pub(crate) fn handle_script_errors>( + world: &mut World, + context: &str, + errors: I, ) { - for e in events.read() { - let (handle, created) = match e { - AssetEvent::Modified { id } => (id, false), - AssetEvent::Added { id } => (id, true), - _ => continue, - }; + let mut error_events = world + .get_resource_mut::>() + .expect("Missing events resource"); - // 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, - ); - } - } - } + for error in errors { + bevy::log::error!("{}. {}", context, error.to_string()); + error_events.send(ScriptErrorEvent { error }); } } -/// 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(); +#[cfg(test)] +mod test { + use std::{borrow::Cow, collections::HashMap}; - let events = state - .event_state - .get_mut(world) - .0 - .iter_prio_range(MAX, MIN) - .collect::>(); + use crate::{ + event::CallbackLabel, + handler::HandlerFn, + script::{Script, ScriptId}, + }; - world.insert_resource(state); + use super::*; + struct OnTestCallback; - // should help a lot with performance on frames where no events are fired - if events.is_empty() { - return; + 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, - }; - - Some(( - ScriptData { - sid: *sid, - entity: *entity, - name, - }, - ctx, - )) + struct TestRuntime { + pub invocations: Vec<(Entity, ScriptId)>, + } + + struct TestContext { + pub invocations: Vec, + } + + fn setup_app( + handler_fn: HandlerFn, + runtime: 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 + } - // 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); + #[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.push(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(); - world.insert_resource(ctxts); - world.insert_resource(host); - world.insert_resource(providers); -} + app.world_mut() + .send_event(ScriptCallbackEvent::::new_for_all( + OnTestCallback::into_callback_label(), + "test_args".to_owned(), + )); + app.update(); -#[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>, - )>, -} + let test_context = app + .world() + .get_non_send_resource::>() + .unwrap(); + let test_runtime = app + .world() + .get_non_send_resource::>() + .unwrap(); -impl FromWorld for CachedScriptState { - fn from_world(world: &mut World) -> Self { - Self { - event_state: SystemState::new(world), - } + assert_eq!( + test_context + .contexts + .get(&test_ctxt_id) + .unwrap() + .invocations, + vec!["test_args"] + ); + + 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.push(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(), + "test_args_script".to_owned(), + crate::event::Recipients::Script(test_script_id.clone()), + )); + + app.world_mut() + .send_event(ScriptCallbackEvent::::new( + OnTestCallback::into_callback_label(), + "test_args_entity".to_owned(), + 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!["test_args_script", "test_args_entity"] + ); + + 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_derive/Cargo.toml b/crates/bevy_mod_scripting_derive/Cargo.toml new file mode 100644 index 0000000000..56257fb9ee --- /dev/null +++ b/crates/bevy_mod_scripting_derive/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "bevy_mod_scripting_derive" +version = "0.6.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" + +[lib] +name = "bevy_mod_scripting_derive" +path = "src/lib.rs" +proc-macro = true + +[dependencies] +paste = "1.0.7" +darling = "0.20.3" +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" +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/bevy_mod_scripting_derive/readme.md b/crates/bevy_mod_scripting_derive/readme.md new file mode 100644 index 0000000000..e058ed4f00 --- /dev/null +++ b/crates/bevy_mod_scripting_derive/readme.md @@ -0,0 +1,3 @@ +# 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/bevy_mod_scripting_derive/src/input.rs b/crates/bevy_mod_scripting_derive/src/input.rs new file mode 100644 index 0000000000..4fc68695f6 --- /dev/null +++ b/crates/bevy_mod_scripting_derive/src/input.rs @@ -0,0 +1,115 @@ +use darling::{util::Flag, FromDeriveInput, FromMeta}; +use proc_macro2::Ident; +use std::ops::{Deref, DerefMut}; +use syn::{spanned::Spanned, visit_mut::VisitMut, Attribute, Field, TraitItemFn, Variant}; + +#[derive(FromMeta)] +pub struct BMSCorePath(pub syn::Path); + +impl Default for BMSCorePath { + fn default() -> Self { + Self(syn::parse_quote!(bevy_mod_scripting::core)) + } +} + +#[derive(FromMeta)] +pub struct BMSLuaPath(pub syn::Path); + +impl Default for BMSLuaPath { + fn default() -> Self { + Self(syn::parse_quote!(bevy_mod_scripting::lua)) + } +} + +#[derive(FromDeriveInput)] +#[darling(attributes(proxy), forward_attrs(allow, doc, cfg))] +pub struct ProxyInput { + /// The name of the type for which we are generating a proxy (target type) + pub ident: syn::Ident, + /// The visibility of the target type + pub vis: syn::Visibility, + /// The generics on the target type + pub generics: syn::Generics, + /// The attributes on the target type + pub attrs: Vec, + + /// The path to the type for which we are generating a proxy if it's a foreign type + pub remote: Option, + + /// if provided will call the function at this path to get the world callback access. Normally this is retrieved using a global variable. + pub get_world_callback_access_fn: Option, + + /// If set will use the given path as the type for the proxy instead of generating a new one + /// Only used for the special world proxies, probably not useful for anything else, the macro assumes we have an inner ReflectReference in the wrapper + pub proxy_as_type: Option, + + /// The path to the bevy_mod_scripting_core crate + #[darling(default)] + pub bms_core_path: BMSCorePath, + /// The path to the bevy_mod_scripting_lua crate + #[darling(default)] + pub bms_lua_path: BMSLuaPath, + + /// 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, + + /// 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()); + } + } +} diff --git a/crates/bevy_mod_scripting_derive/src/lib.rs b/crates/bevy_mod_scripting_derive/src/lib.rs new file mode 100644 index 0000000000..62ef0e9e12 --- /dev/null +++ b/crates/bevy_mod_scripting_derive/src/lib.rs @@ -0,0 +1,548 @@ +mod input; +mod utils; + +use crate::{input::*, utils::doc_attribute_to_string_lit}; + +use darling::util::Flag; +use std::collections::HashMap; +use syn::{ + parse_macro_input, parse_quote, parse_quote_spanned, punctuated::Punctuated, spanned::Spanned, + DeriveInput, ExprClosure, FnArg, Path, Token, TraitItemFn, +}; + +use darling::{FromAttributes, FromDeriveInput}; +use proc_macro::TokenStream; +use proc_macro2::*; +use quote::*; + +const SELF_ALIAS: &str = "_self"; +const CTXT_ALIAS: &str = "lua"; +const PROXY_PREFIX: &str = "Lua"; + +/// Convert receiver to a standardised form, for example: +/// - instead o a `&self` receiver we have a `_self: LuaRefProxy` +/// - instead of a `&mut self` receiver we have a `_self: LuaRefMutProxy` +/// - instead of a `self` receiver we have a `_self: ValLuaProxy` +/// Returns true if the receiver was changed +fn standardise_receiver( + receiver: &mut FnArg, + target_type: &Path, + bms_lua_path: &Path, + proxy_as_type: Option<&Path>, +) -> bool { + let replacement = if let FnArg::Receiver(receiver) = receiver { + let ref_ = &receiver.reference.as_ref().map(|(amp, lifetime)| { + quote_spanned! {receiver.span()=> + #amp #lifetime + } + }); + + let self_ident = syn::Ident::new(SELF_ALIAS, receiver.span()); + let self_ident_type = match proxy_as_type { + Some(target_type) => { + quote_spanned! {receiver.span()=> + #target_type + } + } + None => { + let unproxy_container_name = match (ref_.is_some(), receiver.mutability.is_some()) { + (true, true) => "LuaReflectRefMutProxy", + (true, false) => "LuaReflectRefProxy", + (false, _) => "LuaReflectValProxy", + }; + let unproxy_ident = syn::Ident::new(unproxy_container_name, receiver.span()); + + quote_spanned! {receiver.span()=> + #bms_lua_path::bindings::proxy::#unproxy_ident::<#target_type> + } + } + }; + + Some(syn::FnArg::Typed(parse_quote_spanned! {receiver.span()=> + #self_ident: #self_ident_type + })) + } else { + None + }; + if let Some(replacement) = replacement { + *receiver = replacement; + true + } else { + false + } +} + +/// Collect all arguments into a tuple, for example: +/// - `fn foo(a: i32, b: f32)` becomes `(name: (i32, f32))` +fn collect_args_in_tuple<'a, I: Iterator>( + args: I, + name: &Ident, + outer_mut: bool, +) -> FnArg { + let (_, arg_types) = args + .map(|arg| { + if let FnArg::Typed(arg) = arg { + (arg.pat.clone(), arg.ty.clone()) + } else { + panic!("Function arguments must be typed") + } + }) + .unzip::<_, _, Vec<_>, Vec<_>>(); + + let outer_mut = if outer_mut { + Some(Token![mut](name.span())) + } else { + None + }; + + parse_quote!( #outer_mut #name : (#(#arg_types),*) ) +} + +/// Convert a function definition to a closure, for example: +/// - `fn foo(a: i32, b: f32) -> f32 { a + b }` becomes `|a: i32, b: f32| { a + b} ` +fn convert_function_def_to_closure(f: &TraitItemFn) -> ExprClosure { + let span = f.span(); + let sig = &f.sig.inputs; + let body = f + .default + .as_ref() + .unwrap_or_else(|| panic!("Function {} must have a body", f.sig.ident)); + parse_quote_spanned! {span => + |#sig| #body + } +} + +/// Processes the function def to wrap it in the necessary proxying logic +/// Will convert the function signature to take in two arguments: +/// - a context argument +/// - a tuple of all arguments passed to the underlying function +fn proxy_wrap_function_def( + f: &mut TraitItemFn, + target_type: &Path, + bms_core: &Path, + bms_lua: &Path, + get_world_callback_access_fn: Option<&Path>, + proxy_as_type: Option<&Path>, + mlua: &Path, + attrs: &FunctionAttrs, +) { + // collect all args into tuple and add lua context arg + let ctxt_alias = syn::Ident::new(CTXT_ALIAS, f.sig.inputs.span()); + + let ctxt_arg = if attrs.with_context.is_present() { + f.sig + .inputs + .pop() + .expect("Expected at least one argument for the context") + .into_value() + } else { + parse_quote_spanned! {f.span()=> + #ctxt_alias: &#mlua::Lua + } + }; + + let ctxt_arg_ident = match &ctxt_arg { + FnArg::Typed(arg) => arg.pat.clone(), + _ => panic!("Expected a typed argument, not a receiver for the context argument"), + }; + + let mut has_receiver = false; + if let Some(first_arg) = f.sig.inputs.first_mut() { + has_receiver = standardise_receiver(first_arg, target_type, bms_lua, proxy_as_type); + }; + + let func_name = &f.sig.ident; + let (mut original_arg_idents, _) = f + .sig + .inputs + .iter() + .map(|arg| { + if let FnArg::Typed(arg) = arg { + (arg.pat.clone(), arg.ty.clone()) + } else { + panic!("Function arguments must be typed") + } + }) + .unzip::<_, _, Vec<_>, Vec<_>>(); + + let span = f.span(); + let args_ident = format_ident!("args", span = f.sig.inputs.span()); + let args_tail_ident = format_ident!("args_tail", span = f.sig.inputs.span()); + let args_head_ident = format_ident!("args_head", span = f.sig.inputs.span()); + let args_split = if get_world_callback_access_fn.is_some() { + let tail = (1..original_arg_idents.len()).map(|i| { + let i = syn::Index::from(i); + quote_spanned!(span=> #args_ident.#i) + }); + quote_spanned!(span=> + let #args_head_ident = #args_ident.0; + let #args_tail_ident = (#(#tail),*); + ) + } else { + Default::default() + }; + + // change signature to take in a single args tuple instead of multiple arguments (on top of a context arg) + f.sig.inputs = Punctuated::from_iter(vec![ + ctxt_arg, + collect_args_in_tuple(f.sig.inputs.iter(), &args_ident, true), + ]); + + let args_var_to_use = if get_world_callback_access_fn.is_some() { + original_arg_idents.remove(0); + args_tail_ident + } else { + args_ident + }; + + let out_type = match &f.sig.output { + syn::ReturnType::Default => quote_spanned! {f.span()=> + () + }, + syn::ReturnType::Type(_, ty) => ty.to_token_stream(), + }; + + // wrap function body in our unwrapping and wrapping logic, ignore pre-existing body + let mut fn_call = std::panic::catch_unwind(|| { + match ( + &f.default, + &attrs.as_trait, + get_world_callback_access_fn.is_some(), + ) { + (_, _, true) => quote_spanned!(span=> + world.#func_name(#(#original_arg_idents),*) + ), + (Some(body), _, _) => quote_spanned!(span=> + (||{ #body })() + ), + (_, None, _) => quote_spanned!(span=> + #target_type::#func_name(#(#original_arg_idents),*) + ), + (_, Some(trait_path), _) => { + let trait_path = quote_spanned!(span=> #trait_path); + quote_spanned!(span=> + <#target_type as #trait_path>::#func_name(#(#original_arg_idents),*) + ) + } + } + }) + .unwrap(); // todo: handle the error nicer + + if f.sig.unsafety.is_some() { + fn_call = quote_spanned!(span=> + unsafe { #fn_call } + ); + } + + if attrs.no_proxy.is_present() { + f.default = Some(parse_quote_spanned! {span=> + { + #fn_call + } + }); + } else { + let world = if let Some(world_getter_fn_path) = get_world_callback_access_fn { + quote_spanned!(span=> + let mut world: #bms_core::bindings::WorldCallbackAccess = #world_getter_fn_path(#args_head_ident); + let mut world = world.read().ok_or_else(|| #mlua::Error::external("World no longer exists"))?; + ) + } else { + quote_spanned!(span=> + let mut world: #bms_lua::bindings::proxy::LuaValProxy<#bms_core::bindings::WorldCallbackAccess> = #ctxt_arg_ident.globals().get("world")?; + let mut world = <#bms_lua::bindings::proxy::LuaValProxy<#bms_core::bindings::WorldCallbackAccess> as #bms_core::bindings::Unproxy>::unproxy(&mut world).map_err(#mlua::Error::external)?; + let mut world = world.read().ok_or_else(|| #mlua::Error::external("World no longer exists"))?; + ) + }; + + f.default = Some(parse_quote_spanned! {span=> + { + #args_split + #world + let out: #out_type = world.proxy_call(#args_var_to_use, |(#(#original_arg_idents),*)| { + #fn_call + }).map_err(|e| #mlua::Error::external(e))?; + Ok(out) + } + }); + } +} + +fn generate_methods_registration( + attrs: &FunctionAttrs, + span: Span, + name: proc_macro2::TokenStream, + closure: ExprClosure, +) -> proc_macro2::TokenStream { + let registration_method = if attrs.metamethod.is_some() { + quote_spanned!(span=>add_meta_function) + } else { + quote_spanned!(span=>add_function) + }; + let docs = attrs.doc.iter().map(|doc| { + quote_spanned! {span=> + methods.document(#doc); + } + }); + quote_spanned! {span=> + #(#docs)* + methods.#registration_method(#name, #closure); + } +} + +#[derive(FromAttributes, Clone)] +#[darling(attributes(lua))] +struct FunctionAttrs { + #[darling(multiple)] + pub doc: Vec, + + /// 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, + + /// Marks this to be ignored, only used for fields as functions are opt-in + pub skip: Flag, + + /// If passed will generate statement before calling the method + /// on the type + pub as_trait: Option, + + /// If passed will generate a metamethod call instead of using the function name + pub metamethod: Option, + + /// If true will pass in the context as the last argument, + /// i.e. will remove that argument from the function signature and use it's name as the context alias + pub with_context: Flag, + + /// Skips the unproxying & proxying call, useful for functions that don't need to access the world + pub no_proxy: Flag, +} + +#[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 mut 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 target_type = meta.remote.unwrap_or(meta.ident.clone().into()); + let target_type_str = target_type.segments.last().unwrap().ident.to_string(); + let proxy_type_ident = match meta.proxy_as_type.as_ref() { + Some(proxy_as_type) => proxy_as_type.clone(), + None => meta + .proxy_name + .unwrap_or_else(|| { + format_ident!( + "{PROXY_PREFIX}{}", + &target_type_str, + span = meta.ident.span() + ) + }) + .into(), + }; + + let bms_core = meta.bms_core_path.0; + let bms_lua = meta.bms_lua_path.0; + let tealr: Path = parse_quote_spanned!(bms_lua.span()=> + #bms_lua::tealr + ); + let mlua: Path = parse_quote_spanned!(bms_core.span()=> + #tealr::mlu::mlua + ); + + // 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!(meta.ident.span()=> + methods.document_type(#tkns); + ) + }); + + // extract composites first + let mut composites: HashMap> = HashMap::new(); + meta.functions.0.retain(|f| { + let attrs = FunctionAttrs::from_attributes(&f.attrs).unwrap(); + if let Some(composite_id) = &attrs.composite { + composites + .entry(composite_id.to_owned()) + .or_default() + .push((f.clone(), attrs)); + false + } else { + true + } + }); + + let add_composite_function_stmts = composites.into_values().map(|functions| { + let (first_function, first_function_attrs) = functions + .first() + .cloned() + .expect("At least one function must be a composite for this code to be reached"); + + let name = match &first_function_attrs.metamethod { + Some(metamethod) => quote_spanned!(metamethod.span()=> + #mlua::MetaMethod::#metamethod + ), + None => first_function.sig.ident.to_string().to_token_stream(), + }; + + let value_arg_types = (0..first_function.sig.inputs.len()) + .map(|_| { + quote_spanned!(first_function.span()=> + #mlua::Value + ) + }) + .collect::>(); + + let value_arg_names = (0..first_function.sig.inputs.len()).map(|i| { + format_ident!("arg{}", i, span = first_function.span()) + }).collect::>(); + + let closures = functions + .into_iter() + .map(|(mut f, attrs)| { + proxy_wrap_function_def(&mut f, &target_type, &bms_core, &bms_lua, meta.get_world_callback_access_fn.as_ref() ,meta.proxy_as_type.as_ref(), &mlua, &attrs); + convert_function_def_to_closure(&f) + }) + .collect::>(); + + let closure_args_types = closures.iter().map(|closure| { + let last = closure.inputs.last().unwrap(); + if let syn::Pat::Type(pat_type) = last { + &pat_type.ty + } else { + panic!("Closure must have a single argument tuple as its last argument") + } + }); + + let closure = parse_quote_spanned! {first_function.span()=> + |ctxt, (#(#value_arg_names,)*): (#(#value_arg_types,)*)| { + let args = #mlua::MultiValue::from_vec(vec![#(#value_arg_names,)*]); + #( + if let Ok(args) = <#closure_args_types as #mlua::FromLuaMulti>::from_lua_multi(args.clone(), ctxt) { + let out : Result<_, #mlua::Error> = (#closures)(ctxt, args); + return out?.into_lua(ctxt) + } + )* + Err(#mlua::Error::external("Invalid arguments for composite function")) + } + }; + + generate_methods_registration(&first_function_attrs, first_function.span(), name, closure) + }); + + let add_function_stmts = meta.functions.0.into_iter().filter_map(|mut f| { + let attrs = FunctionAttrs::from_attributes(&f.attrs).unwrap(); + + if attrs.skip.is_present() { + return None; + } + + proxy_wrap_function_def( + &mut f, + &target_type, + &bms_core, + &bms_lua, + meta.get_world_callback_access_fn.as_ref(), + meta.proxy_as_type.as_ref(), + &mlua, + &attrs, + ); + + let name = match &attrs.metamethod { + Some(metamethod) => quote_spanned!(metamethod.span()=> + #mlua::MetaMethod::#metamethod + ), + None => f.sig.ident.to_string().to_token_stream(), + }; + let span = f.span(); + + let closure = convert_function_def_to_closure(&f); + + Some(generate_methods_registration(&attrs, span, name, closure)) + }); + + let vis = &meta.vis; + + let definition = if let Some(proxy_as_type) = meta.proxy_as_type.as_ref() { + Default::default() + } else { + quote_spanned!(derive_input.span()=> + #[derive(Clone, Debug, #tealr::mlu::UserData, #tealr::ToTypename)] + #vis struct #proxy_type_ident (pub #bms_core::bindings::ReflectReference); + ) + }; + + let conversions = if let Some(proxy_as_type) = meta.proxy_as_type.as_ref() { + Default::default() + } else { + quote_spanned!(derive_input.span()=> + impl AsRef<#bms_core::bindings::ReflectReference> for #proxy_type_ident { + fn as_ref(&self) -> &#bms_core::bindings::ReflectReference { + &self.0 + } + } + + impl From<#bms_core::bindings::ReflectReference> for #proxy_type_ident { + fn from(r: #bms_core::bindings::ReflectReference) -> Self { + Self(r) + } + } + ) + }; + + quote_spanned! {meta.ident.span()=> + + #definition + + impl #bms_lua::bindings::proxy::LuaProxied for #target_type { + type Proxy = #proxy_type_ident; + } + + impl #tealr::mlu::TealData for #proxy_type_ident { + fn add_methods<'lua, M: #tealr::mlu::TealDataMethods<'lua, Self>>(methods: &mut M) { + #(#type_level_document_calls)* + #(#add_composite_function_stmts)* + #(#add_function_stmts)* + } + } + + + impl<'lua> #tealr::mlu::mlua::FromLua<'lua> for #proxy_type_ident { + fn from_lua( + value: #tealr::mlu::mlua::Value<'lua>, + _lua: &#tealr::mlu::mlua::Lua, + ) -> Result { + match value { + tealr::mlu::mlua::Value::UserData(ud) => Ok(ud.borrow::()?.clone()), + _ => { + return Err(#tealr::mlu::mlua::Error::FromLuaConversionError { + from: value.type_name(), + to: stringify!(#proxy_type_ident), + message: None, + }) + } + } + } + } + + #conversions + } + .into() +} diff --git a/crates/bevy_mod_scripting_derive/src/utils.rs b/crates/bevy_mod_scripting_derive/src/utils.rs new file mode 100644 index 0000000000..d8df6bb792 --- /dev/null +++ b/crates/bevy_mod_scripting_derive/src/utils.rs @@ -0,0 +1,59 @@ +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/languages/bevy_mod_scripting_lua/Cargo.toml b/crates/languages/bevy_mod_scripting_lua/Cargo.toml index 746078c822..198c5af0d0 100644 --- a/crates/languages/bevy_mod_scripting_lua/Cargo.toml +++ b/crates/languages/bevy_mod_scripting_lua/Cargo.toml @@ -41,7 +41,8 @@ path = "src/lib.rs" [dependencies] bevy = { workspace = true, default-features = false } -bevy_mod_scripting_core = { workspace = true } +bevy_mod_scripting_core = { workspace = true, features = ["mlua_impls"] } +bevy_mod_scripting_derive = { path = "../../bevy_mod_scripting_derive" } tealr = { version = "0.9", features = [ "mlua_vendored", "mlua_send", @@ -50,3 +51,15 @@ tealr = { version = "0.9", features = [ 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 index 7e3e50d74b..79352f5d45 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/assets.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/assets.rs @@ -1,157 +1,156 @@ -use bevy::{ - asset::{io::Reader, Asset, AssetLoader}, - reflect::TypePath, - utils::BoxedFuture, -}; -use bevy_mod_scripting_core::asset::CodeAsset; +// use bevy::{ +// asset::{io::Reader, Asset, AssetLoader}, +// reflect::TypePath, +// utils::BoxedFuture, +// }; -use anyhow::Error; +// use anyhow::Error; -#[derive(Asset, TypePath, Debug)] -/// A lua code file in bytes -pub struct LuaFile { - pub bytes: Vec, -} +// #[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() - } -} +// impl CodeAsset for LuaFile { +// fn bytes(&self) -> &[u8] { +// self.bytes.as_slice() +// } +// } -#[derive(Default)] -/// Asset loader for lua scripts -pub struct LuaLoader; +// #[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; +// 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 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 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`"); - } +// 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 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")); - } +// 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(); +// 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(lua_code.as_bytes().into()) }) +// } - _ => Box::pin(async move { Ok(bytes.into()) }), - } -} -impl AssetLoader for LuaLoader { - type Asset = LuaFile; - type Settings = (); - type Error = Error; +// _ => 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 }) - } +// 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"] - } -} +// #[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 0000000000..78cd9549b3 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/mod.rs @@ -0,0 +1,7 @@ +pub mod providers; +pub mod proxy; +pub mod query; +pub mod reference; +pub mod std; +pub mod type_registration; +pub mod world; diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_a11y.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_a11y.rs new file mode 100644 index 0000000000..8827603674 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_a11y.rs @@ -0,0 +1,58 @@ +// @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, +}; +use crate::{ + bindings::proxy::{ + LuaReflectRefProxy, LuaReflectRefMutProxy, LuaReflectValProxy, LuaValProxy, + LuaIdentityProxy, + }, + type_data::RegisterLua, tealr::mlu::mlua::IntoLua, +}; +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::a11y::Focus", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[] +)] +pub struct Focus(ReflectReference); +#[derive(Default)] +pub(crate) struct Globals; +impl crate::tealr::mlu::ExportInstances for Globals { + fn add_instances<'lua, T: crate::tealr::mlu::InstanceCollector<'lua>>( + self, + instances: &mut T, + ) -> crate::tealr::mlu::mlua::Result<()> { + Ok(()) + } +} +fn bevy_a_11_y_context_initializer( + _: &bevy_mod_scripting_core::script::ScriptId, + ctx: &mut crate::prelude::Lua, +) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { + crate::tealr::mlu::set_global_env(Globals, ctx)?; + Ok(()) +} +pub struct BevyA11YScriptingPlugin; +impl bevy::app::Plugin for BevyA11YScriptingPlugin { + fn build(&self, app: &mut bevy::prelude::App) { + app.register_lua_proxy::(); + app.add_context_initializer::<()>(bevy_a_11_y_context_initializer); + app.add_documentation_fragment( + crate::docs::LuaDocumentationFragment::new( + "BevyA11YAPI", + |tw| { + tw.document_global_instance::() + .expect("Something went wrong documenting globals") + .process_type::() + }, + ), + ); + } +} diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_core.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_core.rs new file mode 100644 index 0000000000..81510b9c0b --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_core.rs @@ -0,0 +1,83 @@ +// @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, +}; +use crate::{ + bindings::proxy::{ + LuaReflectRefProxy, LuaReflectRefMutProxy, LuaReflectValProxy, LuaValProxy, + LuaIdentityProxy, + }, + type_data::RegisterLua, tealr::mlu::mlua::IntoLua, +}; +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::core::prelude::Name", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{}", _self) +} +"#] +)] +pub struct Name {} +#[derive(Default)] +pub(crate) struct Globals; +impl crate::tealr::mlu::ExportInstances for Globals { + fn add_instances<'lua, T: crate::tealr::mlu::InstanceCollector<'lua>>( + self, + instances: &mut T, + ) -> crate::tealr::mlu::mlua::Result<()> { + Ok(()) + } +} +fn bevy_core_context_initializer( + _: &bevy_mod_scripting_core::script::ScriptId, + ctx: &mut crate::prelude::Lua, +) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { + crate::tealr::mlu::set_global_env(Globals, ctx)?; + Ok(()) +} +pub struct BevyCoreScriptingPlugin; +impl bevy::app::Plugin for BevyCoreScriptingPlugin { + fn build(&self, app: &mut bevy::prelude::App) { + app.register_lua_proxy::(); + app.add_context_initializer::<()>(bevy_core_context_initializer); + app.add_documentation_fragment( + crate::docs::LuaDocumentationFragment::new( + "BevyCoreAPI", + |tw| { + tw.document_global_instance::() + .expect("Something went wrong documenting globals") + .process_type::() + }, + ), + ); + } +} diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_ecs.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_ecs.rs new file mode 100644 index 0000000000..e62e60366c --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_ecs.rs @@ -0,0 +1,554 @@ +// @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, +}; +use crate::{ + bindings::proxy::{ + LuaReflectRefProxy, LuaReflectRefMutProxy, LuaReflectValProxy, LuaValProxy, + LuaIdentityProxy, + }, + type_data::RegisterLua, tealr::mlu::mlua::IntoLua, +}; +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::ecs::entity::Entity", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_raw(index: u32) -> LuaReflectValProxy; + +"#, + 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()] + fn to_bits(_self: LuaReflectValProxy) -> 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()] + fn from_bits(bits: u64) -> LuaReflectValProxy; + +"#, + 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()] + fn index(_self: LuaReflectValProxy) -> 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()] + fn generation(_self: LuaReflectValProxy) -> u32; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Entity {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::ecs::world::OnAdd", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct OnAdd {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::ecs::world::OnInsert", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct OnInsert {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::ecs::world::OnRemove", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct OnRemove {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::ecs::world::OnReplace", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct OnReplace {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::ecs::component::ComponentId", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + 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()] + fn new(index: usize) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the index of the current component. + + #[lua()] + fn index(_self: LuaReflectValProxy) -> usize; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct ComponentId(); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::ecs::component::Tick", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new [`Tick`] wrapping the given value. + + #[lua()] + fn new(tick: u32) -> LuaReflectValProxy; + +"#, + r#" +/// Gets the value of this change tick. + + #[lua()] + fn get(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Sets the value of this change tick. + + #[lua()] + fn set(_self: LuaReflectRefMutProxy, 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()] + fn is_newer_than( + _self: LuaReflectValProxy, + last_run: LuaReflectValProxy, + this_run: LuaReflectValProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Tick {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::ecs::component::ComponentTicks", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_added( + _self: LuaReflectRefProxy, + last_run: LuaReflectValProxy, + this_run: LuaReflectValProxy, + ) -> 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()] + fn is_changed( + _self: LuaReflectRefProxy, + last_run: LuaReflectValProxy, + this_run: LuaReflectValProxy, + ) -> bool; + +"#, + r#" +/// Returns the tick recording the time this component or resource was most recently changed. + + #[lua()] + fn last_changed_tick( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the tick recording the time this component or resource was added. + + #[lua()] + fn added_tick( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn set_changed( + _self: LuaReflectRefMutProxy, + change_tick: LuaReflectValProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct ComponentTicks {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::ecs::identifier::Identifier", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Returns the value of the low segment of the [`Identifier`]. + + #[lua()] + fn low(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Returns the masked value of the high segment of the [`Identifier`]. +/// Does not include the flag bits. + + #[lua()] + fn masked_high(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Convert the [`Identifier`] into a `u64`. + + #[lua()] + fn to_bits(_self: LuaReflectValProxy) -> 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()] + fn from_bits(value: u64) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Identifier {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::ecs::entity::EntityHash", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#] +)] +pub struct EntityHash {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::ecs::removal_detection::RemovedComponentEntity", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct RemovedComponentEntity(); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::ecs::system::SystemIdMarker", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[] +)] +pub struct SystemIdMarker {} +#[derive(Default)] +pub(crate) struct Globals; +impl crate::tealr::mlu::ExportInstances for Globals { + fn add_instances<'lua, T: crate::tealr::mlu::InstanceCollector<'lua>>( + self, + instances: &mut T, + ) -> crate::tealr::mlu::mlua::Result<()> { + instances + .add_instance("Entity", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance( + "ComponentId", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance("Tick", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance( + "Identifier", + crate::tealr::mlu::UserDataProxy::::new, + )?; + Ok(()) + } +} +fn bevy_ecs_context_initializer( + _: &bevy_mod_scripting_core::script::ScriptId, + ctx: &mut crate::prelude::Lua, +) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { + crate::tealr::mlu::set_global_env(Globals, ctx)?; + Ok(()) +} +pub struct BevyEcsScriptingPlugin; +impl bevy::app::Plugin for BevyEcsScriptingPlugin { + fn build(&self, app: &mut bevy::prelude::App) { + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.add_context_initializer::<()>(bevy_ecs_context_initializer); + app.add_documentation_fragment( + crate::docs::LuaDocumentationFragment::new( + "BevyEcsAPI", + |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::< + crate::tealr::mlu::UserDataProxy, + >() + .process_type::() + .process_type::>() + .process_type::() + .process_type::() + .process_type::< + crate::tealr::mlu::UserDataProxy, + >() + .process_type::() + .process_type::() + .process_type::() + }, + ), + ); + } +} diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_hierarchy.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_hierarchy.rs new file mode 100644 index 0000000000..bbe353b36b --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_hierarchy.rs @@ -0,0 +1,153 @@ +// @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, +}; +use crate::{ + bindings::proxy::{ + LuaReflectRefProxy, LuaReflectRefMutProxy, LuaReflectValProxy, LuaValProxy, + LuaIdentityProxy, + }, + type_data::RegisterLua, tealr::mlu::mlua::IntoLua, +}; +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::hierarchy::prelude::Children", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Swaps the child at `a_index` with the child at `b_index`. + + #[lua()] + fn swap( + _self: LuaReflectRefMutProxy, + a_index: usize, + b_index: usize, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Children(); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::hierarchy::prelude::Parent", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Parent(); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::hierarchy::HierarchyEvent", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct HierarchyEvent {} +#[derive(Default)] +pub(crate) struct Globals; +impl crate::tealr::mlu::ExportInstances for Globals { + fn add_instances<'lua, T: crate::tealr::mlu::InstanceCollector<'lua>>( + self, + instances: &mut T, + ) -> crate::tealr::mlu::mlua::Result<()> { + Ok(()) + } +} +fn bevy_hierarchy_context_initializer( + _: &bevy_mod_scripting_core::script::ScriptId, + ctx: &mut crate::prelude::Lua, +) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { + crate::tealr::mlu::set_global_env(Globals, ctx)?; + Ok(()) +} +pub struct BevyHierarchyScriptingPlugin; +impl bevy::app::Plugin for BevyHierarchyScriptingPlugin { + fn build(&self, app: &mut bevy::prelude::App) { + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.add_context_initializer::<()>(bevy_hierarchy_context_initializer); + app.add_documentation_fragment( + crate::docs::LuaDocumentationFragment::new( + "BevyHierarchyAPI", + |tw| { + tw.document_global_instance::() + .expect("Something went wrong documenting globals") + .process_type::() + .process_type::() + .process_type::() + }, + ), + ); + } +} diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_input.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_input.rs new file mode 100644 index 0000000000..c55b025c1e --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_input.rs @@ -0,0 +1,1839 @@ +// @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, +}; +use crate::{ + bindings::proxy::{ + LuaReflectRefProxy, LuaReflectRefMutProxy, LuaReflectValProxy, LuaValProxy, + LuaIdentityProxy, + }, + type_data::RegisterLua, tealr::mlu::mlua::IntoLua, +}; +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::Gamepad", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Gamepad { + vendor_id: std::option::Option, + product_id: std::option::Option, + digital: ReflectReference, + analog: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::GamepadAxis", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct GamepadAxis {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::GamepadButton", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct GamepadButton {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::GamepadSettings", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct GamepadSettings { + default_button_settings: bevy::input::gamepad::ButtonSettings, + default_axis_settings: bevy::input::gamepad::AxisSettings, + default_button_axis_settings: bevy::input::gamepad::ButtonAxisSettings, + button_settings: ReflectReference, + axis_settings: ReflectReference, + button_axis_settings: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::keyboard::KeyCode", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct KeyCode {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::mouse::MouseButton", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct MouseButton {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::touch::TouchInput", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct TouchInput { + phase: bevy::input::touch::TouchPhase, + position: ReflectReference, + window: ReflectReference, + force: ReflectReference, + id: u64, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::keyboard::KeyboardFocusLost", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct KeyboardFocusLost {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::keyboard::KeyboardInput", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct KeyboardInput { + key_code: bevy::input::keyboard::KeyCode, + logical_key: bevy::input::keyboard::Key, + state: bevy::input::ButtonState, + repeat: bool, + window: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::mouse::AccumulatedMouseMotion", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct AccumulatedMouseMotion { + delta: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::mouse::AccumulatedMouseScroll", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct AccumulatedMouseScroll { + unit: bevy::input::mouse::MouseScrollUnit, + delta: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::mouse::MouseButtonInput", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct MouseButtonInput { + button: bevy::input::mouse::MouseButton, + state: bevy::input::ButtonState, + window: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::mouse::MouseMotion", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct MouseMotion { + delta: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::mouse::MouseWheel", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct MouseWheel { + unit: bevy::input::mouse::MouseScrollUnit, + x: f32, + y: f32, + window: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::GamepadAxisChangedEvent", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct GamepadAxisChangedEvent { + entity: ReflectReference, + axis: bevy::input::gamepad::GamepadAxis, + value: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::GamepadButtonChangedEvent", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct GamepadButtonChangedEvent { + entity: ReflectReference, + button: bevy::input::gamepad::GamepadButton, + state: bevy::input::ButtonState, + value: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::GamepadButtonStateChangedEvent", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct GamepadButtonStateChangedEvent { + entity: ReflectReference, + button: bevy::input::gamepad::GamepadButton, + state: bevy::input::ButtonState, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::GamepadConnection", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct GamepadConnection {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::GamepadConnectionEvent", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Is the gamepad connected? + + #[lua()] + fn connected( + _self: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Is the gamepad disconnected? + + #[lua()] + fn disconnected( + _self: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct GamepadConnectionEvent { + gamepad: ReflectReference, + connection: bevy::input::gamepad::GamepadConnection, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::GamepadEvent", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct GamepadEvent {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::GamepadInput", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct GamepadInput {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::GamepadRumbleRequest", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#] +)] +pub struct GamepadRumbleRequest {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::RawGamepadAxisChangedEvent", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct RawGamepadAxisChangedEvent { + gamepad: ReflectReference, + axis: bevy::input::gamepad::GamepadAxis, + value: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::RawGamepadButtonChangedEvent", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct RawGamepadButtonChangedEvent { + gamepad: ReflectReference, + button: bevy::input::gamepad::GamepadButton, + value: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::RawGamepadEvent", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct RawGamepadEvent {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gestures::PinchGesture", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct PinchGesture(f32); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gestures::RotationGesture", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct RotationGesture(f32); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gestures::DoubleTapGesture", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct DoubleTapGesture {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gestures::PanGesture", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct PanGesture(ReflectReference); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::ButtonState", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Is this button pressed? + + #[lua()] + fn is_pressed(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct ButtonState {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::ButtonSettings", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_pressed( + _self: LuaReflectRefProxy, + 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()] + fn is_released( + _self: LuaReflectRefProxy, + value: f32, + ) -> bool; + +"#, + r#" +/// Get the button input threshold above which the button is considered pressed. + + #[lua()] + fn press_threshold( + _self: LuaReflectRefProxy, + ) -> 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()] + fn set_press_threshold( + _self: LuaReflectRefMutProxy, + value: f32, + ) -> f32; + +"#, + r#" +/// Get the button input threshold below which the button is considered released. + + #[lua()] + fn release_threshold( + _self: LuaReflectRefProxy, + ) -> 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()] + fn set_release_threshold( + _self: LuaReflectRefMutProxy, + value: f32, + ) -> f32; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct ButtonSettings {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::AxisSettings", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the value above which inputs will be rounded up to 1.0. + + #[lua()] + fn livezone_upperbound( + _self: LuaReflectRefProxy, + ) -> 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()] + fn set_livezone_upperbound( + _self: LuaReflectRefMutProxy, + value: f32, + ) -> f32; + +"#, + r#" +/// Get the value below which positive inputs will be rounded down to 0.0. + + #[lua()] + fn deadzone_upperbound( + _self: LuaReflectRefProxy, + ) -> 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()] + fn set_deadzone_upperbound( + _self: LuaReflectRefMutProxy, + value: f32, + ) -> f32; + +"#, + r#" +/// Get the value below which negative inputs will be rounded down to -1.0. + + #[lua()] + fn livezone_lowerbound( + _self: LuaReflectRefProxy, + ) -> 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()] + fn set_livezone_lowerbound( + _self: LuaReflectRefMutProxy, + value: f32, + ) -> f32; + +"#, + r#" +/// Get the value above which inputs will be rounded up to 0.0. + + #[lua()] + fn deadzone_lowerbound( + _self: LuaReflectRefProxy, + ) -> 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()] + fn set_deadzone_lowerbound( + _self: LuaReflectRefMutProxy, + value: f32, + ) -> f32; + +"#, + r#" +/// Get the minimum value by which input must change before the change is registered. + + #[lua()] + fn threshold(_self: LuaReflectRefProxy) -> 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()] + fn set_threshold( + _self: LuaReflectRefMutProxy, + value: f32, + ) -> f32; + +"#, + r#" +/// Clamps the `raw_value` according to the `AxisSettings`. + + #[lua()] + fn clamp( + _self: LuaReflectRefProxy, + 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()] + fn filter( + _self: LuaReflectRefProxy, + new_value: f32, + old_value: std::option::Option, + ) -> std::option::Option; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct AxisSettings {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::ButtonAxisSettings", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn filter( + _self: LuaReflectRefProxy, + new_value: f32, + old_value: std::option::Option, + ) -> std::option::Option; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct ButtonAxisSettings { + high: f32, + low: f32, + threshold: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::gamepad::GamepadRumbleIntensity", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn weak_motor( + intensity: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn strong_motor( + intensity: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct GamepadRumbleIntensity { + strong_motor: f32, + weak_motor: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::keyboard::Key", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Key {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::keyboard::NativeKeyCode", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct NativeKeyCode {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::keyboard::NativeKey", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct NativeKey {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::mouse::MouseScrollUnit", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct MouseScrollUnit {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::touch::TouchPhase", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct TouchPhase {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::input::touch::ForceTouch", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct ForceTouch {} +#[derive(Default)] +pub(crate) struct Globals; +impl crate::tealr::mlu::ExportInstances for Globals { + fn add_instances<'lua, T: crate::tealr::mlu::InstanceCollector<'lua>>( + self, + instances: &mut T, + ) -> crate::tealr::mlu::mlua::Result<()> { + instances + .add_instance( + "GamepadRumbleIntensity", + crate::tealr::mlu::UserDataProxy::::new, + )?; + Ok(()) + } +} +fn bevy_input_context_initializer( + _: &bevy_mod_scripting_core::script::ScriptId, + ctx: &mut crate::prelude::Lua, +) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { + crate::tealr::mlu::set_global_env(Globals, ctx)?; + Ok(()) +} +pub struct BevyInputScriptingPlugin; +impl bevy::app::Plugin for BevyInputScriptingPlugin { + fn build(&self, app: &mut bevy::prelude::App) { + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.add_context_initializer::<()>(bevy_input_context_initializer); + app.add_documentation_fragment( + crate::docs::LuaDocumentationFragment::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::() + .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::() + .process_type::() + .process_type::() + .process_type::< + crate::tealr::mlu::UserDataProxy, + >() + .process_type::() + .process_type::() + .process_type::() + .process_type::() + .process_type::() + .process_type::() + }, + ), + ); + } +} diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_math.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_math.rs new file mode 100644 index 0000000000..49f55cbfb4 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_math.rs @@ -0,0 +1,4449 @@ +// @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, +}; +use crate::{ + bindings::proxy::{ + LuaReflectRefProxy, LuaReflectRefMutProxy, LuaReflectValProxy, LuaValProxy, + LuaIdentityProxy, + }, + type_data::RegisterLua, tealr::mlu::mlua::IntoLua, +}; +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::AspectRatio", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the aspect ratio as a f32 value. + + #[lua()] + fn ratio(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Returns the inverse of this aspect ratio (height/width). + + #[lua()] + fn inverse( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns true if the aspect ratio represents a landscape orientation. + + #[lua()] + fn is_landscape(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns true if the aspect ratio represents a portrait orientation. + + #[lua()] + fn is_portrait(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns true if the aspect ratio is exactly square. + + #[lua()] + fn is_square(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct AspectRatio(); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::CompassOctant", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct CompassOctant {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::CompassQuadrant", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct CompassQuadrant {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::Isometry2d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Create a two-dimensional isometry from a rotation. + + #[lua()] + fn from_rotation( + rotation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a two-dimensional isometry from a translation with the given `x` and `y` components. + + #[lua()] + fn from_xy(x: f32, y: f32) -> LuaReflectValProxy; + +"#, + r#" +/// The inverse isometry that undoes this one. + + #[lua()] + fn inverse( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn inverse_mul( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Isometry2d { + rotation: bevy::math::Rot2, + translation: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::Isometry3d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a three-dimensional isometry from a translation with the given `x`, `y`, and `z` components. + + #[lua()] + fn from_xyz(x: f32, y: f32, z: f32) -> LuaReflectValProxy; + +"#, + r#" +/// The inverse isometry that undoes this one. + + #[lua()] + fn inverse( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn inverse_mul( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Isometry3d { + rotation: ReflectReference, + translation: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::Ray2d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Ray2d { + origin: ReflectReference, + direction: bevy::math::prelude::Dir2, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::Ray3d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Ray3d { + origin: ReflectReference, + direction: bevy::math::prelude::Dir3, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::Rot2", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Rotates the [`Dir2`] using a [`Rot2`]. + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + direction: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn radians(radians: f32) -> LuaReflectValProxy; + +"#, + 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()] + fn degrees(degrees: f32) -> LuaReflectValProxy; + +"#, + 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()] + fn turn_fraction(fraction: f32) -> LuaReflectValProxy; + +"#, + 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()] + fn from_sin_cos(sin: f32, cos: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the rotation in radians in the `(-pi, pi]` range. + + #[lua()] + fn as_radians(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Returns the rotation in degrees in the `(-180, 180]` range. + + #[lua()] + fn as_degrees(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Returns the rotation as a fraction of a full 360 degree turn. + + #[lua()] + fn as_turn_fraction(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Returns the sine and cosine of the rotation angle in radians. + + #[lua()] + fn sin_cos(_self: LuaReflectValProxy) -> (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()] + fn length(_self: LuaReflectValProxy) -> 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()] + fn length_squared(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Computes `1.0 / self.length()`. +/// For valid results, `self` must _not_ have a length of zero. + + #[lua()] + fn length_recip(_self: LuaReflectValProxy) -> 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()] + fn normalize( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn fast_renormalize( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns `true` if the rotation is neither infinite nor NaN. + + #[lua()] + fn is_finite(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +/// Returns `true` if the rotation is NaN. + + #[lua()] + fn is_nan(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +/// Returns whether `self` has a length of `1.0` or not. +/// Uses a precision threshold of approximately `1e-4`. + + #[lua()] + fn is_normalized(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +/// Returns `true` if the rotation is near [`Rot2::IDENTITY`]. + + #[lua()] + fn is_near_identity(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +/// Returns the angle in radians needed to make `self` and `other` coincide. + + #[lua()] + fn angle_between( + _self: LuaReflectValProxy, + other: LuaReflectValProxy, + ) -> f32; + +"#, + r#" +/// Returns the inverse of the rotation. This is also the conjugate +/// of the unit complex number representing the rotation. + + #[lua()] + fn inverse( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn nlerp( + _self: LuaReflectValProxy, + end: LuaReflectValProxy, + s: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn slerp( + _self: LuaReflectValProxy, + end: LuaReflectValProxy, + s: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Rot2 { + cos: f32, + sin: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::prelude::Dir2", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[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()] + fn from_xy_unchecked( + x: f32, + y: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn slerp( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + s: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the rotation that rotates this direction to `other`. + + #[lua()] + fn rotation_to( + _self: LuaReflectValProxy, + other: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the rotation that rotates `other` to this direction. + + #[lua()] + fn rotation_from( + _self: LuaReflectValProxy, + other: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the rotation that rotates the X-axis to this direction. + + #[lua()] + fn rotation_from_x( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the rotation that rotates this direction to the X-axis. + + #[lua()] + fn rotation_to_x( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the rotation that rotates the Y-axis to this direction. + + #[lua()] + fn rotation_from_y( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the rotation that rotates this direction to the Y-axis. + + #[lua()] + fn rotation_to_y( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn fast_renormalize( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Dir2(); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::prelude::Dir3", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_xyz_unchecked( + x: f32, + y: f32, + z: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn slerp( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + s: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn fast_renormalize( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Dir3(); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::prelude::Dir3A", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_xyz_unchecked( + x: f32, + y: f32, + z: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn slerp( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + s: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn fast_renormalize( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Dir3A(); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::prelude::IRect", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[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()] + fn new( + x0: i32, + y0: i32, + x1: i32, + y1: i32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_empty(_self: LuaReflectRefProxy) -> 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()] + fn width(_self: LuaReflectRefProxy) -> 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()] + fn height(_self: LuaReflectRefProxy) -> i32; + +"#, + 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()] + fn union( + _self: LuaReflectRefProxy, + other: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn intersect( + _self: LuaReflectRefProxy, + other: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn inflate( + _self: LuaReflectRefProxy, + expansion: i32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns self as [`Rect`] (f32) + + #[lua()] + fn as_rect( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns self as [`URect`] (u32) + + #[lua()] + fn as_urect( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct IRect { + min: ReflectReference, + max: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::prelude::Rect", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn new( + x0: f32, + y0: f32, + x1: f32, + y1: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_empty(_self: LuaReflectRefProxy) -> 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()] + fn width(_self: LuaReflectRefProxy) -> 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()] + fn height(_self: LuaReflectRefProxy) -> f32; + +"#, + 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()] + fn union( + _self: LuaReflectRefProxy, + other: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn intersect( + _self: LuaReflectRefProxy, + other: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn inflate( + _self: LuaReflectRefProxy, + expansion: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize( + _self: LuaReflectRefProxy, + other: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns self as [`IRect`] (i32) + + #[lua()] + fn as_irect( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns self as [`URect`] (u32) + + #[lua()] + fn as_urect( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Rect { + min: ReflectReference, + max: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::prelude::URect", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> 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::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()] + fn new( + x0: u32, + y0: u32, + x1: u32, + y1: u32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_empty(_self: LuaReflectRefProxy) -> 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()] + fn width(_self: LuaReflectRefProxy) -> 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()] + fn height(_self: LuaReflectRefProxy) -> u32; + +"#, + 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()] + fn union( + _self: LuaReflectRefProxy, + other: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn intersect( + _self: LuaReflectRefProxy, + other: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn inflate( + _self: LuaReflectRefProxy, + expansion: i32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns self as [`Rect`] (f32) + + #[lua()] + fn as_rect( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns self as [`IRect`] (i32) + + #[lua()] + fn as_irect( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct URect { + min: ReflectReference, + max: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::Affine3", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[] +)] +pub struct Affine3 { + matrix3: ReflectReference, + translation: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::bounding::Aabb2d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the smallest [`BoundingCircle`] containing this [`Aabb2d`]. + + #[lua()] + fn bounding_circle( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Aabb2d { + min: ReflectReference, + max: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::bounding::BoundingCircle", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the radius of the bounding circle + + #[lua()] + fn radius(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Computes the smallest [`Aabb2d`] containing this [`BoundingCircle`]. + + #[lua()] + fn aabb_2d( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct BoundingCircle { + center: ReflectReference, + circle: bevy::math::primitives::Circle, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Circle", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a new [`Circle`] from a `radius` + + #[lua()] + fn new(radius: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Get the diameter of the circle + + #[lua()] + fn diameter(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Circle { + radius: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Annulus", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a new [`Annulus`] from the radii of the inner and outer circle + + #[lua()] + fn new( + inner_radius: f32, + outer_radius: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the diameter of the annulus + + #[lua()] + fn diameter(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Get the thickness of the annulus + + #[lua()] + fn thickness(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Annulus { + inner_circle: bevy::math::primitives::Circle, + outer_circle: bevy::math::primitives::Circle, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Arc2d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Create a new [`Arc2d`] from a `radius` and a `half_angle` + + #[lua()] + fn new( + radius: f32, + half_angle: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a new [`Arc2d`] from a `radius` and an `angle` in radians + + #[lua()] + fn from_radians( + radius: f32, + angle: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a new [`Arc2d`] from a `radius` and an `angle` in degrees. + + #[lua()] + fn from_degrees( + radius: f32, + angle: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a new [`Arc2d`] from a `radius` and a `fraction` of a single turn. +/// For instance, `0.5` turns is a semicircle. + + #[lua()] + fn from_turns( + radius: f32, + fraction: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the angle of the arc + + #[lua()] + fn angle(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Get the length of the arc + + #[lua()] + fn length(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Get half the distance between the endpoints (half the length of the chord) + + #[lua()] + fn half_chord_length( + _self: LuaReflectRefProxy, + ) -> f32; + +"#, + r#" +/// Get the distance between the endpoints (the length of the chord) + + #[lua()] + fn chord_length(_self: LuaReflectRefProxy) -> f32; + +"#, + 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()] + fn apothem(_self: LuaReflectRefProxy) -> 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()] + fn sagitta(_self: LuaReflectRefProxy) -> 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()] + fn is_minor(_self: LuaReflectRefProxy) -> 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()] + fn is_major(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Arc2d { + radius: f32, + half_angle: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Capsule2d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Create a new `Capsule2d` from a radius and length + + #[lua()] + fn new( + radius: f32, + length: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the part connecting the semicircular ends of the capsule as a [`Rectangle`] + + #[lua()] + fn to_inner_rectangle( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Capsule2d { + radius: f32, + half_length: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::CircularSector", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Create a new [`CircularSector`] from a `radius` and an `angle` + + #[lua()] + fn new( + radius: f32, + angle: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a new [`CircularSector`] from a `radius` and an `angle` in radians. + + #[lua()] + fn from_radians( + radius: f32, + angle: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a new [`CircularSector`] from a `radius` and an `angle` in degrees. + + #[lua()] + fn from_degrees( + radius: f32, + angle: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_turns( + radius: f32, + fraction: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get half the angle of the sector + + #[lua()] + fn half_angle( + _self: LuaReflectRefProxy, + ) -> f32; + +"#, + r#" +/// Get the angle of the sector + + #[lua()] + fn angle(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Get the radius of the sector + + #[lua()] + fn radius(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Get the length of the arc defining the sector + + #[lua()] + fn arc_length( + _self: LuaReflectRefProxy, + ) -> f32; + +"#, + r#" +/// Get half the length of the chord defined by the sector +/// See [`Arc2d::half_chord_length`] + + #[lua()] + fn half_chord_length( + _self: LuaReflectRefProxy, + ) -> f32; + +"#, + r#" +/// Get the length of the chord defined by the sector +/// See [`Arc2d::chord_length`] + + #[lua()] + fn chord_length( + _self: LuaReflectRefProxy, + ) -> f32; + +"#, + r#" +/// Get the length of the apothem of this sector +/// See [`Arc2d::apothem`] + + #[lua()] + fn apothem(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Get the length of the sagitta of this sector +/// See [`Arc2d::sagitta`] + + #[lua()] + fn sagitta(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct CircularSector { + arc: bevy::math::primitives::Arc2d, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::CircularSegment", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Create a new [`CircularSegment`] from a `radius`, and an `angle` + + #[lua()] + fn new( + radius: f32, + angle: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a new [`CircularSegment`] from a `radius` and an `angle` in radians. + + #[lua()] + fn from_radians( + radius: f32, + angle: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a new [`CircularSegment`] from a `radius` and an `angle` in degrees. + + #[lua()] + fn from_degrees( + radius: f32, + angle: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_turns( + radius: f32, + fraction: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the half-angle of the segment + + #[lua()] + fn half_angle( + _self: LuaReflectRefProxy, + ) -> f32; + +"#, + r#" +/// Get the angle of the segment + + #[lua()] + fn angle(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Get the radius of the segment + + #[lua()] + fn radius(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Get the length of the arc defining the segment + + #[lua()] + fn arc_length( + _self: LuaReflectRefProxy, + ) -> f32; + +"#, + r#" +/// Get half the length of the segment's base, also known as its chord + + #[lua()] + fn half_chord_length( + _self: LuaReflectRefProxy, + ) -> f32; + +"#, + r#" +/// Get the length of the segment's base, also known as its chord + + #[lua()] + fn chord_length( + _self: LuaReflectRefProxy, + ) -> f32; + +"#, + 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()] + fn apothem( + _self: LuaReflectRefProxy, + ) -> f32; + +"#, + r#" +/// Get the length of the sagitta of this segment, also known as its height +/// See [`Arc2d::sagitta`] + + #[lua()] + fn sagitta( + _self: LuaReflectRefProxy, + ) -> f32; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct CircularSegment { + arc: bevy::math::primitives::Arc2d, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Ellipse", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Create a new `Ellipse` from half of its width and height. +/// This corresponds to the two perpendicular radii defining the ellipse. + + #[lua()] + fn new( + half_width: f32, + half_height: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn eccentricity(_self: LuaReflectRefProxy) -> 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()] + fn focal_length(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Returns the length of the semi-major axis. This corresponds to the longest radius of the ellipse. + + #[lua()] + fn semi_major(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Returns the length of the semi-minor axis. This corresponds to the shortest radius of the ellipse. + + #[lua()] + fn semi_minor(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Ellipse { + half_size: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Line2d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Line2d { + direction: bevy::math::prelude::Dir2, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Plane2d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Plane2d { + normal: bevy::math::prelude::Dir2, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Rectangle", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Create a new `Rectangle` from a full width and height + + #[lua()] + fn new( + width: f32, + height: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a `Rectangle` from a single length. +/// The resulting `Rectangle` will be the same size in every direction. + + #[lua()] + fn from_length(length: f32) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Rectangle { + half_size: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::RegularPolygon", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Create a new `RegularPolygon` +/// from the radius of the circumcircle and a number of sides +/// # Panics +/// Panics if `circumradius` is negative + + #[lua()] + fn new( + circumradius: f32, + sides: u32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the radius of the circumcircle on which all vertices +/// of the regular polygon lie + + #[lua()] + fn circumradius( + _self: LuaReflectRefProxy, + ) -> 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()] + fn inradius( + _self: LuaReflectRefProxy, + ) -> f32; + +"#, + r#" +/// Get the length of one side of the regular polygon + + #[lua()] + fn side_length( + _self: LuaReflectRefProxy, + ) -> 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()] + fn internal_angle_degrees( + _self: LuaReflectRefProxy, + ) -> 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()] + fn internal_angle_radians( + _self: LuaReflectRefProxy, + ) -> 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()] + fn external_angle_degrees( + _self: LuaReflectRefProxy, + ) -> 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()] + fn external_angle_radians( + _self: LuaReflectRefProxy, + ) -> f32; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct RegularPolygon { + circumcircle: bevy::math::primitives::Circle, + sides: u32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Rhombus", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a new `Rhombus` from a vertical and horizontal diagonal sizes. + + #[lua()] + fn new( + horizontal_diagonal: f32, + vertical_diagonal: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a new `Rhombus` from a side length with all inner angles equal. + + #[lua()] + fn from_side(side: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Create a new `Rhombus` from a given inradius with all inner angles equal. + + #[lua()] + fn from_inradius( + inradius: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the length of each side of the rhombus + + #[lua()] + fn side(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Get the radius of the circumcircle on which all vertices +/// of the rhombus lie + + #[lua()] + fn circumradius(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Get the radius of the largest circle that can +/// be drawn within the rhombus + + #[lua()] + fn inradius(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Rhombus { + half_diagonals: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Segment2d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a new `Segment2d` from a direction and full length of the segment + + #[lua()] + fn new( + direction: LuaReflectValProxy, + length: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Segment2d { + direction: bevy::math::prelude::Dir2, + half_length: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Triangle2d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[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()] + fn is_degenerate( + _self: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Checks if the triangle is acute, meaning all angles are less than 90 degrees + + #[lua()] + fn is_acute(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Checks if the triangle is obtuse, meaning one angle is greater than 90 degrees + + #[lua()] + fn is_obtuse(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Reverse the [`WindingOrder`] of the triangle +/// by swapping the first and last vertices. + + #[lua()] + fn reverse(_self: LuaReflectRefMutProxy) -> (); + +"#, + r#" +/// This triangle but reversed. + + #[lua()] + fn reversed( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Triangle2d { + vertices: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::bounding::Aabb3d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the smallest [`BoundingSphere`] containing this [`Aabb3d`]. + + #[lua()] + fn bounding_sphere( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Aabb3d { + min: ReflectReference, + max: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::bounding::BoundingSphere", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Get the radius of the bounding sphere + + #[lua()] + fn radius(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Computes the smallest [`Aabb3d`] containing this [`BoundingSphere`]. + + #[lua()] + fn aabb_3d( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct BoundingSphere { + center: ReflectReference, + sphere: bevy::math::primitives::Sphere, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Sphere", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Create a new [`Sphere`] from a `radius` + + #[lua()] + fn new(radius: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Get the diameter of the sphere + + #[lua()] + fn diameter(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Sphere { + radius: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Cuboid", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Create a new `Cuboid` from a full x, y, and z length + + #[lua()] + fn new( + x_length: f32, + y_length: f32, + z_length: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a `Cuboid` from a single length. +/// The resulting `Cuboid` will be the same size in every direction. + + #[lua()] + fn from_length(length: f32) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Cuboid { + half_size: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Cylinder", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Create a new `Cylinder` from a radius and full height + + #[lua()] + fn new( + radius: f32, + height: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the base of the cylinder as a [`Circle`] + + #[lua()] + fn base( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the surface area of the side of the cylinder, +/// also known as the lateral area + + #[lua()] + fn lateral_area(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Get the surface area of one base of the cylinder + + #[lua()] + fn base_area(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Cylinder { + radius: f32, + half_height: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Capsule3d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a new `Capsule3d` from a radius and length + + #[lua()] + fn new( + radius: f32, + length: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the part connecting the hemispherical ends +/// of the capsule as a [`Cylinder`] + + #[lua()] + fn to_cylinder( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Capsule3d { + radius: f32, + half_length: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Cone", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a new [`Cone`] from a radius and height. + + #[lua()] + fn new(radius: f32, height: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Get the base of the cone as a [`Circle`] + + #[lua()] + fn base( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the slant height of the cone, the length of the line segment +/// connecting a point on the base to the apex + + #[lua()] + fn slant_height(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Get the surface area of the side of the cone, +/// also known as the lateral area + + #[lua()] + fn lateral_area(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Get the surface area of the base of the cone + + #[lua()] + fn base_area(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Cone { + radius: f32, + height: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::ConicalFrustum", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct ConicalFrustum { + radius_top: f32, + radius_bottom: f32, + height: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::InfinitePlane3d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct InfinitePlane3d { + normal: bevy::math::prelude::Dir3, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Line3d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Line3d { + direction: bevy::math::prelude::Dir3, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Segment3d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a new `Segment3d` from a direction and full length of the segment + + #[lua()] + fn new( + direction: LuaReflectValProxy, + length: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Segment3d { + direction: bevy::math::prelude::Dir3, + half_length: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Torus", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + 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()] + fn new( + inner_radius: f32, + outer_radius: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn inner_radius(_self: LuaReflectRefProxy) -> 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()] + fn outer_radius(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Torus { + minor_radius: f32, + major_radius: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Triangle3d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_degenerate( + _self: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Checks if the triangle is acute, meaning all angles are less than 90 degrees + + #[lua()] + fn is_acute(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Checks if the triangle is obtuse, meaning one angle is greater than 90 degrees + + #[lua()] + fn is_obtuse(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Reverse the triangle by swapping the first and last vertices. + + #[lua()] + fn reverse(_self: LuaReflectRefMutProxy) -> (); + +"#, + r#" +/// This triangle but reversed. + + #[lua()] + fn reversed( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Triangle3d { + vertices: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::bounding::RayCast2d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Construct a [`RayCast2d`] from a [`Ray2d`] and max distance. + + #[lua()] + fn from_ray( + ray: LuaReflectValProxy, + max: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the distance of an intersection with an [`Aabb2d`], if any. + + #[lua()] + fn aabb_intersection_at( + _self: LuaReflectRefProxy, + aabb: LuaReflectRefProxy, + ) -> std::option::Option; + +"#, + r#" +/// Get the distance of an intersection with a [`BoundingCircle`], if any. + + #[lua()] + fn circle_intersection_at( + _self: LuaReflectRefProxy, + circle: LuaReflectRefProxy, + ) -> std::option::Option; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct RayCast2d { + ray: bevy::math::Ray2d, + max: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::bounding::AabbCast2d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Construct an [`AabbCast2d`] from an [`Aabb2d`], [`Ray2d`], and max distance. + + #[lua()] + fn from_ray( + aabb: LuaReflectValProxy, + ray: LuaReflectValProxy, + max: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the distance at which the [`Aabb2d`]s collide, if at all. + + #[lua()] + fn aabb_collision_at( + _self: LuaReflectRefProxy, + aabb: LuaReflectValProxy, + ) -> std::option::Option; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct AabbCast2d { + ray: bevy::math::bounding::RayCast2d, + aabb: bevy::math::bounding::Aabb2d, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::bounding::BoundingCircleCast", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Construct a [`BoundingCircleCast`] from a [`BoundingCircle`], [`Ray2d`], and max distance. + + #[lua()] + fn from_ray( + circle: LuaReflectValProxy, + ray: LuaReflectValProxy, + max: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the distance at which the [`BoundingCircle`]s collide, if at all. + + #[lua()] + fn circle_collision_at( + _self: LuaReflectRefProxy, + circle: LuaReflectValProxy, + ) -> std::option::Option; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct BoundingCircleCast { + ray: bevy::math::bounding::RayCast2d, + circle: bevy::math::bounding::BoundingCircle, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::bounding::RayCast3d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Construct a [`RayCast3d`] from a [`Ray3d`] and max distance. + + #[lua()] + fn from_ray( + ray: LuaReflectValProxy, + max: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the distance of an intersection with an [`Aabb3d`], if any. + + #[lua()] + fn aabb_intersection_at( + _self: LuaReflectRefProxy, + aabb: LuaReflectRefProxy, + ) -> std::option::Option; + +"#, + r#" +/// Get the distance of an intersection with a [`BoundingSphere`], if any. + + #[lua()] + fn sphere_intersection_at( + _self: LuaReflectRefProxy, + sphere: LuaReflectRefProxy, + ) -> std::option::Option; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct RayCast3d { + origin: ReflectReference, + direction: bevy::math::prelude::Dir3A, + max: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::bounding::AabbCast3d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Construct an [`AabbCast3d`] from an [`Aabb3d`], [`Ray3d`], and max distance. + + #[lua()] + fn from_ray( + aabb: LuaReflectValProxy, + ray: LuaReflectValProxy, + max: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the distance at which the [`Aabb3d`]s collide, if at all. + + #[lua()] + fn aabb_collision_at( + _self: LuaReflectRefProxy, + aabb: LuaReflectValProxy, + ) -> std::option::Option; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct AabbCast3d { + ray: bevy::math::bounding::RayCast3d, + aabb: bevy::math::bounding::Aabb3d, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::bounding::BoundingSphereCast", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Construct a [`BoundingSphereCast`] from a [`BoundingSphere`], [`Ray3d`], and max distance. + + #[lua()] + fn from_ray( + sphere: LuaReflectValProxy, + ray: LuaReflectValProxy, + max: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Get the distance at which the [`BoundingSphere`]s collide, if at all. + + #[lua()] + fn sphere_collision_at( + _self: LuaReflectRefProxy, + sphere: LuaReflectValProxy, + ) -> std::option::Option; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct BoundingSphereCast { + ray: bevy::math::bounding::RayCast3d, + sphere: bevy::math::bounding::BoundingSphere, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::curve::interval::Interval", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Get the start of this interval. + + #[lua()] + fn start(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Get the end of this interval. + + #[lua()] + fn end(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Get the length of this interval. Note that the result may be infinite (`f32::INFINITY`). + + #[lua()] + fn length(_self: LuaReflectValProxy) -> 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()] + fn is_bounded( + _self: LuaReflectValProxy, + ) -> bool; + +"#, + r#" +/// Returns `true` if this interval has a finite start. + + #[lua()] + fn has_finite_start( + _self: LuaReflectValProxy, + ) -> bool; + +"#, + r#" +/// Returns `true` if this interval has a finite end. + + #[lua()] + fn has_finite_end( + _self: LuaReflectValProxy, + ) -> bool; + +"#, + r#" +/// Returns `true` if `item` is contained in this interval. + + #[lua()] + fn contains( + _self: LuaReflectValProxy, + 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()] + fn contains_interval( + _self: LuaReflectValProxy, + other: LuaReflectValProxy, + ) -> bool; + +"#, + r#" +/// Clamp the given `value` to lie within this interval. + + #[lua()] + fn clamp( + _self: LuaReflectValProxy, + value: f32, + ) -> f32; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Interval {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::FloatOrd", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::PartialOrd::")] + fn lt( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialOrd::")] + fn le( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialOrd::")] + fn gt( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialOrd::")] + fn ge( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct FloatOrd(f32); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Plane3d", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Plane3d { + normal: bevy::math::prelude::Dir3, + half_size: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::primitives::Tetrahedron", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[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()] + fn signed_volume( + _self: LuaReflectRefProxy, + ) -> f32; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Tetrahedron { + vertices: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::curve::easing::EaseFunction", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct EaseFunction {} +#[derive(Default)] +pub(crate) struct Globals; +impl crate::tealr::mlu::ExportInstances for Globals { + fn add_instances<'lua, T: crate::tealr::mlu::InstanceCollector<'lua>>( + self, + instances: &mut T, + ) -> crate::tealr::mlu::mlua::Result<()> { + instances + .add_instance( + "Isometry2d", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "Isometry3d", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance("Rot2", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("Dir2", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("Dir3", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("Dir3A", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("IRect", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("Rect", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("URect", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("Circle", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance( + "Annulus", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance("Arc2d", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance( + "Capsule2d", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "CircularSector", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "CircularSegment", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "Ellipse", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "Rectangle", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "RegularPolygon", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "Rhombus", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "Segment2d", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance("Sphere", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("Cuboid", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance( + "Cylinder", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "Capsule3d", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance("Cone", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance( + "Segment3d", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance("Torus", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance( + "RayCast2d", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "AabbCast2d", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "BoundingCircleCast", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "RayCast3d", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "AabbCast3d", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "BoundingSphereCast", + crate::tealr::mlu::UserDataProxy::::new, + )?; + Ok(()) + } +} +fn bevy_math_context_initializer( + _: &bevy_mod_scripting_core::script::ScriptId, + ctx: &mut crate::prelude::Lua, +) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { + crate::tealr::mlu::set_global_env(Globals, ctx)?; + Ok(()) +} +pub struct BevyMathScriptingPlugin; +impl bevy::app::Plugin for BevyMathScriptingPlugin { + fn build(&self, app: &mut bevy::prelude::App) { + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.add_context_initializer::<()>(bevy_math_context_initializer); + app.add_documentation_fragment( + crate::docs::LuaDocumentationFragment::new( + "BevyMathAPI", + |tw| { + tw.document_global_instance::() + .expect("Something went wrong documenting globals") + .process_type::() + .process_type::() + .process_type::() + .process_type::() + .process_type::< + crate::tealr::mlu::UserDataProxy, + >() + .process_type::() + .process_type::< + crate::tealr::mlu::UserDataProxy, + >() + .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::>() + .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::< + crate::tealr::mlu::UserDataProxy, + >() + .process_type::() + .process_type::< + crate::tealr::mlu::UserDataProxy, + >() + .process_type::() + .process_type::>() + .process_type::() + .process_type::() + .process_type::() + .process_type::>() + .process_type::() + .process_type::< + crate::tealr::mlu::UserDataProxy, + >() + .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::() + .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::< + crate::tealr::mlu::UserDataProxy, + >() + .process_type::() + .process_type::< + crate::tealr::mlu::UserDataProxy, + >() + .process_type::() + .process_type::>() + .process_type::() + .process_type::< + crate::tealr::mlu::UserDataProxy, + >() + .process_type::() + .process_type::< + crate::tealr::mlu::UserDataProxy, + >() + .process_type::() + .process_type::() + .process_type::() + .process_type::() + .process_type::() + }, + ), + ); + } +} diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_reflect.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_reflect.rs new file mode 100644 index 0000000000..b5e5699ac5 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_reflect.rs @@ -0,0 +1,23630 @@ +// @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, +}; +use crate::{ + bindings::proxy::{ + LuaReflectRefProxy, LuaReflectRefMutProxy, LuaReflectValProxy, LuaValProxy, + LuaIdentityProxy, + }, + type_data::RegisterLua, tealr::mlu::mlua::IntoLua, +}; +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "std::sync::atomic::AtomicBool", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + 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()] + fn new(v: bool) -> LuaReflectValProxy; + +"#, + r#" +/// Consumes the atomic and returns the contained value. +/// This is safe because passing `self` by value guarantees that no other threads are +/// concurrently accessing the atomic data. +/// # Examples +/// ``` +/// use std::sync::atomic::AtomicBool; +/// let some_bool = AtomicBool::new(true); +/// assert_eq!(some_bool.into_inner(), true); +/// ``` + + #[lua()] + fn into_inner(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct AtomicBool {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "std::sync::atomic::AtomicI16", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Creates a new atomic integer. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicI16; +///let atomic_forty_two = AtomicI16::new(42); +/// ``` + + #[lua()] + fn new(v: i16) -> LuaReflectValProxy; + +"#, + r#" +/// Consumes the atomic and returns the contained value. +/// This is safe because passing `self` by value guarantees that no other threads are +/// concurrently accessing the atomic data. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicI16; +///let some_var = AtomicI16::new(5); +/// assert_eq!(some_var.into_inner(), 5); +/// ``` + + #[lua()] + fn into_inner(_self: LuaReflectValProxy) -> i16; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct AtomicI16 {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "std::sync::atomic::AtomicI32", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Creates a new atomic integer. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicI32; +///let atomic_forty_two = AtomicI32::new(42); +/// ``` + + #[lua()] + fn new(v: i32) -> LuaReflectValProxy; + +"#, + r#" +/// Consumes the atomic and returns the contained value. +/// This is safe because passing `self` by value guarantees that no other threads are +/// concurrently accessing the atomic data. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicI32; +///let some_var = AtomicI32::new(5); +/// assert_eq!(some_var.into_inner(), 5); +/// ``` + + #[lua()] + fn into_inner(_self: LuaReflectValProxy) -> i32; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct AtomicI32 {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "std::sync::atomic::AtomicI64", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Creates a new atomic integer. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicI64; +///let atomic_forty_two = AtomicI64::new(42); +/// ``` + + #[lua()] + fn new(v: i64) -> LuaReflectValProxy; + +"#, + r#" +/// Consumes the atomic and returns the contained value. +/// This is safe because passing `self` by value guarantees that no other threads are +/// concurrently accessing the atomic data. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicI64; +///let some_var = AtomicI64::new(5); +/// assert_eq!(some_var.into_inner(), 5); +/// ``` + + #[lua()] + fn into_inner(_self: LuaReflectValProxy) -> i64; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct AtomicI64 {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "std::sync::atomic::AtomicI8", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Creates a new atomic integer. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicI8; +///let atomic_forty_two = AtomicI8::new(42); +/// ``` + + #[lua()] + fn new(v: i8) -> LuaReflectValProxy; + +"#, + r#" +/// Consumes the atomic and returns the contained value. +/// This is safe because passing `self` by value guarantees that no other threads are +/// concurrently accessing the atomic data. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicI8; +///let some_var = AtomicI8::new(5); +/// assert_eq!(some_var.into_inner(), 5); +/// ``` + + #[lua()] + fn into_inner(_self: LuaReflectValProxy) -> i8; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct AtomicI8 {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "std::sync::atomic::AtomicIsize", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Creates a new atomic integer. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicIsize; +///let atomic_forty_two = AtomicIsize::new(42); +/// ``` + + #[lua()] + fn new(v: isize) -> LuaReflectValProxy; + +"#, + r#" +/// Consumes the atomic and returns the contained value. +/// This is safe because passing `self` by value guarantees that no other threads are +/// concurrently accessing the atomic data. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicIsize; +///let some_var = AtomicIsize::new(5); +/// assert_eq!(some_var.into_inner(), 5); +/// ``` + + #[lua()] + fn into_inner(_self: LuaReflectValProxy) -> isize; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct AtomicIsize {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "std::sync::atomic::AtomicU16", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Creates a new atomic integer. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicU16; +///let atomic_forty_two = AtomicU16::new(42); +/// ``` + + #[lua()] + fn new(v: u16) -> LuaReflectValProxy; + +"#, + r#" +/// Consumes the atomic and returns the contained value. +/// This is safe because passing `self` by value guarantees that no other threads are +/// concurrently accessing the atomic data. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicU16; +///let some_var = AtomicU16::new(5); +/// assert_eq!(some_var.into_inner(), 5); +/// ``` + + #[lua()] + fn into_inner(_self: LuaReflectValProxy) -> u16; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct AtomicU16 {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "std::sync::atomic::AtomicU32", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Creates a new atomic integer. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicU32; +///let atomic_forty_two = AtomicU32::new(42); +/// ``` + + #[lua()] + fn new(v: u32) -> LuaReflectValProxy; + +"#, + r#" +/// Consumes the atomic and returns the contained value. +/// This is safe because passing `self` by value guarantees that no other threads are +/// concurrently accessing the atomic data. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicU32; +///let some_var = AtomicU32::new(5); +/// assert_eq!(some_var.into_inner(), 5); +/// ``` + + #[lua()] + fn into_inner(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct AtomicU32 {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "std::sync::atomic::AtomicU64", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Creates a new atomic integer. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicU64; +///let atomic_forty_two = AtomicU64::new(42); +/// ``` + + #[lua()] + fn new(v: u64) -> LuaReflectValProxy; + +"#, + r#" +/// Consumes the atomic and returns the contained value. +/// This is safe because passing `self` by value guarantees that no other threads are +/// concurrently accessing the atomic data. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicU64; +///let some_var = AtomicU64::new(5); +/// assert_eq!(some_var.into_inner(), 5); +/// ``` + + #[lua()] + fn into_inner(_self: LuaReflectValProxy) -> u64; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct AtomicU64 {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "std::sync::atomic::AtomicU8", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Creates a new atomic integer. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicU8; +///let atomic_forty_two = AtomicU8::new(42); +/// ``` + + #[lua()] + fn new(v: u8) -> LuaReflectValProxy; + +"#, + r#" +/// Consumes the atomic and returns the contained value. +/// This is safe because passing `self` by value guarantees that no other threads are +/// concurrently accessing the atomic data. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicU8; +///let some_var = AtomicU8::new(5); +/// assert_eq!(some_var.into_inner(), 5); +/// ``` + + #[lua()] + fn into_inner(_self: LuaReflectValProxy) -> u8; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct AtomicU8 {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "std::sync::atomic::AtomicUsize", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Creates a new atomic integer. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicUsize; +///let atomic_forty_two = AtomicUsize::new(42); +/// ``` + + #[lua()] + fn new(v: usize) -> LuaReflectValProxy; + +"#, + r#" +/// Consumes the atomic and returns the contained value. +/// This is safe because passing `self` by value guarantees that no other threads are +/// concurrently accessing the atomic data. +/// # Examples +/// ``` +///use std::sync::atomic::AtomicUsize; +///let some_var = AtomicUsize::new(5); +/// assert_eq!(some_var.into_inner(), 5); +/// ``` + + #[lua()] + fn into_inner(_self: LuaReflectValProxy) -> usize; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct AtomicUsize {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::utils::Duration", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: u32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> 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()] + fn new(secs: u64, nanos: u32) -> LuaReflectValProxy; + +"#, + 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()] + fn from_secs(secs: u64) -> LuaReflectValProxy; + +"#, + 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()] + fn from_millis(millis: u64) -> LuaReflectValProxy; + +"#, + 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()] + fn from_micros(micros: u64) -> LuaReflectValProxy; + +"#, + 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()] + fn from_nanos(nanos: u64) -> LuaReflectValProxy; + +"#, + 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()] + fn is_zero(_self: LuaReflectRefProxy) -> 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()] + fn as_secs(_self: LuaReflectRefProxy) -> 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()] + fn subsec_millis(_self: LuaReflectRefProxy) -> 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()] + fn subsec_micros(_self: LuaReflectRefProxy) -> 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()] + fn subsec_nanos(_self: LuaReflectRefProxy) -> 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()] + fn as_millis(_self: LuaReflectRefProxy) -> 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()] + fn as_micros(_self: LuaReflectRefProxy) -> 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()] + fn as_nanos(_self: LuaReflectRefProxy) -> 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()] + fn abs_diff( + _self: LuaReflectValProxy, + other: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_mul( + _self: LuaReflectValProxy, + rhs: u32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn as_secs_f64(_self: LuaReflectRefProxy) -> 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()] + fn as_secs_f32(_self: LuaReflectRefProxy) -> 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()] + fn from_secs_f64(secs: f64) -> LuaReflectValProxy; + +"#, + 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()] + fn from_secs_f32(secs: f32) -> LuaReflectValProxy; + +"#, + 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()] + fn mul_f64( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn mul_f32( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn div_f64( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn div_f32( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn div_duration_f64( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> 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()] + fn div_duration_f32( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f32; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: u32, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Duration {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::utils::Instant", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + other: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + other: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns an instant corresponding to "now". +/// # Examples +/// ``` +/// use std::time::Instant; +/// let now = Instant::now(); +/// ``` + + #[lua()] + fn now() -> LuaReflectValProxy; + +"#, + 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()] + fn duration_since( + _self: LuaReflectRefProxy, + earlier: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_duration_since( + _self: LuaReflectRefProxy, + earlier: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn elapsed( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + other: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Instant(); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "std::path::PathBuf", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Allocates an empty `PathBuf`. +/// # Examples +/// ``` +/// use std::path::PathBuf; +/// let path = PathBuf::new(); +/// ``` + + #[lua()] + fn new() -> LuaReflectValProxy; + +"#, + 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()] + fn with_capacity(capacity: usize) -> LuaReflectValProxy; + +"#, + 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()] + fn pop(_self: LuaReflectRefMutProxy) -> bool; + +"#, + r#" +/// Invokes [`capacity`] on the underlying instance of [`OsString`]. +/// [`capacity`]: OsString::capacity + + #[lua()] + fn capacity(_self: LuaReflectRefProxy) -> usize; + +"#, + r#" +/// Invokes [`clear`] on the underlying instance of [`OsString`]. +/// [`clear`]: OsString::clear + + #[lua()] + fn clear(_self: LuaReflectRefMutProxy) -> (); + +"#, + r#" +/// Invokes [`reserve`] on the underlying instance of [`OsString`]. +/// [`reserve`]: OsString::reserve + + #[lua()] + fn reserve( + _self: LuaReflectRefMutProxy, + additional: usize, + ) -> (); + +"#, + r#" +/// Invokes [`reserve_exact`] on the underlying instance of [`OsString`]. +/// [`reserve_exact`]: OsString::reserve_exact + + #[lua()] + fn reserve_exact( + _self: LuaReflectRefMutProxy, + additional: usize, + ) -> (); + +"#, + r#" +/// Invokes [`shrink_to_fit`] on the underlying instance of [`OsString`]. +/// [`shrink_to_fit`]: OsString::shrink_to_fit + + #[lua()] + fn shrink_to_fit(_self: LuaReflectRefMutProxy) -> (); + +"#, + r#" +/// Invokes [`shrink_to`] on the underlying instance of [`OsString`]. +/// [`shrink_to`]: OsString::shrink_to + + #[lua()] + fn shrink_to( + _self: LuaReflectRefMutProxy, + min_capacity: usize, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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")] + fn clone_from( + _self: LuaReflectRefMutProxy, + source: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct PathBuf {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "std::ops::RangeFull", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq(_self: LuaReflectRefProxy) -> (); + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct RangeFull {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::Quat", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + 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::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Multiplies a quaternion by a scalar value. +/// The product is not guaranteed to be normalized. + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_xyzw(x: f32, y: f32, z: f32, w: f32) -> LuaReflectValProxy; + +"#, + 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()] + fn from_array(a: [f32; 4]) -> LuaReflectValProxy; + +"#, + 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()] + fn from_vec4( + v: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_axis_angle( + axis: LuaReflectValProxy, + angle: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a quaternion that rotates `v.length()` radians around `v.normalize()`. +/// `from_scaled_axis(Vec3::ZERO)` results in the identity quaternion. + + #[lua()] + fn from_scaled_axis( + v: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a quaternion from the `angle` (in radians) around the x axis. + + #[lua()] + fn from_rotation_x(angle: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a quaternion from the `angle` (in radians) around the y axis. + + #[lua()] + fn from_rotation_y(angle: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a quaternion from the `angle` (in radians) around the z axis. + + #[lua()] + fn from_rotation_z(angle: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a quaternion from the given Euler rotation sequence and the angles (in radians). + + #[lua()] + fn from_euler( + euler: LuaReflectValProxy, + a: f32, + b: f32, + c: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat3( + mat: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat3a( + mat: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat4( + mat: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_rotation_arc( + from: LuaReflectValProxy, + to: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_rotation_arc_colinear( + from: LuaReflectValProxy, + to: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_rotation_arc_2d( + from: LuaReflectValProxy, + to: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the rotation axis scaled by the rotation in radians. + + #[lua()] + fn to_scaled_axis( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the rotation angles for the given euler rotation sequence. + + #[lua()] + fn to_euler( + _self: LuaReflectValProxy, + order: LuaReflectValProxy, + ) -> (f32, f32, f32); + +"#, + r#" +/// `[x, y, z, w]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [f32; 4]; + +"#, + r#" +/// Returns the vector part of the quaternion. + + #[lua()] + fn xyz( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the quaternion conjugate of `self`. For a unit quaternion the +/// conjugate is also the inverse. + + #[lua()] + fn conjugate( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn inverse( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f32; + +"#, + r#" +/// Computes the length of `self`. + + #[lua()] + fn length(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Computes the squared length of `self`. +/// This is generally faster than `length()` as it avoids a square +/// root operation. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Computes `1.0 / length()`. +/// For valid results, `self` must _not_ be of length zero. + + #[lua()] + fn length_recip(_self: LuaReflectValProxy) -> 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()] + fn normalize( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_finite(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +/// Returns `true` if any elements are `NAN`. + + #[lua()] + fn is_nan(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +/// Returns whether `self` of length `1.0` or not. +/// Uses a precision threshold of `1e-6`. + + #[lua()] + fn is_normalized(_self: LuaReflectValProxy) -> bool; + +"#, + r#" + + #[lua()] + fn is_near_identity(_self: LuaReflectValProxy) -> 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()] + fn angle_between( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> 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()] + fn rotate_towards( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + max_angle: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn abs_diff_eq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + 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()] + fn lerp( + _self: LuaReflectValProxy, + end: LuaReflectValProxy, + s: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn slerp( + _self: LuaReflectValProxy, + end: LuaReflectValProxy, + s: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn mul_vec3( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn mul_quat( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_affine3( + a: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Multiplies a quaternion and a 3D vector, returning the rotated vector. + + #[lua()] + fn mul_vec3a( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua()] + fn as_dquat( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Divides a quaternion by a scalar value. +/// The quotient is not guaranteed to be normalized. + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Subtracts the `rhs` quaternion from `self`. +/// The difference is not guaranteed to be normalized. + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Quat(); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::Vec3", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::Vec3>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::Vec3>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::Vec3>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: f32, y: f32, z: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: f32) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [f32; 3]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y, z]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [f32; 3]; + +"#, + r#" +/// Creates a 4D vector from `self` and the given `w` value. + + #[lua()] + fn extend( + _self: LuaReflectValProxy, + w: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn truncate( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `z`. + + #[lua()] + fn with_z( + _self: LuaReflectValProxy, + z: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f32; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the cross product of `self` and `rhs`. + + #[lua()] + fn cross( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the absolute value of each element of `self`. + + #[lua()] + fn abs( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn signum( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with signs of `rhs` and the magnitudes of `self`. + + #[lua()] + fn copysign( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_negative_bitmask(_self: LuaReflectValProxy) -> 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()] + fn is_finite(_self: LuaReflectValProxy) -> 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()] + fn is_finite_mask( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns `true` if any elements are `NaN`. + + #[lua()] + fn is_nan(_self: LuaReflectValProxy) -> 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()] + fn is_nan_mask( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the length of `self`. + + #[lua()] + fn length(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Computes the squared length of `self`. +/// This is faster than `length()` as it avoids a square root operation. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Computes `1.0 / length()`. +/// For valid results, `self` must _not_ be of length zero. + + #[lua()] + fn length_recip(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Computes the Euclidean distance between two points in space. + + #[lua()] + fn distance( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f32; + +"#, + r#" +/// Compute the squared euclidean distance between two points in space. + + #[lua()] + fn distance_squared( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f32; + +"#, + r#" +/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. + + #[lua()] + fn div_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. +/// [Euclidean division]: f32::rem_euclid + + #[lua()] + fn rem_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize_or( + _self: LuaReflectValProxy, + fallback: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize_or_zero( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns whether `self` is length `1.0` or not. +/// Uses a precision threshold of approximately `1e-4`. + + #[lua()] + fn is_normalized(_self: LuaReflectValProxy) -> 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()] + fn project_onto( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reject_from( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn project_onto_normalized( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reject_from_normalized( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn round( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the largest integer less than or equal to a number for each +/// element of `self`. + + #[lua()] + fn floor( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the smallest integer greater than or equal to a number for +/// each element of `self`. + + #[lua()] + fn ceil( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the integer part each element of `self`. This means numbers are +/// always truncated towards zero. + + #[lua()] + fn trunc( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn fract( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn fract_gl( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing `e^self` (the exponential function) for each element of +/// `self`. + + #[lua()] + fn exp( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing each element of `self` raised to the power of `n`. + + #[lua()] + fn powf( + _self: LuaReflectValProxy, + n: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the reciprocal `1.0/n` of each element of `self`. + + #[lua()] + fn recip( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn lerp( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + s: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn move_towards( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + d: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn midpoint( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn abs_diff_eq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + 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()] + fn clamp_length( + _self: LuaReflectValProxy, + min: f32, + max: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with a length no more than `max`. +/// # Panics +/// Will panic if `max` is negative when `glam_assert` is enabled. + + #[lua()] + fn clamp_length_max( + _self: LuaReflectValProxy, + max: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with a length no less than `min`. +/// # Panics +/// Will panic if `min` is negative when `glam_assert` is enabled. + + #[lua()] + fn clamp_length_min( + _self: LuaReflectValProxy, + min: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn mul_add( + _self: LuaReflectValProxy, + a: LuaReflectValProxy, + b: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reflect( + _self: LuaReflectValProxy, + normal: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn refract( + _self: LuaReflectValProxy, + normal: LuaReflectValProxy, + eta: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn angle_between( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> 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()] + fn any_orthogonal_vector( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn any_orthonormal_vector( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f64`. + + #[lua()] + fn as_dvec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i32`. + + #[lua()] + fn as_ivec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u32`. + + #[lua()] + fn as_uvec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i64`. + + #[lua()] + fn as_i64vec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u64`. + + #[lua()] + fn as_u64vec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::Vec3>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::Vec3>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(self, idx: usize) -> LuaIdentityProxy { + _self[idx - 1] +} +"#, + r#" +#[lua(metamethod="NewIndex")] +fn index(&mut self, idx: usize, val: f32) -> () { + _self[idx - 1] = val +} +"#] +)] +pub struct Vec3 { + x: f32, + y: f32, + z: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::IVec2", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::IVec2>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: i32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: i32, y: i32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: i32) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [i32; 2]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [i32; 2]; + +"#, + r#" +/// Creates a 3D vector from `self` and the given `z` value. + + #[lua()] + fn extend( + _self: LuaReflectValProxy, + z: i32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: i32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: i32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> i32; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> i32; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> i32; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> i32; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the absolute value of each element of `self`. + + #[lua()] + fn abs( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn signum( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_negative_bitmask(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Computes the squared length of `self`. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> i32; + +"#, + r#" +/// Compute the squared euclidean distance between two points in space. + + #[lua()] + fn distance_squared( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> 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()] + fn div_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn rem_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector that is equal to `self` rotated by 90 degrees. + + #[lua()] + fn perp( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// The perpendicular dot product of `self` and `rhs`. +/// Also known as the wedge product, 2D cross product, and determinant. + + #[lua()] + fn perp_dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> 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()] + fn rotate( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f64`. + + #[lua()] + fn as_dvec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u32`. + + #[lua()] + fn as_uvec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i64`. + + #[lua()] + fn as_i64vec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u64`. + + #[lua()] + fn as_u64vec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_sub_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// In other words this computes `[self.x.saturating_add_unsigned(rhs.x), self.y.saturating_add_unsigned(rhs.y), ..]`. + + #[lua()] + fn saturating_add_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: i32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::IVec2>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: i32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::IVec2>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::IVec2>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: i32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::IVec2>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: i32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq(_self: LuaReflectRefProxy) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(self, idx: usize) -> LuaIdentityProxy { + _self[idx - 1] +} +"#, + r#" +#[lua(metamethod="NewIndex")] +fn index(&mut self, idx: usize, val: i32) -> () { + _self[idx - 1] = val +} +"#] +)] +pub struct IVec2 { + x: i32, + y: i32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::IVec3", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::IVec3>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: i32, y: i32, z: i32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: i32) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [i32; 3]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y, z]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [i32; 3]; + +"#, + r#" +/// Creates a 4D vector from `self` and the given `w` value. + + #[lua()] + fn extend( + _self: LuaReflectValProxy, + w: i32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn truncate( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: i32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: i32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `z`. + + #[lua()] + fn with_z( + _self: LuaReflectValProxy, + z: i32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> i32; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the cross product of `self` and `rhs`. + + #[lua()] + fn cross( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> i32; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> i32; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> i32; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the absolute value of each element of `self`. + + #[lua()] + fn abs( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn signum( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_negative_bitmask(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Computes the squared length of `self`. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> i32; + +"#, + r#" +/// Compute the squared euclidean distance between two points in space. + + #[lua()] + fn distance_squared( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> 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()] + fn div_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn rem_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec3a( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f64`. + + #[lua()] + fn as_dvec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u32`. + + #[lua()] + fn as_uvec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i64`. + + #[lua()] + fn as_i64vec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u64`. + + #[lua()] + fn as_u64vec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_sub_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// In other words this computes `[self.x.saturating_add_unsigned(rhs.x), self.y.saturating_add_unsigned(rhs.y), ..]`. + + #[lua()] + fn saturating_add_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq(_self: LuaReflectRefProxy) -> (); + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::IVec3>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::IVec3>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: i32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: i32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::IVec3>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: i32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::IVec3>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: i32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: i32, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(self, idx: usize) -> LuaIdentityProxy { + _self[idx - 1] +} +"#, + r#" +#[lua(metamethod="NewIndex")] +fn index(&mut self, idx: usize, val: i32) -> () { + _self[idx - 1] = val +} +"#] +)] +pub struct IVec3 { + x: i32, + y: i32, + z: i32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::IVec4", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq(_self: LuaReflectRefProxy) -> (); + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: i32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::IVec4>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: i32, y: i32, z: i32, w: i32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: i32) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [i32; 4]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y, z, w]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [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()] + fn truncate( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: i32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: i32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `z`. + + #[lua()] + fn with_z( + _self: LuaReflectValProxy, + z: i32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `w`. + + #[lua()] + fn with_w( + _self: LuaReflectValProxy, + w: i32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> i32; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> i32; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> i32; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> i32; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the absolute value of each element of `self`. + + #[lua()] + fn abs( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn signum( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_negative_bitmask(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Computes the squared length of `self`. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> i32; + +"#, + r#" +/// Compute the squared euclidean distance between two points in space. + + #[lua()] + fn distance_squared( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> 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()] + fn div_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn rem_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f64`. + + #[lua()] + fn as_dvec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u32`. + + #[lua()] + fn as_uvec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i64`. + + #[lua()] + fn as_i64vec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u64`. + + #[lua()] + fn as_u64vec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_sub_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// In other words this computes `[self.x.saturating_add_unsigned(rhs.x), self.y.saturating_add_unsigned(rhs.y), ..]`. + + #[lua()] + fn saturating_add_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: i32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: i32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::IVec4>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: i32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::IVec4>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: i32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::IVec4>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::IVec4>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(self, idx: usize) -> LuaIdentityProxy { + _self[idx - 1] +} +"#, + r#" +#[lua(metamethod="NewIndex")] +fn index(&mut self, idx: usize, val: i32) -> () { + _self[idx - 1] = val +} +"#] +)] +pub struct IVec4 { + x: i32, + y: i32, + z: i32, + w: i32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::I64Vec2", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: i64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::I64Vec2>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: i64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::I64Vec2>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: i64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: i64, y: i64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: i64) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [i64; 2]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [i64; 2]; + +"#, + r#" +/// Creates a 3D vector from `self` and the given `z` value. + + #[lua()] + fn extend( + _self: LuaReflectValProxy, + z: i64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: i64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: i64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> i64; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> i64; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> i64; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> i64; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the absolute value of each element of `self`. + + #[lua()] + fn abs( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn signum( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_negative_bitmask(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Computes the squared length of `self`. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> i64; + +"#, + r#" +/// Compute the squared euclidean distance between two points in space. + + #[lua()] + fn distance_squared( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> 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()] + fn div_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn rem_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector that is equal to `self` rotated by 90 degrees. + + #[lua()] + fn perp( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// The perpendicular dot product of `self` and `rhs`. +/// Also known as the wedge product, 2D cross product, and determinant. + + #[lua()] + fn perp_dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> 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()] + fn rotate( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f64`. + + #[lua()] + fn as_dvec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i32`. + + #[lua()] + fn as_ivec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u32`. + + #[lua()] + fn as_uvec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u64`. + + #[lua()] + fn as_u64vec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_sub_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// In other words this computes `[self.x.saturating_add_unsigned(rhs.x), self.y.saturating_add_unsigned(rhs.y), ..]`. + + #[lua()] + fn saturating_add_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: i64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::I64Vec2>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::I64Vec2>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: i64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq(_self: LuaReflectRefProxy) -> (); + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::I64Vec2>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct I64Vec2 { + x: i64, + y: i64, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::I64Vec3", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: i64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::I64Vec3>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::I64Vec3>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: i64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::I64Vec3>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: i64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: i64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq(_self: LuaReflectRefProxy) -> (); + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: i64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::I64Vec3>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::I64Vec3>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: i64, y: i64, z: i64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: i64) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [i64; 3]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y, z]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [i64; 3]; + +"#, + r#" +/// Creates a 4D vector from `self` and the given `w` value. + + #[lua()] + fn extend( + _self: LuaReflectValProxy, + w: i64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn truncate( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: i64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: i64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `z`. + + #[lua()] + fn with_z( + _self: LuaReflectValProxy, + z: i64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> i64; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the cross product of `self` and `rhs`. + + #[lua()] + fn cross( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> i64; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> i64; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> i64; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the absolute value of each element of `self`. + + #[lua()] + fn abs( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn signum( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_negative_bitmask(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Computes the squared length of `self`. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> i64; + +"#, + r#" +/// Compute the squared euclidean distance between two points in space. + + #[lua()] + fn distance_squared( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> 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()] + fn div_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn rem_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec3a( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f64`. + + #[lua()] + fn as_dvec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i32`. + + #[lua()] + fn as_ivec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u32`. + + #[lua()] + fn as_uvec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u64`. + + #[lua()] + fn as_u64vec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_sub_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// In other words this computes `[self.x.saturating_add_unsigned(rhs.x), self.y.saturating_add_unsigned(rhs.y), ..]`. + + #[lua()] + fn saturating_add_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct I64Vec3 { + x: i64, + y: i64, + z: i64, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::I64Vec4", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: i64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::I64Vec4>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: i64, y: i64, z: i64, w: i64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: i64) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [i64; 4]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y, z, w]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [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()] + fn truncate( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: i64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: i64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `z`. + + #[lua()] + fn with_z( + _self: LuaReflectValProxy, + z: i64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `w`. + + #[lua()] + fn with_w( + _self: LuaReflectValProxy, + w: i64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> i64; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> i64; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> i64; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> i64; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the absolute value of each element of `self`. + + #[lua()] + fn abs( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn signum( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_negative_bitmask(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Computes the squared length of `self`. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> i64; + +"#, + r#" +/// Compute the squared euclidean distance between two points in space. + + #[lua()] + fn distance_squared( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> 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()] + fn div_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn rem_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f64`. + + #[lua()] + fn as_dvec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i32`. + + #[lua()] + fn as_ivec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u32`. + + #[lua()] + fn as_uvec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u64`. + + #[lua()] + fn as_u64vec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_sub_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// In other words this computes `[self.x.saturating_add_unsigned(rhs.x), self.y.saturating_add_unsigned(rhs.y), ..]`. + + #[lua()] + fn saturating_add_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub_unsigned( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::I64Vec4>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::I64Vec4>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: i64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq(_self: LuaReflectRefProxy) -> (); + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: i64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::I64Vec4>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: i64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: i64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::I64Vec4>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct I64Vec4 { + x: i64, + y: i64, + z: i64, + w: i64, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::UVec2", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::UVec2>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq(_self: LuaReflectRefProxy) -> (); + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::UVec2>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: u32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: u32, y: u32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: u32) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [u32; 2]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [u32; 2]; + +"#, + r#" +/// Creates a 3D vector from `self` and the given `z` value. + + #[lua()] + fn extend( + _self: LuaReflectValProxy, + z: u32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: u32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: u32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> u32; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the squared length of `self`. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f64`. + + #[lua()] + fn as_dvec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i32`. + + #[lua()] + fn as_ivec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i64`. + + #[lua()] + fn as_i64vec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u64`. + + #[lua()] + fn as_u64vec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add_signed( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add_signed( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::UVec2>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: u32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::UVec2>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: u32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: u32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::UVec2>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: u32, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(self, idx: usize) -> LuaIdentityProxy { + _self[idx - 1] +} +"#, + r#" +#[lua(metamethod="NewIndex")] +fn index(&mut self, idx: usize, val: u32) -> () { + _self[idx - 1] = val +} +"#] +)] +pub struct UVec2 { + x: u32, + y: u32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::UVec3", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::UVec3>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq(_self: LuaReflectRefProxy) -> (); + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: u32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: u32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::UVec3>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: u32, y: u32, z: u32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: u32) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [u32; 3]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y, z]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [u32; 3]; + +"#, + r#" +/// Creates a 4D vector from `self` and the given `w` value. + + #[lua()] + fn extend( + _self: LuaReflectValProxy, + w: u32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn truncate( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: u32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: u32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `z`. + + #[lua()] + fn with_z( + _self: LuaReflectValProxy, + z: u32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> u32; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the cross product of `self` and `rhs`. + + #[lua()] + fn cross( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the squared length of `self`. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec3a( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f64`. + + #[lua()] + fn as_dvec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i32`. + + #[lua()] + fn as_ivec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i64`. + + #[lua()] + fn as_i64vec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u64`. + + #[lua()] + fn as_u64vec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add_signed( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add_signed( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: u32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::UVec3>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: u32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::UVec3>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: u32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::UVec3>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(self, idx: usize) -> LuaIdentityProxy { + _self[idx - 1] +} +"#, + r#" +#[lua(metamethod="NewIndex")] +fn index(&mut self, idx: usize, val: u32) -> () { + _self[idx - 1] = val +} +"#] +)] +pub struct UVec3 { + x: u32, + y: u32, + z: u32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::UVec4", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::UVec4>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: u32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq(_self: LuaReflectRefProxy) -> (); + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: u32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: u32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::UVec4>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::UVec4>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::UVec4>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: u32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::UVec4>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: u32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: u32, y: u32, z: u32, w: u32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: u32) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [u32; 4]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y, z, w]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [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()] + fn truncate( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: u32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: u32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `z`. + + #[lua()] + fn with_z( + _self: LuaReflectValProxy, + z: u32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `w`. + + #[lua()] + fn with_w( + _self: LuaReflectValProxy, + w: u32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> u32; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the squared length of `self`. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f64`. + + #[lua()] + fn as_dvec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i32`. + + #[lua()] + fn as_ivec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i64`. + + #[lua()] + fn as_i64vec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u64`. + + #[lua()] + fn as_u64vec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add_signed( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add_signed( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(self, idx: usize) -> LuaIdentityProxy { + _self[idx - 1] +} +"#, + r#" +#[lua(metamethod="NewIndex")] +fn index(&mut self, idx: usize, val: u32) -> () { + _self[idx - 1] = val +} +"#] +)] +pub struct UVec4 { + x: u32, + y: u32, + z: u32, + w: u32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::U64Vec2", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::U64Vec2>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: u64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::U64Vec2>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::U64Vec2>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::U64Vec2>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: u64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::U64Vec2>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq(_self: LuaReflectRefProxy) -> (); + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: u64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: u64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: u64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: u64, y: u64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: u64) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [u64; 2]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [u64; 2]; + +"#, + r#" +/// Creates a 3D vector from `self` and the given `z` value. + + #[lua()] + fn extend( + _self: LuaReflectValProxy, + z: u64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: u64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: u64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> u64; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> u64; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> u64; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> u64; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the squared length of `self`. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> u64; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f64`. + + #[lua()] + fn as_dvec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i32`. + + #[lua()] + fn as_ivec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u32`. + + #[lua()] + fn as_uvec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i64`. + + #[lua()] + fn as_i64vec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add_signed( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add_signed( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct U64Vec2 { + x: u64, + y: u64, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::U64Vec3", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: u64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: u64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: u64, y: u64, z: u64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: u64) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [u64; 3]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y, z]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [u64; 3]; + +"#, + r#" +/// Creates a 4D vector from `self` and the given `w` value. + + #[lua()] + fn extend( + _self: LuaReflectValProxy, + w: u64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn truncate( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: u64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: u64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `z`. + + #[lua()] + fn with_z( + _self: LuaReflectValProxy, + z: u64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> u64; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the cross product of `self` and `rhs`. + + #[lua()] + fn cross( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> u64; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> u64; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> u64; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the squared length of `self`. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> u64; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec3a( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f64`. + + #[lua()] + fn as_dvec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i32`. + + #[lua()] + fn as_ivec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u32`. + + #[lua()] + fn as_uvec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i64`. + + #[lua()] + fn as_i64vec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add_signed( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add_signed( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::U64Vec3>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: u64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::U64Vec3>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::U64Vec3>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: u64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq(_self: LuaReflectRefProxy) -> (); + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::U64Vec3>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::U64Vec3>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: u64, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct U64Vec3 { + x: u64, + y: u64, + z: u64, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::U64Vec4", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq(_self: LuaReflectRefProxy) -> (); + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: u64, y: u64, z: u64, w: u64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: u64) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [u64; 4]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y, z, w]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [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()] + fn truncate( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: u64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: u64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `z`. + + #[lua()] + fn with_z( + _self: LuaReflectValProxy, + z: u64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `w`. + + #[lua()] + fn with_w( + _self: LuaReflectValProxy, + w: u64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> u64; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> u64; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> u64; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> u64; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the squared length of `self`. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> u64; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f64`. + + #[lua()] + fn as_dvec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i32`. + + #[lua()] + fn as_ivec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u32`. + + #[lua()] + fn as_uvec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i64`. + + #[lua()] + fn as_i64vec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn wrapping_add_signed( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn saturating_add_signed( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: u64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::U64Vec4>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::U64Vec4>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: u64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::U64Vec4>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: u64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::U64Vec4>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: u64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::U64Vec4>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: u64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct U64Vec4 { + x: u64, + y: u64, + z: u64, + w: u64, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::Vec2", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::Vec2>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::Vec2>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::Vec2>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::Vec2>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: f32, y: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: f32) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [f32; 2]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [f32; 2]; + +"#, + r#" +/// Creates a 3D vector from `self` and the given `z` value. + + #[lua()] + fn extend( + _self: LuaReflectValProxy, + z: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f32; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the absolute value of each element of `self`. + + #[lua()] + fn abs( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn signum( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with signs of `rhs` and the magnitudes of `self`. + + #[lua()] + fn copysign( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_negative_bitmask(_self: LuaReflectValProxy) -> 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()] + fn is_finite(_self: LuaReflectValProxy) -> 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()] + fn is_finite_mask( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns `true` if any elements are `NaN`. + + #[lua()] + fn is_nan(_self: LuaReflectValProxy) -> 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()] + fn is_nan_mask( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the length of `self`. + + #[lua()] + fn length(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Computes the squared length of `self`. +/// This is faster than `length()` as it avoids a square root operation. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Computes `1.0 / length()`. +/// For valid results, `self` must _not_ be of length zero. + + #[lua()] + fn length_recip(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Computes the Euclidean distance between two points in space. + + #[lua()] + fn distance( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f32; + +"#, + r#" +/// Compute the squared euclidean distance between two points in space. + + #[lua()] + fn distance_squared( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f32; + +"#, + r#" +/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. + + #[lua()] + fn div_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. +/// [Euclidean division]: f32::rem_euclid + + #[lua()] + fn rem_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize_or( + _self: LuaReflectValProxy, + fallback: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize_or_zero( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns whether `self` is length `1.0` or not. +/// Uses a precision threshold of approximately `1e-4`. + + #[lua()] + fn is_normalized(_self: LuaReflectValProxy) -> 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()] + fn project_onto( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reject_from( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn project_onto_normalized( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reject_from_normalized( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn round( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the largest integer less than or equal to a number for each +/// element of `self`. + + #[lua()] + fn floor( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the smallest integer greater than or equal to a number for +/// each element of `self`. + + #[lua()] + fn ceil( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the integer part each element of `self`. This means numbers are +/// always truncated towards zero. + + #[lua()] + fn trunc( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn fract( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn fract_gl( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing `e^self` (the exponential function) for each element of +/// `self`. + + #[lua()] + fn exp( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing each element of `self` raised to the power of `n`. + + #[lua()] + fn powf( + _self: LuaReflectValProxy, + n: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the reciprocal `1.0/n` of each element of `self`. + + #[lua()] + fn recip( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn lerp( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + s: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn move_towards( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + d: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn midpoint( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn abs_diff_eq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + 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()] + fn clamp_length( + _self: LuaReflectValProxy, + min: f32, + max: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with a length no more than `max`. +/// # Panics +/// Will panic if `max` is negative when `glam_assert` is enabled. + + #[lua()] + fn clamp_length_max( + _self: LuaReflectValProxy, + max: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with a length no less than `min`. +/// # Panics +/// Will panic if `min` is negative when `glam_assert` is enabled. + + #[lua()] + fn clamp_length_min( + _self: LuaReflectValProxy, + min: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn mul_add( + _self: LuaReflectValProxy, + a: LuaReflectValProxy, + b: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reflect( + _self: LuaReflectValProxy, + normal: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn refract( + _self: LuaReflectValProxy, + normal: LuaReflectValProxy, + eta: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_angle(angle: f32) -> LuaReflectValProxy; + +"#, + 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()] + fn to_angle(_self: LuaReflectValProxy) -> f32; + +"#, + r#" + + #[lua()] + fn angle_between( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> 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()] + fn angle_to( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f32; + +"#, + r#" +/// Returns a vector that is equal to `self` rotated by 90 degrees. + + #[lua()] + fn perp( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// The perpendicular dot product of `self` and `rhs`. +/// Also known as the wedge product, 2D cross product, and determinant. + + #[lua()] + fn perp_dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> 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()] + fn rotate( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn rotate_towards( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + max_angle: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f64`. + + #[lua()] + fn as_dvec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i32`. + + #[lua()] + fn as_ivec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u32`. + + #[lua()] + fn as_uvec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i64`. + + #[lua()] + fn as_i64vec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u64`. + + #[lua()] + fn as_u64vec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::Vec2>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(self, idx: usize) -> LuaIdentityProxy { + _self[idx - 1] +} +"#, + r#" +#[lua(metamethod="NewIndex")] +fn index(&mut self, idx: usize, val: f32) -> () { + _self[idx - 1] = val +} +"#] +)] +pub struct Vec2 { + x: f32, + y: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::Vec3A", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::Vec3A>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::Vec3A>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::Vec3A>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::Vec3A>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::Vec3A>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: f32, y: f32, z: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: f32) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [f32; 3]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y, z]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [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()] + fn from_vec4( + v: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` and the given `w` value. + + #[lua()] + fn extend( + _self: LuaReflectValProxy, + w: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn truncate( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `z`. + + #[lua()] + fn with_z( + _self: LuaReflectValProxy, + z: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f32; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the cross product of `self` and `rhs`. + + #[lua()] + fn cross( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the absolute value of each element of `self`. + + #[lua()] + fn abs( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn signum( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with signs of `rhs` and the magnitudes of `self`. + + #[lua()] + fn copysign( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_negative_bitmask(_self: LuaReflectValProxy) -> 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()] + fn is_finite(_self: LuaReflectValProxy) -> 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()] + fn is_finite_mask( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns `true` if any elements are `NaN`. + + #[lua()] + fn is_nan(_self: LuaReflectValProxy) -> 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()] + fn is_nan_mask( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the length of `self`. + + #[lua()] + fn length(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Computes the squared length of `self`. +/// This is faster than `length()` as it avoids a square root operation. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Computes `1.0 / length()`. +/// For valid results, `self` must _not_ be of length zero. + + #[lua()] + fn length_recip(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Computes the Euclidean distance between two points in space. + + #[lua()] + fn distance( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f32; + +"#, + r#" +/// Compute the squared euclidean distance between two points in space. + + #[lua()] + fn distance_squared( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f32; + +"#, + r#" +/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. + + #[lua()] + fn div_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. +/// [Euclidean division]: f32::rem_euclid + + #[lua()] + fn rem_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize_or( + _self: LuaReflectValProxy, + fallback: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize_or_zero( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns whether `self` is length `1.0` or not. +/// Uses a precision threshold of approximately `1e-4`. + + #[lua()] + fn is_normalized(_self: LuaReflectValProxy) -> 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()] + fn project_onto( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reject_from( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn project_onto_normalized( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reject_from_normalized( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn round( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the largest integer less than or equal to a number for each +/// element of `self`. + + #[lua()] + fn floor( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the smallest integer greater than or equal to a number for +/// each element of `self`. + + #[lua()] + fn ceil( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the integer part each element of `self`. This means numbers are +/// always truncated towards zero. + + #[lua()] + fn trunc( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn fract( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn fract_gl( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing `e^self` (the exponential function) for each element of +/// `self`. + + #[lua()] + fn exp( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing each element of `self` raised to the power of `n`. + + #[lua()] + fn powf( + _self: LuaReflectValProxy, + n: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the reciprocal `1.0/n` of each element of `self`. + + #[lua()] + fn recip( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn lerp( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + s: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn move_towards( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + d: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn midpoint( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn abs_diff_eq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + 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()] + fn clamp_length( + _self: LuaReflectValProxy, + min: f32, + max: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with a length no more than `max`. +/// # Panics +/// Will panic if `max` is negative when `glam_assert` is enabled. + + #[lua()] + fn clamp_length_max( + _self: LuaReflectValProxy, + max: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with a length no less than `min`. +/// # Panics +/// Will panic if `min` is negative when `glam_assert` is enabled. + + #[lua()] + fn clamp_length_min( + _self: LuaReflectValProxy, + min: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn mul_add( + _self: LuaReflectValProxy, + a: LuaReflectValProxy, + b: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reflect( + _self: LuaReflectValProxy, + normal: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn refract( + _self: LuaReflectValProxy, + normal: LuaReflectValProxy, + eta: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn angle_between( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> 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()] + fn any_orthogonal_vector( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn any_orthonormal_vector( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f64`. + + #[lua()] + fn as_dvec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i32`. + + #[lua()] + fn as_ivec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u32`. + + #[lua()] + fn as_uvec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i64`. + + #[lua()] + fn as_i64vec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u64`. + + #[lua()] + fn as_u64vec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(self, idx: usize) -> LuaIdentityProxy { + _self[idx - 1] +} +"#, + r#" +#[lua(metamethod="NewIndex")] +fn index(&mut self, idx: usize, val: f32) -> () { + _self[idx - 1] = val +} +"#] +)] +pub struct Vec3A(); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::Vec4", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::Vec4>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::Vec4>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::Vec4>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::Vec4>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: f32, y: f32, z: f32, w: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: f32) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [f32; 4]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y, z, w]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [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()] + fn truncate( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `z`. + + #[lua()] + fn with_z( + _self: LuaReflectValProxy, + z: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `w`. + + #[lua()] + fn with_w( + _self: LuaReflectValProxy, + w: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f32; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the absolute value of each element of `self`. + + #[lua()] + fn abs( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn signum( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with signs of `rhs` and the magnitudes of `self`. + + #[lua()] + fn copysign( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_negative_bitmask(_self: LuaReflectValProxy) -> 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()] + fn is_finite(_self: LuaReflectValProxy) -> 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()] + fn is_finite_mask( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns `true` if any elements are `NaN`. + + #[lua()] + fn is_nan(_self: LuaReflectValProxy) -> 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()] + fn is_nan_mask( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the length of `self`. + + #[lua()] + fn length(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Computes the squared length of `self`. +/// This is faster than `length()` as it avoids a square root operation. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Computes `1.0 / length()`. +/// For valid results, `self` must _not_ be of length zero. + + #[lua()] + fn length_recip(_self: LuaReflectValProxy) -> f32; + +"#, + r#" +/// Computes the Euclidean distance between two points in space. + + #[lua()] + fn distance( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f32; + +"#, + r#" +/// Compute the squared euclidean distance between two points in space. + + #[lua()] + fn distance_squared( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f32; + +"#, + r#" +/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. + + #[lua()] + fn div_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. +/// [Euclidean division]: f32::rem_euclid + + #[lua()] + fn rem_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize_or( + _self: LuaReflectValProxy, + fallback: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize_or_zero( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns whether `self` is length `1.0` or not. +/// Uses a precision threshold of approximately `1e-4`. + + #[lua()] + fn is_normalized(_self: LuaReflectValProxy) -> 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()] + fn project_onto( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reject_from( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn project_onto_normalized( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reject_from_normalized( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn round( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the largest integer less than or equal to a number for each +/// element of `self`. + + #[lua()] + fn floor( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the smallest integer greater than or equal to a number for +/// each element of `self`. + + #[lua()] + fn ceil( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the integer part each element of `self`. This means numbers are +/// always truncated towards zero. + + #[lua()] + fn trunc( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn fract( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn fract_gl( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing `e^self` (the exponential function) for each element of +/// `self`. + + #[lua()] + fn exp( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing each element of `self` raised to the power of `n`. + + #[lua()] + fn powf( + _self: LuaReflectValProxy, + n: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the reciprocal `1.0/n` of each element of `self`. + + #[lua()] + fn recip( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn lerp( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + s: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn move_towards( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + d: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn midpoint( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn abs_diff_eq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + 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()] + fn clamp_length( + _self: LuaReflectValProxy, + min: f32, + max: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with a length no more than `max`. +/// # Panics +/// Will panic if `max` is negative when `glam_assert` is enabled. + + #[lua()] + fn clamp_length_max( + _self: LuaReflectValProxy, + max: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with a length no less than `min`. +/// # Panics +/// Will panic if `min` is negative when `glam_assert` is enabled. + + #[lua()] + fn clamp_length_min( + _self: LuaReflectValProxy, + min: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn mul_add( + _self: LuaReflectValProxy, + a: LuaReflectValProxy, + b: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reflect( + _self: LuaReflectValProxy, + normal: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn refract( + _self: LuaReflectValProxy, + normal: LuaReflectValProxy, + eta: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f64`. + + #[lua()] + fn as_dvec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i32`. + + #[lua()] + fn as_ivec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u32`. + + #[lua()] + fn as_uvec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i64`. + + #[lua()] + fn as_i64vec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u64`. + + #[lua()] + fn as_u64vec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::Vec4>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(self, idx: usize) -> LuaIdentityProxy { + _self[idx - 1] +} +"#, + r#" +#[lua(metamethod="NewIndex")] +fn index(&mut self, idx: usize, val: f32) -> () { + _self[idx - 1] = val +} +"#] +)] +pub struct Vec4(); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::BVec2", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Creates a new vector mask. + + #[lua()] + fn new(x: bool, y: bool) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector mask with all elements set to `v`. + + #[lua()] + fn splat(v: bool) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector mask from a bool array. + + #[lua()] + fn from_array(a: [bool; 2]) -> LuaReflectValProxy; + +"#, + 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()] + fn bitmask(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Returns true if any of the elements are true, false otherwise. + + #[lua()] + fn any(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +/// Returns true if all the elements are true, false otherwise. + + #[lua()] + fn all(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +/// Tests the value at `index`. +/// Panics if `index` is greater than 1. + + #[lua()] + fn test(_self: LuaReflectRefProxy, index: usize) -> bool; + +"#, + r#" +/// Sets the element at `index`. +/// Panics if `index` is greater than 1. + + #[lua()] + fn set( + _self: LuaReflectRefMutProxy, + index: usize, + value: bool, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq(_self: LuaReflectRefProxy) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct BVec2 { + x: bool, + y: bool, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::BVec3", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector mask. + + #[lua()] + fn new(x: bool, y: bool, z: bool) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector mask with all elements set to `v`. + + #[lua()] + fn splat(v: bool) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector mask from a bool array. + + #[lua()] + fn from_array(a: [bool; 3]) -> LuaReflectValProxy; + +"#, + 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()] + fn bitmask(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Returns true if any of the elements are true, false otherwise. + + #[lua()] + fn any(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +/// Returns true if all the elements are true, false otherwise. + + #[lua()] + fn all(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +/// Tests the value at `index`. +/// Panics if `index` is greater than 2. + + #[lua()] + fn test(_self: LuaReflectRefProxy, index: usize) -> bool; + +"#, + r#" +/// Sets the element at `index`. +/// Panics if `index` is greater than 2. + + #[lua()] + fn set( + _self: LuaReflectRefMutProxy, + index: usize, + value: bool, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq(_self: LuaReflectRefProxy) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct BVec3 { + x: bool, + y: bool, + z: bool, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::BVec4", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq(_self: LuaReflectRefProxy) -> (); + +"#, + r#" +/// Creates a new vector mask. + + #[lua()] + fn new(x: bool, y: bool, z: bool, w: bool) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector mask with all elements set to `v`. + + #[lua()] + fn splat(v: bool) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector mask from a bool array. + + #[lua()] + fn from_array(a: [bool; 4]) -> LuaReflectValProxy; + +"#, + 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()] + fn bitmask(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Returns true if any of the elements are true, false otherwise. + + #[lua()] + fn any(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +/// Returns true if all the elements are true, false otherwise. + + #[lua()] + fn all(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +/// Tests the value at `index`. +/// Panics if `index` is greater than 3. + + #[lua()] + fn test(_self: LuaReflectRefProxy, index: usize) -> bool; + +"#, + r#" +/// Sets the element at `index`. +/// Panics if `index` is greater than 3. + + #[lua()] + fn set( + _self: LuaReflectRefMutProxy, + index: usize, + value: bool, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct BVec4 { + x: bool, + y: bool, + z: bool, + w: bool, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::DVec2", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::DVec2>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::DVec2>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: f64, y: f64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: f64) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [f64; 2]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [f64; 2]; + +"#, + r#" +/// Creates a 3D vector from `self` and the given `z` value. + + #[lua()] + fn extend( + _self: LuaReflectValProxy, + z: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f64; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the absolute value of each element of `self`. + + #[lua()] + fn abs( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn signum( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with signs of `rhs` and the magnitudes of `self`. + + #[lua()] + fn copysign( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_negative_bitmask(_self: LuaReflectValProxy) -> 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()] + fn is_finite(_self: LuaReflectValProxy) -> 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()] + fn is_finite_mask( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns `true` if any elements are `NaN`. + + #[lua()] + fn is_nan(_self: LuaReflectValProxy) -> 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()] + fn is_nan_mask( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the length of `self`. + + #[lua()] + fn length(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Computes the squared length of `self`. +/// This is faster than `length()` as it avoids a square root operation. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Computes `1.0 / length()`. +/// For valid results, `self` must _not_ be of length zero. + + #[lua()] + fn length_recip(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Computes the Euclidean distance between two points in space. + + #[lua()] + fn distance( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f64; + +"#, + r#" +/// Compute the squared euclidean distance between two points in space. + + #[lua()] + fn distance_squared( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f64; + +"#, + r#" +/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. + + #[lua()] + fn div_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. +/// [Euclidean division]: f64::rem_euclid + + #[lua()] + fn rem_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize_or( + _self: LuaReflectValProxy, + fallback: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize_or_zero( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns whether `self` is length `1.0` or not. +/// Uses a precision threshold of approximately `1e-4`. + + #[lua()] + fn is_normalized(_self: LuaReflectValProxy) -> 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()] + fn project_onto( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reject_from( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn project_onto_normalized( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reject_from_normalized( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn round( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the largest integer less than or equal to a number for each +/// element of `self`. + + #[lua()] + fn floor( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the smallest integer greater than or equal to a number for +/// each element of `self`. + + #[lua()] + fn ceil( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the integer part each element of `self`. This means numbers are +/// always truncated towards zero. + + #[lua()] + fn trunc( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn fract( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn fract_gl( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing `e^self` (the exponential function) for each element of +/// `self`. + + #[lua()] + fn exp( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing each element of `self` raised to the power of `n`. + + #[lua()] + fn powf( + _self: LuaReflectValProxy, + n: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the reciprocal `1.0/n` of each element of `self`. + + #[lua()] + fn recip( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn lerp( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + s: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn move_towards( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + d: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn midpoint( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn abs_diff_eq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + 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()] + fn clamp_length( + _self: LuaReflectValProxy, + min: f64, + max: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with a length no more than `max`. +/// # Panics +/// Will panic if `max` is negative when `glam_assert` is enabled. + + #[lua()] + fn clamp_length_max( + _self: LuaReflectValProxy, + max: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with a length no less than `min`. +/// # Panics +/// Will panic if `min` is negative when `glam_assert` is enabled. + + #[lua()] + fn clamp_length_min( + _self: LuaReflectValProxy, + min: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn mul_add( + _self: LuaReflectValProxy, + a: LuaReflectValProxy, + b: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reflect( + _self: LuaReflectValProxy, + normal: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn refract( + _self: LuaReflectValProxy, + normal: LuaReflectValProxy, + eta: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_angle(angle: f64) -> LuaReflectValProxy; + +"#, + 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()] + fn to_angle(_self: LuaReflectValProxy) -> f64; + +"#, + r#" + + #[lua()] + fn angle_between( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> 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()] + fn angle_to( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f64; + +"#, + r#" +/// Returns a vector that is equal to `self` rotated by 90 degrees. + + #[lua()] + fn perp( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// The perpendicular dot product of `self` and `rhs`. +/// Also known as the wedge product, 2D cross product, and determinant. + + #[lua()] + fn perp_dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> 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()] + fn rotate( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn rotate_towards( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + max_angle: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i32`. + + #[lua()] + fn as_ivec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u32`. + + #[lua()] + fn as_uvec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i64`. + + #[lua()] + fn as_i64vec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u64`. + + #[lua()] + fn as_u64vec2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::DVec2>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::DVec2>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::DVec2>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(self, idx: usize) -> LuaIdentityProxy { + _self[idx - 1] +} +"#, + r#" +#[lua(metamethod="NewIndex")] +fn index(&mut self, idx: usize, val: f64) -> () { + _self[idx - 1] = val +} +"#] +)] +pub struct DVec2 { + x: f64, + y: f64, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::DVec3", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: f64, y: f64, z: f64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: f64) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [f64; 3]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y, z]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [f64; 3]; + +"#, + r#" +/// Creates a 4D vector from `self` and the given `w` value. + + #[lua()] + fn extend( + _self: LuaReflectValProxy, + w: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn truncate( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D vector from `self` with the given value of `z`. + + #[lua()] + fn with_z( + _self: LuaReflectValProxy, + z: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f64; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the cross product of `self` and `rhs`. + + #[lua()] + fn cross( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the absolute value of each element of `self`. + + #[lua()] + fn abs( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn signum( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with signs of `rhs` and the magnitudes of `self`. + + #[lua()] + fn copysign( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_negative_bitmask(_self: LuaReflectValProxy) -> 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()] + fn is_finite(_self: LuaReflectValProxy) -> 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()] + fn is_finite_mask( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns `true` if any elements are `NaN`. + + #[lua()] + fn is_nan(_self: LuaReflectValProxy) -> 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()] + fn is_nan_mask( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the length of `self`. + + #[lua()] + fn length(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Computes the squared length of `self`. +/// This is faster than `length()` as it avoids a square root operation. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Computes `1.0 / length()`. +/// For valid results, `self` must _not_ be of length zero. + + #[lua()] + fn length_recip(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Computes the Euclidean distance between two points in space. + + #[lua()] + fn distance( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f64; + +"#, + r#" +/// Compute the squared euclidean distance between two points in space. + + #[lua()] + fn distance_squared( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f64; + +"#, + r#" +/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. + + #[lua()] + fn div_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. +/// [Euclidean division]: f64::rem_euclid + + #[lua()] + fn rem_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize_or( + _self: LuaReflectValProxy, + fallback: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize_or_zero( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns whether `self` is length `1.0` or not. +/// Uses a precision threshold of approximately `1e-4`. + + #[lua()] + fn is_normalized(_self: LuaReflectValProxy) -> 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()] + fn project_onto( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reject_from( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn project_onto_normalized( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reject_from_normalized( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn round( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the largest integer less than or equal to a number for each +/// element of `self`. + + #[lua()] + fn floor( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the smallest integer greater than or equal to a number for +/// each element of `self`. + + #[lua()] + fn ceil( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the integer part each element of `self`. This means numbers are +/// always truncated towards zero. + + #[lua()] + fn trunc( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn fract( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn fract_gl( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing `e^self` (the exponential function) for each element of +/// `self`. + + #[lua()] + fn exp( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing each element of `self` raised to the power of `n`. + + #[lua()] + fn powf( + _self: LuaReflectValProxy, + n: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the reciprocal `1.0/n` of each element of `self`. + + #[lua()] + fn recip( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn lerp( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + s: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn move_towards( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + d: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn midpoint( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn abs_diff_eq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + 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()] + fn clamp_length( + _self: LuaReflectValProxy, + min: f64, + max: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with a length no more than `max`. +/// # Panics +/// Will panic if `max` is negative when `glam_assert` is enabled. + + #[lua()] + fn clamp_length_max( + _self: LuaReflectValProxy, + max: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with a length no less than `min`. +/// # Panics +/// Will panic if `min` is negative when `glam_assert` is enabled. + + #[lua()] + fn clamp_length_min( + _self: LuaReflectValProxy, + min: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn mul_add( + _self: LuaReflectValProxy, + a: LuaReflectValProxy, + b: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reflect( + _self: LuaReflectValProxy, + normal: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn refract( + _self: LuaReflectValProxy, + normal: LuaReflectValProxy, + eta: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn angle_between( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> 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()] + fn any_orthogonal_vector( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn any_orthonormal_vector( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec3a( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i32`. + + #[lua()] + fn as_ivec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u32`. + + #[lua()] + fn as_uvec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i64`. + + #[lua()] + fn as_i64vec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u64`. + + #[lua()] + fn as_u64vec3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::DVec3>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::DVec3>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::DVec3>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::DVec3>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::DVec3>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(self, idx: usize) -> LuaIdentityProxy { + _self[idx - 1] +} +"#, + r#" +#[lua(metamethod="NewIndex")] +fn index(&mut self, idx: usize, val: f64) -> () { + _self[idx - 1] = val +} +"#] +)] +pub struct DVec3 { + x: f64, + y: f64, + z: f64, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::DVec4", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Div::<&bevy::math::DVec4>", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::<&bevy::math::DVec4>", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::<&bevy::math::DVec4>", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::<&bevy::math::DVec4>", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::<&bevy::math::DVec4>", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector. + + #[lua()] + fn new(x: f64, y: f64, z: f64, w: f64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector with all elements set to `v`. + + #[lua()] + fn splat(v: f64) -> LuaReflectValProxy; + +"#, + 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()] + fn select( + mask: LuaReflectValProxy, + if_true: LuaReflectValProxy, + if_false: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector from an array. + + #[lua()] + fn from_array(a: [f64; 4]) -> LuaReflectValProxy; + +"#, + r#" +/// `[x, y, z, w]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [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()] + fn truncate( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `x`. + + #[lua()] + fn with_x( + _self: LuaReflectValProxy, + x: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `y`. + + #[lua()] + fn with_y( + _self: LuaReflectValProxy, + y: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `z`. + + #[lua()] + fn with_z( + _self: LuaReflectValProxy, + z: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4D vector from `self` with the given value of `w`. + + #[lua()] + fn with_w( + _self: LuaReflectValProxy, + w: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the dot product of `self` and `rhs`. + + #[lua()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f64; + +"#, + r#" +/// Returns a vector where every component is the dot product of `self` and `rhs`. + + #[lua()] + fn dot_into_vec( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn min( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn max( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn clamp( + _self: LuaReflectValProxy, + min: LuaReflectValProxy, + max: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the horizontal minimum of `self`. +/// In other words this computes `min(x, y, ..)`. + + #[lua()] + fn min_element(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Returns the horizontal maximum of `self`. +/// In other words this computes `max(x, y, ..)`. + + #[lua()] + fn max_element(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Returns the sum of all elements of `self`. +/// In other words, this computes `self.x + self.y + ..`. + + #[lua()] + fn element_sum(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Returns the product of all elements of `self`. +/// In other words, this computes `self.x * self.y * ..`. + + #[lua()] + fn element_product(_self: LuaReflectValProxy) -> 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()] + fn cmpeq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpne( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpge( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmpgt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmple( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn cmplt( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the absolute value of each element of `self`. + + #[lua()] + fn abs( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn signum( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with signs of `rhs` and the magnitudes of `self`. + + #[lua()] + fn copysign( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_negative_bitmask(_self: LuaReflectValProxy) -> 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()] + fn is_finite(_self: LuaReflectValProxy) -> 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()] + fn is_finite_mask( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns `true` if any elements are `NaN`. + + #[lua()] + fn is_nan(_self: LuaReflectValProxy) -> 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()] + fn is_nan_mask( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Computes the length of `self`. + + #[lua()] + fn length(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Computes the squared length of `self`. +/// This is faster than `length()` as it avoids a square root operation. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Computes `1.0 / length()`. +/// For valid results, `self` must _not_ be of length zero. + + #[lua()] + fn length_recip(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Computes the Euclidean distance between two points in space. + + #[lua()] + fn distance( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f64; + +"#, + r#" +/// Compute the squared euclidean distance between two points in space. + + #[lua()] + fn distance_squared( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f64; + +"#, + r#" +/// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`. + + #[lua()] + fn div_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`. +/// [Euclidean division]: f64::rem_euclid + + #[lua()] + fn rem_euclid( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize_or( + _self: LuaReflectValProxy, + fallback: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn normalize_or_zero( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns whether `self` is length `1.0` or not. +/// Uses a precision threshold of approximately `1e-4`. + + #[lua()] + fn is_normalized(_self: LuaReflectValProxy) -> 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()] + fn project_onto( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reject_from( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn project_onto_normalized( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reject_from_normalized( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn round( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the largest integer less than or equal to a number for each +/// element of `self`. + + #[lua()] + fn floor( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the smallest integer greater than or equal to a number for +/// each element of `self`. + + #[lua()] + fn ceil( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the integer part each element of `self`. This means numbers are +/// always truncated towards zero. + + #[lua()] + fn trunc( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn fract( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn fract_gl( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing `e^self` (the exponential function) for each element of +/// `self`. + + #[lua()] + fn exp( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing each element of `self` raised to the power of `n`. + + #[lua()] + fn powf( + _self: LuaReflectValProxy, + n: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector containing the reciprocal `1.0/n` of each element of `self`. + + #[lua()] + fn recip( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn lerp( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + s: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn move_towards( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + d: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn midpoint( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn abs_diff_eq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + 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()] + fn clamp_length( + _self: LuaReflectValProxy, + min: f64, + max: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with a length no more than `max`. +/// # Panics +/// Will panic if `max` is negative when `glam_assert` is enabled. + + #[lua()] + fn clamp_length_max( + _self: LuaReflectValProxy, + max: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns a vector with a length no less than `min`. +/// # Panics +/// Will panic if `min` is negative when `glam_assert` is enabled. + + #[lua()] + fn clamp_length_min( + _self: LuaReflectValProxy, + min: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn mul_add( + _self: LuaReflectValProxy, + a: LuaReflectValProxy, + b: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reflect( + _self: LuaReflectValProxy, + normal: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn refract( + _self: LuaReflectValProxy, + normal: LuaReflectValProxy, + eta: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `f32`. + + #[lua()] + fn as_vec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i32`. + + #[lua()] + fn as_ivec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u32`. + + #[lua()] + fn as_uvec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `i64`. + + #[lua()] + fn as_i64vec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Casts all elements of `self` to `u64`. + + #[lua()] + fn as_u64vec4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Rem::", composite = "rem")] + fn rem( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(self, idx: usize) -> LuaIdentityProxy { + _self[idx - 1] +} +"#, + r#" +#[lua(metamethod="NewIndex")] +fn index(&mut self, idx: usize, val: f64) -> () { + _self[idx - 1] = val +} +"#] +)] +pub struct DVec4 { + x: f64, + y: f64, + z: f64, + w: f64, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::Mat2", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Creates a 2x2 matrix from two column vectors. + + #[lua()] + fn from_cols( + x_axis: LuaReflectValProxy, + y_axis: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn to_cols_array(_self: LuaReflectRefProxy) -> [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()] + fn to_cols_array_2d(_self: LuaReflectRefProxy) -> [[f32; 2]; 2]; + +"#, + r#" +/// Creates a 2x2 matrix with its diagonal set to `diagonal` and all other entries set to 0. + + #[lua()] + fn from_diagonal( + diagonal: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2x2 matrix containing the combining non-uniform `scale` and rotation of +/// `angle` (in radians). + + #[lua()] + fn from_scale_angle( + scale: LuaReflectValProxy, + angle: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2x2 matrix containing a rotation of `angle` (in radians). + + #[lua()] + fn from_angle(angle: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column. + + #[lua()] + fn from_mat3( + m: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat3_minor( + m: LuaReflectValProxy, + i: usize, + j: usize, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column. + + #[lua()] + fn from_mat3a( + m: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat3a_minor( + m: LuaReflectValProxy, + i: usize, + j: usize, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the matrix column for the given `index`. +/// # Panics +/// Panics if `index` is greater than 1. + + #[lua()] + fn col( + _self: LuaReflectRefProxy, + index: usize, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the matrix row for the given `index`. +/// # Panics +/// Panics if `index` is greater than 1. + + #[lua()] + fn row( + _self: LuaReflectRefProxy, + index: usize, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_finite(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns `true` if any elements are `NaN`. + + #[lua()] + fn is_nan(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns the transpose of `self`. + + #[lua()] + fn transpose( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the determinant of `self`. + + #[lua()] + fn determinant(_self: LuaReflectRefProxy) -> 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()] + fn inverse( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms a 2D vector. + + #[lua()] + fn mul_vec2( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Multiplies two 2x2 matrices. + + #[lua()] + fn mul_mat2( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Adds two 2x2 matrices. + + #[lua()] + fn add_mat2( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Subtracts two 2x2 matrices. + + #[lua()] + fn sub_mat2( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Multiplies a 2x2 matrix by a scalar. + + #[lua()] + fn mul_scalar( + _self: LuaReflectRefProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Divides a 2x2 matrix by a scalar. + + #[lua()] + fn div_scalar( + _self: LuaReflectRefProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn abs_diff_eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + max_abs_diff: f32, + ) -> bool; + +"#, + r#" +/// Takes the absolute value of each element in `self` + + #[lua()] + fn abs( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua()] + fn as_dmat2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(_self: LuaIdentityProxy, idx: usize) -> LuaIdentityProxy { + let mut curr_ref = _self.0.clone(); + let def_ref = bevy_mod_scripting_core::bindings::DeferredReflection{ + get: std::sync::Arc::new(|ref_| Err(bevy::reflect::ReflectPathError::InvalidDowncast)), + get_mut: std::sync::Arc::new(move |ref_| { + if let Some(ret) = ref_.try_as_reflect_mut().map(|ret| ret.downcast_mut::()).flatten(){ + Ok(ret.col_mut(idx - 1)) + } else { + Err(bevy::reflect::ReflectPathError::InvalidDowncast) + } + }) + }; + curr_ref.reflect_path.push(bevy_mod_scripting_core::bindings::ReflectionPathElem::new_deferred(def_ref)); + LuaVec2(curr_ref) +} +"#] +)] +pub struct Mat2(); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::Mat3", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3x3 matrix from three column vectors. + + #[lua()] + fn from_cols( + x_axis: LuaReflectValProxy, + y_axis: LuaReflectValProxy, + z_axis: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn to_cols_array(_self: LuaReflectRefProxy) -> [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()] + fn to_cols_array_2d(_self: LuaReflectRefProxy) -> [[f32; 3]; 3]; + +"#, + r#" +/// Creates a 3x3 matrix with its diagonal set to `diagonal` and all other entries set to 0. + + #[lua()] + fn from_diagonal( + diagonal: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3x3 matrix from a 4x4 matrix, discarding the 4th row and column. + + #[lua()] + fn from_mat4( + m: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat4_minor( + m: LuaReflectValProxy, + i: usize, + j: usize, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D rotation matrix from the given quaternion. +/// # Panics +/// Will panic if `rotation` is not normalized when `glam_assert` is enabled. + + #[lua()] + fn from_quat( + rotation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_axis_angle( + axis: LuaReflectValProxy, + angle: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D rotation matrix from the given euler rotation sequence and the angles (in +/// radians). + + #[lua()] + fn from_euler( + order: LuaReflectValProxy, + a: f32, + b: f32, + c: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn to_euler( + _self: LuaReflectRefProxy, + order: LuaReflectValProxy, + ) -> (f32, f32, f32); + +"#, + r#" +/// Creates a 3D rotation matrix from `angle` (in radians) around the x axis. + + #[lua()] + fn from_rotation_x(angle: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D rotation matrix from `angle` (in radians) around the y axis. + + #[lua()] + fn from_rotation_y(angle: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D rotation matrix from `angle` (in radians) around the z axis. + + #[lua()] + fn from_rotation_z(angle: f32) -> LuaReflectValProxy; + +"#, + 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()] + fn from_translation( + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_angle(angle: f32) -> LuaReflectValProxy; + +"#, + 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()] + fn from_scale_angle_translation( + scale: LuaReflectValProxy, + angle: f32, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_scale( + scale: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat2( + m: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the matrix column for the given `index`. +/// # Panics +/// Panics if `index` is greater than 2. + + #[lua()] + fn col( + _self: LuaReflectRefProxy, + index: usize, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the matrix row for the given `index`. +/// # Panics +/// Panics if `index` is greater than 2. + + #[lua()] + fn row( + _self: LuaReflectRefProxy, + index: usize, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_finite(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns `true` if any elements are `NaN`. + + #[lua()] + fn is_nan(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns the transpose of `self`. + + #[lua()] + fn transpose( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the determinant of `self`. + + #[lua()] + fn determinant(_self: LuaReflectRefProxy) -> 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()] + fn inverse( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn transform_point2( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn transform_vector2( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms a 3D vector. + + #[lua()] + fn mul_vec3( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms a [`Vec3A`]. + + #[lua()] + fn mul_vec3a( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Multiplies two 3x3 matrices. + + #[lua()] + fn mul_mat3( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Adds two 3x3 matrices. + + #[lua()] + fn add_mat3( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Subtracts two 3x3 matrices. + + #[lua()] + fn sub_mat3( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Multiplies a 3x3 matrix by a scalar. + + #[lua()] + fn mul_scalar( + _self: LuaReflectRefProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Divides a 3x3 matrix by a scalar. + + #[lua()] + fn div_scalar( + _self: LuaReflectRefProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn abs_diff_eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + max_abs_diff: f32, + ) -> bool; + +"#, + r#" +/// Takes the absolute value of each element in `self` + + #[lua()] + fn abs( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua()] + fn as_dmat3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(_self: LuaIdentityProxy, idx: usize) -> LuaIdentityProxy { + let mut curr_ref = _self.0.clone(); + let def_ref = bevy_mod_scripting_core::bindings::DeferredReflection{ + get: std::sync::Arc::new(|ref_| Err(bevy::reflect::ReflectPathError::InvalidDowncast)), + get_mut: std::sync::Arc::new(move |ref_| { + if let Some(ret) = ref_.try_as_reflect_mut().map(|ret| ret.downcast_mut::()).flatten(){ + Ok(ret.col_mut(idx - 1)) + } else { + Err(bevy::reflect::ReflectPathError::InvalidDowncast) + } + }) + }; + curr_ref.reflect_path.push(bevy_mod_scripting_core::bindings::ReflectionPathElem::new_deferred(def_ref)); + LuaVec3(curr_ref) +} +"#] +)] +pub struct Mat3 { + x_axis: bevy::math::Vec3, + y_axis: bevy::math::Vec3, + z_axis: bevy::math::Vec3, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::Mat3A", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Creates a 3x3 matrix from three column vectors. + + #[lua()] + fn from_cols( + x_axis: LuaReflectValProxy, + y_axis: LuaReflectValProxy, + z_axis: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn to_cols_array(_self: LuaReflectRefProxy) -> [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()] + fn to_cols_array_2d(_self: LuaReflectRefProxy) -> [[f32; 3]; 3]; + +"#, + r#" +/// Creates a 3x3 matrix with its diagonal set to `diagonal` and all other entries set to 0. + + #[lua()] + fn from_diagonal( + diagonal: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3x3 matrix from a 4x4 matrix, discarding the 4th row and column. + + #[lua()] + fn from_mat4( + m: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat4_minor( + m: LuaReflectValProxy, + i: usize, + j: usize, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D rotation matrix from the given quaternion. +/// # Panics +/// Will panic if `rotation` is not normalized when `glam_assert` is enabled. + + #[lua()] + fn from_quat( + rotation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_axis_angle( + axis: LuaReflectValProxy, + angle: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D rotation matrix from the given euler rotation sequence and the angles (in +/// radians). + + #[lua()] + fn from_euler( + order: LuaReflectValProxy, + a: f32, + b: f32, + c: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn to_euler( + _self: LuaReflectRefProxy, + order: LuaReflectValProxy, + ) -> (f32, f32, f32); + +"#, + r#" +/// Creates a 3D rotation matrix from `angle` (in radians) around the x axis. + + #[lua()] + fn from_rotation_x(angle: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D rotation matrix from `angle` (in radians) around the y axis. + + #[lua()] + fn from_rotation_y(angle: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D rotation matrix from `angle` (in radians) around the z axis. + + #[lua()] + fn from_rotation_z(angle: f32) -> LuaReflectValProxy; + +"#, + 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()] + fn from_translation( + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_angle(angle: f32) -> LuaReflectValProxy; + +"#, + 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()] + fn from_scale_angle_translation( + scale: LuaReflectValProxy, + angle: f32, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_scale( + scale: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat2( + m: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the matrix column for the given `index`. +/// # Panics +/// Panics if `index` is greater than 2. + + #[lua()] + fn col( + _self: LuaReflectRefProxy, + index: usize, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the matrix row for the given `index`. +/// # Panics +/// Panics if `index` is greater than 2. + + #[lua()] + fn row( + _self: LuaReflectRefProxy, + index: usize, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_finite(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns `true` if any elements are `NaN`. + + #[lua()] + fn is_nan(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns the transpose of `self`. + + #[lua()] + fn transpose( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the determinant of `self`. + + #[lua()] + fn determinant(_self: LuaReflectRefProxy) -> 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()] + fn inverse( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn transform_point2( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn transform_vector2( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms a 3D vector. + + #[lua()] + fn mul_vec3( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms a [`Vec3A`]. + + #[lua()] + fn mul_vec3a( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Multiplies two 3x3 matrices. + + #[lua()] + fn mul_mat3( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Adds two 3x3 matrices. + + #[lua()] + fn add_mat3( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Subtracts two 3x3 matrices. + + #[lua()] + fn sub_mat3( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Multiplies a 3x3 matrix by a scalar. + + #[lua()] + fn mul_scalar( + _self: LuaReflectRefProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Divides a 3x3 matrix by a scalar. + + #[lua()] + fn div_scalar( + _self: LuaReflectRefProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn abs_diff_eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + max_abs_diff: f32, + ) -> bool; + +"#, + r#" +/// Takes the absolute value of each element in `self` + + #[lua()] + fn abs( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua()] + fn as_dmat3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(_self: LuaIdentityProxy, idx: usize) -> LuaIdentityProxy { + let mut curr_ref = _self.0.clone(); + let def_ref = bevy_mod_scripting_core::bindings::DeferredReflection{ + get: std::sync::Arc::new(|ref_| Err(bevy::reflect::ReflectPathError::InvalidDowncast)), + get_mut: std::sync::Arc::new(move |ref_| { + if let Some(ret) = ref_.try_as_reflect_mut().map(|ret| ret.downcast_mut::()).flatten(){ + Ok(ret.col_mut(idx - 1)) + } else { + Err(bevy::reflect::ReflectPathError::InvalidDowncast) + } + }) + }; + curr_ref.reflect_path.push(bevy_mod_scripting_core::bindings::ReflectionPathElem::new_deferred(def_ref)); + LuaVec3A(curr_ref) +} +"#] +)] +pub struct Mat3A { + x_axis: bevy::math::Vec3A, + y_axis: bevy::math::Vec3A, + z_axis: bevy::math::Vec3A, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::Mat4", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4x4 matrix from four column vectors. + + #[lua()] + fn from_cols( + x_axis: LuaReflectValProxy, + y_axis: LuaReflectValProxy, + z_axis: LuaReflectValProxy, + w_axis: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn to_cols_array(_self: LuaReflectRefProxy) -> [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()] + fn to_cols_array_2d(_self: LuaReflectRefProxy) -> [[f32; 4]; 4]; + +"#, + r#" +/// Creates a 4x4 matrix with its diagonal set to `diagonal` and all other entries set to 0. + + #[lua()] + fn from_diagonal( + diagonal: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_scale_rotation_translation( + scale: LuaReflectValProxy, + rotation: LuaReflectValProxy, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_rotation_translation( + rotation: LuaReflectValProxy, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_quat( + rotation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat3( + m: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat3a( + m: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_translation( + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_axis_angle( + axis: LuaReflectValProxy, + angle: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_euler( + order: LuaReflectValProxy, + a: f32, + b: f32, + c: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn to_euler( + _self: LuaReflectRefProxy, + order: LuaReflectValProxy, + ) -> (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()] + fn from_rotation_x(angle: f32) -> LuaReflectValProxy; + +"#, + 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()] + fn from_rotation_y(angle: f32) -> LuaReflectValProxy; + +"#, + 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()] + fn from_rotation_z(angle: f32) -> LuaReflectValProxy; + +"#, + 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()] + fn from_scale( + scale: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the matrix column for the given `index`. +/// # Panics +/// Panics if `index` is greater than 3. + + #[lua()] + fn col( + _self: LuaReflectRefProxy, + index: usize, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the matrix row for the given `index`. +/// # Panics +/// Panics if `index` is greater than 3. + + #[lua()] + fn row( + _self: LuaReflectRefProxy, + index: usize, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_finite(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns `true` if any elements are `NaN`. + + #[lua()] + fn is_nan(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns the transpose of `self`. + + #[lua()] + fn transpose( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the determinant of `self`. + + #[lua()] + fn determinant(_self: LuaReflectRefProxy) -> 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()] + fn inverse( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn look_to_lh( + eye: LuaReflectValProxy, + dir: LuaReflectValProxy, + up: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn look_to_rh( + eye: LuaReflectValProxy, + dir: LuaReflectValProxy, + up: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn look_at_lh( + eye: LuaReflectValProxy, + center: LuaReflectValProxy, + up: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn look_at_rh( + eye: LuaReflectValProxy, + center: LuaReflectValProxy, + up: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn perspective_rh_gl( + fov_y_radians: f32, + aspect_ratio: f32, + z_near: f32, + z_far: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn perspective_lh( + fov_y_radians: f32, + aspect_ratio: f32, + z_near: f32, + z_far: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn perspective_rh( + fov_y_radians: f32, + aspect_ratio: f32, + z_near: f32, + z_far: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn perspective_infinite_lh( + fov_y_radians: f32, + aspect_ratio: f32, + z_near: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn perspective_infinite_reverse_lh( + fov_y_radians: f32, + aspect_ratio: f32, + z_near: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn perspective_infinite_rh( + fov_y_radians: f32, + aspect_ratio: f32, + z_near: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn perspective_infinite_reverse_rh( + fov_y_radians: f32, + aspect_ratio: f32, + z_near: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn orthographic_rh_gl( + left: f32, + right: f32, + bottom: f32, + top: f32, + near: f32, + far: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn orthographic_lh( + left: f32, + right: f32, + bottom: f32, + top: f32, + near: f32, + far: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn orthographic_rh( + left: f32, + right: f32, + bottom: f32, + top: f32, + near: f32, + far: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn project_point3( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn transform_point3( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn transform_vector3( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn project_point3a( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn transform_point3a( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn transform_vector3a( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms a 4D vector. + + #[lua()] + fn mul_vec4( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Multiplies two 4x4 matrices. + + #[lua()] + fn mul_mat4( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Adds two 4x4 matrices. + + #[lua()] + fn add_mat4( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Subtracts two 4x4 matrices. + + #[lua()] + fn sub_mat4( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Multiplies a 4x4 matrix by a scalar. + + #[lua()] + fn mul_scalar( + _self: LuaReflectRefProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Divides a 4x4 matrix by a scalar. + + #[lua()] + fn div_scalar( + _self: LuaReflectRefProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn abs_diff_eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + max_abs_diff: f32, + ) -> bool; + +"#, + r#" +/// Takes the absolute value of each element in `self` + + #[lua()] + fn abs( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua()] + fn as_dmat4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: f32, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(_self: LuaIdentityProxy, idx: usize) -> LuaIdentityProxy { + let mut curr_ref = _self.0.clone(); + let def_ref = bevy_mod_scripting_core::bindings::DeferredReflection{ + get: std::sync::Arc::new(|ref_| Err(bevy::reflect::ReflectPathError::InvalidDowncast)), + get_mut: std::sync::Arc::new(move |ref_| { + if let Some(ret) = ref_.try_as_reflect_mut().map(|ret| ret.downcast_mut::()).flatten(){ + Ok(ret.col_mut(idx - 1)) + } else { + Err(bevy::reflect::ReflectPathError::InvalidDowncast) + } + }) + }; + curr_ref.reflect_path.push(bevy_mod_scripting_core::bindings::ReflectionPathElem::new_deferred(def_ref)); + LuaVec4(curr_ref) +} +"#] +)] +pub struct Mat4 { + x_axis: bevy::math::Vec4, + y_axis: bevy::math::Vec4, + z_axis: bevy::math::Vec4, + w_axis: bevy::math::Vec4, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::DMat2", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2x2 matrix from two column vectors. + + #[lua()] + fn from_cols( + x_axis: LuaReflectValProxy, + y_axis: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn to_cols_array(_self: LuaReflectRefProxy) -> [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()] + fn to_cols_array_2d(_self: LuaReflectRefProxy) -> [[f64; 2]; 2]; + +"#, + r#" +/// Creates a 2x2 matrix with its diagonal set to `diagonal` and all other entries set to 0. + + #[lua()] + fn from_diagonal( + diagonal: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2x2 matrix containing the combining non-uniform `scale` and rotation of +/// `angle` (in radians). + + #[lua()] + fn from_scale_angle( + scale: LuaReflectValProxy, + angle: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2x2 matrix containing a rotation of `angle` (in radians). + + #[lua()] + fn from_angle(angle: f64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column. + + #[lua()] + fn from_mat3( + m: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat3_minor( + m: LuaReflectValProxy, + i: usize, + j: usize, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the matrix column for the given `index`. +/// # Panics +/// Panics if `index` is greater than 1. + + #[lua()] + fn col( + _self: LuaReflectRefProxy, + index: usize, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the matrix row for the given `index`. +/// # Panics +/// Panics if `index` is greater than 1. + + #[lua()] + fn row( + _self: LuaReflectRefProxy, + index: usize, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_finite(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns `true` if any elements are `NaN`. + + #[lua()] + fn is_nan(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns the transpose of `self`. + + #[lua()] + fn transpose( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the determinant of `self`. + + #[lua()] + fn determinant(_self: LuaReflectRefProxy) -> 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()] + fn inverse( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms a 2D vector. + + #[lua()] + fn mul_vec2( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Multiplies two 2x2 matrices. + + #[lua()] + fn mul_mat2( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Adds two 2x2 matrices. + + #[lua()] + fn add_mat2( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Subtracts two 2x2 matrices. + + #[lua()] + fn sub_mat2( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Multiplies a 2x2 matrix by a scalar. + + #[lua()] + fn mul_scalar( + _self: LuaReflectRefProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Divides a 2x2 matrix by a scalar. + + #[lua()] + fn div_scalar( + _self: LuaReflectRefProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn abs_diff_eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + max_abs_diff: f64, + ) -> bool; + +"#, + r#" +/// Takes the absolute value of each element in `self` + + #[lua()] + fn abs( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua()] + fn as_mat2( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(_self: LuaIdentityProxy, idx: usize) -> LuaIdentityProxy { + let mut curr_ref = _self.0.clone(); + let def_ref = bevy_mod_scripting_core::bindings::DeferredReflection{ + get: std::sync::Arc::new(|ref_| Err(bevy::reflect::ReflectPathError::InvalidDowncast)), + get_mut: std::sync::Arc::new(move |ref_| { + if let Some(ret) = ref_.try_as_reflect_mut().map(|ret| ret.downcast_mut::()).flatten(){ + Ok(ret.col_mut(idx - 1)) + } else { + Err(bevy::reflect::ReflectPathError::InvalidDowncast) + } + }) + }; + curr_ref.reflect_path.push(bevy_mod_scripting_core::bindings::ReflectionPathElem::new_deferred(def_ref)); + LuaDVec2(curr_ref) +} +"#] +)] +pub struct DMat2 { + x_axis: bevy::math::DVec2, + y_axis: bevy::math::DVec2, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::DMat3", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3x3 matrix from three column vectors. + + #[lua()] + fn from_cols( + x_axis: LuaReflectValProxy, + y_axis: LuaReflectValProxy, + z_axis: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn to_cols_array(_self: LuaReflectRefProxy) -> [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()] + fn to_cols_array_2d(_self: LuaReflectRefProxy) -> [[f64; 3]; 3]; + +"#, + r#" +/// Creates a 3x3 matrix with its diagonal set to `diagonal` and all other entries set to 0. + + #[lua()] + fn from_diagonal( + diagonal: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3x3 matrix from a 4x4 matrix, discarding the 4th row and column. + + #[lua()] + fn from_mat4( + m: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat4_minor( + m: LuaReflectValProxy, + i: usize, + j: usize, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D rotation matrix from the given quaternion. +/// # Panics +/// Will panic if `rotation` is not normalized when `glam_assert` is enabled. + + #[lua()] + fn from_quat( + rotation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_axis_angle( + axis: LuaReflectValProxy, + angle: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D rotation matrix from the given euler rotation sequence and the angles (in +/// radians). + + #[lua()] + fn from_euler( + order: LuaReflectValProxy, + a: f64, + b: f64, + c: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn to_euler( + _self: LuaReflectRefProxy, + order: LuaReflectValProxy, + ) -> (f64, f64, f64); + +"#, + r#" +/// Creates a 3D rotation matrix from `angle` (in radians) around the x axis. + + #[lua()] + fn from_rotation_x(angle: f64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D rotation matrix from `angle` (in radians) around the y axis. + + #[lua()] + fn from_rotation_y(angle: f64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 3D rotation matrix from `angle` (in radians) around the z axis. + + #[lua()] + fn from_rotation_z(angle: f64) -> LuaReflectValProxy; + +"#, + 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()] + fn from_translation( + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_angle(angle: f64) -> LuaReflectValProxy; + +"#, + 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()] + fn from_scale_angle_translation( + scale: LuaReflectValProxy, + angle: f64, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_scale( + scale: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat2( + m: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the matrix column for the given `index`. +/// # Panics +/// Panics if `index` is greater than 2. + + #[lua()] + fn col( + _self: LuaReflectRefProxy, + index: usize, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the matrix row for the given `index`. +/// # Panics +/// Panics if `index` is greater than 2. + + #[lua()] + fn row( + _self: LuaReflectRefProxy, + index: usize, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_finite(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns `true` if any elements are `NaN`. + + #[lua()] + fn is_nan(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns the transpose of `self`. + + #[lua()] + fn transpose( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the determinant of `self`. + + #[lua()] + fn determinant(_self: LuaReflectRefProxy) -> 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()] + fn inverse( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn transform_point2( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn transform_vector2( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms a 3D vector. + + #[lua()] + fn mul_vec3( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Multiplies two 3x3 matrices. + + #[lua()] + fn mul_mat3( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Adds two 3x3 matrices. + + #[lua()] + fn add_mat3( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Subtracts two 3x3 matrices. + + #[lua()] + fn sub_mat3( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Multiplies a 3x3 matrix by a scalar. + + #[lua()] + fn mul_scalar( + _self: LuaReflectRefProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Divides a 3x3 matrix by a scalar. + + #[lua()] + fn div_scalar( + _self: LuaReflectRefProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn abs_diff_eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + max_abs_diff: f64, + ) -> bool; + +"#, + r#" +/// Takes the absolute value of each element in `self` + + #[lua()] + fn abs( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua()] + fn as_mat3( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(_self: LuaIdentityProxy, idx: usize) -> LuaIdentityProxy { + let mut curr_ref = _self.0.clone(); + let def_ref = bevy_mod_scripting_core::bindings::DeferredReflection{ + get: std::sync::Arc::new(|ref_| Err(bevy::reflect::ReflectPathError::InvalidDowncast)), + get_mut: std::sync::Arc::new(move |ref_| { + if let Some(ret) = ref_.try_as_reflect_mut().map(|ret| ret.downcast_mut::()).flatten(){ + Ok(ret.col_mut(idx - 1)) + } else { + Err(bevy::reflect::ReflectPathError::InvalidDowncast) + } + }) + }; + curr_ref.reflect_path.push(bevy_mod_scripting_core::bindings::ReflectionPathElem::new_deferred(def_ref)); + LuaDVec3(curr_ref) +} +"#] +)] +pub struct DMat3 { + x_axis: bevy::math::DVec3, + y_axis: bevy::math::DVec3, + z_axis: bevy::math::DVec3, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::DMat4", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a 4x4 matrix from four column vectors. + + #[lua()] + fn from_cols( + x_axis: LuaReflectValProxy, + y_axis: LuaReflectValProxy, + z_axis: LuaReflectValProxy, + w_axis: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn to_cols_array(_self: LuaReflectRefProxy) -> [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()] + fn to_cols_array_2d(_self: LuaReflectRefProxy) -> [[f64; 4]; 4]; + +"#, + r#" +/// Creates a 4x4 matrix with its diagonal set to `diagonal` and all other entries set to 0. + + #[lua()] + fn from_diagonal( + diagonal: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_scale_rotation_translation( + scale: LuaReflectValProxy, + rotation: LuaReflectValProxy, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_rotation_translation( + rotation: LuaReflectValProxy, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_quat( + rotation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat3( + m: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_translation( + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_axis_angle( + axis: LuaReflectValProxy, + angle: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_euler( + order: LuaReflectValProxy, + a: f64, + b: f64, + c: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn to_euler( + _self: LuaReflectRefProxy, + order: LuaReflectValProxy, + ) -> (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()] + fn from_rotation_x(angle: f64) -> LuaReflectValProxy; + +"#, + 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()] + fn from_rotation_y(angle: f64) -> LuaReflectValProxy; + +"#, + 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()] + fn from_rotation_z(angle: f64) -> LuaReflectValProxy; + +"#, + 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()] + fn from_scale( + scale: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the matrix column for the given `index`. +/// # Panics +/// Panics if `index` is greater than 3. + + #[lua()] + fn col( + _self: LuaReflectRefProxy, + index: usize, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the matrix row for the given `index`. +/// # Panics +/// Panics if `index` is greater than 3. + + #[lua()] + fn row( + _self: LuaReflectRefProxy, + index: usize, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_finite(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns `true` if any elements are `NaN`. + + #[lua()] + fn is_nan(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns the transpose of `self`. + + #[lua()] + fn transpose( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the determinant of `self`. + + #[lua()] + fn determinant(_self: LuaReflectRefProxy) -> 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()] + fn inverse( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn look_to_lh( + eye: LuaReflectValProxy, + dir: LuaReflectValProxy, + up: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn look_to_rh( + eye: LuaReflectValProxy, + dir: LuaReflectValProxy, + up: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn look_at_lh( + eye: LuaReflectValProxy, + center: LuaReflectValProxy, + up: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn look_at_rh( + eye: LuaReflectValProxy, + center: LuaReflectValProxy, + up: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn perspective_rh_gl( + fov_y_radians: f64, + aspect_ratio: f64, + z_near: f64, + z_far: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn perspective_lh( + fov_y_radians: f64, + aspect_ratio: f64, + z_near: f64, + z_far: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn perspective_rh( + fov_y_radians: f64, + aspect_ratio: f64, + z_near: f64, + z_far: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn perspective_infinite_lh( + fov_y_radians: f64, + aspect_ratio: f64, + z_near: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn perspective_infinite_reverse_lh( + fov_y_radians: f64, + aspect_ratio: f64, + z_near: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn perspective_infinite_rh( + fov_y_radians: f64, + aspect_ratio: f64, + z_near: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn perspective_infinite_reverse_rh( + fov_y_radians: f64, + aspect_ratio: f64, + z_near: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn orthographic_rh_gl( + left: f64, + right: f64, + bottom: f64, + top: f64, + near: f64, + far: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn orthographic_lh( + left: f64, + right: f64, + bottom: f64, + top: f64, + near: f64, + far: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn orthographic_rh( + left: f64, + right: f64, + bottom: f64, + top: f64, + near: f64, + far: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn project_point3( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn transform_point3( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn transform_vector3( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms a 4D vector. + + #[lua()] + fn mul_vec4( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Multiplies two 4x4 matrices. + + #[lua()] + fn mul_mat4( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Adds two 4x4 matrices. + + #[lua()] + fn add_mat4( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Subtracts two 4x4 matrices. + + #[lua()] + fn sub_mat4( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Multiplies a 4x4 matrix by a scalar. + + #[lua()] + fn mul_scalar( + _self: LuaReflectRefProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Divides a 4x4 matrix by a scalar. + + #[lua()] + fn div_scalar( + _self: LuaReflectRefProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn abs_diff_eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + max_abs_diff: f64, + ) -> bool; + +"#, + r#" +/// Takes the absolute value of each element in `self` + + #[lua()] + fn abs( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua()] + fn as_mat4( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Add::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#, + r#" +#[lua(metamethod="Index")] +fn index(_self: LuaIdentityProxy, idx: usize) -> LuaIdentityProxy { + let mut curr_ref = _self.0.clone(); + let def_ref = bevy_mod_scripting_core::bindings::DeferredReflection{ + get: std::sync::Arc::new(|ref_| Err(bevy::reflect::ReflectPathError::InvalidDowncast)), + get_mut: std::sync::Arc::new(move |ref_| { + if let Some(ret) = ref_.try_as_reflect_mut().map(|ret| ret.downcast_mut::()).flatten(){ + Ok(ret.col_mut(idx - 1)) + } else { + Err(bevy::reflect::ReflectPathError::InvalidDowncast) + } + }) + }; + curr_ref.reflect_path.push(bevy_mod_scripting_core::bindings::ReflectionPathElem::new_deferred(def_ref)); + LuaDVec4(curr_ref) +} +"#] +)] +pub struct DMat4 { + x_axis: bevy::math::DVec4, + y_axis: bevy::math::DVec4, + z_axis: bevy::math::DVec4, + w_axis: bevy::math::DVec4, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::Affine2", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform from three column vectors. + + #[lua()] + fn from_cols( + x_axis: LuaReflectValProxy, + y_axis: LuaReflectValProxy, + z_axis: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a `[f32; 6]` array storing data in column major order. + + #[lua()] + fn to_cols_array(_self: LuaReflectRefProxy) -> [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()] + fn to_cols_array_2d(_self: LuaReflectRefProxy) -> [[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()] + fn from_scale( + scale: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform from the given rotation `angle`. + + #[lua()] + fn from_angle(angle: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transformation from the given 2D `translation`. + + #[lua()] + fn from_translation( + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform from a 2x2 matrix (expressing scale, shear and rotation) + + #[lua()] + fn from_mat2( + matrix2: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat2_translation( + matrix2: LuaReflectValProxy, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_scale_angle_translation( + scale: LuaReflectValProxy, + angle: f32, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_angle_translation( + angle: f32, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// The given `Mat3` must be an affine transform, + + #[lua()] + fn from_mat3( + m: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// The given [`Mat3A`] must be an affine transform, + + #[lua()] + fn from_mat3a( + m: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms the given 2D point, applying shear, scale, rotation and translation. + + #[lua()] + fn transform_point2( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms the given 2D vector, applying shear, scale and rotation (but NOT +/// translation). +/// To also apply translation, use [`Self::transform_point2()`] instead. + + #[lua()] + fn transform_vector2( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_finite(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns `true` if any elements are `NaN`. + + #[lua()] + fn is_nan(_self: LuaReflectRefProxy) -> 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()] + fn abs_diff_eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + 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()] + fn inverse( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Affine2 { + matrix2: bevy::math::Mat2, + translation: bevy::math::Vec2, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::Affine3A", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Creates an affine transform from three column vectors. + + #[lua()] + fn from_cols( + x_axis: LuaReflectValProxy, + y_axis: LuaReflectValProxy, + z_axis: LuaReflectValProxy, + w_axis: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a `[f32; 12]` array storing data in column major order. + + #[lua()] + fn to_cols_array(_self: LuaReflectRefProxy) -> [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()] + fn to_cols_array_2d( + _self: LuaReflectRefProxy, + ) -> [[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()] + fn from_scale( + scale: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform from the given `rotation` quaternion. + + #[lua()] + fn from_quat( + rotation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform containing a 3D rotation around a normalized +/// rotation `axis` of `angle` (in radians). + + #[lua()] + fn from_axis_angle( + axis: LuaReflectValProxy, + angle: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform containing a 3D rotation around the x axis of +/// `angle` (in radians). + + #[lua()] + fn from_rotation_x(angle: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform containing a 3D rotation around the y axis of +/// `angle` (in radians). + + #[lua()] + fn from_rotation_y(angle: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform containing a 3D rotation around the z axis of +/// `angle` (in radians). + + #[lua()] + fn from_rotation_z(angle: f32) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transformation from the given 3D `translation`. + + #[lua()] + fn from_translation( + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform from a 3x3 matrix (expressing scale, shear and +/// rotation) + + #[lua()] + fn from_mat3( + mat3: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat3_translation( + mat3: LuaReflectValProxy, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_scale_rotation_translation( + scale: LuaReflectValProxy, + rotation: LuaReflectValProxy, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform from the given 3D `rotation` and `translation`. +/// Equivalent to `Affine3A::from_translation(translation) * Affine3A::from_quat(rotation)` + + #[lua()] + fn from_rotation_translation( + rotation: LuaReflectValProxy, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// The given `Mat4` must be an affine transform, +/// i.e. contain no perspective transform. + + #[lua()] + fn from_mat4( + m: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn look_to_lh( + eye: LuaReflectValProxy, + dir: LuaReflectValProxy, + up: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn look_to_rh( + eye: LuaReflectValProxy, + dir: LuaReflectValProxy, + up: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn look_at_lh( + eye: LuaReflectValProxy, + center: LuaReflectValProxy, + up: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn look_at_rh( + eye: LuaReflectValProxy, + center: LuaReflectValProxy, + up: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms the given 3D points, applying shear, scale, rotation and translation. + + #[lua()] + fn transform_point3( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms the given 3D vector, applying shear, scale and rotation (but NOT +/// translation). +/// To also apply translation, use [`Self::transform_point3()`] instead. + + #[lua()] + fn transform_vector3( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms the given [`Vec3A`], applying shear, scale, rotation and translation. + + #[lua()] + fn transform_point3a( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms the given [`Vec3A`], applying shear, scale and rotation (but NOT +/// translation). +/// To also apply translation, use [`Self::transform_point3a()`] instead. + + #[lua()] + fn transform_vector3a( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_finite(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns `true` if any elements are `NaN`. + + #[lua()] + fn is_nan(_self: LuaReflectRefProxy) -> 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()] + fn abs_diff_eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + 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()] + fn inverse( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Affine3A { + matrix3: bevy::math::Mat3A, + translation: bevy::math::Vec3A, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::DAffine2", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Creates an affine transform from three column vectors. + + #[lua()] + fn from_cols( + x_axis: LuaReflectValProxy, + y_axis: LuaReflectValProxy, + z_axis: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a `[f64; 6]` array storing data in column major order. + + #[lua()] + fn to_cols_array(_self: LuaReflectRefProxy) -> [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()] + fn to_cols_array_2d( + _self: LuaReflectRefProxy, + ) -> [[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()] + fn from_scale( + scale: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform from the given rotation `angle`. + + #[lua()] + fn from_angle(angle: f64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transformation from the given 2D `translation`. + + #[lua()] + fn from_translation( + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform from a 2x2 matrix (expressing scale, shear and rotation) + + #[lua()] + fn from_mat2( + matrix2: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat2_translation( + matrix2: LuaReflectValProxy, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_scale_angle_translation( + scale: LuaReflectValProxy, + angle: f64, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_angle_translation( + angle: f64, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// The given `DMat3` must be an affine transform, + + #[lua()] + fn from_mat3( + m: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms the given 2D point, applying shear, scale, rotation and translation. + + #[lua()] + fn transform_point2( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms the given 2D vector, applying shear, scale and rotation (but NOT +/// translation). +/// To also apply translation, use [`Self::transform_point2()`] instead. + + #[lua()] + fn transform_vector2( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_finite(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns `true` if any elements are `NaN`. + + #[lua()] + fn is_nan(_self: LuaReflectRefProxy) -> 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()] + fn abs_diff_eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + 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()] + fn inverse( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct DAffine2 { + matrix2: bevy::math::DMat2, + translation: bevy::math::DVec2, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::DAffine3", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Creates an affine transform from three column vectors. + + #[lua()] + fn from_cols( + x_axis: LuaReflectValProxy, + y_axis: LuaReflectValProxy, + z_axis: LuaReflectValProxy, + w_axis: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a `[f64; 12]` array storing data in column major order. + + #[lua()] + fn to_cols_array(_self: LuaReflectRefProxy) -> [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()] + fn to_cols_array_2d( + _self: LuaReflectRefProxy, + ) -> [[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()] + fn from_scale( + scale: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform from the given `rotation` quaternion. + + #[lua()] + fn from_quat( + rotation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform containing a 3D rotation around a normalized +/// rotation `axis` of `angle` (in radians). + + #[lua()] + fn from_axis_angle( + axis: LuaReflectValProxy, + angle: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform containing a 3D rotation around the x axis of +/// `angle` (in radians). + + #[lua()] + fn from_rotation_x(angle: f64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform containing a 3D rotation around the y axis of +/// `angle` (in radians). + + #[lua()] + fn from_rotation_y(angle: f64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform containing a 3D rotation around the z axis of +/// `angle` (in radians). + + #[lua()] + fn from_rotation_z(angle: f64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transformation from the given 3D `translation`. + + #[lua()] + fn from_translation( + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform from a 3x3 matrix (expressing scale, shear and +/// rotation) + + #[lua()] + fn from_mat3( + mat3: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat3_translation( + mat3: LuaReflectValProxy, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_scale_rotation_translation( + scale: LuaReflectValProxy, + rotation: LuaReflectValProxy, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates an affine transform from the given 3D `rotation` and `translation`. +/// Equivalent to `DAffine3::from_translation(translation) * DAffine3::from_quat(rotation)` + + #[lua()] + fn from_rotation_translation( + rotation: LuaReflectValProxy, + translation: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// The given `DMat4` must be an affine transform, +/// i.e. contain no perspective transform. + + #[lua()] + fn from_mat4( + m: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn look_to_lh( + eye: LuaReflectValProxy, + dir: LuaReflectValProxy, + up: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn look_to_rh( + eye: LuaReflectValProxy, + dir: LuaReflectValProxy, + up: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn look_at_lh( + eye: LuaReflectValProxy, + center: LuaReflectValProxy, + up: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn look_at_rh( + eye: LuaReflectValProxy, + center: LuaReflectValProxy, + up: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms the given 3D points, applying shear, scale, rotation and translation. + + #[lua()] + fn transform_point3( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Transforms the given 3D vector, applying shear, scale and rotation (but NOT +/// translation). +/// To also apply translation, use [`Self::transform_point3()`] instead. + + #[lua()] + fn transform_vector3( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_finite(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns `true` if any elements are `NaN`. + + #[lua()] + fn is_nan(_self: LuaReflectRefProxy) -> 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()] + fn abs_diff_eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + 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()] + fn inverse( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct DAffine3 { + matrix3: bevy::math::DMat3, + translation: bevy::math::DVec3, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::DQuat", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[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::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Multiplies a quaternion by a scalar value. +/// The product is not guaranteed to be normalized. + + #[lua(as_trait = "std::ops::Mul::", composite = "mul")] + fn mul( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Divides a quaternion by a scalar value. +/// The quotient is not guaranteed to be normalized. + + #[lua(as_trait = "std::ops::Div::", composite = "div")] + fn div( + _self: LuaReflectValProxy, + rhs: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Subtracts the `rhs` quaternion from `self`. +/// The difference is not guaranteed to be normalized. + + #[lua(as_trait = "std::ops::Sub::", composite = "sub")] + fn sub( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::ops::Neg", composite = "neg")] + fn neg( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_xyzw( + x: f64, + y: f64, + z: f64, + w: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_array(a: [f64; 4]) -> LuaReflectValProxy; + +"#, + 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()] + fn from_vec4( + v: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_axis_angle( + axis: LuaReflectValProxy, + angle: f64, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Create a quaternion that rotates `v.length()` radians around `v.normalize()`. +/// `from_scaled_axis(Vec3::ZERO)` results in the identity quaternion. + + #[lua()] + fn from_scaled_axis( + v: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a quaternion from the `angle` (in radians) around the x axis. + + #[lua()] + fn from_rotation_x(angle: f64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a quaternion from the `angle` (in radians) around the y axis. + + #[lua()] + fn from_rotation_y(angle: f64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a quaternion from the `angle` (in radians) around the z axis. + + #[lua()] + fn from_rotation_z(angle: f64) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a quaternion from the given Euler rotation sequence and the angles (in radians). + + #[lua()] + fn from_euler( + euler: LuaReflectValProxy, + a: f64, + b: f64, + c: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat3( + mat: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_mat4( + mat: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_rotation_arc( + from: LuaReflectValProxy, + to: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_rotation_arc_colinear( + from: LuaReflectValProxy, + to: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_rotation_arc_2d( + from: LuaReflectValProxy, + to: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the rotation axis scaled by the rotation in radians. + + #[lua()] + fn to_scaled_axis( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the rotation angles for the given euler rotation sequence. + + #[lua()] + fn to_euler( + _self: LuaReflectValProxy, + order: LuaReflectValProxy, + ) -> (f64, f64, f64); + +"#, + r#" +/// `[x, y, z, w]` + + #[lua()] + fn to_array(_self: LuaReflectRefProxy) -> [f64; 4]; + +"#, + r#" +/// Returns the vector part of the quaternion. + + #[lua()] + fn xyz( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Returns the quaternion conjugate of `self`. For a unit quaternion the +/// conjugate is also the inverse. + + #[lua()] + fn conjugate( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn inverse( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn dot( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> f64; + +"#, + r#" +/// Computes the length of `self`. + + #[lua()] + fn length(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Computes the squared length of `self`. +/// This is generally faster than `length()` as it avoids a square +/// root operation. + + #[lua()] + fn length_squared(_self: LuaReflectValProxy) -> f64; + +"#, + r#" +/// Computes `1.0 / length()`. +/// For valid results, `self` must _not_ be of length zero. + + #[lua()] + fn length_recip(_self: LuaReflectValProxy) -> 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()] + fn normalize( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_finite(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +/// Returns `true` if any elements are `NAN`. + + #[lua()] + fn is_nan(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +/// Returns whether `self` of length `1.0` or not. +/// Uses a precision threshold of `1e-6`. + + #[lua()] + fn is_normalized(_self: LuaReflectValProxy) -> bool; + +"#, + r#" + + #[lua()] + fn is_near_identity(_self: LuaReflectValProxy) -> 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()] + fn angle_between( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> 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()] + fn rotate_towards( + _self: LuaReflectRefProxy, + rhs: LuaReflectValProxy, + max_angle: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn abs_diff_eq( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + 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()] + fn lerp( + _self: LuaReflectValProxy, + end: LuaReflectValProxy, + s: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn slerp( + _self: LuaReflectValProxy, + end: LuaReflectValProxy, + s: f64, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn mul_vec3( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn mul_quat( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_affine3( + a: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua()] + fn as_quat( + _self: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> bool; + +"#, + 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::", composite = "add")] + fn add( + _self: LuaReflectValProxy, + rhs: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct DQuat { + x: f64, + y: f64, + z: f64, + w: f64, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::EulerRot", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct EulerRot {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::BVec3A", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Creates a new vector mask. + + #[lua()] + fn new(x: bool, y: bool, z: bool) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector mask with all elements set to `v`. + + #[lua()] + fn splat(v: bool) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector mask from a bool array. + + #[lua()] + fn from_array(a: [bool; 3]) -> LuaReflectValProxy; + +"#, + 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()] + fn bitmask(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Returns true if any of the elements are true, false otherwise. + + #[lua()] + fn any(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +/// Returns true if all the elements are true, false otherwise. + + #[lua()] + fn all(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +/// Tests the value at `index`. +/// Panics if `index` is greater than 2. + + #[lua()] + fn test(_self: LuaReflectRefProxy, index: usize) -> bool; + +"#, + r#" +/// Sets the element at `index`. +/// Panics if `index` is greater than 2. + + #[lua()] + fn set( + _self: LuaReflectRefMutProxy, + index: usize, + value: bool, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct BVec3A(); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::math::BVec4A", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + rhs: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Creates a new vector mask. + + #[lua()] + fn new(x: bool, y: bool, z: bool, w: bool) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a vector mask with all elements set to `v`. + + #[lua()] + fn splat(v: bool) -> LuaReflectValProxy; + +"#, + r#" +/// Creates a new vector mask from a bool array. + + #[lua()] + fn from_array(a: [bool; 4]) -> LuaReflectValProxy; + +"#, + 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()] + fn bitmask(_self: LuaReflectValProxy) -> u32; + +"#, + r#" +/// Returns true if any of the elements are true, false otherwise. + + #[lua()] + fn any(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +/// Returns true if all the elements are true, false otherwise. + + #[lua()] + fn all(_self: LuaReflectValProxy) -> bool; + +"#, + r#" +/// Tests the value at `index`. +/// Panics if `index` is greater than 3. + + #[lua()] + fn test(_self: LuaReflectRefProxy, index: usize) -> bool; + +"#, + r#" +/// Sets the element at `index`. +/// Panics if `index` is greater than 3. + + #[lua()] + fn set( + _self: LuaReflectRefMutProxy, + index: usize, + value: bool, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct BVec4A(); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "smol_str::SmolStr", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua()] + fn to_string(_self: LuaReflectRefProxy) -> std::string::String; + +"#, + r#" + + #[lua()] + fn len(_self: LuaReflectRefProxy) -> usize; + +"#, + r#" + + #[lua()] + fn is_empty(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" + + #[lua()] + fn is_heap_allocated(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct SmolStr(); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "uuid::Uuid", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[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()] + fn get_version_num(_self: LuaReflectRefProxy) -> 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()] + fn as_u128(_self: LuaReflectRefProxy) -> 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()] + fn to_u128_le(_self: LuaReflectRefProxy) -> 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()] + fn as_u64_pair(_self: LuaReflectRefProxy) -> (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()] + fn into_bytes(_self: LuaReflectValProxy) -> [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()] + fn to_bytes_le(_self: LuaReflectRefProxy) -> [u8; 16]; + +"#, + r#" +/// Tests if the UUID is nil (all zeros). + + #[lua()] + fn is_nil(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Tests if the UUID is max (all ones). + + #[lua()] + fn is_max(_self: LuaReflectRefProxy) -> 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()] + 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()] + fn get_node_id( + _self: LuaReflectRefProxy, + ) -> bevy::reflect::erased_serde::__private::serde::__private::Option<[u8; 6]>; + +"#, + r#" + + #[lua(as_trait = "bevy::reflect::erased_serde::__private::serde::__private::Clone")] + fn clone(_self: LuaReflectRefProxy) -> LuaReflectValProxy; + +"#, + 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()] + fn new_v4() -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq(_self: LuaReflectRefProxy) -> (); + +"#, + 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()] + fn nil() -> LuaReflectValProxy; + +"#, + 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()] + fn max() -> LuaReflectValProxy; + +"#, + 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()] + fn from_u128(v: u128) -> LuaReflectValProxy; + +"#, + 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()] + fn from_u128_le(v: u128) -> LuaReflectValProxy; + +"#, + 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()] + fn from_u64_pair(high_bits: u64, low_bits: u64) -> LuaReflectValProxy; + +"#, + 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()] + fn from_bytes(bytes: [u8; 16]) -> LuaReflectValProxy; + +"#, + 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()] + fn from_bytes_le(b: [u8; 16]) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Uuid(); +#[derive(Default)] +pub(crate) struct Globals; +impl crate::tealr::mlu::ExportInstances for Globals { + fn add_instances<'lua, T: crate::tealr::mlu::InstanceCollector<'lua>>( + self, + instances: &mut T, + ) -> crate::tealr::mlu::mlua::Result<()> { + instances + .add_instance( + "AtomicBool", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "AtomicI16", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "AtomicI32", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "AtomicI64", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "AtomicI8", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "AtomicIsize", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "AtomicU16", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "AtomicU32", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "AtomicU64", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "AtomicU8", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "AtomicUsize", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "Duration", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "Instant", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "PathBuf", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance("Quat", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("Vec3", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("IVec2", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("IVec3", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("IVec4", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance( + "I64Vec2", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "I64Vec3", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "I64Vec4", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance("UVec2", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("UVec3", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("UVec4", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance( + "U64Vec2", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "U64Vec3", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "U64Vec4", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance("Vec2", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("Vec3A", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("Vec4", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("BVec2", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("BVec3", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("BVec4", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("DVec2", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("DVec3", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("DVec4", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("Mat2", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("Mat3", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("Mat3A", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("Mat4", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("DMat2", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("DMat3", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("DMat4", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance( + "Affine2", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "Affine3A", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "DAffine2", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "DAffine3", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance("DQuat", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("BVec3A", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("BVec4A", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance("Uuid", crate::tealr::mlu::UserDataProxy::::new)?; + Ok(()) + } +} +fn bevy_reflect_context_initializer( + _: &bevy_mod_scripting_core::script::ScriptId, + ctx: &mut crate::prelude::Lua, +) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { + crate::tealr::mlu::set_global_env(Globals, ctx)?; + Ok(()) +} +pub struct BevyReflectScriptingPlugin; +impl bevy::app::Plugin for BevyReflectScriptingPlugin { + fn build(&self, app: &mut bevy::prelude::App) { + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.add_context_initializer::<()>(bevy_reflect_context_initializer); + app.add_documentation_fragment( + crate::docs::LuaDocumentationFragment::new( + "BevyReflectAPI", + |tw| { + tw.document_global_instance::() + .expect("Something went wrong documenting globals") + .process_type::() + .process_type::< + crate::tealr::mlu::UserDataProxy, + >() + .process_type::() + .process_type::>() + .process_type::() + .process_type::>() + .process_type::() + .process_type::>() + .process_type::() + .process_type::>() + .process_type::() + .process_type::< + crate::tealr::mlu::UserDataProxy, + >() + .process_type::() + .process_type::>() + .process_type::() + .process_type::>() + .process_type::() + .process_type::>() + .process_type::() + .process_type::>() + .process_type::() + .process_type::< + crate::tealr::mlu::UserDataProxy, + >() + .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::() + .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::() + .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::() + .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::() + .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::>() + .process_type::() + .process_type::>() + .process_type::() + .process_type::() + .process_type::>() + }, + ), + ); + } +} diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_time.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_time.rs new file mode 100644 index 0000000000..34b1e2fd95 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_time.rs @@ -0,0 +1,615 @@ +// @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, +}; +use crate::{ + bindings::proxy::{ + LuaReflectRefProxy, LuaReflectRefMutProxy, LuaReflectValProxy, LuaValProxy, + LuaIdentityProxy, + }, + type_data::RegisterLua, tealr::mlu::mlua::IntoLua, +}; +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::time::prelude::Fixed", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Fixed {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::time::prelude::Real", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Real {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::time::prelude::Timer", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_seconds( + duration: f32, + mode: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn finished(_self: LuaReflectRefProxy) -> 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()] + fn just_finished(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" +/// Returns the time elapsed on the timer as an `f32`. +/// See also [`Timer::elapsed`](Timer::elapsed). + + #[lua()] + fn elapsed_secs(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// Returns the time elapsed on the timer as an `f64`. +/// See also [`Timer::elapsed`](Timer::elapsed). + + #[lua()] + fn elapsed_secs_f64(_self: LuaReflectRefProxy) -> f64; + +"#, + 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()] + fn mode( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn set_mode( + _self: LuaReflectRefMutProxy, + mode: LuaReflectValProxy, + ) -> (); + +"#, + 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()] + fn pause(_self: LuaReflectRefMutProxy) -> (); + +"#, + 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()] + fn unpause(_self: LuaReflectRefMutProxy) -> (); + +"#, + 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()] + fn paused(_self: LuaReflectRefProxy) -> 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()] + fn reset(_self: LuaReflectRefMutProxy) -> (); + +"#, + 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()] + fn fraction(_self: LuaReflectRefProxy) -> 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()] + fn fraction_remaining(_self: LuaReflectRefProxy) -> 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()] + fn remaining_secs(_self: LuaReflectRefProxy) -> f32; + +"#, + 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()] + fn times_finished_this_tick( + _self: LuaReflectRefProxy, + ) -> u32; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Timer {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::time::prelude::TimerMode", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct TimerMode {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::time::prelude::Virtual", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Virtual {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::time::Stopwatch", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[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()] + fn new() -> LuaReflectValProxy; + +"#, + 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()] + fn elapsed_secs(_self: LuaReflectRefProxy) -> 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()] + fn elapsed_secs_f64(_self: LuaReflectRefProxy) -> f64; + +"#, + 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()] + fn pause(_self: LuaReflectRefMutProxy) -> (); + +"#, + 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()] + fn unpause(_self: LuaReflectRefMutProxy) -> (); + +"#, + 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()] + fn is_paused(_self: LuaReflectRefProxy) -> 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()] + fn reset(_self: LuaReflectRefMutProxy) -> (); + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::PartialEq::", composite = "eq")] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Stopwatch {} +#[derive(Default)] +pub(crate) struct Globals; +impl crate::tealr::mlu::ExportInstances for Globals { + fn add_instances<'lua, T: crate::tealr::mlu::InstanceCollector<'lua>>( + self, + instances: &mut T, + ) -> crate::tealr::mlu::mlua::Result<()> { + instances + .add_instance("Timer", crate::tealr::mlu::UserDataProxy::::new)?; + instances + .add_instance( + "Stopwatch", + crate::tealr::mlu::UserDataProxy::::new, + )?; + Ok(()) + } +} +fn bevy_time_context_initializer( + _: &bevy_mod_scripting_core::script::ScriptId, + ctx: &mut crate::prelude::Lua, +) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { + crate::tealr::mlu::set_global_env(Globals, ctx)?; + Ok(()) +} +pub struct BevyTimeScriptingPlugin; +impl bevy::app::Plugin for BevyTimeScriptingPlugin { + fn build(&self, app: &mut bevy::prelude::App) { + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.add_context_initializer::<()>(bevy_time_context_initializer); + app.add_documentation_fragment( + crate::docs::LuaDocumentationFragment::new( + "BevyTimeAPI", + |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::>() + }, + ), + ); + } +} diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_transform.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_transform.rs new file mode 100644 index 0000000000..9ce8f17e40 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_transform.rs @@ -0,0 +1,360 @@ +// @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, +}; +use crate::{ + bindings::proxy::{ + LuaReflectRefProxy, LuaReflectRefMutProxy, LuaReflectValProxy, LuaValProxy, + LuaIdentityProxy, + }, + type_data::RegisterLua, tealr::mlu::mlua::IntoLua, +}; +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::transform::components::GlobalTransform", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::ops::Mul::", + composite = "mul", + )] + fn mul( + _self: LuaReflectValProxy, + transform: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::ops::Mul::", + composite = "mul", + )] + fn mul( + _self: LuaReflectValProxy, + global_transform: LuaReflectValProxy< + bevy::transform::components::GlobalTransform, + >, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua()] + fn from_xyz( + x: f32, + y: f32, + z: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn compute_transform( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn reparented_to( + _self: LuaReflectRefProxy, + parent: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Multiplies `self` with `transform` component by component, returning the +/// resulting [`GlobalTransform`] + + #[lua()] + fn mul_transform( + _self: LuaReflectRefProxy, + transform: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct GlobalTransform(); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::transform::components::Transform", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua( + as_trait = "std::ops::Mul::", + composite = "mul", + )] + fn mul( + _self: LuaReflectValProxy, + global_transform: LuaReflectValProxy< + bevy::transform::components::GlobalTransform, + >, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn from_xyz( + x: f32, + y: f32, + z: f32, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn rotate_x( + _self: LuaReflectRefMutProxy, + 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()] + fn rotate_y( + _self: LuaReflectRefMutProxy, + 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()] + fn rotate_z( + _self: LuaReflectRefMutProxy, + angle: f32, + ) -> (); + +"#, + r#" +/// Rotates this [`Transform`] around its local `X` axis by `angle` (in radians). + + #[lua()] + fn rotate_local_x( + _self: LuaReflectRefMutProxy, + angle: f32, + ) -> (); + +"#, + r#" +/// Rotates this [`Transform`] around its local `Y` axis by `angle` (in radians). + + #[lua()] + fn rotate_local_y( + _self: LuaReflectRefMutProxy, + angle: f32, + ) -> (); + +"#, + r#" +/// Rotates this [`Transform`] around its local `Z` axis by `angle` (in radians). + + #[lua()] + fn rotate_local_z( + _self: LuaReflectRefMutProxy, + angle: f32, + ) -> (); + +"#, + r#" +/// Multiplies `self` with `transform` component by component, returning the +/// resulting [`Transform`] + + #[lua()] + fn mul_transform( + _self: LuaReflectRefProxy, + transform: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + 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()] + fn is_finite( + _self: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::ops::Mul::", + composite = "mul", + )] + fn mul( + _self: LuaReflectValProxy, + transform: LuaReflectValProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Transform { + translation: ReflectReference, + rotation: ReflectReference, + scale: ReflectReference, +} +#[derive(Default)] +pub(crate) struct Globals; +impl crate::tealr::mlu::ExportInstances for Globals { + fn add_instances<'lua, T: crate::tealr::mlu::InstanceCollector<'lua>>( + self, + instances: &mut T, + ) -> crate::tealr::mlu::mlua::Result<()> { + instances + .add_instance( + "GlobalTransform", + crate::tealr::mlu::UserDataProxy::::new, + )?; + instances + .add_instance( + "Transform", + crate::tealr::mlu::UserDataProxy::::new, + )?; + Ok(()) + } +} +fn bevy_transform_context_initializer( + _: &bevy_mod_scripting_core::script::ScriptId, + ctx: &mut crate::prelude::Lua, +) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { + crate::tealr::mlu::set_global_env(Globals, ctx)?; + Ok(()) +} +pub struct BevyTransformScriptingPlugin; +impl bevy::app::Plugin for BevyTransformScriptingPlugin { + fn build(&self, app: &mut bevy::prelude::App) { + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.add_context_initializer::<()>(bevy_transform_context_initializer); + app.add_documentation_fragment( + crate::docs::LuaDocumentationFragment::new( + "BevyTransformAPI", + |tw| { + tw.document_global_instance::() + .expect("Something went wrong documenting globals") + .process_type::() + .process_type::< + crate::tealr::mlu::UserDataProxy, + >() + .process_type::() + .process_type::>() + }, + ), + ); + } +} diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_window.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_window.rs new file mode 100644 index 0000000000..1814800abc --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_window.rs @@ -0,0 +1,1987 @@ +// @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_a11y::*; +use super::bevy_ecs::*; +use super::bevy_reflect::*; +use super::bevy_core::*; +use super::bevy_input::*; +use super::bevy_math::*; +use bevy_mod_scripting_core::{ + AddContextInitializer, StoreDocumentation, bindings::ReflectReference, +}; +use crate::{ + bindings::proxy::{ + LuaReflectRefProxy, LuaReflectRefMutProxy, LuaReflectValProxy, LuaValProxy, + LuaIdentityProxy, + }, + type_data::RegisterLua, tealr::mlu::mlua::IntoLua, +}; +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::prelude::CursorEntered", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct CursorEntered { + window: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::prelude::CursorLeft", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct CursorLeft { + window: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::prelude::CursorMoved", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct CursorMoved { + window: ReflectReference, + position: ReflectReference, + delta: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::prelude::FileDragAndDrop", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct FileDragAndDrop {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::prelude::Ime", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Ime {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::prelude::MonitorSelection", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct MonitorSelection {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::prelude::Window", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Setting to true will attempt to maximize the window. +/// Setting to false will attempt to un-maximize the window. + + #[lua()] + fn set_maximized( + _self: LuaReflectRefMutProxy, + maximized: bool, + ) -> (); + +"#, + r#" +/// Setting to true will attempt to minimize the window. +/// Setting to false will attempt to un-minimize the window. + + #[lua()] + fn set_minimized( + _self: LuaReflectRefMutProxy, + minimized: bool, + ) -> (); + +"#, + r#" +/// Calling this will attempt to start a drag-move of the window. +/// There is no guarantee that this will work unless the left mouse button was +/// pressed immediately before this function was called. + + #[lua()] + fn start_drag_move( + _self: LuaReflectRefMutProxy, + ) -> (); + +"#, + r#" +/// The window's client area width in logical pixels. +/// See [`WindowResolution`] for an explanation about logical/physical sizes. + + #[lua()] + fn width(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// The window's client area height in logical pixels. +/// See [`WindowResolution`] for an explanation about logical/physical sizes. + + #[lua()] + fn height(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// The window's client area width in physical pixels. +/// See [`WindowResolution`] for an explanation about logical/physical sizes. + + #[lua()] + fn physical_width(_self: LuaReflectRefProxy) -> u32; + +"#, + r#" +/// The window's client area height in physical pixels. +/// See [`WindowResolution`] for an explanation about logical/physical sizes. + + #[lua()] + fn physical_height(_self: LuaReflectRefProxy) -> u32; + +"#, + r#" +/// The window's scale factor. +/// Ratio of physical size to logical size, see [`WindowResolution`]. + + #[lua()] + fn scale_factor(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Window { + cursor_options: bevy::window::CursorOptions, + present_mode: bevy::window::PresentMode, + mode: bevy::window::WindowMode, + position: bevy::window::prelude::WindowPosition, + resolution: bevy::window::WindowResolution, + title: std::string::String, + name: std::option::Option, + composite_alpha_mode: bevy::window::CompositeAlphaMode, + resize_constraints: bevy::window::prelude::WindowResizeConstraints, + resizable: bool, + enabled_buttons: bevy::window::EnabledButtons, + decorations: bool, + transparent: bool, + focused: bool, + window_level: bevy::window::WindowLevel, + canvas: std::option::Option, + fit_canvas_to_parent: bool, + prevent_default_event_handling: bool, + internal: bevy::window::InternalWindowState, + ime_enabled: bool, + ime_position: ReflectReference, + window_theme: ReflectReference, + visible: bool, + skip_taskbar: bool, + desired_maximum_frame_latency: ReflectReference, + recognize_pinch_gesture: bool, + recognize_rotation_gesture: bool, + recognize_doubletap_gesture: bool, + recognize_pan_gesture: ReflectReference, + movable_by_window_background: bool, + fullsize_content_view: bool, + has_shadow: bool, + titlebar_shown: bool, + titlebar_transparent: bool, + titlebar_show_title: bool, + titlebar_show_buttons: bool, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::prelude::WindowMoved", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowMoved { + window: ReflectReference, + position: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::prelude::WindowPosition", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Set the window to a specific monitor. + + #[lua()] + fn center( + _self: LuaReflectRefMutProxy, + monitor: LuaReflectValProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowPosition {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::prelude::WindowResizeConstraints", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Checks if the constraints are valid. +/// Will output warnings if it isn't. + + #[lua()] + fn check_constraints( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowResizeConstraints { + min_width: f32, + min_height: f32, + max_width: f32, + max_height: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::WindowEvent", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowEvent {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::WindowResized", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowResized { + window: ReflectReference, + width: f32, + height: f32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::WindowCreated", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowCreated { + window: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::WindowClosing", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowClosing { + window: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::WindowClosed", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowClosed { + window: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::WindowCloseRequested", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowCloseRequested { + window: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::WindowDestroyed", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowDestroyed { + window: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::RequestRedraw", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct RequestRedraw {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::WindowFocused", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowFocused { + window: ReflectReference, + focused: bool, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::WindowOccluded", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowOccluded { + window: ReflectReference, + occluded: bool, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::WindowScaleFactorChanged", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowScaleFactorChanged { + window: ReflectReference, + scale_factor: f64, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::WindowBackendScaleFactorChanged", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowBackendScaleFactorChanged { + window: ReflectReference, + scale_factor: f64, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::WindowThemeChanged", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowThemeChanged { + window: ReflectReference, + theme: bevy::window::WindowTheme, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::AppLifecycle", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Return `true` if the app can be updated. + + #[lua()] + fn is_active(_self: LuaReflectRefProxy) -> bool; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct AppLifecycle {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::PrimaryWindow", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct PrimaryWindow {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::WindowTheme", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowTheme {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::Monitor", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct Monitor { + name: std::option::Option, + physical_height: u32, + physical_width: u32, + physical_position: ReflectReference, + refresh_rate_millihertz: std::option::Option, + scale_factor: f64, + video_modes: ReflectReference, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::VideoMode", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct VideoMode { + physical_size: ReflectReference, + bit_depth: u16, + refresh_rate_millihertz: u32, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::PrimaryMonitor", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct PrimaryMonitor {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::SystemCursorIcon", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct SystemCursorIcon {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::WindowRef", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowRef {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::NormalizedWindowRef", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct NormalizedWindowRef(); +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::CursorOptions", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct CursorOptions { + visible: bool, + grab_mode: bevy::window::CursorGrabMode, + hit_test: bool, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::PresentMode", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct PresentMode {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::WindowMode", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowMode {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::WindowResolution", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" +/// Creates a new [`WindowResolution`]. + + #[lua()] + fn new( + physical_width: f32, + physical_height: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// Builder method for adding a scale factor override to the resolution. + + #[lua()] + fn with_scale_factor_override( + _self: LuaReflectValProxy, + scale_factor_override: f32, + ) -> LuaReflectValProxy; + +"#, + r#" +/// The window's client area width in logical pixels. + + #[lua()] + fn width(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// The window's client area height in logical pixels. + + #[lua()] + fn height(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// The window's client area width in physical pixels. + + #[lua()] + fn physical_width(_self: LuaReflectRefProxy) -> u32; + +"#, + r#" +/// The window's client area height in physical pixels. + + #[lua()] + fn physical_height(_self: LuaReflectRefProxy) -> u32; + +"#, + r#" +/// The ratio of physical pixels to logical pixels. +/// `physical_pixels = logical_pixels * scale_factor` + + #[lua()] + fn scale_factor(_self: LuaReflectRefProxy) -> f32; + +"#, + r#" +/// The window scale factor as reported by the window backend. +/// This value is unaffected by [`WindowResolution::scale_factor_override`]. + + #[lua()] + fn base_scale_factor( + _self: LuaReflectRefProxy, + ) -> f32; + +"#, + r#" +/// The scale factor set with [`WindowResolution::set_scale_factor_override`]. +/// This value may be different from the scale factor reported by the window backend. + + #[lua()] + fn scale_factor_override( + _self: LuaReflectRefProxy, + ) -> std::option::Option; + +"#, + r#" +/// Set the window's logical resolution. + + #[lua()] + fn set( + _self: LuaReflectRefMutProxy, + width: f32, + height: f32, + ) -> (); + +"#, + r#" +/// Set the window's physical resolution. +/// This will ignore the scale factor setting, so most of the time you should +/// prefer to use [`WindowResolution::set`]. + + #[lua()] + fn set_physical_resolution( + _self: LuaReflectRefMutProxy, + width: u32, + height: u32, + ) -> (); + +"#, + r#" +/// Set the window's scale factor, this may get overridden by the backend. + + #[lua()] + fn set_scale_factor( + _self: LuaReflectRefMutProxy, + scale_factor: f32, + ) -> (); + +"#, + r#" +/// Set the window's scale factor, and apply it to the currently known physical size. +/// This may get overridden by the backend. This is mostly useful on window creation, +/// so that the window is created with the expected size instead of waiting for a resize +/// event after its creation. + + #[lua()] + fn set_scale_factor_and_apply_to_physical_size( + _self: LuaReflectRefMutProxy, + scale_factor: f32, + ) -> (); + +"#, + r#" +/// Set the window's scale factor, this will be used over what the backend decides. +/// This can change the logical and physical sizes if the resulting physical +/// size is not within the limits. + + #[lua()] + fn set_scale_factor_override( + _self: LuaReflectRefMutProxy, + scale_factor_override: std::option::Option, + ) -> (); + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowResolution {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::CompositeAlphaMode", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct CompositeAlphaMode {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::EnabledButtons", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct EnabledButtons { + minimize: bool, + maximize: bool, + close: bool, +} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::WindowLevel", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct WindowLevel {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::InternalWindowState", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" +/// Consumes the current maximize request, if it exists. This should only be called by window backends. + + #[lua()] + fn take_maximize_request( + _self: LuaReflectRefMutProxy, + ) -> std::option::Option; + +"#, + r#" +/// Consumes the current minimize request, if it exists. This should only be called by window backends. + + #[lua()] + fn take_minimize_request( + _self: LuaReflectRefMutProxy, + ) -> std::option::Option; + +"#, + r#" +/// Consumes the current move request, if it exists. This should only be called by window backends. + + #[lua()] + fn take_move_request( + _self: LuaReflectRefMutProxy, + ) -> bool; + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct InternalWindowState {} +#[derive(bevy_mod_scripting_derive::LuaProxy)] +#[proxy( + remote = "bevy::window::CursorGrabMode", + bms_core_path = "bevy_mod_scripting_core", + bms_lua_path = "crate", + functions[r#" + + #[lua( + as_trait = "std::cmp::PartialEq::", + composite = "eq", + )] + fn eq( + _self: LuaReflectRefProxy, + other: LuaReflectRefProxy, + ) -> bool; + +"#, + r#" + + #[lua(as_trait = "std::clone::Clone")] + fn clone( + _self: LuaReflectRefProxy, + ) -> LuaReflectValProxy; + +"#, + r#" + + #[lua(as_trait = "std::cmp::Eq")] + fn assert_receiver_is_total_eq( + _self: LuaReflectRefProxy, + ) -> (); + +"#, + r#" +#[lua(metamethod="ToString")] +fn index(&self) -> String { + format!("{:?}", _self) +} +"#] +)] +pub struct CursorGrabMode {} +#[derive(Default)] +pub(crate) struct Globals; +impl crate::tealr::mlu::ExportInstances for Globals { + fn add_instances<'lua, T: crate::tealr::mlu::InstanceCollector<'lua>>( + self, + instances: &mut T, + ) -> crate::tealr::mlu::mlua::Result<()> { + instances + .add_instance( + "WindowResolution", + crate::tealr::mlu::UserDataProxy::::new, + )?; + Ok(()) + } +} +fn bevy_window_context_initializer( + _: &bevy_mod_scripting_core::script::ScriptId, + ctx: &mut crate::prelude::Lua, +) -> Result<(), bevy_mod_scripting_core::error::ScriptError> { + crate::tealr::mlu::set_global_env(Globals, ctx)?; + Ok(()) +} +pub struct BevyWindowScriptingPlugin; +impl bevy::app::Plugin for BevyWindowScriptingPlugin { + fn build(&self, app: &mut bevy::prelude::App) { + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.register_lua_proxy::(); + app.add_context_initializer::<()>(bevy_window_context_initializer); + app.add_documentation_fragment( + crate::docs::LuaDocumentationFragment::new( + "BevyWindowAPI", + |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::() + .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::() + .process_type::() + .process_type::() + .process_type::() + .process_type::() + .process_type::< + crate::tealr::mlu::UserDataProxy, + >() + .process_type::() + .process_type::() + .process_type::() + .process_type::() + .process_type::() + }, + ), + ); + } +} diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/mod.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/mod.rs new file mode 100644 index 0000000000..8354d705cc --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/providers/mod.rs @@ -0,0 +1,29 @@ +// @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_a11y; +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_window; +pub mod bevy_reflect; +pub struct LuaBevyScriptingPlugin; +impl bevy::app::Plugin for LuaBevyScriptingPlugin { + fn build(&self, app: &mut bevy::prelude::App) { + bevy_a11y::BevyA11YScriptingPlugin.build(app); + bevy_ecs::BevyEcsScriptingPlugin.build(app); + bevy_transform::BevyTransformScriptingPlugin.build(app); + bevy_math::BevyMathScriptingPlugin.build(app); + bevy_input::BevyInputScriptingPlugin.build(app); + bevy_core::BevyCoreScriptingPlugin.build(app); + bevy_time::BevyTimeScriptingPlugin.build(app); + bevy_hierarchy::BevyHierarchyScriptingPlugin.build(app); + bevy_window::BevyWindowScriptingPlugin.build(app); + bevy_reflect::BevyReflectScriptingPlugin.build(app); + } +} diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/proxy.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/proxy.rs new file mode 100644 index 0000000000..83689e639a --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/proxy.rs @@ -0,0 +1,248 @@ +//! Set of traits used to define how types are turned into and from proxies in Lua. +//! Proxies can either be logical "copies" or owned "direct representations" of the instance, or references to one via the [`bevy_mod_scripting_core::bindings::ReflectReference`] construct. + +use bevy::reflect::{FromReflect, Reflect, TypeRegistry}; +use bevy_mod_scripting_core::{ + bindings::{ + Proxy, ReflectAllocator, ReflectRefMutProxy, ReflectRefProxy, ReflectReference, + ReflectValProxy, Unproxy, ValProxy, WorldAccessGuard, WorldAccessUnit, WorldAccessWrite, + }, + error::{ScriptError, ScriptResult}, +}; +use tealr::{ + mlu::mlua::{Error, FromLua, IntoLua, IntoLuaMulti, Lua, Value}, + ToTypename, +}; + +use super::world::Nil; + +/// Think of this as a Local trait alias for the [`Proxy`] trait. Specifies the proxy type for a given type. +pub trait LuaProxied { + type Proxy; +} + +/// Proxy which acts exactly like `T` when converting to Lua, but provides a `ToTypename` implementation based on another type `N`. +/// Used internally basically only to support Result types in Lua directly. +/// Will be unnecessary once I get rid of tealr. +pub(crate) struct TypenameProxy(T, std::marker::PhantomData); + +impl TypenameProxy { + pub fn new(value: T) -> Self { + Self(value, std::marker::PhantomData) + } +} + +impl ToTypename for TypenameProxy { + fn to_typename() -> tealr::Type { + N::to_typename() + } +} + +impl<'a, T: IntoLuaMulti<'a>, N: ToTypename> IntoLua<'a> for TypenameProxy { + fn into_lua(self, lua: &'a Lua) -> tealr::mlu::mlua::Result> { + self.0 + .into_lua_multi(lua) + .map(|mut v| v.pop_front().unwrap_or_else(|| Value::Nil)) + } +} + +/// Proxy which converts to lua by throwing the error. Can be used inside a [`Result`] to proxy into a result which will throw the error if it's an [`Err`] when converting to Lua. +pub struct ErrorProxy(E); + +impl<'a, E: Into>> IntoLua<'a> + for ErrorProxy +{ + fn into_lua(self, _: &'a Lua) -> tealr::mlu::mlua::prelude::LuaResult> { + Err(Error::external(self.0)) + } +} + +/// This should never really need to be used, but it's here so we can use the type in Lua. +impl ToTypename for ErrorProxy { + fn to_typename() -> tealr::Type { + tealr::Type::new_single("Error", tealr::KindOfType::External) + } +} + +impl>> Proxy for ErrorProxy { + type Input<'i> = E; + fn proxy<'i>(value: Self::Input<'i>) -> ScriptResult { + Ok(Self(value)) + } +} + +/// Convenience for proxying a type into lua via itself without implementing [`Proxy`] on it. +/// Converts to Lua via T's implementation of IntoLua directly +pub struct LuaIdentityProxy(pub Option); + +impl Proxy for LuaIdentityProxy { + type Input<'i> = T; + fn proxy<'i>(value: Self::Input<'i>) -> ScriptResult { + Ok(Self(Some(value))) + } +} + +impl Unproxy for LuaIdentityProxy { + type Output<'o> = T where + Self: 'o; + + fn unproxy<'o>(&'o mut self) -> ScriptResult> { + Ok(self + .0 + .take() + .expect("IdentityProxy was already unproxied before")) + } +} + +impl ToTypename for LuaIdentityProxy { + fn to_typename() -> tealr::Type { + T::to_typename() + } +} + +impl<'a, T: IntoLua<'a>> IntoLua<'a> for LuaIdentityProxy { + fn into_lua(self, lua: &'a Lua) -> tealr::mlu::mlua::prelude::LuaResult> { + self.0.into_lua(lua) + } +} + +impl<'a, T: FromLua<'a>> FromLua<'a> for LuaIdentityProxy { + fn from_lua(value: Value<'a>, lua: &'a Lua) -> Result { + Ok(Self(Some(T::from_lua(value, lua)?))) + } +} + +/// Proxy which uses [`ValProxy`] to represent the type in Lua. Requires that the type implements [`LuaProxied`] and that the proxy implements [`From`] for the type. +/// +/// Used for types which are copied into lua rather than references to originals in the world. +/// Use when your type does not implement Reflect or if it's a simple type that can be copied into lua. +pub struct LuaValProxy(pub ValProxy); + +/// Proxy which uses [`ReflectValProxy`] to represent the type in Lua. Requires that the type implements [`LuaProxied`] and [`FromReflect`] and that the proxy implements [`AsRef`]. +/// Think of the proxy as just a container for a [`ReflectReference`]. +/// +/// Semantically equivalent to `T`, use it where you would use the `T` type. +pub struct LuaReflectValProxy(pub ReflectValProxy); + +/// Proxy which uses [`ReflectRefProxy`] to represent the type in Lua. Requires that the type implements [`LuaProxied`] and [`Reflect`] and that the proxy implements [`AsRef`]. +/// Think of the proxy as just a container for a [`ReflectReference`]. +/// +/// Semantically equivalent to `&T`, use it where you would use the `&T` type. +pub struct LuaReflectRefProxy(pub ReflectRefProxy); + +/// Proxy which uses [`ReflectRefMutProxy`] to represent the type in Lua. Requires that the type implements [`LuaProxied`] and [`Reflect`] and that the proxy implements [`AsRef`]. +/// Think of the proxy as just a container for a [`ReflectReference`]. +/// +/// Semantically equivalent to `&mut T`, use it where you would use the `&mut T` type. +pub struct LuaReflectRefMutProxy(pub ReflectRefMutProxy); + +macro_rules! impl_lua_unproxy { + ($ty:ident as $as:ident ($generic:tt) $($bound_var:path : ($($bounds:tt)+),)*) => { + impl <$generic> Unproxy for $ty<$generic> + where + $($bound_var : $($bounds)+),* + { + type Output<'b> = <$as<$generic,$generic::Proxy> as Unproxy>::Output<'b> where Self: 'b; + + fn collect_accesses<'w>( + &self, + guard: &WorldAccessGuard<'w>, + accesses: &mut smallvec::SmallVec<[WorldAccessWrite<'w>; 1]>, + ) -> ScriptResult<()> { + self.0.collect_accesses(guard, accesses) + } + + fn unproxy(&mut self) -> ScriptResult> { + self.0.unproxy() + } + + unsafe fn unproxy_with_world<'w,'o>( + &'o mut self, + guard: &WorldAccessGuard<'w>, + accesses: &'o [WorldAccessUnit<'w>], + type_registry: &TypeRegistry, + allocator: &ReflectAllocator, + ) -> ScriptResult> { + self.0 + .unproxy_with_world(guard, accesses, type_registry, allocator) + } + + fn accesses_len(&self) -> usize { + self.0.accesses_len() + } + } + + impl<'lua, $generic: LuaProxied> FromLua<'lua> for $ty<$generic> + where + $generic::Proxy: FromLua<'lua>, + { + fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result { + let inner: $generic::Proxy = $generic::Proxy::from_lua(value, lua)?; + let inner = $as::<$generic,$generic::Proxy>::new(inner); + Ok(Self(inner)) + } + } + + impl<'lua, $generic: LuaProxied> IntoLua<'lua> for $ty<$generic> + where + $generic::Proxy: IntoLua<'lua>, + { + fn into_lua(self, lua: &'lua Lua) -> tealr::mlu::mlua::prelude::LuaResult> { + self.0.0.into_lua(lua) + } + } + + impl ToTypename for $ty where T::Proxy: ToTypename { + fn to_typename() -> tealr::Type { + T::Proxy::to_typename() + } + } + }; +} + +macro_rules! impl_lua_proxy { + ($ty:ident as $as:ident => $generic:tt : $($bounds:path),* $(| T::Proxy: $($proxy_bounds:tt)*)?) => { + impl<$generic> bevy_mod_scripting_core::bindings::Proxy for $ty<$generic> + where + T::Proxy: $($($proxy_bounds)*)?, + T: $($bounds+)*, + { + type Input<'i>=<$as<$generic, $generic::Proxy> as bevy_mod_scripting_core::bindings::Proxy>::Input<'i>; + fn proxy<'i>(value: Self::Input<'i>) -> ScriptResult { + Ok(Self($as::<$generic,$generic::Proxy>::proxy(value)?)) + } + + fn proxy_with_allocator<'i>( + value: Self::Input<'i>, + allocator: &mut bevy_mod_scripting_core::bindings::ReflectAllocator, + ) -> ScriptResult { + Ok(Self($as::<$generic,$generic::Proxy>::proxy_with_allocator(value, allocator)?)) + } + } + + + }; +} + +impl_lua_proxy!(LuaValProxy as ValProxy => T : LuaProxied | T::Proxy: From); +impl_lua_proxy!(LuaReflectValProxy as ReflectValProxy => T : LuaProxied,Reflect | T::Proxy: From ); + +impl_lua_unproxy!(LuaValProxy as ValProxy (T) + T: (LuaProxied), + T: (for <'l> From<&'l T::Proxy>), +); +impl_lua_unproxy!(LuaReflectValProxy as ReflectValProxy (T) + T: (FromReflect), + T: (LuaProxied), + T::Proxy: (AsRef), +); +impl_lua_unproxy!(LuaReflectRefProxy as ReflectRefProxy (T) + T: (LuaProxied), + T: (Reflect), + T::Proxy: (AsRef), +); +impl_lua_unproxy!(LuaReflectRefMutProxy as ReflectRefMutProxy (T) + T: (LuaProxied), + T: (Reflect), + T::Proxy: (AsRef), +); diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/query.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/query.rs new file mode 100644 index 0000000000..5e5b1d0cfb --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/query.rs @@ -0,0 +1,122 @@ +use std::ops::{Deref, DerefMut}; + +use bevy::prelude::Entity; +use bevy_mod_scripting_core::bindings::{ + ReflectAllocator, ReflectReference, ScriptQueryBuilder, ScriptTypeRegistration, Unproxy, + ValProxy, +}; +use tealr::{ + mlu::{ + mlua::{IntoLua, Value}, + TealData, TypedFunction, + }, + ToTypename, +}; + +use crate::{impl_userdata_from_lua, impl_userdata_with_tealdata, util::Variadic}; + +use super::{ + proxy::{LuaProxied, LuaValProxy}, + reference::LuaReflectReference, + world::GetWorld, +}; + +#[derive(Default, Clone)] +pub struct LuaQueryBuilder(pub(crate) ScriptQueryBuilder); + +impl Deref for LuaQueryBuilder { + type Target = ScriptQueryBuilder; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for LuaQueryBuilder { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl LuaQueryBuilder {} + +impl LuaProxied for ScriptQueryBuilder { + type Proxy = LuaQueryBuilder; +} + +impl_userdata_from_lua!(LuaQueryBuilder); +impl_userdata_with_tealdata!(LuaQueryBuilder); + +impl TealData for LuaQueryBuilder { + fn add_methods<'lua, T: tealr::mlu::TealDataMethods<'lua, Self>>(methods: &mut T) { + methods.add_function( + "with", + |_, (mut this, mut query): (Self, Variadic>)| { + let registrations: Vec<_> = query + .iter_mut() + .map(|v| v.unproxy()) + .collect::>() + .map_err(tealr::mlu::mlua::Error::external)?; + this.0.with(registrations); + Ok(this) + }, + ); + + methods.add_function( + "without", + |_, (mut this, mut query): (Self, Variadic>)| { + let registrations: Vec<_> = query + .iter_mut() + .map(|v| v.unproxy()) + .collect::>() + .map_err(tealr::mlu::mlua::Error::external)?; + this.0.without(registrations); + Ok(this) + }, + ); + + methods.add_function("iter", |l, this: LuaQueryBuilder| { + let world = l.get_world(); + let mut result = world + .query(this.0) + .map_err(tealr::mlu::mlua::Error::external)?; + let mut len = result.len(); + let iterator = TypedFunction::from_rust_mut( + move |lua, ()| { + if len > 0 { + let result = result + .pop_front() + .expect("invariant: len of array = len && len > 0"); + let entity = + world.with_resource::(|_, mut allocator| { + ReflectReference::new_allocated(result.0, &mut allocator) + }); + let proxy_entity = + ::Proxy::from(entity).into_lua(lua)?; + let component_refs: Vec<_> = result + .1 + .into_iter() + .map(|r| LuaReflectReference(r).to_lua_proxy(lua)) + .collect::>()?; + + len -= 1; + + Ok(Variadic::new( + std::iter::once(proxy_entity).chain(component_refs.into_iter()), + )) + } else { + Ok(Variadic::new(vec![Value::Nil, Value::Nil])) + } + }, + l, + )?; + Ok(iterator) + }); + } +} + +impl ToTypename for LuaQueryBuilder { + fn to_typename() -> tealr::Type { + tealr::Type::new_single("QueryBuilder", tealr::KindOfType::External) + } +} 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 0000000000..17908091a3 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs @@ -0,0 +1,531 @@ +use std::{ + any::{Any, TypeId}, + error::Error, +}; + +use bevy::{ + ecs::{reflect::AppTypeRegistry, world::Mut}, + reflect::{OffsetAccess, ParsedPath, ReflectFromReflect}, +}; +use bevy_mod_scripting_core::{ + bindings::{ + ReflectAllocator, ReflectRefIter, ReflectReference, ReflectionPathElem, Unproxy, + WorldCallbackAccess, + }, + error::ScriptError, +}; +use tealr::mlu::{ + generics::Q, + mlua::{self, FromLua, IntoLua, Lua, MetaMethod, UserData, Value}, + TealData, TypedFunction, +}; + +use crate::{ + impl_userdata_from_lua, impl_userdata_with_tealdata, ReflectLuaProxied, ReflectLuaValue, +}; + +use super::{ + proxy::{LuaProxied, LuaValProxy}, + world::GetWorld, +}; + +/// 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, tealr::mlu::UserData, tealr::ToTypename, PartialEq)] +pub struct LuaReflectReference(pub ReflectReference); + +impl AsRef for LuaReflectReference { + fn as_ref(&self) -> &ReflectReference { + &self.0 + } +} + +impl LuaReflectReference { + pub fn len(&self, lua: &Lua) -> Result, mlua::Error> { + let world = lua.get_world(); + self.0 + .len(&world) + .map_err(tealr::mlu::mlua::Error::external) + } + + /// Queries the reflection system for a proxy registration for the underlying type. + /// If found will convert to lua using this proxy + /// If not found will use ::into_lua to convert to lua + pub fn to_lua_proxy(self, lua: &Lua) -> Result, mlua::Error> { + // note we do not need to refer to LuaWorld here, it does not matter what the proxy is, that's pretty neat, + let world = lua.get_world(); + // TODO: i don't like the pingponging between errors here, need something more ergonomic + // first we need the type id of the pointed to object to figure out how to work with it + let type_id = self.0.with_reflect(&world, |r, _, _| { + r.get_represented_type_info().map(|t| t.type_id()) + })?; + + // convenience, ideally we probably should just avoid lookups when no type id is here, but for now we just use a dummy type nothing will ever + // be registered for. If the type we're reflecting doesn't represent anything or a registered type, we use a generic reflect reference. + struct Dummy; + let type_id_or_dummy = type_id.unwrap_or(TypeId::of::()); + + if let Some(type_data) = world.with_resource::(|_, type_registry| { + type_registry + .read() + .get_type_data::(type_id_or_dummy) + .cloned() + }) { + self.0 + .with_reflect(&world, |r, _, _| (type_data.into_value)(r, lua))? + } else if let Some(type_data) = + world.with_resource::(|_, type_registry| { + type_registry + .read() + .get_type_data::(type_id_or_dummy) + .cloned() + }) + { + Ok((type_data.into_proxy)(self.0.clone(), lua)?) + } else { + Ok(self.clone().into_lua(lua)?) + } + } + + pub fn set_with_lua_proxy(&self, lua: &Lua, value: Value) -> Result<(), mlua::Error> { + bevy::log::debug!("Setting lua reflect reference with value: {:?}", value); + + let world = lua.get_world(); + let type_id = self.0.with_reflect(&world, |r, _, _| { + r.get_represented_type_info().map(|t| t.type_id()) + })?; + + // convenience, ideally we probably should just avoid lookups when no type id is here, but for now we just use a dummy type nothing will ever + // be registered for. If the type we're reflecting doesn't represent anything or a registered type, we use a generic reflect reference. + struct Unknown; + let type_id_or_dummy = type_id.unwrap_or(TypeId::of::()); + + if let Some(type_data) = world.with_resource::(|_, type_registry| { + type_registry + .read() + .get_type_data::(type_id_or_dummy) + .cloned() + }) { + bevy::log::debug!("Setting value with ReflectLuaValue registration"); + let other = (type_data.from_value)(value, lua)?; + self.0.with_reflect_mut(&world, |r, _, _| { + r.try_apply(other.as_partial_reflect()) + .map_err(ScriptError::new_reflection_error) + })??; + } else if let Some(type_data) = + world.with_resource::(|_, type_registry| { + type_registry + .read() + .get_type_data::(type_id_or_dummy) + .cloned() + }) + { + bevy::log::debug!("Setting value with ReflectLuaProxied registration"); + let other = (type_data.from_proxy)(value, lua)?; + let other = other.with_reflect(&world, |r, _, _| r.clone_value())?; + // now we can set it + self.0.with_reflect_mut(&world, |r, _, _| { + if let Some(set) = type_data.opt_set { + set(r, other) + } else { + r.try_apply(other.as_partial_reflect()) + .map_err(ScriptError::new_reflection_error)?; + Ok(()) + } + })??; + } else { + bevy::log::debug!("No registration found, throwing error"); + // we don't know how to assign the value + // prod to see if it's a common container (i.e. Option or Vec) + world.with_resource::(|_,type_registry| { + let type_registry = type_registry.read(); + Err(ScriptError::new_runtime_error(format!( + "Invalid assignment `{:?}` = `{:?}`. The underlying type does: `{}` not support assignment.", + self.0.print_with_type_registry(&type_registry), + value, + type_registry.get_type_info(type_id_or_dummy).map(|t| t.type_path()).unwrap_or_else(|| "Unknown") + ))) + })?; + }; + Ok(()) + } + + /// Adjusts all the numeric accesses in the path from 1-indexed to 0-indexed + pub fn to_host_index(path: &mut ParsedPath) { + path.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, + _ => {} + }); + } + + /// Adjusts all the numeric accesses in the path from 0-indexed to 1-indexed + pub fn from_host_index(path: &mut ParsedPath) { + path.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, + _ => {} + }); + } + + pub fn parse_value_index(value: Value) -> Result { + if let Some(num) = value.as_usize() { + Ok(vec![OffsetAccess { + access: bevy::reflect::Access::ListIndex(num), + offset: Some(1), + }] + .into()) + } else if let Some(key) = value.as_str() { + if let Some(tuple_struct_index) = key.strip_prefix("_") { + if let Ok(index) = tuple_struct_index.parse::() { + return Ok(vec![OffsetAccess { + access: bevy::reflect::Access::TupleIndex(index), + offset: Some(1), + }] + .into()); + } + } + + ParsedPath::parse(key).map_err(|e| mlua::Error::external(e.to_string())) + } else { + Err(mlua::Error::external("Invalid index")) + } + } +} + +impl_userdata_from_lua!(LuaReflectReference); + +impl LuaProxied for ReflectReference { + type Proxy = LuaReflectReference; +} + +impl From for ReflectReference { + fn from(value: LuaReflectReference) -> Self { + value.0 + } +} + +impl From for LuaReflectReference { + fn from(value: ReflectReference) -> Self { + Self(value) + } +} + +impl TealData for LuaReflectReference { + fn add_methods<'lua, T: tealr::mlu::TealDataMethods<'lua, Self>>(m: &mut T) { + m.add_meta_function( + MetaMethod::Index, + |l, (mut self_, key): (LuaReflectReference, Value)| { + bevy::log::debug!( + "ReflectReference::Index with key: {:?} and value: {:?}", + key, + self_ + ); + // catchall, parse the path + let mut elem = Self::parse_value_index(key)?; + Self::to_host_index(&mut elem); + self_.0.index_path(elem); + bevy::log::debug!("Target reflect reference after indexing key: {:?}", self_.0); + self_.to_lua_proxy(l) + }, + ); + m.add_meta_function( + MetaMethod::NewIndex, + |l, (mut self_, key, value): (LuaReflectReference, Value, Value)| { + bevy::log::debug!( + "ReflectReference::NewIndex with key: {:?} and value: {:?}", + key, + value + ); + + let mut elem = Self::parse_value_index(key)?; + Self::to_host_index(&mut elem); + self_.0.index_path(elem); + bevy::log::debug!("Target reflect reference after indexing key: {:?}", self_.0); + self_.set_with_lua_proxy(l, value) + }, + ); + + m.add_function_mut( + "insert", + |l, (mut self_, key): (LuaReflectReference, usize, LuaReflect)| { + self_.0.insert_at(key, l.get_world()) + }, + ); + + m.add_meta_function(MetaMethod::Len, |l, self_: LuaReflectReference| { + self_.len(l) + }); + + #[cfg(any( + feature = "lua54", + feature = "lua53", + feature = "lua52", + feature = "luajit52", + ))] + m.add_meta_function(MetaMethod::Pairs, |l, s: LuaReflectReference| { + bevy::log::debug!("ReflectReference::Pairs with value: {:?}", s); + let mut iterator_base = s.0.into_iter_infinite(); + let iterator = TypedFunction::from_rust_mut( + move |l, ()| { + let (next_ref, idx) = iterator_base.next_ref(); + bevy::log::debug!("iteration: {:?}", idx); + let next = LuaReflectReference(next_ref).to_lua_proxy(l); + let next = match next { + Ok(n) => Some(n), + Err(e) => { + bevy::log::debug!("Error in iteration: {:?}", e); + None + } + }; + bevy::log::debug!("next: {:?}", next); + // TODO: we should differentiate between no more values and an actual error + match (next, idx) { + (None, bevy_mod_scripting_core::bindings::IterationKey::Index(_)) => { + Ok((Value::Nil, Value::Nil)) + } + (Some(n), bevy_mod_scripting_core::bindings::IterationKey::Index(i)) => { + Ok((Value::Integer((i + 1) as i64), n)) + } + } + }, + l, + )?; + + Ok((iterator, Value::Nil, Value::Nil)) + }); + + m.add_meta_function(MetaMethod::ToString, |lua, self_: LuaReflectReference| { + let world = lua.get_world(); + Ok(self_.0.print_with_world(&world)) + }); + } +} + +#[cfg(test)] +mod test { + + use bevy::{ + app::App, + ecs::{reflect::AppTypeRegistry, world::World}, + reflect::{FromReflect, OffsetAccess, Reflect}, + }; + use bevy_mod_scripting_core::{ + bindings::ReflectAllocator, + bindings::{ReflectBase, ReflectBaseType, WorldAccessGuard, WorldCallbackAccess}, + }; + use bevy_mod_scripting_derive::LuaProxy; + + use crate::{bindings::world::LuaWorld, type_data::RegisterLua}; + + use super::*; + + #[derive(Reflect)] + struct TestStruct { + value: usize, + proxy: TestProxied, + proxies: Vec, + } + + #[derive(Reflect)] + struct TestTupleStruct(usize, TestProxied, Vec); + + #[derive(Reflect)] + enum TestTupleEnum { + Value(usize), + Proxy(TestProxied), + Proxies(Vec), + } + + #[derive(Reflect, LuaProxy)] + #[proxy(bms_core_path = "bevy_mod_scripting_core", bms_lua_path = "crate")] + #[reflect(LuaProxied)] + pub struct TestProxied; + + impl PartialEq for LuaTestProxied { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } + } + + /// asserts that setting then indexing into a LuaReflectReference of type T with the given expression returns the expected value. + /// Provides `t and `world` globals, with t being the LuaReflectReference to the provided value. + fn assert_lua_set_get_returns< + T: Reflect, + F: Fn(ReflectReference) -> O, + O: for<'l> FromLua<'l> + for<'l> IntoLua<'l> + PartialEq + std::fmt::Debug, + >( + mut world: &mut World, + val: T, + expr: &'static str, + expected: F, + ) { + let lua = Lua::new(); + let mut allocator = ReflectAllocator::default(); + let reflect_ref = LuaReflectReference(ReflectReference::new_allocated(val, &mut allocator)); + world.insert_resource(allocator); + + WorldCallbackAccess::with_callback_access(world, |access| { + let globals = lua.globals(); + globals.set("test", reflect_ref.clone()).unwrap(); + globals.set("world", LuaWorld(access.clone())).unwrap(); + globals + .set("expected", expected(reflect_ref.0.clone())) + .unwrap(); + + let lua_code = format!( + r#" + {expr} = expected + return {expr} + "# + ); + let result = lua + .load(&lua_code) + .into_function() + .unwrap_or_else(|e| panic!("Could not load lua code into function: `{e}`")) + .call(()) + .unwrap_or_else(|e| { + panic!("Could not convert expression value to expected type: `{e}`") + }); + let result: O = result; + assert_eq!(result, expected(reflect_ref.0)); + }); + } + + #[test] + fn test_index_lua_value() { + // so we have the registry and can just do this + let mut app = App::new(); + app.register_lua_value::(); + + assert_lua_set_get_returns( + app.world_mut(), + TestStruct { + value: 123, + proxy: TestProxied, + proxies: vec![], + }, + "test.value", + |_| 123usize, + ); + + let mut app = App::new(); + app.register_lua_value::(); + + assert_lua_set_get_returns( + app.world_mut(), + TestTupleStruct(123, TestProxied, vec![]), + "test._1", + |_| 123usize, + ); + + let mut app = App::new(); + app.register_lua_value::(); + + assert_lua_set_get_returns( + app.world_mut(), + TestTupleEnum::Value(123usize), + "test._1", + |_| 123usize, + ); + } + + #[test] + fn test_index_lua_proxy() { + // so we have the registry and can just do this + let mut app = App::new(); + app.register_lua_proxy::(); + + assert_lua_set_get_returns( + app.world_mut(), + TestStruct { + value: 123, + proxy: TestProxied, + proxies: vec![], + }, + "test.proxy", + |mut r| { + r.index_path(ParsedPath::parse_static("proxy").unwrap()); + LuaTestProxied(r) + }, + ); + + let mut app = App::new(); + app.register_lua_proxy::(); + + assert_lua_set_get_returns( + app.world_mut(), + TestTupleStruct(123, TestProxied, vec![]), + "test._2", + |mut r| { + r.index_path(ParsedPath::parse_static(".1").unwrap()); + LuaTestProxied(r) + }, + ); + + let mut app = App::new(); + app.register_lua_proxy::(); + + assert_lua_set_get_returns( + app.world_mut(), + TestTupleEnum::Proxy(TestProxied), + "test._1", + |mut r| { + r.index_path(ParsedPath::parse_static(".0").unwrap()); + LuaTestProxied(r) + }, + ); + } + + #[test] + fn test_index_lua_proxy_vec() { + // so we have the registry and can just do this + let mut app = App::new(); + app.register_lua_proxy::(); + + assert_lua_set_get_returns( + app.world_mut(), + TestStruct { + value: 123, + proxy: TestProxied, + proxies: vec![TestProxied], + }, + "test.proxies[1]", + |mut r| { + r.index_path(ParsedPath::parse_static("proxies").unwrap()); + r.index_path(ParsedPath::parse_static("[0]").unwrap()); + LuaTestProxied(r) + }, + ); + + let mut app = App::new(); + app.register_lua_proxy::(); + + assert_lua_set_get_returns( + app.world_mut(), + TestTupleStruct(123, TestProxied, vec![TestProxied]), + "test._3[1]", + |mut r| { + r.index_path(ParsedPath::parse_static(".2").unwrap()); + r.index_path(ParsedPath::parse_static("[0]").unwrap()); + LuaTestProxied(r) + }, + ); + + let mut app = App::new(); + app.register_lua_proxy::(); + + assert_lua_set_get_returns( + app.world_mut(), + TestTupleEnum::Proxies(vec![TestProxied]), + "test._1[1]", + |mut r| { + r.index_path(ParsedPath::parse_static(".0").unwrap()); + r.index_path(ParsedPath::parse_static("[0]").unwrap()); + LuaTestProxied(r) + }, + ); + } +} diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/std.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/std.rs new file mode 100644 index 0000000000..41a3e35c00 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/std.rs @@ -0,0 +1,39 @@ +// use tealr::{ +// mlu::{mlua::IntoLua, TealData}, +// ToTypename, +// }; + +// pub struct LuaResult(Result); + +// impl TealData for LuaResult +// where +// T: ToTypename + for<'l> IntoLua<'l>, +// E: ToTypename + for<'l> IntoLua<'l>, +// { +// fn add_methods<'lua, M: tealr::mlu::TealDataMethods<'lua, Self>>(methods: &mut M) { +// methods.add_method("is_ok", |_, this, _: ()| Ok(this.0.is_ok())); +// methods.add_method("is_err", |_, this, _: ()| Ok(this.0.is_err())); +// methods.add_function("unwrap", |_, this: LuaResult| match this.0 { +// Ok(value) => Ok(value), +// Err(_) => Err(tealr::mlu::mlua::Error::RuntimeError( +// "called `LuaResult::unwrap()` on an `Err` value".to_string(), +// )), +// }); +// methods.add_method("unwrap_err", |_, this, _: ()| match &this.0 { +// Ok(_) => Err(tealr::mlu::mlua::Error::RuntimeError( +// "called `LuaResult::unwrap_err()` on an `Ok` value".to_string(), +// )), +// Err(value) => Ok(value), +// }); +// } + +// fn add_fields<'lua, F: tealr::mlu::TealDataFields<'lua, Self>>(_fields: &mut F) {} +// } + +// impl ToTypename for LuaResult { +// fn to_typename() -> tealr::Type { +// let t = std::any::type_name::(); +// let e = std::any::type_name::(); +// tealr::Type::new_single(format!("LuaResult<{t},{e}>"), tealr::KindOfType::External) +// } +// } diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/type_registration.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/type_registration.rs new file mode 100644 index 0000000000..eba4c05d81 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/type_registration.rs @@ -0,0 +1,41 @@ +use std::sync::Arc; + +use bevy::reflect::TypeRegistration; +use bevy_mod_scripting_core::bindings::ScriptTypeRegistration; +use tealr::mlu::TealData; + +use crate::impl_userdata_from_lua; + +use super::proxy::LuaProxied; + +/// Caches information about type data +#[derive(Clone, tealr::mlu::UserData, tealr::ToTypename)] +pub struct LuaTypeRegistration(pub ScriptTypeRegistration); + +impl_userdata_from_lua!(LuaTypeRegistration); + +impl TealData for LuaTypeRegistration { + 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.0.short_name().to_owned())); + + fields.document("The full name of the type"); + fields.add_field_method_get("type_name", |_, s| Ok(s.0.type_name())); + } +} + +impl From for LuaTypeRegistration { + fn from(value: ScriptTypeRegistration) -> Self { + Self(value) + } +} + +impl From<&LuaTypeRegistration> for ScriptTypeRegistration { + fn from(value: &LuaTypeRegistration) -> Self { + value.0.clone() + } +} + +impl LuaProxied for ScriptTypeRegistration { + type Proxy = LuaTypeRegistration; +} 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 0000000000..b817776c3f --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/world.rs @@ -0,0 +1,448 @@ +use std::sync::Arc; + +use bevy::ecs::{component::ComponentId, reflect::AppTypeRegistry, world::Mut}; +use bevy::prelude::Entity; + +use bevy_mod_scripting_core::{ + bindings::{ + ReflectReference, ScriptTypeRegistration, Unproxy, WorldAccessGuard, WorldCallbackAccess, + }, + error::ScriptError, +}; +use bevy_mod_scripting_derive::LuaProxy; +use tealr::mlu::mlua::IntoLua; +use tealr::{ + mlu::{ + mlua::{self, FromLua}, + FromToLua, TealData, + }, + ToTypename, Type, +}; + +use super::proxy::LuaReflectRefProxy; +use super::query::LuaQueryBuilder; +use super::{ + providers::bevy_ecs::LuaEntity, + proxy::{ + ErrorProxy, LuaIdentityProxy, LuaProxied, LuaReflectValProxy, LuaValProxy, TypenameProxy, + }, + type_registration::LuaTypeRegistration, +}; +use crate::util::Variadic; +use crate::{impl_userdata_from_lua, impl_userdata_with_tealdata}; + +pub struct Nil; + +impl ToTypename for Nil { + fn to_typename() -> Type { + Type::new_single("nil", tealr::KindOfType::Builtin) + } +} + +#[derive(Clone, Debug)] +pub struct LuaWorld(pub WorldCallbackAccess); + +impl LuaWorld { + pub fn world_callback_access(self) -> WorldCallbackAccess { + self.0.clone() + } +} + +impl ToTypename for LuaWorld { + fn to_typename() -> Type { + Type::new_single("LuaWorld", tealr::KindOfType::External) + } +} + +impl TealData for LuaWorld { + fn add_methods<'lua, T: tealr::mlu::TealDataMethods<'lua, Self>>(methods: &mut T) { + methods.add_method("_list_accesses", |_, this, ()| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let accesses = world + .list_accesses() + .into_iter() + .map(|v| format!("Access to: {v:?}")) + .collect::>(); + Ok(accesses) + }); + + methods.add_method("spawn", |_, this, ()| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let entity: LuaReflectValProxy = world + .proxy_call((), |()| world.spawn()) + .map_err(mlua::Error::external)?; + Ok(entity) + }); + + methods.add_method("get_type_by_name", |_, this, type_name: String| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let out: Option> = world + .proxy_call(type_name, |type_name| world.get_type_by_name(type_name)) + .map_err(mlua::Error::external)?; + + Ok(out) + }); + + methods.add_method( + "add_default_component", + |_, + this, + args: ( + LuaReflectValProxy, + LuaValProxy, + )| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let out: Result<(), ErrorProxy> = world + .proxy_call(args, |(entity, registration)| { + world.add_default_component(entity, registration) + }) + .map_err(mlua::Error::external)?; + + Ok(TypenameProxy::<_, Nil>::new(out)) + }, + ); + + methods.add_method( + "get_component", + |_, + this, + args: ( + LuaReflectValProxy, + LuaValProxy, + )| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let out: Result>, ErrorProxy> = + world + .proxy_call(args, |(entity, component_id)| { + match component_id.component_id() { + Some(component_id) => world.get_component(entity, component_id), + None => Ok(None), + } + }) + .map_err(mlua::Error::external)?; + + Ok(TypenameProxy::< + _, + Option>, + >::new(out)) + }, + ); + + methods.add_method( + "has_component", + |_, + this, + args: ( + LuaReflectValProxy, + LuaValProxy, + )| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let out: Result> = world + .proxy_call(args, |(entity, registration)| { + match registration.component_id() { + Some(component_id) => world.has_component(entity, component_id), + None => Ok(false), + } + }) + .map_err(mlua::Error::external)?; + + Ok(TypenameProxy::<_, bool>::new(out)) + }, + ); + + methods.add_method( + "remove_component", + |_, + this, + args: ( + LuaReflectValProxy, + LuaValProxy, + )| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let out: Result<(), ErrorProxy> = world + .proxy_call(args, |(entity, registration)| { + world.remove_component(entity, registration) + }) + .map_err(mlua::Error::external)?; + + Ok(TypenameProxy::<_, Nil>::new(out)) + }, + ); + + methods.add_method( + "get_resource", + |_, this, registration: LuaValProxy| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let out: Result>, ErrorProxy> = + world + .proxy_call(registration, |registration| { + match registration.resource_id { + Some(resource_id) => world.get_resource(resource_id), + None => Ok(None), + } + }) + .map_err(mlua::Error::external)?; + + Ok(TypenameProxy::<_, LuaReflectRefProxy>::new(out)) + }, + ); + + methods.add_method( + "remove_resource", + |_, this, registration: LuaValProxy| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let out: Result<(), ErrorProxy> = world + .proxy_call(registration, |registration| { + world.remove_resource(registration) + }) + .map_err(mlua::Error::external)?; + + Ok(TypenameProxy::<_, Nil>::new(out)) + }, + ); + + methods.add_method( + "has_resource", + |_, this, registration: LuaValProxy| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let out: bool = world + .proxy_call(registration, |registration| { + match registration.resource_id { + Some(resource_id) => world.has_resource(resource_id), + None => false, + } + }) + .map_err(mlua::Error::external)?; + + Ok(out) + }, + ); + + methods.add_method( + "has_entity", + |_, this, entity: LuaReflectValProxy| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let out: bool = world + .proxy_call(entity, |entity| world.has_entity(entity)) + .map_err(mlua::Error::external)?; + + Ok(out) + }, + ); + + methods.add_method( + "get_children", + |_, this, entity: LuaReflectValProxy| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let out: Result>, ErrorProxy> = world + .proxy_call(entity, |entity| world.get_children(entity)) + .map_err(mlua::Error::external)?; + + Ok(TypenameProxy::<_, Vec>>::new( + out, + )) + }, + ); + + methods.add_method( + "get_parent", + |_, this, entity: LuaReflectValProxy| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let out: Result>, ErrorProxy> = + world + .proxy_call(entity, |entity| world.get_parent(entity)) + .map_err(mlua::Error::external)?; + + Ok(TypenameProxy::<_, Option>>::new( + out, + )) + }, + ); + + methods.add_method( + "push_children", + |_, this, args: (LuaReflectValProxy, Vec>)| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let out: Result<(), ErrorProxy> = world + .proxy_call(args, |(parent, children)| { + world.push_children(parent, &children) + }) + .map_err(mlua::Error::external)?; + + Ok(TypenameProxy::<_, Nil>::new(out)) + }, + ); + + methods.add_method( + "remove_children", + |_, this, args: (LuaReflectValProxy, Vec>)| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let out: Result<(), ErrorProxy> = world + .proxy_call(args, |(parent, children)| { + world.remove_children(parent, &children) + }) + .map_err(mlua::Error::external)?; + + Ok(TypenameProxy::<_, Nil>::new(out)) + }, + ); + + methods.add_method( + "insert_children", + |_, + this, + args: ( + LuaReflectValProxy, + usize, + Vec>, + )| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let out: Result<(), ErrorProxy> = world + .proxy_call(args, |(parent, index, children)| { + world.insert_children(parent, index - 1, &children) + }) + .map_err(mlua::Error::external)?; + + Ok(TypenameProxy::<_, Nil>::new(out)) + }, + ); + + methods.add_method( + "despawn_recursive", + |_, this, entity: LuaReflectValProxy| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let out: Result<(), ErrorProxy> = world + .proxy_call(entity, |entity| world.despawn_recursive(entity)) + .map_err(mlua::Error::external)?; + + Ok(TypenameProxy::<_, Nil>::new(out)) + }, + ); + + methods.add_method("despawn", |_, this, entity: LuaReflectValProxy| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let out: Result<(), ErrorProxy> = world + .proxy_call(entity, |entity| world.despawn(entity)) + .map_err(mlua::Error::external)?; + + Ok(TypenameProxy::<_, Nil>::new(out)) + }); + + methods.add_method( + "despawn_descendants", + |_, this, entity: LuaReflectValProxy| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let out: Result<(), ErrorProxy> = world + .proxy_call(entity, |entity| world.despawn_descendants(entity)) + .map_err(mlua::Error::external)?; + + Ok(TypenameProxy::<_, Nil>::new(out)) + }, + ); + + methods.add_method( + "query", + |_, this, mut components: Variadic>| { + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + let mut builder = LuaQueryBuilder::default(); + let deque = components.0; + builder.components( + deque + .into_iter() + .map(|mut c| c.unproxy()) + .collect::>() + .map_err(tealr::mlu::mlua::Error::external)?, + ); + Ok(builder) + }, + ); + + methods.add_method("exit", |lua, this, ()| { + // TODO: somehow end control flow on lua side + let world = this.0.read().ok_or_else(|| { + mlua::Error::external(ScriptError::new_reflection_error("Stale world access")) + })?; + world.exit(); + Ok(()) + }); + } + + fn add_fields<'lua, F: tealr::mlu::TealDataFields<'lua, Self>>(_fields: &mut F) {} +} + +impl_userdata_from_lua!(LuaWorld); +impl_userdata_with_tealdata!(LuaWorld); + +impl LuaProxied for WorldCallbackAccess { + type Proxy = LuaWorld; +} + +impl From<&LuaWorld> for WorldCallbackAccess { + fn from(value: &LuaWorld) -> Self { + value.0.clone() + } +} + +pub trait GetWorld { + fn get_world(&self) -> Arc>; + fn try_get_world(&self) -> Result>, mlua::Error>; +} + +impl GetWorld for mlua::Lua { + fn try_get_world(&self) -> Result>, mlua::Error> { + self.globals() + .get::<_, LuaValProxy>("world")? + .unproxy() + .and_then(|guard| { + guard + .read() + .ok_or_else(|| ScriptError::new_reflection_error("Stale world access")) + }) + .map_err(mlua::Error::external) + } + + fn get_world(&self) -> Arc> { + 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 index 9fbb42b0d5..7850478082 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/docs.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/docs.rs @@ -1,17 +1,14 @@ -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}; +use tealr::{TypeGenerator, TypeWalker}; pub type TypeWalkerBuilder = fn(TypeWalker) -> TypeWalker; @@ -51,14 +48,14 @@ struct Fragment { builder: TypeWalkerBuilder, } -pub struct LuaDocFragment { +pub struct LuaDocumentationFragment { 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 { +impl LuaDocumentationFragment { pub fn new(name: &'static str, f: TypeWalkerBuilder) -> Self { Self { name, @@ -67,7 +64,7 @@ impl LuaDocFragment { } } -impl DocFragment for LuaDocFragment { +impl DocumentationFragment for LuaDocumentationFragment { fn name(&self) -> &'static str { self.name } @@ -77,7 +74,7 @@ impl DocFragment for LuaDocFragment { self } - fn gen_docs(self) -> Result<(), ScriptError> { + fn gen_docs(self) -> Result<(), Box> { let script_asset_path = &FileAssetReader::get_base_path() .join("assets") .join("scripts"); @@ -100,128 +97,54 @@ impl DocFragment for LuaDocFragment { // 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 = serde_json::to_string_pretty(&tw)?; 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()))?; - + (File::create(json_path).and_then(|mut file| { + file.write_all(json.as_bytes())?; + file.flush() + }))?; // 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()))?; + (File::create(config_path) + .and_then(|mut file| file.write_all(DEFAULT_DOC_CONFIG(&docs_name).as_bytes())))? } // generate docs - Command::new("tealr_doc_gen") + (Command::new("tealr_doc_gen") .current_dir(script_doc_dir) .args(["run"]) - .status() - .map_err(|e| ScriptError::DocGenError(e.to_string()))?; + .status())?; #[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() - )) - })?; + (fs::create_dir_all(&definition_directory))?; 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() - )) - })?; + (fs::copy(&definition_file_path, &output_definition_file_path))?; // 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()))?; + let mut tl_file = (File::create(tl_config_path))?; + (tl_file.write_all(DEFAULT_TEAL_CONFIG.as_bytes()))?; } } 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 d356fade06..2c4527256b 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/lib.rs @@ -1,197 +1,178 @@ -use crate::{ - assets::{LuaFile, LuaLoader}, - docs::LuaDocFragment, -}; -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 type_data; pub mod util; +use bevy::{ + app::{App, Plugin, Startup}, + ecs::{entity::Entity, world::World}, + prelude::{AppTypeRegistry, Mut}, + reflect::{impl_reflect, FromType, GetTypeRegistration, PartialReflect, Reflect, TypePath}, +}; +use bevy_mod_scripting_core::{ + bindings::{ReflectAllocator, ReflectReference, WorldCallbackAccess}, + context::{ContextBuilder, ContextInitializer, ContextPreHandlingInitializer}, + error::ScriptError, + event::CallbackLabel, + handler::Args, + script::ScriptId, + AddContextPreHandlingInitializer, ScriptingPlugin, +}; +use bindings::{ + providers::bevy_ecs::LuaEntity, + proxy::LuaProxied, + world::{GetWorld, LuaWorld}, +}; pub use tealr; +pub mod bindings; +use tealr::mlu::mlua::{FromLua, Function, IntoLua, IntoLuaMulti, Lua, Value}; +use type_data::{ + pre_register_common_containers, register_lua_values, ReflectLuaProxied, ReflectLuaValue, +}; + pub mod prelude { - pub use crate::{ - assets::{LuaFile, LuaLoader}, - docs::{LuaDocFragment, TypeWalkerBuilder}, - tealr::{ - self, - mlu::{ - mlua::{self, prelude::*, Value}, - TealData, - }, + pub use crate::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 {} +pub trait LuaEventArg: Args + for<'l> IntoLuaMulti<'l> {} +impl IntoLuaMulti<'l>> LuaEventArg 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, +pub struct LuaScriptingPlugin IntoLuaMulti<'l>> { + pub scripting_plugin: ScriptingPlugin, } -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() +impl Default for LuaScriptingPlugin { + fn default() -> Self { + 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 ScriptEvent for LuaEvent { - fn recipients(&self) -> &crate::Recipients { - &self.recipients +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(); + let lua_entity = world.with_resource::(|_, mut allocator| { + let reflect_reference = ReflectReference::new_allocated(entity, &mut allocator); + ::Proxy::from(reflect_reference) + }); + + context.globals().set("script_id", script_id.to_owned())?; + context.globals().set("entity", lua_entity)?; + Ok(()) + }); } -} -#[derive(Resource)] -/// Lua script host, enables Lua scripting. -pub struct LuaScriptHost { - _ph: PhantomData, -} + fn cleanup(&self, app: &mut App) { + let mut type_registry = app.world_mut().get_resource_mut().unwrap(); -impl Default for LuaScriptHost { - fn default() -> Self { - Self { - _ph: Default::default(), - } + // 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); } } -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), - ); - } +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 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()?; + Ok(()) + })?; + + Ok(context) +} - 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(), - })?; - - Ok(lua) - } +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(()) +} - fn setup_script( - &mut self, - script_data: &ScriptData, - ctx: &mut Self::ScriptContext, - providers: &mut APIProviders, - ) -> Result<(), ScriptError> { - providers.setup_all(script_data, ctx) - } +#[allow(clippy::too_many_arguments)] +pub fn lua_handler IntoLuaMulti<'l>>( + args: A, + 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(()), + }; + + handler.call::<_, ()>(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(|(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; - } - - let f: Function = match globals.raw_get(event.hook_name.clone()) { - Ok(f) => f, - Err(_) => continue, // not subscribed to this event - }; - - if let Err(error) = f.call::<_, ()>(event.args.clone()) { - 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); - } - } - }); - } +/// 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", LuaWorld(guard.clone()))?; + f(context) + }) } diff --git a/crates/languages/bevy_mod_scripting_lua/src/type_data.rs b/crates/languages/bevy_mod_scripting_lua/src/type_data.rs new file mode 100644 index 0000000000..5abd838a5f --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/src/type_data.rs @@ -0,0 +1,1017 @@ +use std::{ + any::{Any, TypeId}, + clone, + collections::{HashMap, HashSet}, + sync::Arc, +}; + +use bevy::{ + app::App, + log::debug, + prelude::{AppTypeRegistry, Mut}, + reflect::{ + impl_reflect, DynamicEnum, DynamicList, DynamicTuple, DynamicVariant, FromType, + GetTypeRegistration, List, ParsedPath, PartialReflect, Reflect, ReflectFromReflect, + ReflectMut, ReflectPathError, TypeInfo, TypePath, TypeRegistration, + }, +}; +use bevy_mod_scripting_core::{ + bindings::{DeferredReflection, ReflectAllocator, ReflectReference, ReflectionPathElem}, error::ScriptError, new_deferred_reflection, reflection_extensions::PartialReflectExt +}; +use tealr::mlu::mlua::{FromLua, IntoLua, Lua, Table, Value}; + +use crate::bindings::{proxy::LuaProxied, reference::LuaReflectReference, world::GetWorld}; + +/// Stores the procedure used to convert a lua value to a reflect value and vice versa, Used for types which are represented in lua via proxies which store +/// a reference to the actual value. +/// This is used for types which are represented in lua with pass by reference semantics +#[derive(Clone)] +pub struct ReflectLuaProxied { + // TODO: should these be script errors? + pub into_proxy: Arc< + dyn for<'l> Fn(ReflectReference, &'l Lua) -> Result, tealr::mlu::mlua::Error> + + Send + + Sync + + 'static, + >, + pub from_proxy: Arc< + dyn for<'l> Fn(Value<'l>, &'l Lua) -> Result + + Send + + Sync + + 'static, + >, + /// Optional override for setting behavior, should be respected by all handling types for unproxying to work recurively. + /// Normally used when [`PartialReflect::apply`] does not do the right thing. + pub opt_set: Option< + Arc< + dyn for<'l> Fn( + &mut dyn PartialReflect, + Box, + ) -> Result<(), ScriptError> + + Send + + Sync + + 'static, + >, + >, +} + +impl ReflectLuaProxied { + /// Generates a type data which can be used on [`Option`] types which are represented in lua with pass by reference semantics + fn new_for_option(inner_lua_proxied_data: &ReflectLuaProxied, container_type_info: &'static TypeInfo) -> Self { + let ref_into_option = |mut r: ReflectReference| { + r.index_path(ParsedPath::parse_static("0").expect("Invalid reflection path")); + // why is this necessary? well we need for the from_proxy to work correctly + // we need to know if the reference came from this impl so we can pop the last element + r.index_path(ReflectionPathElem::Identity); + r + }; + let into_proxy_clone = inner_lua_proxied_data.into_proxy.clone(); + let from_proxy_clone = inner_lua_proxied_data.from_proxy.clone(); + Self { + into_proxy: Arc::new(move |reflect_ref, l| { + // read the value and check if it is None, if so return nil + // otherwise use the inner type's into_proxy + let world = l.get_world(); + let is_some = reflect_ref + .with_reflect(&world, |s, _, _| s.as_option().map(|r| r.is_some()))??; + + if is_some { + (into_proxy_clone)(ref_into_option(reflect_ref), l) + } else { + Ok(Value::Nil) + } + }), + from_proxy: Arc::new(move |v, l| { + if v.is_nil() { + bevy::log::debug!("Option from proxy: Nil"); + // we need to allocate a new reflect reference since we don't have one existing + let mut dynamic_value = DynamicEnum::new("None", DynamicVariant::Unit); + dynamic_value.set_represented_type(Some(container_type_info)); + let world = l.get_world(); + let reflect_ref = + world.with_resource(|_, mut allocator: Mut| { + Ok::<_, tealr::mlu::mlua::Error>(ReflectReference::new_allocated( + dynamic_value, + &mut allocator, + )) + })?; + + Ok(reflect_ref) + } else { + // this ref could've come from this into_proxy or from something else, we need to differentiate here + // we need to + let mut inner_ref = (from_proxy_clone)(v, l)?; + if inner_ref.reflect_path.last().is_some_and(|p| p == &ReflectionPathElem::Identity) { + // if the last path element is identity, then it came from this impl + // we need to remove the path derefing to the inner value and we're done + inner_ref.reflect_path.pop(); + Ok(inner_ref) + } else { + // otherwise we need to wrap it in an option dynamically so it's an option, to do that we need to reflect the value and box it + let world = l.get_world(); + let reflect_ref = inner_ref.with_reflect(&world, |r,_, mut allocator| { + let mut dynamic = DynamicEnum::new("Some", DynamicVariant::Tuple([r.clone_value()].into_iter().collect())); + dynamic.set_represented_type(Some(container_type_info)); + ReflectReference::new_allocated( + dynamic, + &mut allocator, + ) + })?; + Ok(reflect_ref) + } + } + }), + opt_set: None, + } + } + + fn dynamic_list_from_value<'lua>( + v: Table<'lua>, + lua: &'lua Lua, + from_proxy: &Arc< + dyn for<'l> Fn( + Value<'l>, + &'l Lua, + ) + -> Result, tealr::mlu::mlua::Error> + + Send + + Sync + + 'static, + >, + container_type_info: &'static TypeInfo + ) -> Result { + let lua_values = v.sequence_values().collect::, _>>()?; + + let converted_values = lua_values + .into_iter() + .map(|v| (from_proxy)(v, lua)) + .collect::, _>>()?; + + let mut dynamic_type = DynamicList::from_iter(converted_values); + dynamic_type.set_represented_type(Some(container_type_info)); + Ok(dynamic_type) + } + + fn dynamic_list_from_proxy<'lua>( + v: Table<'lua>, + lua: &'lua Lua, + from_proxy: &Arc< + dyn for<'l> Fn(Value<'l>, &'l Lua) -> Result + + Send + + Sync + + 'static, + >, + container_type_info: &'static TypeInfo, + ) -> Result { + let lua_values = v.sequence_values().collect::, _>>()?; + + // TODO: less allocations plz, i can't be bothered to do this right now + let converted_values = lua_values + .into_iter() + .map(|v| (from_proxy)(v, lua)) + .collect::, _>>()?; + let world = lua.get_world(); + + let boxed_values = converted_values + .into_iter() + .map(|v| v.with_reflect(&world, |r, _, _| r.clone_value())) + .collect::, _>>()?; + + let mut dynamic_type = DynamicList::from_iter(boxed_values); + // TODO: what to do with this memory, I think it's fine to leave hanging till exit + dynamic_type.set_represented_type(Some(container_type_info)); + Ok(dynamic_type) + } + + fn new_for_listlike_value( + inner_lua_value_data: &ReflectLuaValue, + container_type_info: &'static TypeInfo, + ) -> Self { + let from_value_clone = inner_lua_value_data.from_value.clone(); + Self { + into_proxy: Arc::new(|r, l| LuaReflectReference(r).into_lua(l)), + from_proxy: Arc::new(move |v, l| { + if let Value::Table(t) = v { + let dynamic_table = Self::dynamic_list_from_value(t, l, &from_value_clone, container_type_info)?; + let world = l.get_world(); + let allocated = + world.with_resource(|_, mut allocator: Mut| { + ReflectReference::new_allocated(dynamic_table, &mut allocator) + }); + Ok(allocated) + } else { + LuaReflectReference::from_lua(v, l).map(|v| v.0) + } + }), + opt_set: Some(Arc::new(|r, other| { + r.set_as_list(other, |a, b| { + Ok(a.try_apply(b)?) + }) + })), + } + } + + fn new_for_listlike_proxy(inner_lua_proxied_data: &ReflectLuaProxied) -> Self { + // let from_proxy_clone = inner_lua_proxied_data.from_proxy.clone(); + Self { + into_proxy: Arc::new(|r, l| LuaReflectReference(r).into_lua(l)), + // from_proxy: Arc::new(|v, l| { + // // if it's a table, set existing elements using underlying from proxy + // // if it's a ref, return the ref + + // if let Value::Table(t) = v { + // let ts = t.sequence_values::(); + // for e in ts { + // let v = e?; + // let elem_ref = (from_proxy_clone)(v, l)?; + // } + // } else { + // LuaReflectReference::from_lua(v, l) + // } + // }), + from_proxy: Arc::new(|v, l| { + // can either be a table or a direct ref + // construct dynamic vec either way + // if let Value::Table(t) = v { + // for v in t.sequence_values::() { + // let lua_elem = v?; + // } + // } else { + // todo!() + // } + todo!() + }), + opt_set: todo!(), // set_from_proxy: todo!(), // set_from_proxy: Arc::new(|r, v, l| { + // // let table = if let Value::Table(t) = v { + // // t + // // } else { + // // return Err(tealr::mlu::mlua::Error::external( + // // ScriptError::new_runtime_error(format!( + // // "Cannot set value of type `{}` via type: `{}`. Expected table", + // // v.type_name(), + // // "List", + // // )), + // // )); + // // }; + + // // let lua_values = table.sequence_values().collect::, _>>()?; + + // // let converted_values = lua_values + // // .into_iter() + // // .map(|v| (from_proxy)(v, lua)) + // // .collect::, _>>()?; + + // // let target_list = r.as_list().map_err(tealr::mlu::mlua::Error::external)?; + // // }), + } + } +} + +impl FromType for ReflectLuaProxied +where + T::Proxy: for<'l> IntoLua<'l> + for<'l> FromLua<'l>, + T::Proxy: From + AsRef, +{ + fn from_type() -> Self { + Self { + into_proxy: Arc::new(|p, l| T::Proxy::from(p).into_lua(l)), + from_proxy: Arc::new(|v, l| T::Proxy::from_lua(v, l).map(|p| p.as_ref().clone())), + opt_set: None, + // set_from_proxy: Arc::new(|r, v, l| { + // let proxy = T::Proxy::from_lua(v, l).map(|p| p.as_ref().clone())?; + // let world = l.get_world(); + // proxy.with_reflect(&world, |other, _, _| { + // r.apply(other); + // Ok::<_, tealr::mlu::mlua::Error>(()) + // })?; + // Ok(()) + // }), + } + } +} + +/// Stores the procedure used to convert a lua value to a reflect value and vice versa, Used for types which are represented directly in lua with +/// pass by value semantics, These need to implement [`Clone`] +#[derive(Clone)] +pub struct ReflectLuaValue { + pub into_value: Arc< + dyn for<'l> Fn(&dyn PartialReflect, &'l Lua) -> Result, tealr::mlu::mlua::Error> + + Send + + Sync + + 'static, + >, + // pub set_value: Arc< + // dyn for<'l> Fn( + // &mut dyn PartialReflect, + // Value<'l>, + // &'l Lua, + // ) -> Result<(), tealr::mlu::mlua::Error> + // + Send + // + Sync + // + 'static, + // >, + pub from_value: Arc< + dyn for<'l> Fn( + Value<'l>, + &'l Lua, + ) -> Result, tealr::mlu::mlua::Error> + + Send + + Sync + + 'static, + >, +} + +impl ReflectLuaValue { + fn dynamic_option_from_value<'lua>( + v: Value<'lua>, + lua: &'lua Lua, + from_value: &Arc< + dyn for<'l> Fn( + Value<'l>, + &'l Lua, + ) + -> Result, tealr::mlu::mlua::Error> + + Send + + Sync + + 'static, + >, + container_type_info: &'static TypeInfo, + ) -> Result { + let mut dynamic_enum = if v.is_nil() { + DynamicEnum::new("None", DynamicVariant::Unit) + } else { + let inner = (from_value)(v, lua)?; + DynamicEnum::new("Some", DynamicVariant::Tuple([inner].into_iter().collect())) + }; + + dynamic_enum.set_represented_type(Some(container_type_info)); + + Ok(dynamic_enum) + } + + /// generates implementation for an inner type wrapped by an option + /// + /// the option should check if the value is None if so return nil, + /// if the value is some use ReflectLuaValue implementation of the inner type. + /// + /// If there is a type mismatch at any point will return an error + pub fn new_for_option(inner_reflect_lua_value: &ReflectLuaValue, container_type_info: &'static TypeInfo) -> Self { + let into_value_clone = inner_reflect_lua_value.into_value.clone(); + // we have to do this so the closures can be moved into the arc + let from_value_clone2 = inner_reflect_lua_value.from_value.clone(); + Self { + into_value: Arc::new(move |r, lua| { + r.as_option() + .map_err(tealr::mlu::mlua::Error::external)? + .map(|inner| (into_value_clone)(inner, lua)) + .unwrap_or_else(|| Ok(Value::Nil)) + }), + from_value: Arc::new(move |v, l| { + let dynamic_option = Self::dynamic_option_from_value(v, l, &from_value_clone2, container_type_info)?; + + Ok(Box::new(dynamic_option)) + }), + // set_value: Arc::new(move |r, v, l| { + // let dynamic = Self::dynamic_option_from_value(v, l, &from_value_clone)?; + // r.apply(&dynamic); + // Ok(()) + // }), + } + } + + // fn dynamic_list_from_value<'lua>( + // v: Value<'lua>, + // lua: &'lua Lua, + // from_value: &Arc< + // dyn for<'l> Fn( + // Value<'l>, + // &'l Lua, + // ) + // -> Result, tealr::mlu::mlua::Error> + // + Send + // + Sync + // + 'static, + // >, + // ) -> Result { + // let table = if let Value::Table(t) = v { + // t + // } else { + // return Err(tealr::mlu::mlua::Error::external( + // ScriptError::new_runtime_error(format!( + // "Cannot set value of type `{}` via type: `{}`. Expected table", + // v.type_name(), + // "List", + // )), + // )); + // }; + + // let lua_values = table.sequence_values().collect::, _>>()?; + + // let converted_values = lua_values + // .into_iter() + // .map(|v| (from_value)(v, lua)) + // .collect::, _>>()?; + // let dynamic_type = DynamicList::from_iter(converted_values); + // // TODO: set the represented type, need to pass type info + // // dynamic_type.set_represented_type(represented_type); + // Ok(dynamic_type) + // } + + // pub fn new_for_list(inner_reflect_lua_value: &ReflectLuaValue) -> Self { + // let into_value_clone = inner_reflect_lua_value.into_value.clone(); + // let from_value_clone = inner_reflect_lua_value.from_value.clone(); + // let from_value_clone2 = inner_reflect_lua_value.from_value.clone(); + // Self { + // into_value: Arc::new(move |r, l| { + // let inner = r.as_list().map_err(tealr::mlu::mlua::Error::external)?; + // let inner = inner + // .map(|i| (into_value_clone)(i, l)) + // .collect::, _>>()?; + + // let t = l.create_table_from( + // inner + // .into_iter() + // .enumerate() + // .map(|(i, v)| (Value::Integer(i as i64 + 1), v)), + // )?; + + // Ok(Value::Table(t)) + // }), + // set_value: Arc::new(move |r, v, l| { + // let dynamic = Self::dynamic_list_from_value(v, l, &from_value_clone)?; + + // // apply will not remove excess elements + // if let ReflectMut::List(list) = r.reflect_mut() { + // if dynamic.len() < list.len() { + // (dynamic.len()..list.len()).rev().for_each(|i| { + // list.remove(i); + // }); + // } + // } + // println!("reflect: {:?}", r); + // println!("dynamic: {:?}", dynamic); + + // r.apply(&dynamic); + // Ok(()) + // }), + // from_value: Arc::new(move |v, l| { + // let dynamic = Self::dynamic_list_from_value(v, l, &from_value_clone2)?; + // Ok(Box::new(dynamic)) + // }), + // } + // } +} + +impl IntoLua<'l> + for<'l> FromLua<'l>> FromType + for ReflectLuaValue +{ + fn from_type() -> Self { + Self { + into_value: Arc::new(|v, l| { + bevy::log::debug!("Converting lua value to lua: {:?}", v); + v.try_downcast_ref::() + .unwrap_or_else(|| { + panic!( + "Expected type: {}, got: {}", + std::any::type_name::(), + v.reflect_type_path() + ) + }) + .clone() + .into_lua(l) + }), + // set_value: Arc::new(|t, v, l| { + // bevy::log::debug!("Setting lua value: {:?}, with {:?}", t, v); + // let t = t.try_downcast_mut::().unwrap(); + // *t = T::from_lua(v, l)?; + // Ok(()) + // }), + from_value: Arc::new(|v, l| { + bevy::log::debug!("Building concrete type from lua value: {:?}", v); + T::from_lua(v, l).map(|v| Box::new(v) as Box) + }), + } + } +} + +/// Registers a lua proxy object via the reflection system +pub trait RegisterLua { + fn register_lua_proxy( + &mut self, + ) -> &mut Self + where + T::Proxy: for<'l> IntoLua<'l> + for<'l> FromLua<'l>, + T::Proxy: From + AsRef; + + fn register_lua_value(&mut self) -> &mut Self + where + T: for<'l> IntoLua<'l> + for<'l> FromLua<'l>, + T: Reflect + Clone + TypePath + GetTypeRegistration; +} + +impl RegisterLua for App { + fn register_lua_proxy( + &mut self, + ) -> &mut Self + where + T::Proxy: for<'l> IntoLua<'l> + for<'l> FromLua<'l>, + T::Proxy: From + AsRef, + { + self.register_type::(); + self.register_type_data::() + } + + fn register_lua_value(&mut self) -> &mut Self + where + T: for<'l> IntoLua<'l> + for<'l> FromLua<'l>, + T: Reflect + Clone + TypePath + GetTypeRegistration, + { + self.register_type::(); + self.register_type_data::() + } +} + +/// Checks if the type registration is for a type which matches the pattern `core::option::Option`, and extracts `T`'s typeId as well as the Option's typeId +fn destructure_option_type(reg: &TypeRegistration) -> Option<(TypeId, TypeId)> { + let type_path_table = reg.type_info().type_path_table(); + let is_core = type_path_table.crate_name().is_some_and(|s| s == "core"); + let is_option = type_path_table.ident().is_some_and(|s| s == "Option"); + + if is_core && is_option { + reg.type_info() + .generics() + .get_named("T") + .map(|t| (reg.type_id(), t.type_id())) + } else { + None + } +} + +fn destructure_list_type(reg: &TypeRegistration) -> Option<(TypeId, TypeId)> { + let type_path_table = reg.type_info().as_list().ok()?; + + let inner_type_id = type_path_table.item_ty().id(); + Some((reg.type_id(), inner_type_id)) +} + +/// iterates over type data for all types which have registered [`ReflectLuaProxied`] and [`ReflectLuaValue`] implementations, +/// and registers corresponding [`Option`] [`Result`] etc type data equivalents. +/// for combinations of nested containers, this should be run more times per level of nesting required. +pub fn pre_register_common_containers(type_registry: &mut AppTypeRegistry) { + let mut type_registry = type_registry.write(); + + let mut lua_value_insertions: HashMap = Default::default(); + let mut lua_proxied_insertions: HashMap = Default::default(); + for (option_type_id, inner_type_id) in type_registry.iter().filter_map(destructure_option_type) + { + let container_type_info = type_registry.get(option_type_id).expect("invariant").type_info(); + // TODO: reuse the leaked box in both branches when either is true + if let Some(inner_lua_value_data) = + type_registry.get_type_data::(inner_type_id) + { + let option_lua_proxied_data = ReflectLuaValue::new_for_option(inner_lua_value_data, Box::leak(Box::new(container_type_info.clone()))); + lua_value_insertions.insert(option_type_id, option_lua_proxied_data); + } + + if let Some(inner_lua_proxied_data) = + type_registry.get_type_data::(inner_type_id) + { + let option_lua_proxied_data = ReflectLuaProxied::new_for_option(inner_lua_proxied_data, Box::leak(Box::new(container_type_info.clone()))); + + lua_proxied_insertions.insert(option_type_id, option_lua_proxied_data); + } + } + + for (vec_type_id, inner_type_id) in type_registry.iter().filter_map(destructure_list_type) { + let container_type_info = type_registry.get(vec_type_id).expect("invariant").type_info(); + if let Some(inner_lua_value_data) = + type_registry.get_type_data::(inner_type_id) + { + let vec_lua_proxied_data = + ReflectLuaProxied::new_for_listlike_value(inner_lua_value_data, Box::leak(Box::new(container_type_info.clone()))); + lua_proxied_insertions.insert(vec_type_id, vec_lua_proxied_data); + } + } + + for (type_id, lua_value_data) in lua_value_insertions { + type_registry + .get_mut(type_id) + .expect("We just found the type id from the type registry") + .insert(lua_value_data); + } + + for (type_id, lua_proxied_data) in lua_proxied_insertions { + type_registry + .get_mut(type_id) + .expect("We just found the type id from the type registry") + .insert(lua_proxied_data); + } +} + +pub fn register_lua_values(app: &mut bevy::prelude::App) { + app.register_lua_value::(); + app.register_lua_value::(); + app.register_lua_value::(); + app.register_lua_value::(); + app.register_lua_value::(); + app.register_lua_value::(); + app.register_lua_value::(); + app.register_lua_value::(); + app.register_lua_value::(); + app.register_lua_value::(); + app.register_lua_value::(); + app.register_lua_value::(); + app.register_lua_value::(); + app.register_lua_value::(); + app.register_lua_value::(); + app.register_lua_value::(); +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::bindings::{reference::LuaReflectReference, world::LuaWorld}; + use bevy::{ + prelude::World, + reflect::{TypeRegistry, TypeRegistryArc}, + }; + use bevy_mod_scripting_core::bindings::WorldCallbackAccess; + use std::sync::Arc; + + #[derive(Reflect, Debug, PartialEq)] + struct Proxied(usize); + + impl LuaProxied for Proxied { + type Proxy = LuaReflectReference; + } + + fn setup_type_registry() -> AppTypeRegistry + where + T1: GetTypeRegistration, + T2: GetTypeRegistration, + { + let mut type_registry = TypeRegistry::default(); + type_registry.register::(); + type_registry.register::(); + + let type_registry_arc = TypeRegistryArc { + internal: Arc::new(type_registry.into()), + }; + AppTypeRegistry(type_registry_arc) + } + + macro_rules! prepare_type_registry_with_common_containers { + ($target_type:ty, $container_type:ty, $type_data:ty) => {{ + { + let mut type_registry = setup_type_registry::<$target_type, $container_type>(); + type_registry + .write() + .register_type_data::<$target_type, $type_data>(); + + pre_register_common_containers(&mut type_registry); + type_registry + } + }}; + } + + macro_rules! assert_transitively_registers { + ($target_type:ty = $inner_type_data:ty, $container_type:ty = $type_data:ty) => {{ + let type_registry = prepare_type_registry_with_common_containers!( + $target_type, + $container_type, + $inner_type_data + ); + + let type_registry = type_registry.read(); + let container_type_id = std::any::TypeId::of::<$container_type>(); + let container_type_registration = type_registry.get(container_type_id).unwrap(); + + let type_data = container_type_registration.contains::<$type_data>(); + assert!( + type_data, + "{:?} should have type data {:?}", + std::any::type_name::<$container_type>(), + std::any::type_name::<$type_data>() + ); + }}; + } + + macro_rules! assert_lua_value_into_equals { + ($target_type:ty, $container_type:ty, $type_data:ty, $val:expr => $exp:expr) => {{ + let type_registry = prepare_type_registry_with_common_containers!( + $target_type, + $container_type, + $type_data + ); + + let type_registry = type_registry.read(); + let container_type_id = std::any::TypeId::of::<$container_type>(); + let container_type_data = type_registry + .get_type_data::<$type_data>(container_type_id) + .unwrap(); + let l = Lua::new(); + let out = (container_type_data.into_value)(&$val, &l).unwrap(); + assert_eq!(out, $exp); + }}; + } + + macro_rules! assert_lua_container_value_from_equals { + ($target_type:ty, $container_type:ty, $type_data:ty, $val:expr => $exp:expr) => {{ + let type_registry = prepare_type_registry_with_common_containers!( + $target_type, + $container_type, + $type_data + ); + + let type_registry = type_registry.read(); + let container_type_id = std::any::TypeId::of::<$container_type>(); + let container_type_data = type_registry + .get_type_data::<$type_data>(container_type_id) + .unwrap(); + let l = Lua::new(); + let out = (container_type_data.from_value)($val, &l).unwrap(); + assert!(out.reflect_partial_eq(&$exp).unwrap()); + }}; + } + + // macro_rules! assert_lua_container_value_after_set_equals { + // ($target_type:ty, $container_type:ty, $type_data:ty, $val:expr => $set:expr => $exp:expr) => {{ + // let type_registry = prepare_type_registry_with_common_containers!( + // $target_type, + // $container_type, + // $type_data + // ); + + // let type_registry = type_registry.read(); + // let container_type_id = std::any::TypeId::of::<$container_type>(); + // let container_type_data = type_registry + // .get_type_data::<$type_data>(container_type_id) + // .unwrap(); + // let l = Lua::new(); + // let mut target = $val; + // (container_type_data.set_value)(&mut target, $set, &l).unwrap(); + // assert!( + // target.reflect_partial_eq(&$exp).unwrap(), + // "Expected {:?} got: {:?}", + // $exp, + // target + // ); + // }}; + // } + + macro_rules! assert_lua_container_proxy_into_proxy { + (;WITH; $target_type:ty = $inner_type_data:ty, $container_type:ty = $type_data:ty ;FROM; $val:expr ;INTO; $exp:expr) => {{ + let app_type_registry = prepare_type_registry_with_common_containers!( + $target_type, + $container_type, + $inner_type_data + ); + let mut world = World::new(); + + let type_registry = app_type_registry.read(); + let container_type_id = std::any::TypeId::of::<$container_type>(); + let container_type_data = type_registry + .get_type_data::<$type_data>(container_type_id) + .unwrap() + .clone(); + + let mut allocator = ReflectAllocator::default(); + let allocated_value = ReflectReference::new_allocated($val, &mut allocator); + world.insert_resource(allocator); + drop(type_registry); + world.insert_resource(app_type_registry); + let lua = Lua::new(); + WorldCallbackAccess::with_callback_access(&mut world, |world| { + lua.globals().set("world", LuaWorld(world.clone())).unwrap(); + + let gotten_into_value = + (container_type_data.into_proxy)(allocated_value, &lua).unwrap(); + let converted_ref = LuaReflectReference::from_lua(gotten_into_value.clone(), &lua) + .expect(&format!( + "Could not convert to lua reflect reference got: {:?}", + gotten_into_value + )) + .0; + let world = world.read().unwrap(); + converted_ref.with_reflect(&world, |r, _, _| { + assert!( + r.reflect_partial_eq(&$exp).unwrap(), + "Expected {:?} got {:?}", + $exp, + r + ); + }); + }); + }}; + } + + macro_rules! assert_lua_container_proxy_opt_set { + ($allocator:ident, $lua:ident ;WITH; $target_type:ty = $inner_type_data:ty, $container_type:ty = $type_data:ty ;SET; $val:expr ;TO; $set:expr ;EXPECT; $exp:expr) => {{ + let app_type_registry = prepare_type_registry_with_common_containers!( + $target_type, + $container_type, + $inner_type_data + ); + let mut world = World::new(); + + let type_registry = app_type_registry.read(); + let container_type_id = std::any::TypeId::of::<$container_type>(); + let container_type_data = type_registry + .get_type_data::<$type_data>(container_type_id) + .unwrap() + .clone(); + + let mut $allocator = ReflectAllocator::default(); + drop(type_registry); + world.insert_resource(app_type_registry); + let $lua = Lua::new(); + let set_expr = Box::new($set); + world.insert_resource($allocator); + WorldCallbackAccess::with_callback_access(&mut world, |world| { + $lua.globals() + .set("world", LuaWorld(world.clone())) + .unwrap(); + let mut target = $val; + (container_type_data.opt_set.unwrap())(&mut target, set_expr).unwrap(); + assert!(target.reflect_partial_eq(&$exp).unwrap()); + }); + }}; + } + + macro_rules! assert_lua_container_proxy_into_proxy_lua_only { + (;WITH; $target_type:ty = $inner_type_data:ty, $container_type:ty = $type_data:ty ;FROM; $val:expr ;INTO; $exp:expr) => {{ + let app_type_registry = prepare_type_registry_with_common_containers!( + $target_type, + $container_type, + $inner_type_data + ); + let mut world = World::new(); + + let type_registry = app_type_registry.read(); + let container_type_id = std::any::TypeId::of::<$container_type>(); + let container_type_data = type_registry + .get_type_data::<$type_data>(container_type_id) + .unwrap() + .clone(); + + let mut allocator = ReflectAllocator::default(); + let allocated_value = ReflectReference::new_allocated($val, &mut allocator); + world.insert_resource(allocator); + drop(type_registry); + world.insert_resource(app_type_registry); + let lua = Lua::new(); + WorldCallbackAccess::with_callback_access(&mut world, |world| { + lua.globals().set("world", LuaWorld(world.clone())).unwrap(); + + let gotten_into_value = + (container_type_data.into_proxy)(allocated_value, &lua).unwrap(); + assert_eq!(gotten_into_value, $exp); + }); + }}; + } + + #[test] + fn test_pre_register_common_containers_lua_value() { + assert_transitively_registers!(usize = ReflectLuaValue, Option = ReflectLuaValue); + assert_transitively_registers!(usize = ReflectLuaValue, Vec = ReflectLuaProxied); + } + + #[test] + fn test_pre_register_common_containers_lua_proxy() { + assert_transitively_registers!(Proxied = ReflectLuaProxied, Option = ReflectLuaProxied ); + } + + #[test] + fn test_option_container_impls() { + // Inner Value + // into + assert_lua_value_into_equals!( + usize, + Option, + ReflectLuaValue, + Some(2usize) => Value::Integer(2) + ); + assert_lua_value_into_equals!( + usize, + Option, + ReflectLuaValue, + None:: => Value::Nil + ); + + // from + assert_lua_container_value_from_equals!( + usize, + Option, + ReflectLuaValue, + Value::Integer(2) => Some(2usize) + ); + assert_lua_container_value_from_equals!( + usize,Option, + ReflectLuaValue, + Value::Nil => None:: + ); + + // set + // assert_lua_container_value_after_set_equals!( + // usize, Option, + // ReflectLuaValue, + // Some(2usize) => Value::Nil => None:: + // ); + // assert_lua_container_value_after_set_equals!( + // usize, Option, + // ReflectLuaValue, + // None:: => Value::Integer(2) => Some(2usize) + // ); + // assert_lua_container_value_after_set_equals!( + // usize, Option, + // ReflectLuaValue, + // None:: => Value::Nil => None:: + // ); + // assert_lua_container_value_after_set_equals!( + // usize, Option, + // ReflectLuaValue, + // Some(2usize) => Value::Integer(3) => Some(3usize) + // ); + + // Inner Proxy + // into + assert_lua_container_proxy_into_proxy!( + ;WITH; Proxied = ReflectLuaProxied, Option = ReflectLuaProxied + ;FROM; Some(Proxied(2)) + ;INTO; Proxied(2usize)); + assert_lua_container_proxy_into_proxy_lua_only!( + ;WITH; Proxied = ReflectLuaProxied, Option = ReflectLuaProxied + ;FROM; None:: + ;INTO; Value::Nil + ); + + // set from + // assert_lua_container_proxy_opt_set!(alloc, lua, Proxied, Option, ReflectLuaProxied, + // Some(Proxied(2)) + // => None:: + // => None::); + // assert_lua_container_proxy_opt_set!(alloc, lua, Proxied, Option, ReflectLuaProxied, + // None:: + // => Proxied(2)// LuaReflectReference(ReflectReference::new_allocated(Proxied(2), &mut alloc)) + // => Some(Proxied(2))); + // assert_lua_container_proxy_opt_set!(alloc, lua, Proxied, Option, ReflectLuaProxied, + // Some(Proxied(2)) + // => Proxied(3) // LuaReflectReference(ReflectReference::new_allocated(Proxied(3), &mut alloc)) + // => Some(Proxied(3))); + // assert_lua_container_proxy_opt_set!(alloc, lua, Proxied, Option, ReflectLuaProxied, + // None:: + // => None:: + // => None::); + } + + #[test] + fn test_listlike_container_impls() { + // Inner Value + // into + assert_lua_container_proxy_into_proxy!( + ;WITH; usize = ReflectLuaValue, Vec = ReflectLuaProxied + ;FROM; vec![Proxied(2), Proxied(3)] + ;INTO; vec![Proxied(2), Proxied(3)] + ); + assert_lua_container_proxy_into_proxy!( + ;WITH; usize = ReflectLuaValue, Vec = ReflectLuaProxied + ;FROM; Vec::::default() + ;INTO; Vec::::default() + ); + + assert_lua_container_proxy_opt_set!(alloc, lua + ;WITH; usize = ReflectLuaValue, Vec = ReflectLuaProxied + ;SET; Vec::::default() + ;TO; Vec::::default() + ;EXPECT; Vec::::default() + ); + + assert_lua_container_proxy_opt_set!(alloc, lua + ;WITH; usize = ReflectLuaValue, Vec = ReflectLuaProxied + ;SET; Vec::::default() + ;TO; vec![Proxied(2)] + ;EXPECT; vec![Proxied(2)] + ); + } + + #[test] + fn test_get_inner_type_id_option() { + let app_type_registry = setup_type_registry::>(); + + let type_registry = app_type_registry.read(); + let option_type_id = std::any::TypeId::of::>(); + let inner_type_id = std::any::TypeId::of::(); + let option_type_registration = type_registry.get(option_type_id).unwrap(); + + let (gotten_option_type_id, gotten_inner_type_id) = + destructure_option_type(option_type_registration).unwrap(); + assert_eq!( + gotten_inner_type_id, inner_type_id, + "Option should have inner type usize" + ); + assert_eq!( + gotten_option_type_id, option_type_id, + "Option should have type id Option" + ); + } +} diff --git a/crates/languages/bevy_mod_scripting_lua/src/util.rs b/crates/languages/bevy_mod_scripting_lua/src/util.rs index 9b84ba5584..52d4308a5c 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/util.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/util.rs @@ -1,3 +1,10 @@ +use std::ops::{Deref, DerefMut}; + +use tealr::{ + mlu::mlua::{FromLua, FromLuaMulti, IntoLua, IntoLuaMulti}, + ToTypename, +}; + /// generates path to the given script depending on build configuration. /// (optimized builds don't have the teal compiler available) /// @@ -153,3 +160,104 @@ macro_rules! __cfg_feature_any_lua52_lua53_lua54_luajit52 { macro_rules! __cfg_feature_any_lua52_lua53_lua54_luajit52 { ( $( $tok:tt )* ) => {}; } + +#[macro_export] +macro_rules! impl_userdata_from_lua { + ($ty:ident) => { + impl<'lua> ::tealr::mlu::mlua::FromLua<'lua> for $ty { + fn from_lua( + value: ::tealr::mlu::mlua::Value<'lua>, + _lua: &::tealr::mlu::mlua::Lua, + ) -> Result { + match value { + tealr::mlu::mlua::Value::UserData(ud) => { + // for types which deref to something else we need to be explicit + let self_ref: std::cell::Ref = ud.borrow::()?; + let self_ref: &Self = std::ops::Deref::deref(&self_ref); + Ok(self_ref.clone()) + } + _ => { + return Err(::tealr::mlu::mlua::Error::FromLuaConversionError { + from: value.type_name(), + to: stringify!($ty), + message: None, + }) + } + } + } + } + }; +} + +#[macro_export] +macro_rules! impl_userdata_with_tealdata { + ($ty:ident) => { + impl ::tealr::mlu::mlua::UserData for $ty + where + Self: ::tealr::mlu::TealData, + { + fn add_methods<'lua, T: ::tealr::mlu::mlua::UserDataMethods<'lua, Self>>( + methods: &mut T, + ) { + let mut wrapper = tealr::mlu::UserDataWrapper::from_user_data_methods(methods); + ::add_methods(&mut wrapper); + } + + fn add_fields<'lua, T: ::tealr::mlu::mlua::UserDataFields<'lua, Self>>(fields: &mut T) { + let mut wrapper = tealr::mlu::UserDataWrapper::from_user_data_fields(fields); + ::add_fields(&mut wrapper); + } + } + }; +} + +/// Variadic newtype with [`ToTypename`] implemantation +pub struct Variadic(pub(crate) tealr::mlu::mlua::Variadic); + +impl Variadic { + pub fn new>(iter: I) -> Self { + Variadic(tealr::mlu::mlua::Variadic::from_iter(iter.into_iter())) + } +} + +impl Deref for Variadic { + type Target = tealr::mlu::mlua::Variadic; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for Variadic { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl ToTypename for Variadic { + fn to_typename() -> tealr::Type { + let single_type = T::to_typename(); + let collection_type = >::to_typename(); + tealr::Type::Or(vec![single_type, collection_type]) + } +} + +impl<'lua, T: FromLua<'lua>> FromLuaMulti<'lua> for Variadic { + fn from_lua_multi( + values: tealr::mlu::mlua::MultiValue<'lua>, + lua: &'lua tealr::mlu::mlua::Lua, + ) -> tealr::mlu::mlua::Result { + Ok(Variadic(tealr::mlu::mlua::Variadic::from_lua_multi( + values, lua, + )?)) + } +} + +impl<'lua, T: IntoLua<'lua>> IntoLuaMulti<'lua> for Variadic { + fn into_lua_multi( + self, + lua: &'lua tealr::mlu::mlua::Lua, + ) -> tealr::mlu::mlua::Result> { + self.0.into_lua_multi(lua) + } +} 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 0000000000..aa31351705 --- /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, "Does not have ReflectDefault or ReflectFromWorld data registered") \ 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 0000000000..cb7026bdff --- /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 0000000000..bf4ba3d294 --- /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, "Does not have ReflectComponent") 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 0000000000..797e8ce998 --- /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 0000000000..6f4f467703 --- /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, 'Does not have ReflectComponent data registered') \ 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 0000000000..0048f7f653 --- /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 0000000000..50c2e90ed8 --- /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/despawn/despawns_only_root.lua b/crates/languages/bevy_mod_scripting_lua/tests/data/despawn/despawns_only_root.lua new file mode 100644 index 0000000000..2cc5a6f0b7 --- /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 0000000000..de6961bebb --- /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, "parent Entity does not exist") \ 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 0000000000..1b0f617540 --- /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 0000000000..de6961bebb --- /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, "parent Entity does not exist") \ 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 0000000000..554fe5dc9b --- /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 0000000000..de6961bebb --- /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, "parent Entity does not exist") \ 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 0000000000..7640c6f9c0 --- /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(entity) + +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 0000000000..2516a20860 --- /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, "Entity does not exist") 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 0000000000..49992aecf3 --- /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 0000000000..c9f8550d9d --- /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 0000000000..264f4badca --- /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 0000000000..79d541883b --- /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 0000000000..955a467b13 --- /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(entity) + +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 0000000000..06500f3360 --- /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, "Entity does not exist") 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 0000000000..723c709a56 --- /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 0000000000..a2fd345a6f --- /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 0000000000..8bd6133492 --- /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 0000000000..2d21bf08a6 --- /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 0000000000..bbd1c6f119 --- /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 0000000000..d46f9ad774 --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/get_type_by_name/registered_type_returns_correct_type.lua @@ -0,0 +1,10 @@ +local type = world:get_type_by_name('TestComponent') + +local expected = { + type_name = 'test_utils::test_data::TestComponent', + short_name = 'TestComponent', +} + +assert(type ~= nil, 'Type not found') +assert(type.type_name == expected.type_name, 'type_name mismatch, expected: ' .. expected.type_name .. ', got: ' .. type.type_name) +assert(type.short_name == expected.short_name, 'short_name mismatch, expected: ' .. expected.short_name .. ', got: ' .. type.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 0000000000..7c86b381a6 --- /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 0000000000..fc1129e5cc --- /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 0000000000..a15920ea94 --- /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 0000000000..f0d5e1fbf2 --- /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 0000000000..6976b8d800 --- /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 0000000000..7f720c2f05 --- /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_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 0000000000..014d3bb892 --- /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 0000000000..6f7f133beb --- /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 0000000000..b9360485fc --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/data/insert_children/adds_children_to_existing_enttity.lua @@ -0,0 +1,7 @@ +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 0000000000..528f1eb64d --- /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, "parent Entity does not exist") + +local entity = world:spawn() +assert_throws(function() + world:insert_children(entity, 1, {fake_entity}) +end, "the Entity does not exist") \ 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 0000000000..350383361a --- /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 0000000000..1f082f1a1d --- /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 0000000000..eae6c3b0c4 --- /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, "The parent Entity does not exist") + +local entity = world:spawn() +assert_throws(function() + world:push_children(entity, {fake_entity}) +end, "the Entity does not exist") \ 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 0000000000..d31939bdb9 --- /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 entity,_ in world:query(component_a):with(component_a):without(component_a):iter() 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 0000000000..b624260ed7 --- /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 entity, comp in world:query(component_with):with(component_with):without(component_without):iter() do + table.insert(found_entities, entity) +end + +assert(#found_entities == 3, "Expected 3 entities, got " .. #found_entities) + +expected_entities = { + entity_d, + entity_a, + entity_c, +} + +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_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 0000000000..fd535a7f46 --- /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 0000000000..572cddd599 --- /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, "Does not have ReflectComponent data registered") 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 0000000000..294430d420 --- /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 0000000000..ae802adacb --- /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 0000000000..03f456e7ff --- /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, "Does not have ReflectResource data registered") 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 0000000000..86a21cb4ce --- /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/lua_tests.rs b/crates/languages/bevy_mod_scripting_lua/tests/lua_tests.rs new file mode 100644 index 0000000000..778bb8c3ef --- /dev/null +++ b/crates/languages/bevy_mod_scripting_lua/tests/lua_tests.rs @@ -0,0 +1,238 @@ +use bevy::{ + app::App, + asset::{AssetPlugin, AssetServer}, + prelude::{AppTypeRegistry, Children, Entity, HierarchyPlugin, Parent, World}, + reflect::{Reflect, TypeRegistration}, + MinimalPlugins, +}; +use bevy_mod_scripting_core::{ + bindings::{ + Proxy, ReflectAllocator, ReflectReference, ReflectValProxy, ScriptTypeRegistration, + WorldCallbackAccess, + }, + context::ContextLoadingSettings, + error::ScriptError, + event::CallbackLabel, + script::ScriptId, +}; +use bevy_mod_scripting_lua::{ + bindings::{ + providers::bevy_ecs::LuaEntity, + proxy::{LuaProxied, LuaReflectValProxy}, + world::{GetWorld, LuaWorld}, + }, + lua_context_load, lua_handler, + prelude::{Lua, LuaFunction, LuaHookTriggers}, + type_data::{register_lua_values, ReflectLuaValue}, + LuaScriptingPlugin, +}; +use libtest_mimic::{Arguments, Failed, Trial}; +use std::{ + any::TypeId, + borrow::Cow, + 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(bevy_mod_scripting_lua::bindings::providers::LuaBevyScriptingPlugin); + + // 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: &Cow<'static, str>, lua: &mut Lua) -> Result<(), ScriptError> { + let _get_mock_type = lua + .create_function(|_, ()| { + #[derive(Reflect)] + struct Dummy; + let reg = + ScriptTypeRegistration::new(Arc::new(TypeRegistration::of::()), None, None); + Ok(::Proxy::from(reg)) + }) + .unwrap(); + + let _get_entity_with_test_component = lua + .create_function(|l, s: String| { + let world = l.get_world(); + let opt_entity = world.with_resource::(|_, mut allocator| { + let a = World::enumerate_test_components() + .iter() + .find(|(name, _, _)| name.contains(&s)) + .map(|(_, _, c)| { + let reference = ReflectReference::new_allocated( + c.unwrap_or(Entity::from_raw(9999)), + &mut allocator, + ); + <::Proxy>::from(reference) + }); + + a + }); + + Ok(opt_entity) + }) + .unwrap(); + + let assert_throws = lua + .create_function(|_, (f, regex): (LuaFunction, String)| { + let result = f.call::<(), ()>(()); + let err = match result { + Ok(_) => { + return Err(tealr::mlu::mlua::Error::RuntimeError( + "Expected function to throw error, but it did not.".into(), + )) + } + Err(e) => e.to_string(), + }; + + let regex = regex::Regex::new(®ex).unwrap(); + if regex.is_match(&err) { + Ok(()) + } else { + Err(tealr::mlu::mlua::Error::RuntimeError(format!( + "Expected error message to match the regex: \n{}\n\nBut got:\n{}", + regex.as_str(), + err + ))) + } + }) + .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(); + 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 (), + )?; + + lua_handler( + (), + 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(), + )?; + + // WorldCallbackAccess::with_callback_access(app.world_mut(), |world| { + // lua.globals().set("world", LuaWorld(world.clone())).unwrap(); + + // let code = lua.load(self.code).set_name(self.path.to_string_lossy()); + // code.exec().map_err(|e| e.to_string()) + // })?; + 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_rhai/src/lib.rs b/crates/languages/bevy_mod_scripting_rhai/src/lib.rs index cbb0eb1687..267f2758ae 100644 --- a/crates/languages/bevy_mod_scripting_rhai/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_rhai/src/lib.rs @@ -1,202 +1,351 @@ -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::WorldCallbackAccess, + context::{ContextAssigner, ContextBuilder, ContextInitializer, ContextPreHandlingInitializer}, + error::ScriptError, + event::CallbackLabel, + handler::Args, + script::ScriptId, + ScriptingPlugin, +}; +use rhai::{CallFnOptions, Engine, FnPtr, FuncArgs, 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 use rhai::FuncArgs; } -#[derive(Resource)] -pub struct RhaiScriptHost { - pub engine: Engine, - _ph: PhantomData, +pub trait RhaiEventArg: Args + FuncArgs {} +impl RhaiEventArg for T {} + +pub type RhaiRuntime = Engine; + +pub struct RhaiScriptContext { + pub ast: AST, + pub scope: Scope<'static>, } -#[allow(deprecated)] -impl Default for RhaiScriptHost { +pub struct RhaiScriptingPlugin { + pub scripting_plugin: ScriptingPlugin, +} + +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, |mut 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"); - }, - ); - } +#[allow(clippy::too_many_arguments)] +pub fn rhai_callback_handler( + args: A, + 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))?; - fn setup_script( - &mut self, - script_data: &ScriptData, - ctx: &mut Self::ScriptContext, - providers: &mut APIProviders, - ) -> Result<(), ScriptError> { - providers.setup_all(script_data, ctx) - } + if context + .scope + .get_value::(callback.as_ref()) + .is_none() + { + // not subscribed to this handler + return Ok(()); + }; - 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 }) - } + // 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) + }) } +// use crate::{ +// assets::{RhaiFile, RhaiLoader}, +// docs::RhaiDocFragment, +// }; +// use bevy::{ecs::schedule::ScheduleLabel, prelude::*}; +// use bevy_mod_scripting_core::{prelude::*, systems::*}; +// use rhai::*; +// use std::marker::PhantomData; + +// 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::{RhaiRuntime, FuncArgs}; +// } + +// #[derive(Resource)] +// pub struct RhaiScriptHost { +// pub RhaiRuntime: RhaiRuntime, +// _ph: PhantomData, +// } + +// #[allow(deprecated)] +// impl Default for RhaiScriptHost { +// fn default() -> Self { +// let mut e = RhaiRuntime::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 { +// RhaiRuntime: e, +// _ph: Default::default(), +// } +// } +// } + +// pub struct RhaiContext { +// pub ast: AST, +// pub scope: Scope<'static>, +// } + +// #[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, +// } + +// impl ScriptEvent for RhaiEvent { +// fn recipients(&self) -> &crate::Recipients { +// &self.recipients +// } +// } + +// impl ScriptHost for RhaiScriptHost { +// type ScriptContext = RhaiContext; +// type ScriptEvent = RhaiEvent; +// type ScriptAsset = RhaiFile; +// type APITarget = RhaiRuntime; +// 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 RhaiRuntime +// .add_systems( +// Startup, +// |mut providers: ResMut>, mut host: ResMut| { +// providers +// .attach_all(&mut host.RhaiRuntime) +// .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 +// .RhaiRuntime +// .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 }) +// } + +// fn handle_events<'a>( +// &mut self, +// world: &mut World, +// events: &[Self::ScriptEvent], +// ctxs: impl Iterator, &'a mut Self::ScriptContext)>, +// _providers: &mut APIProviders, +// ) { +// ctxs.for_each(|(fd, ctx)| { +// for event in events.iter() { +// // check if this script should handle this event +// if !event.recipients().is_recipient(&fd) { +// continue; +// }; + +// match self.RhaiRuntime.call_fn( +// &mut ctx.scope, +// &ctx.ast, +// &event.hook_name, +// event.args.clone(), +// ) { +// Ok(v) => v, +// Err(e) => { +// let mut state: CachedScriptState = world.remove_resource().unwrap(); + +// match *e { +// EvalAltResult::ErrorFunctionNotFound(..) => {} +// _ => { +// let (_, mut error_wrt, _) = state.event_state.get_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(); +// }); +// } +// } diff --git a/crates/languages/bevy_mod_scripting_rune/src/lib.rs b/crates/languages/bevy_mod_scripting_rune/src/lib.rs index 4c7dc0652a..cbcc14d4ac 100644 --- a/crates/languages/bevy_mod_scripting_rune/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_rune/src/lib.rs @@ -1,271 +1,292 @@ -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::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 - } -} - -/// A cached Rune Vm used to execute units. -struct RuneVm(Vm); +pub trait RuneEventArg: Args + Clone + Send + Sync + 'static {} +impl RuneEventArg for T {} -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; + +pub struct RuneScriptingPlugin { + pub scripting_plugin: ScriptingPlugin, } -impl Default for RuneScriptHost { +impl Default for RuneScriptingPlugin { fn default() -> Self { Self { - _ph: Default::default(), + scripting_plugin: ScriptingPlugin { + runtime_builder: todo!(), + runtime_settings: todo!(), + callback_handler: todo!(), + context_builder: todo!(), + context_assigner: todo!(), + }, } } } -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); - } -} - -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)); - } -} +// 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 index d8b651d323..b8598211bd 100644 --- a/crates/macro_tests/Cargo.toml +++ b/crates/macro_tests/Cargo.toml @@ -16,11 +16,7 @@ debug = false [dev-dependencies] trybuild = "1.0" bevy = { version = "0.15.0", default-features = false } -bevy_mod_scripting = { path = "../../", features = [ - "lua", - "lua_script_api", - "lua54", -] } +bevy_mod_scripting = { path = "../../", features = ["lua", "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/test_utils/Cargo.toml b/crates/test_utils/Cargo.toml new file mode 100644 index 0000000000..9c3b96d895 --- /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 0000000000..363a59ff80 --- /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 0000000000..cf5fc1cc23 --- /dev/null +++ b/crates/test_utils/src/test_data.rs @@ -0,0 +1,240 @@ +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")) + } +} + +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 + ] +); + +/// 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/examples/lua/bevy_api.rs b/examples/lua/bevy_api.rs index 493bec50b4..51088c542b 100644 --- a/examples/lua/bevy_api.rs +++ b/examples/lua/bevy_api.rs @@ -1,9 +1,10 @@ +use asset::ScriptAsset; use bevy::app::AppExit; - use bevy::prelude::*; +use bevy_mod_scripting::lua::LuaScriptingPlugin; use bevy_mod_scripting::prelude::*; - -use bevy_script_api::lua::RegisterForeignLuaType; +use bevy_mod_scripting_lua::bindings::providers::LuaBevyScriptingPlugin; +use script::ScriptComponent; #[derive(Component, Default, Reflect)] #[reflect(Component)] @@ -13,192 +14,72 @@ pub struct MyComponent { usize: usize, f32: f32, mat3: Mat3, + vec_of_usize: Vec, + vec_of_usize2: Vec, + option_usize: Option, 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 +const SCRIPT_NAME: &str = "scripts/bevy_api.lua"; - 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) +fn load_script(server: Res, mut handle: Local>) { + let handle_ = server.load::(SCRIPT_NAME); + *handle = handle_; +} - 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) +fn init_data(mut commands: Commands) { + commands.spawn(( + 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]), + vec_of_usize: vec![1, 2, 3], + vec_of_usize2: vec![4, 5, 6], + option_usize: None, + }, + ScriptComponent::new(vec![SCRIPT_NAME.into()]), + )); +} - print("============") +struct EventCallbackLabel; +impl IntoCallbackLabel for EventCallbackLabel { + fn into_callback_label() -> CallbackLabel { + "on_event".into() + } +} - -- this is an example of something impossible to achieve with plain bevy reflection under the hood - comp.mat3[1][1] = 42 +pub fn send_event(mut writer: EventWriter>) { + writer.send(ScriptCallbackEvent::new_for_all( + EventCallbackLabel::into_callback_label(), + (), + )); +} - -- 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!"); - }); +fn main() -> std::io::Result<()> { + let mut app = App::new(); - world.send_event(AppExit::Success); - }, + app.add_plugins(DefaultPlugins) + .add_plugins(LuaScriptingPlugin::<()>::default()) + .add_plugins(LuaBevyScriptingPlugin) + .register_type::() + .add_systems(Startup, (init_data, load_script)) + .add_systems( + Update, + ( + send_event, + event_handler::.after(send_event), + ), ); app.run(); diff --git a/examples/lua/complex_game_loop.rs b/examples/lua/complex_game_loop.rs deleted file mode 100644 index 55efa6573a..0000000000 --- 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/coroutines.rs b/examples/lua/coroutines.rs index 2285984a6d..9c41bb56a7 100644 --- a/examples/lua/coroutines.rs +++ b/examples/lua/coroutines.rs @@ -1,39 +1,49 @@ +use asset::ScriptAsset; use bevy::prelude::*; +use bevy_mod_scripting::lua::LuaScriptingPlugin; use bevy_mod_scripting::prelude::*; +use script::ScriptComponent; -/// 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); +struct OnEventCallback; +impl IntoCallbackLabel for OnEventCallback { + fn into_callback_label() -> CallbackLabel { + "on_update".into() + } } -fn load_our_scripts(server: Res, mut commands: Commands) { +fn load_script( + server: Res, + mut commands: Commands, + mut handle: Local>, +) { let path = "scripts/coroutines.lua"; - let handle = server.load::(path); - let script = Script::::new(path.to_string(), handle); + let handle_ = server.load::(path); + *handle = handle_; + + commands.spawn(ScriptComponent::new(vec![path.into()])); +} - commands.spawn(()).insert(ScriptCollection:: { - scripts: vec![script], - }); +fn send_event(mut writer: EventWriter>) { + writer.send(ScriptCallbackEvent::new_for_all( + OnEventCallback::into_callback_label(), + (), + )); } 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_plugins(LuaScriptingPlugin::<()>::default()) + .add_systems(Startup, load_script) + .add_systems( + Update, + ( + send_event, + event_handler::.after(send_event), + ), + ); + app.run(); Ok(()) diff --git a/examples/lua/dynamic_queries.rs b/examples/lua/dynamic_queries.rs index 9a07eb646d..d2e89aac31 100644 --- a/examples/lua/dynamic_queries.rs +++ b/examples/lua/dynamic_queries.rs @@ -1,5 +1,8 @@ -use bevy::prelude::*; +use asset::ScriptAsset; +use bevy::{core::FrameCount, prelude::*}; use bevy_mod_scripting::prelude::*; +use bevy_mod_scripting_lua::{bindings::providers::LuaBevyScriptingPlugin, LuaScriptingPlugin}; +use script::ScriptComponent; #[derive(Component, Reflect)] #[reflect(Component)] @@ -13,22 +16,32 @@ pub struct ComponentB; #[reflect(Component)] pub struct ComponentC; +fn load_script( + server: Res, + mut commands: Commands, + mut handle: Local>, +) { + let path = "scripts/dynamic_queries.lua"; + let handle_ = server.load::(path); + *handle = handle_; + + commands.spawn(ScriptComponent::new(vec![path.into()])); +} + fn main() { let mut app = App::new(); - app.add_plugins((DefaultPlugins, ScriptingPlugin)) + app.add_plugins(DefaultPlugins); + app.add_plugins(LuaScriptingPlugin::<()>::default()); + app.add_plugins(LuaBevyScriptingPlugin) .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()) + .add_systems(Startup, (setup, load_script)) .run(); } -fn setup(mut commands: Commands, asset_server: Res) { +fn setup(mut commands: Commands) { commands.spawn((ComponentA,)); commands.spawn((ComponentA, ComponentB)); commands.spawn((ComponentA, ComponentC)); @@ -43,22 +56,4 @@ fn setup(mut commands: Commands, asset_server: Res) { 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 index 3a8a75e106..861b88381b 100644 --- a/examples/lua/event_recipients.rs +++ b/examples/lua/event_recipients.rs @@ -1,134 +1,62 @@ -use bevy::prelude::*; +use bevy::{app::AppExit, core::FrameCount, prelude::*}; +use bevy_mod_scripting::lua::LuaScriptingPlugin; use bevy_mod_scripting::prelude::*; -use rand::prelude::SliceRandom; -use std::sync::atomic::Ordering::Relaxed; -use std::sync::{atomic::AtomicU32, Mutex}; +use bevy_mod_scripting_core::{asset::ScriptAsset, script::ScriptComponent}; -#[derive(Clone)] -pub struct MyLuaArg(usize); +fn load_script( + server: Res, + mut commands: Commands, + mut handle: Local>, +) { + let path = "scripts/event_recipients.lua"; + let handle_ = server.load::(path); + *handle = handle_; -impl<'lua> IntoLua<'lua> for MyLuaArg { - fn into_lua(self, lua: &'lua Lua) -> mlua::Result> { - self.0.into_lua(lua) - } + commands.spawn(ScriptComponent::new(vec![path.into()])); + commands.spawn(ScriptComponent::new(vec![path.into()])); } -#[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(()) - } +fn trigger_script_callback(mut writer: EventWriter>) { + writer.send(ScriptCallbackEvent::new_for_all( + OnEventCallback::into_callback_label(), + 1, + )); + + writer.send(ScriptCallbackEvent::new( + OnEventCallback::into_callback_label(), + 2, + Recipients::Entity(Entity::from_raw(6)), + )); } -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); +fn quit_after_few_frames(mut exit: EventWriter, count: Res) { + if count.0 > 5 { + exit.send(AppExit::Success); + } } -#[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 }); +pub struct OnEventCallback; +impl IntoCallbackLabel for OnEventCallback { + fn into_callback_label() -> CallbackLabel { + "on_event".into() + } } 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(); + .add_plugins(LuaScriptingPlugin::::default()) + .add_systems(Startup, load_script) + .add_systems( + Update, + ( + trigger_script_callback, + event_handler::.after(trigger_script_callback), + quit_after_few_frames, + ), + ) + .run(); Ok(()) } diff --git a/makefile b/makefile index 5fc3883bdd..f6419d30d1 100644 --- a/makefile +++ b/makefile @@ -28,13 +28,15 @@ 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/languages/bevy_mod_scripting_lua/src/bindings/providers 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 + 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}' -vv deletion_confirmation: @echo -n "This action will delete ALL files in directories: '${GENERATED_SRC_PATH}' amd ${OUTPUT_PATH} (y/N) " diff --git a/src/lib.rs b/src/lib.rs index 82d53079ed..cb50ebb838 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,11 +19,6 @@ 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::*; @@ -43,9 +28,6 @@ pub mod 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::*; + // #[cfg(feature = "rune")] + // pub use bevy_mod_scripting_rune::prelude::*; }