From b6acdc5a8c7880c0fb115b07261abaa6be6a2331 Mon Sep 17 00:00:00 2001 From: James Bell Date: Sat, 2 Mar 2024 13:47:43 -0500 Subject: [PATCH] Refactor core and remove render --- .vscode/settings.json | 1 - Cargo.lock | 1316 +++++++++-------- Cargo.toml | 5 +- crates/bevy_tiles/.vscode/settings.json | 5 - crates/bevy_tiles/README.md | 7 +- crates/bevy_tiles/examples/basic_2d.rs | 35 +- crates/bevy_tiles/examples/basic_3d.rs | 36 +- crates/bevy_tiles/examples/logo.rs | 16 +- crates/bevy_tiles/examples/spatial.rs | 32 +- crates/bevy_tiles/src/chunks.rs | 60 +- crates/bevy_tiles/src/chunks/chunk_query.rs | 241 ++- crates/bevy_tiles/src/commands.rs | 765 ++++++---- crates/bevy_tiles/src/commands/chunk_batch.rs | 22 +- .../bevy_tiles/src/commands/chunk_single.rs | 24 +- crates/bevy_tiles/src/commands/map.rs | 61 +- crates/bevy_tiles/src/commands/tile_batch.rs | 59 +- crates/bevy_tiles/src/commands/tile_single.rs | 85 +- crates/bevy_tiles/src/coords.rs | 2 - crates/bevy_tiles/src/lib.rs | 8 +- crates/bevy_tiles/src/maps.rs | 51 +- crates/bevy_tiles/src/tiles.rs | 58 +- crates/bevy_tiles/src/tiles/tile_query.rs | 387 ++--- crates/bevy_tiles_render/Cargo.toml | 38 - crates/bevy_tiles_render/README.md | 29 - crates/bevy_tiles_render/assets/block.png | Bin 201 -> 0 bytes crates/bevy_tiles_render/assets/character.png | Bin 265 -> 0 bytes .../bevy_tiles_render/examples/hello_tile.rs | 80 - crates/bevy_tiles_render/src/bindings.rs | 262 ---- .../src/buffer_helpers/gpu_storage_buffer.rs | 104 -- .../src/buffer_helpers/mod.rs | 3 - .../bevy_tiles_render/src/chunk/internal.rs | 27 - crates/bevy_tiles_render/src/chunk/mod.rs | 4 - crates/bevy_tiles_render/src/cleanup.rs | 38 - crates/bevy_tiles_render/src/draw.rs | 120 -- crates/bevy_tiles_render/src/extract.rs | 136 -- crates/bevy_tiles_render/src/lib.rs | 93 -- crates/bevy_tiles_render/src/maps/internal.rs | 24 - crates/bevy_tiles_render/src/maps/mod.rs | 54 - crates/bevy_tiles_render/src/pipeline.rs | 101 -- crates/bevy_tiles_render/src/prepare.rs | 138 -- crates/bevy_tiles_render/src/queue.rs | 118 -- .../src/shaders/tiles_frag.wgsl | 18 - .../src/shaders/tiles_vert.wgsl | 105 -- crates/bevy_tiles_render/src/tiles.rs | 1 - 44 files changed, 1681 insertions(+), 3088 deletions(-) delete mode 100644 crates/bevy_tiles/.vscode/settings.json delete mode 100644 crates/bevy_tiles_render/Cargo.toml delete mode 100644 crates/bevy_tiles_render/README.md delete mode 100644 crates/bevy_tiles_render/assets/block.png delete mode 100644 crates/bevy_tiles_render/assets/character.png delete mode 100644 crates/bevy_tiles_render/examples/hello_tile.rs delete mode 100644 crates/bevy_tiles_render/src/bindings.rs delete mode 100644 crates/bevy_tiles_render/src/buffer_helpers/gpu_storage_buffer.rs delete mode 100644 crates/bevy_tiles_render/src/buffer_helpers/mod.rs delete mode 100644 crates/bevy_tiles_render/src/chunk/internal.rs delete mode 100644 crates/bevy_tiles_render/src/chunk/mod.rs delete mode 100644 crates/bevy_tiles_render/src/cleanup.rs delete mode 100644 crates/bevy_tiles_render/src/draw.rs delete mode 100644 crates/bevy_tiles_render/src/extract.rs delete mode 100644 crates/bevy_tiles_render/src/lib.rs delete mode 100644 crates/bevy_tiles_render/src/maps/internal.rs delete mode 100644 crates/bevy_tiles_render/src/maps/mod.rs delete mode 100644 crates/bevy_tiles_render/src/pipeline.rs delete mode 100644 crates/bevy_tiles_render/src/prepare.rs delete mode 100644 crates/bevy_tiles_render/src/queue.rs delete mode 100644 crates/bevy_tiles_render/src/shaders/tiles_frag.wgsl delete mode 100644 crates/bevy_tiles_render/src/shaders/tiles_vert.wgsl delete mode 100644 crates/bevy_tiles_render/src/tiles.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index e9c6015..1146b1a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,5 @@ { "rust-analyzer.linkedProjects": [ - ".\\crates\\bevy_tiles_render\\Cargo.toml", ".\\crates\\bevy_tiles\\Cargo.toml" ] } \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index edf4eaf..5848087 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,7 +41,7 @@ checksum = "cd3b6ae1eabbfbced10e840fd3fce8a93ae84f174b3e4ba892ab7bcb42e477a7" dependencies = [ "accesskit", "accesskit_consumer", - "objc2", + "objc2 0.3.0-beta.3.patch-leaks.3", "once_cell", ] @@ -61,25 +61,17 @@ dependencies = [ [[package]] name = "accesskit_winit" -version = "0.15.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88e39fcec2e10971e188730b7a76bab60647dacc973d4591855ebebcadfaa738" +checksum = "45f8f7c9f66d454d5fd8e344c8c8c7324b57194e1041b955519fc58a01e77a25" dependencies = [ "accesskit", "accesskit_macos", "accesskit_windows", + "raw-window-handle 0.6.0", "winit", ] -[[package]] -name = "addr2line" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" -dependencies = [ - "gimli", -] - [[package]] name = "adler" version = "1.0.2" @@ -88,9 +80,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "d713b3834d76b85304d4d525563c1276e2e30dc97cc67bfb4585a4a29fc2c89f" dependencies = [ "cfg-if", "getrandom", @@ -138,20 +130,23 @@ dependencies = [ [[package]] name = "android-activity" -version = "0.4.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64529721f27c2314ced0890ce45e469574a73e5e6fdd6e9da1860eb29285f5e0" +checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289" dependencies = [ "android-properties", - "bitflags 1.3.2", + "bitflags 2.4.1", "cc", + "cesu8", + "jni 0.21.1", "jni-sys", "libc", "log", - "ndk", + "ndk 0.8.0", "ndk-context", - "ndk-sys", - "num_enum 0.6.1", + "ndk-sys 0.5.0+25.2.9519653", + "num_enum 0.7.2", + "thiserror", ] [[package]] @@ -196,6 +191,12 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "as-raw-xcb-connection" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" + [[package]] name = "ash" version = "0.37.3+1.3.251" @@ -215,17 +216,6 @@ dependencies = [ "futures-core", ] -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener 2.5.3", - "futures-core", -] - [[package]] name = "async-channel" version = "2.1.0" @@ -245,33 +235,23 @@ version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc5ea910c42e5ab19012bab31f53cb4d63d54c3a27730f9a833a88efcf4bb52d" dependencies = [ - "async-lock 3.1.1", + "async-lock", "async-task", "concurrent-queue", - "fastrand 2.0.1", - "futures-lite 2.0.1", + "fastrand", + "futures-lite", "slab", ] [[package]] name = "async-fs" -version = "1.6.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +checksum = "bc19683171f287921f2405677dd2ed2549c3b3bda697a563ebc3a121ace2aba1" dependencies = [ - "async-lock 2.8.0", - "autocfg", + "async-lock", "blocking", - "futures-lite 1.13.0", -] - -[[package]] -name = "async-lock" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" -dependencies = [ - "event-listener 2.5.3", + "futures-lite", ] [[package]] @@ -303,27 +283,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "backtrace" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - [[package]] name = "base64" version = "0.21.5" @@ -332,18 +291,18 @@ checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "bevy" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4bc7e09282a82a48d70ade0c4c1154b0fd7882a735a39c66766a5d0f4718ea9" +checksum = "611dd99f412e862610adb43e2243b16436c6d8009f6d9dbe8ce3d6d840b34029" dependencies = [ "bevy_internal", ] [[package]] name = "bevy_a11y" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68080288c932634f6563d3a8299efe0ddc9ea6787539c4c771ba250d089a94f0" +checksum = "5bf80cd6d0dca4073f9b34b16f1d187a4caa035fd841892519431783bbc9e287" dependencies = [ "accesskit", "bevy_app", @@ -353,9 +312,9 @@ dependencies = [ [[package]] name = "bevy_animation" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aa37683b1281e1ba8cf285644e6e3f0704f14b3901c5ee282067ff7ff6f4a56" +checksum = "aa4ef4c35533df3f0c4e938cf6a831456ea563775bab799336f74331140c7665" dependencies = [ "bevy_app", "bevy_asset", @@ -372,9 +331,9 @@ dependencies = [ [[package]] name = "bevy_app" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d41731817993f92e4363dd3335558e779e290bc71eefc0b5547052b85810907e" +checksum = "8bce3544afc010ffed39c136f6d5a9322d20d38df1394d468ba9106caa0434cb" dependencies = [ "bevy_derive", "bevy_ecs", @@ -388,13 +347,13 @@ dependencies = [ [[package]] name = "bevy_asset" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "935984568f75867dd7357133b06f4b1502cd2be55e4642d483ce597e46e63bff" +checksum = "ac185d8e29c7eb0194f8aae7af3f7234f7ca7a448293be1d3d0d8fef435f65ec" dependencies = [ "async-broadcast", "async-fs", - "async-lock 2.8.0", + "async-lock", "bevy_app", "bevy_asset_macros", "bevy_ecs", @@ -407,7 +366,7 @@ dependencies = [ "crossbeam-channel", "downcast-rs", "futures-io", - "futures-lite 1.13.0", + "futures-lite", "js-sys", "parking_lot", "ron", @@ -420,21 +379,21 @@ dependencies = [ [[package]] name = "bevy_asset_macros" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f48b9bbe4ec605e4910b5cd1e1a0acbfbe0b80af5f3bcc4489a9fdd1e80058c" +checksum = "cb82d1aac8251378c45a8d0ad788d1bf75f54db28c1750f84f1fd7c00127927a" dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.50", ] [[package]] name = "bevy_audio" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a69889e1bfa4dbac4e641536b94f91c441da55796ad9832e77836b8264688b" +checksum = "f4fe7f952e5e0a343fbde43180db7b8e719ad78594480c91b26876623944a3a1" dependencies = [ "bevy_app", "bevy_asset", @@ -450,9 +409,9 @@ dependencies = [ [[package]] name = "bevy_core" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3daa24502a14839509f02407bc7e48299fe84d260877de23b60662de0f4f4b6c" +checksum = "f7b1b340b8d08f48ecd51b97589d261f5023a7b073d25e300382c49146524103" dependencies = [ "bevy_app", "bevy_ecs", @@ -465,9 +424,9 @@ dependencies = [ [[package]] name = "bevy_core_pipeline" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b77c4fca6e90edbe2e72da7bc9aa7aed7dfdfded0920ae0a0c845f5e11084a" +checksum = "626a5aaadbdd69eae020c5856575d2d0113423ae1ae1351377e20956d940052c" dependencies = [ "bevy_app", "bevy_asset", @@ -487,20 +446,20 @@ dependencies = [ [[package]] name = "bevy_derive" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f484318350462c58ba3942a45a656c1fd6b6e484a6b6b7abc3a787ad1a51e500" +checksum = "028ae2a34678055185d7f1beebb1ebe6a8dcf3733e139e4ee1383a7f29ae8ba6" dependencies = [ "bevy_macro_utils", "quote", - "syn 2.0.39", + "syn 2.0.50", ] [[package]] name = "bevy_diagnostic" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa38ca5967d335cc1006a0e0f1a86c350e2f15fd1878449f61d04cd57a7c4060" +checksum = "01a104acfdc5280accd01a3524810daf3bda72924e3da0c8a9ec816a57eef4e3" dependencies = [ "bevy_app", "bevy_core", @@ -508,23 +467,23 @@ dependencies = [ "bevy_log", "bevy_time", "bevy_utils", + "const-fnv1a-hash", "sysinfo", ] [[package]] name = "bevy_ecs" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709fbd22f81fb681534cd913c41e1cd18b17143368743281195d7f024b61aea" +checksum = "b85406d5febbbdbcac4444ef61cd9a816f2f025ed692a3fc5439a32153070304" dependencies = [ - "async-channel 1.9.0", + "async-channel", "bevy_ecs_macros", "bevy_ptr", "bevy_reflect", "bevy_tasks", "bevy_utils", "downcast-rs", - "event-listener 2.5.3", "fixedbitset", "rustc-hash", "serde", @@ -534,21 +493,21 @@ dependencies = [ [[package]] name = "bevy_ecs_macros" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8843aa489f159f25cdcd9fee75cd7d221a7098a71eaa72cb2d6b40ac4e3f1ba" +checksum = "9a3ce4b65d7c5f1990e729df75cec2ea6e2241b4a0c37b31c281a04c59c11b7b" dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.50", ] [[package]] name = "bevy_encase_derive" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5328a3715e933ebbff07d0e99528dc423c4f7a53590ed1ac19a120348b028990" +checksum = "6c3d301922e76b16819e17c8cc43b34e92c13ccd06ad19dfa3e52a91a0e13e5c" dependencies = [ "bevy_macro_utils", "encase_derive_impl", @@ -556,9 +515,9 @@ dependencies = [ [[package]] name = "bevy_gilrs" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b81ca2ebf66cbc7f998f1f142b15038ffe3c4ae1d51f70adda26dcf51b0c4ca" +checksum = "96364a1875ee4545fcf825c78dc065ddb9a3b2a509083ef11142f9de0eb8aa17" dependencies = [ "bevy_app", "bevy_ecs", @@ -572,15 +531,17 @@ dependencies = [ [[package]] name = "bevy_gizmos" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db232274ddca2ae452eb2731b98267b795d133ddd14013121bc7daddde1c7491" +checksum = "bdca80b7b4db340eb666d69374a0195b3935759120d0b990fcef8b27d0fb3680" dependencies = [ "bevy_app", "bevy_asset", "bevy_core", "bevy_core_pipeline", "bevy_ecs", + "bevy_gizmos_macros", + "bevy_log", "bevy_math", "bevy_pbr", "bevy_reflect", @@ -590,13 +551,25 @@ dependencies = [ "bevy_utils", ] +[[package]] +name = "bevy_gizmos_macros" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a949eb8b4538a6e4d875321cda2b63dc0fb0317cf18c8245ca5a32f24f6d26d" +dependencies = [ + "bevy_macro_utils", + "proc-macro2", + "quote", + "syn 2.0.50", +] + [[package]] name = "bevy_gltf" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85adc6b1fc86687bf67149e0bafaa4d6da432232fa956472d1b37f19121d3ace" +checksum = "031d0c2a7c0353bb9ac08a5130e58b9a2de3cdaa3c31b5da00b22a9e4732a155" dependencies = [ - "base64 0.13.1", + "base64", "bevy_animation", "bevy_app", "bevy_asset", @@ -622,9 +595,9 @@ dependencies = [ [[package]] name = "bevy_hierarchy" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06bd477152ce2ae1430f5e0a4f19216e5785c22fee1ab23788b5982dc59d1a55" +checksum = "a9f9f843e43d921f07658c24eae74285efc7a335c87998596f3f365155320c69" dependencies = [ "bevy_app", "bevy_core", @@ -632,28 +605,28 @@ dependencies = [ "bevy_log", "bevy_reflect", "bevy_utils", - "smallvec", ] [[package]] name = "bevy_input" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab9a599189b2a694c182d60cd52219dd9364f9892ff542d87799b8e45d9e6dc" +checksum = "a9cb5b2f3747ffb00cf7e3d6b52f7384476921cd31f0cfd3d1ddff31f83d9252" dependencies = [ "bevy_app", "bevy_ecs", "bevy_math", "bevy_reflect", "bevy_utils", + "smol_str", "thiserror", ] [[package]] name = "bevy_internal" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f124bece9831afd80897815231072d51bfe3ac58c6bb58eca8880963b6d0487c" +checksum = "7af89c7083830b1d65fcf0260c3d2537c397fe8ce871471b6e97198a4704f23e" dependencies = [ "bevy_a11y", "bevy_animation", @@ -690,9 +663,9 @@ dependencies = [ [[package]] name = "bevy_log" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc10ba1d225a8477b9e80a1bf797d8a8b8274e83c9b24fb4d9351aec9229755" +checksum = "cfd5bcc3531f8008897fb03cc8751b86d0d29ef94f8fd38b422f9603b7ae80d0" dependencies = [ "android_log-sys", "bevy_app", @@ -706,22 +679,22 @@ dependencies = [ [[package]] name = "bevy_macro_utils" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e566640c6b6dced73d2006c764c2cffebe1a82be4809486c4a5d7b4b50efed4d" +checksum = "ac4401c25b197e7c1455a4875a90b61bba047a9e8d290ce029082c818ab1a21c" dependencies = [ "proc-macro2", "quote", "rustc-hash", - "syn 2.0.39", - "toml_edit 0.20.7", + "syn 2.0.50", + "toml_edit 0.21.1", ] [[package]] name = "bevy_math" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ddc2b76783939c530178f88e5711a1b01044d7b02db4033e2eb8b43b6cf4ec" +checksum = "6f312b1b8aa6d3965b65040b08e33efac030db3071f20b44f9da9c4c3dfcaf76" dependencies = [ "glam", "serde", @@ -729,18 +702,18 @@ dependencies = [ [[package]] name = "bevy_mikktspace" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ec4962977a746d870170532fc92759e04d3dbcae8b7b82e7ca3bb83b1d75277" +checksum = "3075c01f2b1799945892d5310fc1836e47c045dfe6af5878a304a475931a0c5f" dependencies = [ "glam", ] [[package]] name = "bevy_pbr" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520bfd2a898c74f84ea52cfb8eb061f37373ad15e623489d5f75d27ebd6138fe" +checksum = "c31c72bf12e50ff76c9ed9a7c51ceb88bfea9865d00f24d95b12344fffe1e270" dependencies = [ "bevy_app", "bevy_asset", @@ -756,7 +729,6 @@ dependencies = [ "bitflags 2.4.1", "bytemuck", "fixedbitset", - "naga_oil", "radsort", "smallvec", "thread_local", @@ -764,15 +736,15 @@ dependencies = [ [[package]] name = "bevy_ptr" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77ec20c8fafcdc196508ef5ccb4f0400a8d193cb61f7b14a36ed9a25ad423cf" +checksum = "86afa4a88ee06b10fe1e6f28a796ba2eedd16804717cbbb911df0cbb0cd6677b" [[package]] name = "bevy_reflect" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7921f15fc944c9c8ad01d7dbcea6505b8909c6655cd9382bab1407181556038" +checksum = "133dfab8d403d0575eeed9084e85780bbb449dcf75dd687448439117789b40a2" dependencies = [ "bevy_math", "bevy_ptr", @@ -782,31 +754,30 @@ dependencies = [ "erased-serde", "glam", "serde", - "smallvec", "smol_str", "thiserror", ] [[package]] name = "bevy_reflect_derive" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4a8c5475f216e751ef4452a1306b00711f33d2d04d9f149e4c845dfeb6753a0" +checksum = "ce1679a4dfdb2c9ff24ca590914c3cec119d7c9e1b56fa637776913acc030386" dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.50", "uuid", ] [[package]] name = "bevy_render" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdefdd3737125b0d94a6ff20bb70fa8cfe9d7d5dcd72ba4dfe6c5f1d30d9f6e4" +checksum = "d3b194b7029b7541ef9206ac3cb696d3cb37f70bd3260d293fc00d378547e892" dependencies = [ - "async-channel 1.9.0", + "async-channel", "bevy_app", "bevy_asset", "bevy_core", @@ -829,7 +800,7 @@ dependencies = [ "codespan-reporting", "downcast-rs", "encase", - "futures-lite 1.13.0", + "futures-lite", "hexasphere", "image", "js-sys", @@ -838,7 +809,6 @@ dependencies = [ "naga_oil", "ruzstd", "serde", - "smallvec", "thiserror", "thread_local", "wasm-bindgen", @@ -848,21 +818,21 @@ dependencies = [ [[package]] name = "bevy_render_macros" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64d86bfc5a1e7fbeeaec0c4ceab18155530f5506624670965db3415f75826bea" +checksum = "4aa6d99b50375bb7f63be2c3055dfe2f926f7b3c4db108bb0b1181b4f02766aa" dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.50", ] [[package]] name = "bevy_scene" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7df078b5e406e37c8a1c6ba0d652bf105fde713ce3c3efda7263fe27467eee5" +checksum = "2c3c82eaff0b22949183a75a7e2d7fc4ece808235918b34c5b282aab52c3563a" dependencies = [ "bevy_app", "bevy_asset", @@ -873,7 +843,6 @@ dependencies = [ "bevy_render", "bevy_transform", "bevy_utils", - "ron", "serde", "thiserror", "uuid", @@ -881,9 +850,9 @@ dependencies = [ [[package]] name = "bevy_sprite" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7cc0c9d946e17e3e0aaa202f182837bc796c4f862b2e5a805134f873f21cf7f" +checksum = "5ea977d7d7c48fc4ba283d449f09528c4e70db17c9048e32e99ecd9890d72223" dependencies = [ "bevy_app", "bevy_asset", @@ -907,23 +876,23 @@ dependencies = [ [[package]] name = "bevy_tasks" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fefa7fe0da8923525f7500e274f1bd60dbd79918a25cf7d0dfa0a6ba15c1cf" +checksum = "b20f243f6fc4c4ba10c2dbff891e947ddae947bb20b263f43e023558b35294bd" dependencies = [ - "async-channel 1.9.0", + "async-channel", "async-executor", "async-task", "concurrent-queue", - "futures-lite 1.13.0", + "futures-lite", "wasm-bindgen-futures", ] [[package]] name = "bevy_text" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9a79d49ca06170d69149949b134c14e8b99ace1444c1ca2cd4743b19d5b055" +checksum = "006990d27551dbc339774178e833290952511621662fd5ca23a4e6e922ab2d9f" dependencies = [ "ab_glyph", "bevy_app", @@ -943,30 +912,18 @@ dependencies = [ [[package]] name = "bevy_tiles" -version = "0.1.0" +version = "0.0.0-dev1" dependencies = [ "bevy", "bimap", "rstest", ] -[[package]] -name = "bevy_tiles_render" -version = "0.1.0" -dependencies = [ - "bevy", - "bevy_tiles", - "crossbeam", - "dashmap", - "rand", - "rstest", -] - [[package]] name = "bevy_time" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6250d76eed3077128b6a3d004f9f198b01107800b9824051e32bb658054e837" +checksum = "9738901b6b251d2c9250542af7002d6f671401fc3b74504682697c5ec822f210" dependencies = [ "bevy_app", "bevy_ecs", @@ -978,9 +935,9 @@ dependencies = [ [[package]] name = "bevy_transform" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d541e0c292edbd96afae816ee680e02247422423ccd5dc635c1e211a20ed64be" +checksum = "ba73744a95bc4b8683e91cea3e79b1ad0844c1d677f31fbbc1814c79a5b4f8f0" dependencies = [ "bevy_app", "bevy_ecs", @@ -992,9 +949,9 @@ dependencies = [ [[package]] name = "bevy_ui" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d785e3b75dabcb2a8ad0d50933f8f3446d59e512cabc2d2a145e28c2bb8792ba" +checksum = "fafe872906bac6d7fc8ecff166f56b4253465b2895ed88801499aa113548ccc6" dependencies = [ "bevy_a11y", "bevy_app", @@ -1014,46 +971,45 @@ dependencies = [ "bevy_utils", "bevy_window", "bytemuck", - "serde", - "smallvec", "taffy", "thiserror", ] [[package]] name = "bevy_utils" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7915222f4a08ccc782e08d10b751b42e5f9d786e697d0cb3fd09333cb7e8b6ea" +checksum = "94a06aca1c1863606416b892f4c79e300dbc6211b6690953269051a431c2cca0" dependencies = [ "ahash", "bevy_utils_proc_macros", "getrandom", - "hashbrown 0.14.2", - "instant", + "hashbrown", "nonmax", "petgraph", + "smallvec", "thiserror", "tracing", "uuid", + "web-time", ] [[package]] name = "bevy_utils_proc_macros" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aafecc952b6b8eb1a93c12590bd867d25df2f4ae1033a01dfdfc3c35ebccfff" +checksum = "31ae98e9c0c08b0f5c90e22cd713201f759b98d4fd570b99867a695f8641859a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.50", ] [[package]] name = "bevy_window" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ee72bf7f974000e9b31bb971a89387f1432ba9413f35c4fef59fef49767260" +checksum = "cb627efd7622a61398ac0d3674f93c997cffe16f13c59fb8ae8a05c9e28de961" dependencies = [ "bevy_a11y", "bevy_app", @@ -1062,14 +1018,15 @@ dependencies = [ "bevy_math", "bevy_reflect", "bevy_utils", - "raw-window-handle", + "raw-window-handle 0.6.0", + "smol_str", ] [[package]] name = "bevy_winit" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1eb71f287eca9006dda998784c7b931e400ae2cc4c505da315882a8b082f21ad" +checksum = "55105324a201941ae587790f83f6d9caa327e0baa0205558ec41e5ee05a1f703" dependencies = [ "accesskit_winit", "approx", @@ -1084,7 +1041,7 @@ dependencies = [ "bevy_utils", "bevy_window", "crossbeam-channel", - "raw-window-handle", + "raw-window-handle 0.6.0", "wasm-bindgen", "web-sys", "winit", @@ -1113,7 +1070,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.39", + "syn 2.0.50", ] [[package]] @@ -1171,7 +1128,16 @@ version = "0.1.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa55741ee90902547802152aaf3f8e5248aab7e21468089560d4c8840561146" dependencies = [ - "objc-sys", + "objc-sys 0.2.0-beta.2", +] + +[[package]] +name = "block-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae85a0696e7ea3b835a453750bf002770776609115e6d25c6d2ff28a8200f7e7" +dependencies = [ + "objc-sys 0.3.2", ] [[package]] @@ -1180,8 +1146,18 @@ version = "0.2.0-alpha.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8dd9e63c1744f755c2f60332b88de39d341e5e86239014ad839bd71c106dec42" dependencies = [ - "block-sys", - "objc2-encode", + "block-sys 0.1.0-beta.1", + "objc2-encode 2.0.0-pre.2", +] + +[[package]] +name = "block2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" +dependencies = [ + "block-sys 0.2.1", + "objc2 0.4.1", ] [[package]] @@ -1190,12 +1166,12 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" dependencies = [ - "async-channel 2.1.0", - "async-lock 3.1.1", + "async-channel", + "async-lock", "async-task", - "fastrand 2.0.1", + "fastrand", "futures-io", - "futures-lite 2.0.1", + "futures-lite", "piper", "tracing", ] @@ -1223,7 +1199,7 @@ checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.50", ] [[package]] @@ -1238,6 +1214,20 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +[[package]] +name = "calloop" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" +dependencies = [ + "bitflags 2.4.1", + "log", + "polling", + "rustix", + "slab", + "thiserror", +] + [[package]] name = "cc" version = "1.0.83" @@ -1303,10 +1293,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] -name = "com-rs" -version = "0.2.1" +name = "com" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf43edc576402991846b093a7ca18a3477e0ef9c588cde84964b5d3e43016642" +checksum = "7e17887fd17353b65b1b2ef1c526c83e26cd72e74f598a8dc1bee13a48f3d9f6" +dependencies = [ + "com_macros", +] + +[[package]] +name = "com_macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d375883580a668c7481ea6631fc1a8863e33cc335bf56bfad8d7e6d4b04b13a5" +dependencies = [ + "com_macros_support", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "com_macros_support" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad899a1087a9296d5644792d7cb72b8e34c1bec8e7d4fbc002230169a6e8710c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] name = "combine" @@ -1337,6 +1352,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "const-fnv1a-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b13ea120a812beba79e34316b3942a857c86ec1593cb34f27bb28272ce2cca" + [[package]] name = "const_panic" version = "0.2.8" @@ -1382,14 +1403,14 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "core-graphics" -version = "0.22.3" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +checksum = "970a29baf4110c26fedbc7f82107d42c23f7e88e404c4577ed73fe99ff85a212" dependencies = [ "bitflags 1.3.2", "core-foundation", "core-graphics-types", - "foreign-types 0.3.2", + "foreign-types", "libc", ] @@ -1438,7 +1459,7 @@ dependencies = [ "js-sys", "libc", "mach2", - "ndk", + "ndk 0.7.0", "ndk-context", "oboe", "once_cell", @@ -1458,20 +1479,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crossbeam" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eb9105919ca8e40d437fc9cbb8f1975d916f1bd28afe795a48aae32a2cc8920" -dependencies = [ - "cfg-if", - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-epoch", - "crossbeam-queue", - "crossbeam-utils", -] - [[package]] name = "crossbeam-channel" version = "0.5.10" @@ -1482,38 +1489,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "crossbeam-deque" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-queue" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc6598521bb5a83d491e8c1fe51db7296019d2ca3cb93cc6c2a20369a4d78a2" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.18" @@ -1523,30 +1498,23 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "cursor-icon" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" + [[package]] name = "d3d12" -version = "0.7.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16e44ab292b1dddfdaf7be62cfd8877df52f2f3fde5858d95bab606be259f20" +checksum = "3e3d747f100290a1ca24b752186f61f6637e1deffe3bf6320de6fcb29510a307" dependencies = [ "bitflags 2.4.1", "libloading 0.8.1", "winapi", ] -[[package]] -name = "dashmap" -version = "5.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" -dependencies = [ - "cfg-if", - "hashbrown 0.14.2", - "lock_api", - "once_cell", - "parking_lot_core", -] - [[package]] name = "dasp_sample" version = "0.11.0" @@ -1559,12 +1527,32 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "dispatch" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading 0.8.1", +] + [[package]] name = "downcast-rs" version = "1.2.0" @@ -1573,9 +1561,9 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "encase" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fce2eeef77fd4a293a54b62aa00ac9daebfbcda4bf8998c5a815635b004aa1c" +checksum = "95ed933078d2e659745df651f4c180511cd582e5b9414ff896e7d50d207e3103" dependencies = [ "const_panic", "encase_derive", @@ -1585,22 +1573,22 @@ dependencies = [ [[package]] name = "encase_derive" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e520cde08cbf4f7cc097f61573ec06ce467019803de8ae82fb2823fa1554a0e" +checksum = "f4ce1449c7d19eba6cc0abd231150ad81620a8dce29601d7f8d236e5d431d72a" dependencies = [ "encase_derive_impl", ] [[package]] name = "encase_derive_impl" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fe2568f851fd6144a45fa91cfed8fe5ca8fc0b56ba6797bfc1ed2771b90e37c" +checksum = "92959a9e8d13eaa13b8ae8c7b583c3bf1669ca7a8e7708a088d12587ba86effc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.50", ] [[package]] @@ -1611,13 +1599,23 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "erased-serde" -version = "0.3.31" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +checksum = "388979d208a049ffdfb22fa33b9c81942215b940910bccfe258caeb25d125cb3" dependencies = [ "serde", ] +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "euclid" version = "0.22.9" @@ -1654,15 +1652,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - [[package]] name = "fastrand" version = "2.0.1" @@ -1700,15 +1689,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared 0.1.1", -] - [[package]] name = "foreign-types" version = "0.5.0" @@ -1716,7 +1696,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ "foreign-types-macros", - "foreign-types-shared 0.3.1", + "foreign-types-shared", ] [[package]] @@ -1727,15 +1707,9 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.50", ] -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "foreign-types-shared" version = "0.3.1" @@ -1790,28 +1764,13 @@ version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" -[[package]] -name = "futures-lite" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" -dependencies = [ - "fastrand 1.9.0", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - [[package]] name = "futures-lite" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3831c2651acb5177cbd83943f3d9c8912c5ad03c76afcc0e9511ba568ec5ebb" dependencies = [ - "fastrand 2.0.1", + "fastrand", "futures-core", "futures-io", "memchr", @@ -1827,7 +1786,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.50", ] [[package]] @@ -1866,6 +1825,16 @@ dependencies = [ "slab", ] +[[package]] +name = "gethostname" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +dependencies = [ + "libc", + "windows-targets 0.48.5", +] + [[package]] name = "getrandom" version = "0.2.11" @@ -1914,16 +1883,21 @@ dependencies = [ ] [[package]] -name = "gimli" -version = "0.28.0" +name = "gl_generator" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] [[package]] name = "glam" -version = "0.24.2" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945" +checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3" dependencies = [ "bytemuck", "serde", @@ -1937,9 +1911,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "glow" -version = "0.12.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0fe580e4b60a8ab24a868bc08e2f03cbcb20d3d676601fa909386713333728" +checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" dependencies = [ "js-sys", "slotmap", @@ -1949,32 +1923,33 @@ dependencies = [ [[package]] name = "gltf" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad2dcfb6dd7a66f9eb3d181a29dcfb22d146b0bcdc2e1ed1713cbf03939a88ea" +checksum = "3b78f069cf941075835822953c345b9e1edd67ae347b81ace3aea9de38c2ef33" dependencies = [ "byteorder", "gltf-json", "lazy_static", + "serde_json", ] [[package]] name = "gltf-derive" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cbcea5dd47e7ad4e9ee6f040384fcd7204bbf671aa4f9e7ca7dfc9bfa1de20" +checksum = "438ffe1a5540d75403feaf23636b164e816e93f6f03131674722b3886ce32a57" dependencies = [ "inflections", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.50", ] [[package]] name = "gltf-json" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5b810806b78dde4b71a95cc0e6fdcab34c4c617da3574df166f9987be97d03" +checksum = "655951ba557f2bc69ea4b0799446bae281fa78efae6319968bdd2c3e9a06d8e1" dependencies = [ "gltf-derive", "serde", @@ -1982,6 +1957,15 @@ dependencies = [ "serde_json", ] +[[package]] +name = "glutin_wgl_sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead" +dependencies = [ + "gl_generator", +] + [[package]] name = "glyph_brush_layout" version = "0.2.3" @@ -2014,15 +1998,15 @@ dependencies = [ [[package]] name = "gpu-allocator" -version = "0.22.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce95f9e2e11c2c6fadfce42b5af60005db06576f231f5c92550fdded43c423e8" +checksum = "6f56f6318968d03c18e1bcf4857ff88c61157e9da8e47c5f29055d60e1228884" dependencies = [ - "backtrace", "log", + "presser", "thiserror", "winapi", - "windows 0.44.0", + "windows 0.51.1", ] [[package]] @@ -2033,7 +2017,7 @@ checksum = "cc11df1ace8e7e564511f53af41f3e42ddc95b56fd07b3f4445d2a6048bc682c" dependencies = [ "bitflags 2.4.1", "gpu-descriptor-types", - "hashbrown 0.14.2", + "hashbrown", ] [[package]] @@ -2061,12 +2045,6 @@ dependencies = [ "svg_fmt", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "hashbrown" version = "0.14.2" @@ -2080,14 +2058,14 @@ dependencies = [ [[package]] name = "hassle-rs" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1397650ee315e8891a0df210707f0fc61771b0cc518c3023896064c5407cb3b0" +checksum = "af2a7e73e1f34c48da31fb668a907f250794837e08faa144fd24f0b8b741e890" dependencies = [ - "bitflags 1.3.2", - "com-rs", + "bitflags 2.4.1", + "com", "libc", - "libloading 0.7.4", + "libloading 0.8.1", "thiserror", "widestring", "winapi", @@ -2095,9 +2073,9 @@ dependencies = [ [[package]] name = "hexasphere" -version = "9.1.0" +version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cb3df16a7bcb1b5bc092abd55e14f77ca70aea14445026e264586fc62889a10" +checksum = "f33ddb7f7143d9e703c072e88b98cd8b9719f174137a671429351bd2ee43c02a" dependencies = [ "constgebra", "glam", @@ -2109,6 +2087,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +[[package]] +name = "icrate" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" +dependencies = [ + "block2 0.3.0", + "dispatch", + "objc2 0.4.1", +] + [[package]] name = "image" version = "0.24.7" @@ -2123,16 +2112,6 @@ dependencies = [ "png", ] -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - [[package]] name = "indexmap" version = "2.1.0" @@ -2140,7 +2119,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.14.2", + "hashbrown", ] [[package]] @@ -2169,18 +2148,6 @@ dependencies = [ "libc", ] -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "io-kit-sys" version = "0.4.0" @@ -2213,16 +2180,32 @@ dependencies = [ [[package]] name = "jni" -version = "0.20.0" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", +] + +[[package]] +name = "jni" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" dependencies = [ "cesu8", + "cfg-if", "combine", "jni-sys", "log", "thiserror", "walkdir", + "windows-sys 0.45.0", ] [[package]] @@ -2242,24 +2225,30 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.65" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" dependencies = [ "wasm-bindgen", ] [[package]] name = "khronos-egl" -version = "4.1.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c2352bd1d0bceb871cb9d40f24360c8133c11d7486b68b5381c1dd1a32015e3" +checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" dependencies = [ "libc", - "libloading 0.7.4", + "libloading 0.8.1", "pkg-config", ] +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + [[package]] name = "ktx2" version = "0.3.0" @@ -2339,6 +2328,12 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + [[package]] name = "lock_api" version = "0.4.11" @@ -2390,14 +2385,14 @@ checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "metal" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "623b5e6cefd76e58f774bd3cc0c6f5c7615c58c03a97815245a25c3c9bdee318" +checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25" dependencies = [ "bitflags 2.4.1", "block", "core-graphics-types", - "foreign-types 0.5.0", + "foreign-types", "log", "objc", "paste", @@ -2419,29 +2414,17 @@ dependencies = [ "simd-adler32", ] -[[package]] -name = "mio" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys 0.48.0", -] - [[package]] name = "naga" -version = "0.13.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ceaaa4eedaece7e4ec08c55c640ba03dbb73fb812a6570a59bcf1930d0f70e" +checksum = "8878eb410fc90853da3908aebfe61d73d26d4437ef850b70050461f939509899" dependencies = [ "bit-set", "bitflags 2.4.1", "codespan-reporting", "hexf-parse", - "indexmap 1.9.3", + "indexmap", "log", "num-traits", "pp-rs", @@ -2454,18 +2437,18 @@ dependencies = [ [[package]] name = "naga_oil" -version = "0.10.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac54c77b3529887f9668d3dd81e955e58f252b31a333f836e3548c06460b958" +checksum = "c0ea62ae0f2787456afca7209ca180522b41f00cbe159ee369eba1e07d365cd1" dependencies = [ "bit-set", "codespan-reporting", "data-encoding", - "indexmap 1.9.3", + "indexmap", "naga", "once_cell", "regex", - "regex-syntax 0.7.5", + "regex-syntax 0.8.2", "rustc-hash", "thiserror", "tracing", @@ -2480,9 +2463,24 @@ checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" dependencies = [ "bitflags 1.3.2", "jni-sys", - "ndk-sys", + "ndk-sys 0.4.1+23.1.7779620", "num_enum 0.5.11", - "raw-window-handle", + "raw-window-handle 0.5.2", + "thiserror", +] + +[[package]] +name = "ndk" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" +dependencies = [ + "bitflags 2.4.1", + "jni-sys", + "log", + "ndk-sys 0.5.0+25.2.9519653", + "num_enum 0.7.2", + "raw-window-handle 0.6.0", "thiserror", ] @@ -2501,6 +2499,15 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "ndk-sys" +version = "0.5.0+25.2.9519653" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys", +] + [[package]] name = "nix" version = "0.24.3" @@ -2610,11 +2617,11 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.6.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" dependencies = [ - "num_enum_derive 0.6.1", + "num_enum_derive 0.7.2", ] [[package]] @@ -2631,14 +2638,14 @@ dependencies = [ [[package]] name = "num_enum_derive" -version = "0.6.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.50", ] [[package]] @@ -2657,15 +2664,31 @@ version = "0.2.0-beta.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b9834c1e95694a05a828b59f55fa2afec6288359cda67146126b3f90a55d7" +[[package]] +name = "objc-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c71324e4180d0899963fc83d9d241ac39e699609fc1025a850aadac8257459" + [[package]] name = "objc2" version = "0.3.0-beta.3.patch-leaks.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e01640f9f2cb1220bbe80325e179e532cb3379ebcd1bf2279d703c19fe3a468" dependencies = [ - "block2", - "objc-sys", - "objc2-encode", + "block2 0.2.0-alpha.6", + "objc-sys 0.2.0-beta.2", + "objc2-encode 2.0.0-pre.2", +] + +[[package]] +name = "objc2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" +dependencies = [ + "objc-sys 0.3.2", + "objc2-encode 3.0.0", ] [[package]] @@ -2674,9 +2697,15 @@ version = "2.0.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abfcac41015b00a120608fdaa6938c44cb983fee294351cc4bac7638b4e50512" dependencies = [ - "objc-sys", + "objc-sys 0.2.0-beta.2", ] +[[package]] +name = "objc2-encode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" + [[package]] name = "objc_exception" version = "0.1.2" @@ -2686,15 +2715,6 @@ dependencies = [ "cc", ] -[[package]] -name = "object" -version = "0.32.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" -dependencies = [ - "memchr", -] - [[package]] name = "oboe" version = "0.5.0" @@ -2702,7 +2722,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8868cc237ee02e2d9618539a23a8d228b9bb3fc2e7a5b11eed3831de77c395d0" dependencies = [ "jni 0.20.0", - "ndk", + "ndk 0.7.0", "ndk-context", "num-derive", "num-traits", @@ -2729,9 +2749,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "orbclient" @@ -2811,7 +2831,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.1.0", + "indexmap", ] [[package]] @@ -2833,7 +2853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" dependencies = [ "atomic-waker", - "fastrand 2.0.1", + "fastrand", "futures-io", ] @@ -2856,6 +2876,20 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "polling" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30054e72317ab98eddd8561db0f6524df3367636884b7b21b703e4b280a84a14" +dependencies = [ + "cfg-if", + "concurrent-queue", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "pp-rs" version = "0.2.1" @@ -2866,10 +2900,10 @@ dependencies = [ ] [[package]] -name = "ppv-lite86" -version = "0.2.17" +name = "presser" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" [[package]] name = "proc-macro-crate" @@ -2883,9 +2917,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -2898,9 +2932,9 @@ checksum = "f89dff0959d98c9758c88826cc002e2c3d0b9dfac4139711d1f30de442f1139b" [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -2911,36 +2945,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17fd96390ed3feda12e1dfe2645ed587e0bea749e319333f104a33ff62f77a0b" -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - [[package]] name = "range-alloc" version = "0.1.3" @@ -2953,6 +2957,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" +[[package]] +name = "raw-window-handle" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544" + [[package]] name = "rectangle-pack" version = "0.4.2" @@ -3015,12 +3025,6 @@ version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" -[[package]] -name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - [[package]] name = "regex-syntax" version = "0.8.2" @@ -3055,7 +3059,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ - "base64 0.21.5", + "base64", "bitflags 2.4.1", "serde", "serde_derive", @@ -3086,16 +3090,10 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn 2.0.39", + "syn 2.0.50", "unicode-ident", ] -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - [[package]] name = "rustc-hash" version = "1.1.0" @@ -3111,14 +3109,27 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + [[package]] name = "ruzstd" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3ffab8f9715a0d455df4bbb9d21e91135aab3cd3ca187af0cd0c3c3f868fdc" +checksum = "58c4eb8a81997cf040a091d1f7e1938aeab6749d3a0dfa73af43cdc32393483d" dependencies = [ "byteorder", - "thiserror-core", + "derive_more", "twox-hash", ] @@ -3151,22 +3162,22 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" -version = "1.0.193" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.50", ] [[package]] @@ -3239,12 +3250,11 @@ dependencies = [ [[package]] name = "spirv" -version = "0.2.0+1.5.4" +version = "0.3.0+sdk-1.3.268.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246bfa38fe3db3f1dfc8ca5a2cdeb7348c78be2112740cc0ec8ef18b6d94f830" +checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" dependencies = [ - "bitflags 1.3.2", - "num-traits", + "bitflags 2.4.1", ] [[package]] @@ -3272,9 +3282,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb" dependencies = [ "proc-macro2", "quote", @@ -3283,16 +3293,16 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.29.10" +version = "0.30.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a18d114d420ada3a891e6bc8e96a2023402203296a47cdd65083377dad18ba5" +checksum = "1fb4f3438c8f6389c864e61221cbc97e9bca98b4daf39a5beb7bea660f528bb2" dependencies = [ "cfg-if", "core-foundation-sys", "libc", "ntapi", "once_cell", - "winapi", + "windows 0.52.0", ] [[package]] @@ -3309,51 +3319,31 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] -[[package]] -name = "thiserror-core" -version = "1.0.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c001ee18b7e5e3f62cbf58c7fe220119e68d902bb7443179c0c8aef30090e999" -dependencies = [ - "thiserror-core-impl", -] - -[[package]] -name = "thiserror-core-impl" -version = "1.0.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c60d69f36615a077cc7663b9cb8e42275722d23e58a7fa3d2c7f2915d09d04" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.39", -] - [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.50", ] [[package]] @@ -3393,18 +3383,18 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.1.0", + "indexmap", "toml_datetime", "winnow", ] [[package]] name = "toml_edit" -version = "0.20.7" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.1.0", + "indexmap", "toml_datetime", "winnow", ] @@ -3428,7 +3418,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.50", ] [[package]] @@ -3514,6 +3504,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + [[package]] name = "unicode-width" version = "0.1.11" @@ -3554,12 +3550,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "waker-fn" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" - [[package]] name = "walkdir" version = "2.4.0" @@ -3578,9 +3568,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.88" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3588,24 +3578,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.88" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.50", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.38" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" +checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" dependencies = [ "cfg-if", "js-sys", @@ -3615,9 +3605,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.88" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3625,39 +3615,38 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.88" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.50", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.88" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" [[package]] -name = "wayland-scanner" -version = "0.29.5" +name = "web-sys" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" dependencies = [ - "proc-macro2", - "quote", - "xml-rs", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "web-sys" -version = "0.3.65" +name = "web-time" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" +checksum = "aa30049b1c872b72c89866d458eae9f20380ab280ffd1b1e18df2d3e2d98cfe0" dependencies = [ "js-sys", "wasm-bindgen", @@ -3665,18 +3654,19 @@ dependencies = [ [[package]] name = "wgpu" -version = "0.17.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "752e44d3998ef35f71830dd1ad3da513e628e2e4d4aedb0ab580f850827a0b41" +checksum = "0bfe9a310dcf2e6b85f00c46059aaeaf4184caa8e29a1ecd4b7a704c3482332d" dependencies = [ "arrayvec", "cfg-if", + "cfg_aliases", "js-sys", "log", "naga", "parking_lot", "profiling", - "raw-window-handle", + "raw-window-handle 0.6.0", "smallvec", "static_assertions", "wasm-bindgen", @@ -3689,19 +3679,22 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "0.17.1" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f8a44dd301a30ceeed3c27d8c0090433d3da04d7b2a4042738095a424d12ae7" +checksum = "6b15e451d4060ada0d99a64df44e4d590213496da7c4f245572d51071e8e30ed" dependencies = [ "arrayvec", "bit-vec", "bitflags 2.4.1", + "cfg_aliases", "codespan-reporting", + "indexmap", "log", "naga", + "once_cell", "parking_lot", "profiling", - "raw-window-handle", + "raw-window-handle 0.6.0", "rustc-hash", "smallvec", "thiserror", @@ -3712,9 +3705,9 @@ dependencies = [ [[package]] name = "wgpu-hal" -version = "0.17.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a80bf0e3c77399bb52850cb0830af9bad073d5cfcb9dd8253bef8125c42db17" +checksum = "e3bb47856236bfafc0bc591a925eb036ac19cd987624a447ff353e7a7e7e6f72" dependencies = [ "android_system_properties", "arrayvec", @@ -3722,9 +3715,11 @@ dependencies = [ "bit-set", "bitflags 2.4.1", "block", + "cfg_aliases", "core-graphics-types", "d3d12", "glow", + "glutin_wgl_sys", "gpu-alloc", "gpu-allocator", "gpu-descriptor", @@ -3737,10 +3732,11 @@ dependencies = [ "metal", "naga", "objc", + "once_cell", "parking_lot", "profiling", "range-alloc", - "raw-window-handle", + "raw-window-handle 0.6.0", "renderdoc-sys", "rustc-hash", "smallvec", @@ -3753,9 +3749,9 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "0.17.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee64d7398d0c2f9ca48922c902ef69c42d000c759f3db41e355f4a570b052b67" +checksum = "895fcbeb772bfb049eb80b2d6e47f6c9af235284e9703c96fc0218a42ffd5af2" dependencies = [ "bitflags 2.4.1", "js-sys", @@ -3799,15 +3795,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.44.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows" version = "0.46.0" @@ -3834,10 +3821,20 @@ version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" dependencies = [ - "windows-core", + "windows-core 0.51.1", "windows-targets 0.48.5", ] +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core 0.52.0", + "windows-targets 0.52.3", +] + [[package]] name = "windows-core" version = "0.51.1" @@ -3847,6 +3844,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.3", +] + [[package]] name = "windows-implement" version = "0.48.0" @@ -3887,6 +3893,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.3", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -3917,6 +3932,21 @@ dependencies = [ "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-targets" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d380ba1dc7187569a8a9e91ed34b8ccfc33123bbacb8c0aed2d1ad7f3ef2dc5f" +dependencies = [ + "windows_aarch64_gnullvm 0.52.3", + "windows_aarch64_msvc 0.52.3", + "windows_i686_gnu 0.52.3", + "windows_i686_msvc 0.52.3", + "windows_x86_64_gnu 0.52.3", + "windows_x86_64_gnullvm 0.52.3", + "windows_x86_64_msvc 0.52.3", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -3929,6 +3959,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68e5dcfb9413f53afd9c8f86e56a7b4d86d9a2fa26090ea2dc9e40fba56c6ec6" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -3941,6 +3977,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dab469ebbc45798319e69eebf92308e541ce46760b49b18c6b3fe5e8965b30f" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -3953,6 +3995,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a4e9b6a7cac734a8b4138a4e1044eac3404d8326b6c0f939276560687a033fb" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -3965,6 +4013,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b0ec9c422ca95ff34a78755cfa6ad4a51371da2a5ace67500cf7ca5f232c58" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -3977,6 +4031,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704131571ba93e89d7cd43482277d6632589b18ecf4468f591fbae0a8b101614" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -3989,6 +4049,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42079295511643151e98d61c38c0acc444e52dd42ab456f7ccfd5152e8ecf21c" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -4001,34 +4067,50 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6" + [[package]] name = "winit" -version = "0.28.7" +version = "0.29.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9596d90b45384f5281384ab204224876e8e8bf7d58366d9b795ad99aa9894b94" +checksum = "4c824f11941eeae66ec71111cc2674373c772f482b58939bb4066b642aa2ffcf" dependencies = [ "android-activity", - "bitflags 1.3.2", + "atomic-waker", + "bitflags 2.4.1", + "bytemuck", + "calloop", "cfg_aliases", "core-foundation", "core-graphics", - "dispatch", - "instant", + "cursor-icon", + "icrate", + "js-sys", "libc", "log", - "mio", - "ndk", - "objc2", + "ndk 0.8.0", + "ndk-sys 0.5.0+25.2.9519653", + "objc2 0.4.1", "once_cell", "orbclient", "percent-encoding", - "raw-window-handle", + "raw-window-handle 0.6.0", "redox_syscall 0.3.5", + "rustix", + "smol_str", + "unicode-segmentation", "wasm-bindgen", - "wayland-scanner", + "wasm-bindgen-futures", "web-sys", - "windows-sys 0.45.0", + "web-time", + "windows-sys 0.48.0", "x11-dl", + "x11rb", + "xkbcommon-dl", ] [[package]] @@ -4051,12 +4133,52 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "x11rb" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8f25ead8c7e4cba123243a6367da5d3990e0d3affa708ea19dce96356bd9f1a" +dependencies = [ + "as-raw-xcb-connection", + "gethostname", + "libc", + "libloading 0.8.1", + "once_cell", + "rustix", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e63e71c4b8bd9ffec2c963173a4dc4cbde9ee96961d4fcb4429db9929b606c34" + [[package]] name = "xi-unicode" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a67300977d3dc3f8034dae89778f502b6ba20b269527b3223ba59c0cf393bb8a" +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.4.1", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054a8e68b76250b253f671d1268cb7f1ae089ec35e195b2efb2a4e9a836d0621" + [[package]] name = "xml-rs" version = "0.8.19" @@ -4065,20 +4187,20 @@ checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" [[package]] name = "zerocopy" -version = "0.7.26" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.26" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.50", ] diff --git a/Cargo.toml b/Cargo.toml index 3326109..1dc4913 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,11 +2,10 @@ resolver = "2" members=[ "crates/bevy_tiles", - "crates/bevy_tiles_render", ] [workspace.package] -version = "0.1.0" +version = "0.0.0-dev1" edition = "2021" authors = ["James Bell "] license = "MIT" @@ -21,7 +20,7 @@ opt-level = 1 opt-level = 3 [workspace.dependencies] -bevy = {version = "0.12.1", default-features = false} +bevy = {version = "0.13.0", default-features = false} rstest = "0.18.2" bimap = "0.6.3" rand = "0.8.5" diff --git a/crates/bevy_tiles/.vscode/settings.json b/crates/bevy_tiles/.vscode/settings.json deleted file mode 100644 index ec17418..0000000 --- a/crates/bevy_tiles/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rust-analyzer.linkedProjects": [ - ".\\Cargo.toml" - ] -} \ No newline at end of file diff --git a/crates/bevy_tiles/README.md b/crates/bevy_tiles/README.md index 088cdf4..4b7f1ab 100644 --- a/crates/bevy_tiles/README.md +++ b/crates/bevy_tiles/README.md @@ -5,7 +5,7 @@ [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/OxidizedGames/bevy_tiles/blob/main/LICENSE) [![Crates.io](https://img.shields.io/crates/d/bevy_tiles)](https://crates.io/crates/bevy_tiles) -A general purpose grided entity library meant to support tilemap libraries, or other libraries that require accessing entities in a grid based manner built on top of the [`aery`](https://github.com/iiYese/aery) relations crate. The goal is to keep the API surface as simple and intuitive as possible, and to avoid deferred operations/states where possible to make the structures more intuitive work with (ex: an update in one system should be seen by the following system, not the following frame.). +A general purpose grided entity library meant to support tilemap libraries, or other libraries that require accessing entities in a grid based manner. The goal is to keep the API surface as simple and intuitive as possible, and to avoid deferred operations/states where possible to make the structures more intuitive work with (ex: an update in one system should be seen by the following system, not the following frame when a system has run.). # Features @@ -19,8 +19,8 @@ Currently, `bevy_tiles` supports the following: * Batched operations for better performance on large groups of tiles or chunks Upcoming features: -* Automatigically handle hierarchical deletes (via aery support or supported directly in this crate) -* Sort tiles in memory based on chunk and map (will require bevy API additions in the future) +* Automagically handle hierarchical deletes. +* Sort tiles in memory based on chunk and map (will require bevy API additions in the future). # API @@ -69,5 +69,6 @@ More examples can be found in the [examples](/examples) folder! | Bevy version | bevy_tiles verison | |--------------|--------------------| +| 0.13 | 0.2 | | 0.12 | 0.1 | | 0.11 | 0.1-dev | \ No newline at end of file diff --git a/crates/bevy_tiles/examples/basic_2d.rs b/crates/bevy_tiles/examples/basic_2d.rs index 215ca8b..9c90321 100644 --- a/crates/bevy_tiles/examples/basic_2d.rs +++ b/crates/bevy_tiles/examples/basic_2d.rs @@ -17,18 +17,15 @@ struct Block; #[derive(Component)] struct Character; +#[derive(Component)] struct GameLayer; -impl TileMapLabel for GameLayer { - const CHUNK_SIZE: usize = 16; -} - fn spawn(mut commands: Commands, asset_server: Res) { let block = asset_server.load("block.png"); let character = asset_server.load("character.png"); commands.spawn(Camera2dBundle::default()); - let mut tile_commands = commands.tiles::(); + let mut map = commands.spawn_map::<2>(16, GameLayer); let sprite_bundle = SpriteBundle { texture: block, @@ -36,7 +33,7 @@ fn spawn(mut commands: Commands, asset_server: Res) { }; // spawn a 10 * 10 room - tile_commands.spawn_tile_batch( + map.spawn_tile_batch( CoordIterator::new([-5, 5], [5, 5]) .chain(CoordIterator::new([-5, -5], [5, -5])) .chain(CoordIterator::new([5, -4], [5, 4])) @@ -45,7 +42,7 @@ fn spawn(mut commands: Commands, asset_server: Res) { ); // spawn a player - tile_commands.spawn_tile( + map.spawn_tile( [0, 0], ( Character, @@ -58,31 +55,33 @@ fn spawn(mut commands: Commands, asset_server: Res) { } fn move_character( - keyboard_input: Res>, + keyboard_input: Res>, mut commands: Commands, - character: TileQuery>, - walls: TileQuery>, + map: Query>, + character: Query<&TileCoord, With>, + walls_maps: TileMapQuery<(), With>, ) { - let mut tile_commands = commands.tiles::(); + let map_id = map.single(); + let walls = walls_maps.get_map(map_id).unwrap(); - let mut x = if keyboard_input.just_pressed(KeyCode::A) { + let mut x = if keyboard_input.just_pressed(KeyCode::KeyA) { -1 } else { 0 }; - x += if keyboard_input.just_pressed(KeyCode::D) { + x += if keyboard_input.just_pressed(KeyCode::KeyD) { 1 } else { 0 }; - let mut y = if keyboard_input.just_pressed(KeyCode::W) { + let mut y = if keyboard_input.just_pressed(KeyCode::KeyW) { 1 } else { 0 }; - y -= if keyboard_input.just_pressed(KeyCode::S) { + y -= if keyboard_input.just_pressed(KeyCode::KeyS) { 1 } else { 0 @@ -92,13 +91,11 @@ fn move_character( let new_coord = [char_c[0] + x, char_c[1] + y]; if (x != 0 || y != 0) && walls.get_at(new_coord).is_none() { - tile_commands.move_tile(**char_c, new_coord); + commands.move_tile(map_id, **char_c, new_coord); } } -fn sync_tile_transforms( - mut tiles: TileQuery>, -) { +fn sync_tile_transforms(mut tiles: Query<(&TileCoord, &mut Transform), Changed>) { for (tile_c, mut transform) in tiles.iter_mut() { transform.translation.x = tile_c[0] as f32 * 16.0; transform.translation.y = tile_c[1] as f32 * 16.0; diff --git a/crates/bevy_tiles/examples/basic_3d.rs b/crates/bevy_tiles/examples/basic_3d.rs index b20b1fd..875c666 100644 --- a/crates/bevy_tiles/examples/basic_3d.rs +++ b/crates/bevy_tiles/examples/basic_3d.rs @@ -19,18 +19,17 @@ struct Block; #[derive(Component)] struct Character; +#[derive(Component)] struct GameLayer; -impl TileMapLabel for GameLayer { - const CHUNK_SIZE: usize = 16; -} - fn spawn( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, ) { - let cube = meshes.add(Mesh::from(shape::Cube { size: 1.0 })); + let cube = meshes.add(Mesh::from(Cuboid { + half_size: Vec3::ONE, + })); let color_block = materials.add(StandardMaterial { base_color: Color::BLUE, @@ -57,7 +56,7 @@ fn spawn( ..Default::default() }; - let mut tile_commands = commands.tiles::(); + let mut tile_commands = commands.spawn_map::<3>(16, GameLayer); // spawn a 10 * 10 room tile_commands.spawn_tile_batch( @@ -106,30 +105,32 @@ fn spawn( } fn move_character( - keyboard_input: Res>, + keyboard_input: Res>, mut commands: Commands, - character: TileQuery, With, 3>, - walls: TileQuery, 3>, + map: Query>, + character: Query<&TileCoord<3>, With>, + walls_maps: TileMapQuery<(), With, 3>, ) { - let mut tile_commands = commands.tiles::(); + let map_id = map.single(); + let walls = walls_maps.get_map(map_id).unwrap(); - let mut x = if keyboard_input.just_pressed(KeyCode::A) { + let mut x = if keyboard_input.just_pressed(KeyCode::KeyA) { -1 } else { 0 }; - x += if keyboard_input.just_pressed(KeyCode::D) { + x += if keyboard_input.just_pressed(KeyCode::KeyD) { 1 } else { 0 }; - let mut z = if keyboard_input.just_pressed(KeyCode::W) { + let mut z = if keyboard_input.just_pressed(KeyCode::KeyW) { -1 } else { 0 }; - z += if keyboard_input.just_pressed(KeyCode::S) { + z += if keyboard_input.just_pressed(KeyCode::KeyS) { 1 } else { 0 @@ -150,14 +151,11 @@ fn move_character( let new_coord = [char_c[0] + x, char_c[1] + y, char_c[2] + z]; if walls.get_at(new_coord).is_none() { - tile_commands.move_tile(**char_c, new_coord); + commands.move_tile(map_id, **char_c, new_coord); } } -fn sync_tile_transforms( - // Important, you have to put the 3 in all these places at the moment!!! - mut tiles: TileQuery, &mut Transform), Changed>, 3>, -) { +fn sync_tile_transforms(mut tiles: Query<(&TileCoord<3>, &mut Transform), Changed>>) { for (tile_c, mut transform) in tiles.iter_mut() { transform.translation.x = tile_c[0] as f32; transform.translation.y = tile_c[1] as f32; diff --git a/crates/bevy_tiles/examples/logo.rs b/crates/bevy_tiles/examples/logo.rs index d17d282..b6eaf08 100644 --- a/crates/bevy_tiles/examples/logo.rs +++ b/crates/bevy_tiles/examples/logo.rs @@ -5,20 +5,16 @@ fn main() { App::new() .add_plugins(DefaultPlugins) .add_plugins(TilesPlugin) - .add_systems(Startup, spawn) - .add_systems(Update, sync_tile_transforms) + .add_systems(Startup, (spawn, sync_tile_transforms).chain()) .run(); } #[derive(Component)] struct Block; +#[derive(Component)] struct GameLayer; -impl TileMapLabel for GameLayer { - const CHUNK_SIZE: usize = 16; -} - fn spawn(mut commands: Commands, asset_server: Res) { let block = asset_server.load("block.png"); @@ -26,7 +22,7 @@ fn spawn(mut commands: Commands, asset_server: Res) { transform: Transform::from_translation(Vec3::new(480.0, 32.0, 0.0)), ..Default::default() }); - let mut tile_commands = commands.tiles::(); + let mut map = commands.spawn_map::<2>(16, GameLayer); let sprite_bundle = SpriteBundle { texture: block, @@ -51,14 +47,12 @@ eeeee eeee e e e e eeee8 eeeee e eeee eeeee }); // spawn a 10 * 10 room - tile_commands.spawn_tile_batch(logo.collect::>(), move |_| { + map.spawn_tile_batch(logo.collect::>(), move |_| { (Block, sprite_bundle.clone()) }); } -fn sync_tile_transforms( - mut tiles: TileQuery>, -) { +fn sync_tile_transforms(mut tiles: Query<(&TileCoord, &mut Transform), Changed>) { for (tile_c, mut transform) in tiles.iter_mut() { transform.translation.x = tile_c[0] as f32 * 16.0; transform.translation.y = tile_c[1] as f32 * 16.0; diff --git a/crates/bevy_tiles/examples/spatial.rs b/crates/bevy_tiles/examples/spatial.rs index b7b008e..e13771d 100644 --- a/crates/bevy_tiles/examples/spatial.rs +++ b/crates/bevy_tiles/examples/spatial.rs @@ -41,12 +41,9 @@ impl DerefMut for Damage { } } +#[derive(Component)] struct GameLayer; -impl TileMapLabel for GameLayer { - const CHUNK_SIZE: usize = 16; -} - fn spawn(mut commands: Commands, asset_server: Res) { let block = asset_server.load("block.png"); @@ -57,26 +54,33 @@ fn spawn(mut commands: Commands, asset_server: Res) { }, ..Default::default() }); - let mut tile_commands = commands.tiles::(); + let mut tile_commands = commands.spawn_map::<2>(32, GameLayer); let sprite_bundle = SpriteBundle { texture: block, ..Default::default() }; - tile_commands.spawn_tile_batch(CoordIterator::new([-250, -250], [250, 250]), move |_| { - (Block, sprite_bundle.clone()) - }) + let size = 200; + + tile_commands.spawn_tile_batch( + CoordIterator::new([-size, -size], [size, size]), + move |_| (Block, sprite_bundle.clone()), + ); } fn add_damage( mut commands: Commands, - mut blocks: TileQuery), With>, + mut block_maps: TileMapQuery<(Entity, Option<&mut Damage>), With>, + map: Query<(Entity, &TileMap), With>, windows: Query<&Window, With>, camera: Query<(&Camera, &GlobalTransform)>, - buttons: Res>, + buttons: Res>, ) { + let (map_id, map) = map.single(); let (cam, cam_t) = camera.single(); + let mut blocks = block_maps.get_map_mut(map_id).unwrap(); + let cursor_pos = windows .single() .cursor_position() @@ -104,8 +108,8 @@ fn add_damage( .then_some(cursor_pos) .flatten() { - let chunk_c = calculate_chunk_coordinate(damage_pos, GameLayer::CHUNK_SIZE); - commands.tiles::().despawn_chunk(chunk_c); + let chunk_c = calculate_chunk_coordinate(damage_pos, map.get_chunk_size()); + commands.tile_map::<2>(map_id).despawn_chunk(chunk_c); } } @@ -129,9 +133,7 @@ fn check_damage( } } -fn sync_tile_transforms( - mut tiles: TileQuery>, -) { +fn sync_tile_transforms(mut tiles: Query<(&TileCoord, &mut Transform), Changed>) { for (tile_c, mut transform) in tiles.iter_mut() { transform.translation.x = tile_c[0] as f32 * 16.0; transform.translation.y = tile_c[1] as f32 * 16.0; diff --git a/crates/bevy_tiles/src/chunks.rs b/crates/bevy_tiles/src/chunks.rs index 979e17f..43e025d 100644 --- a/crates/bevy_tiles/src/chunks.rs +++ b/crates/bevy_tiles/src/chunks.rs @@ -1,8 +1,6 @@ -use std::ops::Deref; - use bevy::{ ecs::{component::Component, entity::Entity}, - math::Vec2, + prelude::Deref, }; mod chunk_query; @@ -10,67 +8,27 @@ mod chunk_query; pub use chunk_query::*; /// An relation on chunks that point towards the map they are a part of. -#[derive(Component, Clone)] +#[derive(Component, Deref, Debug)] pub struct InMap(pub(crate) Entity); -impl InMap { - /// Get the entity this chunk is in - pub fn get(&self) -> Entity { - self.0 - } -} - /// The coordinate of a given chunk. /// # Note -/// Right now, changes to this coordinate don't automatically update any information. -/// If you wish to move a chunk, add, or remove a chunk, please do so via commands. -/// Use this if you wish to track changes or other information. -#[derive(Component, Debug, PartialEq, Eq, Hash, Clone, Copy)] -pub struct ChunkCoord([isize; N]); - -impl From<[isize; N]> for ChunkCoord { - fn from(value: [isize; N]) -> Self { - Self(value) - } -} - -impl Deref for ChunkCoord { - type Target = [isize; N]; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl From<&ChunkCoord<2>> for Vec2 { - fn from(value: &ChunkCoord<2>) -> Self { - Vec2::new(value.0[0] as f32, value.0[1] as f32) - } -} +#[derive(Component, Clone, Copy, Deref, Debug, PartialEq, Eq, Hash)] +pub struct ChunkCoord(pub(crate) [isize; N]); /// Holds handles to all the tiles in a chunk. /// # Note /// Manually updating this value, adding it, or removing it from an entity may /// cause issues, please only mutate chunk information via commands. -#[derive(Component)] -pub struct Chunk { - pub(crate) tiles: Vec>, -} +#[derive(Component, Deref, Debug)] +pub struct Chunk(pub(crate) Vec>); impl Chunk { pub(crate) fn new(chunk_size: usize) -> Self { - Self { - tiles: vec![None; chunk_size], - } - } - - /// Gets the total number of tiles this chunk can hold. - pub fn total_size(&self) -> usize { - self.tiles.len() + Self(vec![None; chunk_size]) } - /// Gets a readonly reference to the underlying chunk data. - pub fn get_tiles(&self) -> &Vec> { - &self.tiles + pub(crate) fn get(&self, tile_i: usize) -> Option { + self.0.get(tile_i).cloned().flatten() } } diff --git a/crates/bevy_tiles/src/chunks/chunk_query.rs b/crates/bevy_tiles/src/chunks/chunk_query.rs index a2f64b5..f2d7ee7 100644 --- a/crates/bevy_tiles/src/chunks/chunk_query.rs +++ b/crates/bevy_tiles/src/chunks/chunk_query.rs @@ -2,8 +2,9 @@ use std::ops::{Deref, DerefMut}; use bevy::{ ecs::{ + entity::Entity, prelude::With, - query::{ReadOnlyWorldQuery, WorldQuery}, + query::{QueryData, QueryFilter, WorldQuery}, system::SystemParam, }, prelude::Query, @@ -11,55 +12,68 @@ use bevy::{ use crate::{ chunks::ChunkCoord, - maps::{MapLabel, TileMap, TileMapLabel}, - prelude::{calculate_chunk_coordinate, Chunk, CoordIterator, InMap}, + maps::TileMap, + prelude::{Chunk, CoordIterator, InMap}, }; -/// Used to query chunks from a tile map. +/// Used to query chunks from any tile map. /// This query also implicitly queries maps /// in order to properly resolve chunks. #[derive(SystemParam)] -pub struct ChunkQuery<'w, 's, L, Q, F = (), const N: usize = 2> +pub struct ChunkMapQuery<'w, 's, Q, F = (), const N: usize = 2> where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, + Q: QueryData + 'static, + F: QueryFilter + 'static, { - chunk_q: Query<'w, 's, Q, (F, With, With, With>)>, - map_q: Query<'w, 's, &'static TileMap, With>>, + chunk_q: Query<'w, 's, Q, (F, With, With)>, + map_q: Query<'w, 's, &'static TileMap>, } -impl<'w, 's, L, Q, F, const N: usize> Deref for ChunkQuery<'w, 's, L, Q, F, N> +impl<'w, 's, Q, F, const N: usize> ChunkMapQuery<'w, 's, Q, F, N> where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, + Q: QueryData + 'static, + F: QueryFilter + 'static, { - type Target = Query<'w, 's, Q, (F, With, With, With>)>; + /// Gets the query for a given map. + pub fn get_map( + &self, + map_id: Entity, + ) -> Option, With)>, N>> { + let map = self.map_q.get(map_id).ok()?; + + Some(ChunkQuery { + chunk_q: &self.chunk_q, + map, + }) + } - #[inline] - fn deref(&self) -> &Self::Target { - &self.chunk_q + /// Gets the query for a given map. + pub fn get_map_mut( + &mut self, + map_id: Entity, + ) -> Option, With)>, N>> { + let map = self.map_q.get(map_id).ok()?; + + Some(ChunkQuery { + chunk_q: &mut self.chunk_q, + map, + }) } } -impl<'w, 's, L, Q, F, const N: usize> DerefMut for ChunkQuery<'w, 's, L, Q, F, N> -where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, -{ - #[inline] - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.chunk_q - } +/// Used to query chunks from a tile map. +/// This query also implicitly queries maps +/// in order to properly resolve chunks. +pub struct ChunkQuery<'a, C, const N: usize> { + chunk_q: C, + map: &'a TileMap, } -impl<'w, 's, L, Q, F, const N: usize> ChunkQuery<'w, 's, L, Q, F, N> +impl<'a, 'w: 'a, 's: 'a, Q, F, C, const N: usize> ChunkQuery<'a, C, N> where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, + C: Deref, With)>>, + Q: QueryData + 'static, + F: QueryFilter + 'static, { /// Get's the readonly query item for the given tile. /// # Note @@ -67,25 +81,11 @@ where #[inline] pub fn get_at( &self, - tile_c: [isize; N], - ) -> Option<<::ReadOnly as WorldQuery>::Item<'_>> { - let map = self.map_q.get_single().ok()?; - let chunk_c = calculate_chunk_coordinate(tile_c, L::CHUNK_SIZE); - let chunk_e = map.chunks.get::>(&chunk_c.into())?; + chunk_c: [isize; N], + ) -> Option<<::ReadOnly as WorldQuery>::Item<'_>> { + let chunk_id = self.map.get_from_chunk(ChunkCoord(chunk_c))?; - self.chunk_q.get(*chunk_e).ok() - } - - /// Get's the query item for the given tile. - /// # Note - /// Coordinates are for these calls are in chunk coordinates. - #[inline] - pub fn get_at_mut(&mut self, tile_c: [isize; N]) -> Option<::Item<'_>> { - let map = self.map_q.get_single().ok()?; - let chunk_c = calculate_chunk_coordinate(tile_c, L::CHUNK_SIZE); - let chunk_e = map.chunks.get::>(&chunk_c.into())?; - - self.chunk_q.get_mut(*chunk_e).ok() + self.chunk_q.get(chunk_id).ok() } /// Get's the query item for the given chunk. @@ -96,13 +96,11 @@ where #[inline] pub unsafe fn get_at_unchecked( &self, - tile_c: [isize; N], + chunk_c: [isize; N], ) -> Option<::Item<'_>> { - let map = self.map_q.get_single().ok()?; - let chunk_c = calculate_chunk_coordinate(tile_c, L::CHUNK_SIZE); - let chunk_e = map.chunks.get::>(&chunk_c.into())?; + let chunk_id = self.map.get_from_chunk(ChunkCoord(chunk_c))?; - self.chunk_q.get_unchecked(*chunk_e).ok() + self.chunk_q.get_unchecked(chunk_id).ok() } /// Iterate over all the chunks in a given space, starting at `corner_1` @@ -114,9 +112,26 @@ where &self, corner_1: [isize; N], corner_2: [isize; N], - ) -> ChunkQueryIter<'_, 's, L, Q, F, N> { + ) -> ChunkQueryIter<'_, 'a, C, N> { ChunkQueryIter::new(self, corner_1, corner_2) } +} + +impl<'a, 'w: 'a, 's: 'a, Q, F, C, const N: usize> ChunkQuery<'a, C, N> +where + C: DerefMut, With)>>, + Q: QueryData + 'static, + F: QueryFilter + 'static, +{ + /// Get's the query item for the given tile. + /// # Note + /// Coordinates are for these calls are in chunk coordinates. + #[inline] + pub fn get_at_mut(&mut self, chunk_c: [isize; N]) -> Option<::Item<'_>> { + let chunk_id = self.map.get_from_chunk(ChunkCoord(chunk_c))?; + + self.chunk_q.get_mut(chunk_id).ok() + } /// Iterate over all the chunks in a given space, starting at `corner_1` /// inclusive over `corner_2`. @@ -127,70 +142,39 @@ where &mut self, corner_1: [isize; N], corner_2: [isize; N], - ) -> ChunkQueryIterMut<'_, 's, L, Q, F, N> { - // SAFETY: Use case is safe since this is the mut version and the function signature - // stops us from borrowing this mutably twice - unsafe { ChunkQueryIterMut::new(self, corner_1, corner_2) } - } - - /// Get the readonly version of this query. - #[inline] - pub fn to_readonly( - &self, - ) -> ChunkQuery<'_, 's, L, ::ReadOnly, ::ReadOnly, N> { - ChunkQuery::::ReadOnly, ::ReadOnly, N> { - chunk_q: self.chunk_q.to_readonly(), - map_q: self.map_q.to_readonly(), - } + ) -> ChunkQueryIterMut<'_, 'a, C, N> { + ChunkQueryIterMut::new(self, corner_1, corner_2) } } /// Iterates over a range of chunks using chunk coordinates. -pub struct ChunkQueryIter<'w, 's, L, Q, F, const N: usize> -where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, -{ +pub struct ChunkQueryIter<'i, 'a, C, const N: usize> { coord_iter: CoordIterator, - tile_q: &'w ChunkQuery<'w, 's, L, Q, F, N>, + chunk_q: &'i ChunkQuery<'a, C, N>, } -impl<'w, 's, L, Q, F, const N: usize> ChunkQueryIter<'w, 's, L, Q, F, N> -where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, -{ - /// # Safety - /// This iterator uses unchecked get's to get around some lifetime issue I don't understand yet. - /// Due to this, you should only call this constructor from a context where the query is actually - /// borrowed mutabley. - fn new( - tile_q: &'w ChunkQuery<'w, 's, L, Q, F, N>, - corner_1: [isize; N], - corner_2: [isize; N], - ) -> Self { +impl<'i, 'a, C, const N: usize> ChunkQueryIter<'i, 'a, C, N> { + fn new(chunk_q: &'i ChunkQuery<'a, C, N>, corner_1: [isize; N], corner_2: [isize; N]) -> Self { Self { - tile_q, + chunk_q, coord_iter: CoordIterator::new(corner_1, corner_2), } } } -impl<'w, 's, L, Q, F, const N: usize> Iterator for ChunkQueryIter<'w, 's, L, Q, F, N> +impl<'i, 'a: 'i, 'w: 'a, 's: 'a, Q, F, C, const N: usize> Iterator for ChunkQueryIter<'i, 'a, C, N> where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, + C: Deref, With)>>, + Q: QueryData + 'static, + F: QueryFilter + 'static, { - type Item = <::ReadOnly as WorldQuery>::Item<'w>; + type Item = <::ReadOnly as WorldQuery>::Item<'i>; #[allow(clippy::while_let_on_iterator)] #[inline] fn next(&mut self) -> Option { while let Some(target) = self.coord_iter.next() { - let tile = self.tile_q.get_at(target); + let tile = self.chunk_q.get_at(target); if tile.is_some() { return tile; } @@ -200,65 +184,36 @@ where } } -/// Iterates over a range of chunks mutably using chunk coordinates. -/// # Note -/// Due to weird borrow checker stuff, this is a seperate struct. -/// In the future, we may find a way to combine the iterators. -/// ```compile_fail -///# // Because we're using unsafe, we need to make sure we don't mutabley alias. -///# fn multiple_iter_mut(mut tile_query: ChunkQuery) { -///# let mut iter_1 = tile_query.iter_in([0, 0], [3, 3]); -///# let mut iter_2 = tile_query.iter_in_mut([0, 0], [3, 3]); -///# let _ = iter_1.next(); -///# let _ = iter_2.next(); -///# } -/// ``` -pub struct ChunkQueryIterMut<'w, 's, L, Q, F, const N: usize> -where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, -{ +/// Iterates over a range of chunks using chunk coordinates. +pub struct ChunkQueryIterMut<'i, 'a, C, const N: usize> { coord_iter: CoordIterator, - tile_q: &'w ChunkQuery<'w, 's, L, Q, F, N>, + chunk_q: &'i ChunkQuery<'a, C, N>, } -impl<'w, 's, L, Q, F, const N: usize> ChunkQueryIterMut<'w, 's, L, Q, F, N> -where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, -{ - /// # Safety - /// This iterator uses unchecked get's to get around some lifetime issue I don't understand yet. - /// Due to this, you should only call this constructor from a context where the query is actually - /// borrowed mutabley. - unsafe fn new( - tile_q: &'w ChunkQuery<'w, 's, L, Q, F, N>, - corner_1: [isize; N], - corner_2: [isize; N], - ) -> Self { +impl<'i, 'a, C, const N: usize> ChunkQueryIterMut<'i, 'a, C, N> { + fn new(chunk_q: &'i ChunkQuery<'a, C, N>, corner_1: [isize; N], corner_2: [isize; N]) -> Self { Self { - tile_q, + chunk_q, coord_iter: CoordIterator::new(corner_1, corner_2), } } } -impl<'w, 's, L, Q, F, const N: usize> Iterator for ChunkQueryIterMut<'w, 's, L, Q, F, N> +impl<'i, 'a: 'i, 'w: 'a, 's: 'a, Q, F, C, const N: usize> Iterator + for ChunkQueryIterMut<'i, 'a, C, N> where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, + C: DerefMut, With)>>, + Q: QueryData + 'static, + F: QueryFilter + 'static, { - type Item = ::Item<'w>; + type Item = ::Item<'i>; #[allow(clippy::while_let_on_iterator)] #[inline] fn next(&mut self) -> Option { while let Some(target) = self.coord_iter.next() { - // SAFETY: This fixes some lifetime issue that I'm not sure I understand quite yet, will do testing - let tile = unsafe { self.tile_q.get_at_unchecked(target) }; + // SAFETY: Safe as long as the constructor requires a mutable reference + let tile = unsafe { self.chunk_q.get_at_unchecked(target) }; if tile.is_some() { return tile; } diff --git a/crates/bevy_tiles/src/commands.rs b/crates/bevy_tiles/src/commands.rs index e99b0b9..d208acf 100644 --- a/crates/bevy_tiles/src/commands.rs +++ b/crates/bevy_tiles/src/commands.rs @@ -1,22 +1,15 @@ -use std::{ - cmp::Eq, - hash::Hash, - marker::PhantomData, - ops::{Deref, DerefMut}, -}; +use std::{cmp::Eq, hash::Hash}; use crate::{ - maps::MapLabel, prelude::{ calculate_chunk_coordinate, calculate_tile_index, Chunk, ChunkCoord, InMap, TileMap, - TileMapLabel, }, tiles::{InChunk, TileCoord, TileIndex}, }; use bevy::{ - ecs::system::{Command, EntityCommands}, - prelude::{Bundle, Commands, Entity, With, World}, + ecs::system::EntityCommands, + prelude::{Bundle, Commands, Entity, World}, utils::{hashbrown::hash_map::Entry, HashMap}, }; @@ -33,213 +26,399 @@ use tile_batch::*; use tile_single::*; /// Applies commands to a specific tile map. -pub struct TileCommands<'a, 'w, 's, L, const N: usize> { +pub struct TileMapCommands<'a, 'w, 's, const N: usize> { commands: &'a mut Commands<'w, 's>, - phantom: PhantomData, + map_id: Entity, } -impl<'a, 'w, 's, L, const N: usize> Deref for TileCommands<'a, 'w, 's, L, N> -where - L: TileMapLabel + 'static, -{ - type Target = Commands<'w, 's>; +impl<'a, 'w, 's, const N: usize> TileMapCommands<'a, 'w, 's, N> { + /// Spawns a tile and returns a handle to the underlying entity. + /// This will despawn any tile that already exists in this coordinate + pub fn spawn_tile(&mut self, tile_c: [isize; N], bundle: impl Bundle) -> EntityCommands<'_> { + self.commands.spawn_tile(self.map_id, tile_c, bundle) + } - fn deref(&self) -> &Self::Target { + /// Spawns tiles from the given iterator using the given function. + /// This will despawn any tile that already exists in this coordinate + pub fn spawn_tile_batch(&mut self, tile_cs: IC, bundle_f: F) -> &mut Self + where + F: Fn([isize; N]) -> B + Send + 'static, + B: Bundle + Send + 'static, + IC: IntoIterator + Send + 'static, + { self.commands + .spawn_tile_batch(self.map_id, tile_cs, bundle_f); + self } -} -impl<'a, 'w, 's, L, const N: usize> DerefMut for TileCommands<'a, 'w, 's, L, N> -where - L: TileMapLabel + 'static, -{ - fn deref_mut(&mut self) -> &mut Self::Target { + /// Despawns a tile. + pub fn despawn_tile(&mut self, tile_c: [isize; N]) -> &mut Self { + self.commands.despawn_tile(self.map_id, tile_c); + self + } + + /// Despawns tiles from the given iterator. + pub fn despawn_tile_batch(&mut self, tile_cs: IC) -> &mut Self + where + IC: IntoIterator + Send + 'static, + { + self.commands.despawn_tile_batch(self.map_id, tile_cs); + self + } + + /// Moves a tile from one coordinate to another, overwriting and despawning any tile in the new coordinate. + pub fn move_tile(&mut self, old_c: [isize; N], new_c: [isize; N]) -> &mut Self { + self.commands.move_tile(self.map_id, old_c, new_c); + self + } + + /// Move tiles from the first coordinate to the second coordinate, despawning + /// any tile found in the second coordinate. + pub fn move_tile_batch(&mut self, tile_cs: IC) -> &mut Self + where + IC: IntoIterator + Send + 'static, + { + self.commands.move_tile_batch(self.map_id, tile_cs); + self + } + + /// Swaps two tiles if both exist, or moves one tile if the other doesn't exist. + pub fn swap_tiles(&mut self, tile_c_1: [isize; N], tile_c_2: [isize; N]) -> &mut Self { + self.commands.swap_tiles(self.map_id, tile_c_1, tile_c_2); + self + } + + /// Swap tiles from the first coordinate and the second coordinate + pub fn swap_tile_batch(&mut self, tile_cs: IC) -> &mut Self + where + IC: IntoIterator + Send + 'static, + { + self.commands.swap_tile_batch(self.map_id, tile_cs); + self + } + + /// Manually spawn a chunk entity, note that this will overwrite and despawn existing chunks at this location. + pub fn spawn_chunk(&mut self, chunk_c: [isize; N], bundle: impl Bundle) -> EntityCommands<'_> { + self.commands.spawn_chunk(self.map_id, chunk_c, bundle) + } + + /// Spawns chunks from the given iterator using the given function. + /// This will despawn any chunks (and their tiles) that already exists in this coordinate + pub fn spawn_chunk_batch_with(&mut self, chunk_cs: IC, bundle_f: F) -> &mut Self + where + F: Fn([isize; N]) -> B + Send + 'static, + B: Bundle + Send + 'static, + IC: IntoIterator + Send + 'static, + { self.commands + .spawn_chunk_batch_with(self.map_id, chunk_cs, bundle_f); + self + } + + /// Recursively despawn a chunk and all it's tiles. + pub fn despawn_chunk(&mut self, chunk_c: [isize; N]) -> &mut Self { + self.commands.despawn_chunk(self.map_id, chunk_c); + self + } + + /// Despawns chunks (and their tiles) from the given iterator. + pub fn despawn_chunk_batch(&mut self, chunk_cs: IC) -> &mut Self + where + IC: IntoIterator + Send + 'static, + { + self.commands.despawn_chunk_batch(self.map_id, chunk_cs); + self + } + + /// Recursively despawns a map and all it's chunks and tiles. + pub fn despawn_map(self) { + self.commands.despawn_map::(self.map_id); + } + + /// Get the id of the map. + pub fn id(&self) -> Entity { + self.map_id + } + + /// Adds entities to the tilemap. + pub fn insert(&mut self, bundle: impl Bundle) -> &mut Self { + self.commands.entity(self.map_id).insert(bundle); + self } } /// Helper method for creating map specific commands. pub trait TileCommandExt<'w, 's> { - /// Gets the [TileCommands] to apply commands at the tile map level. - fn tiles<'a, L, const N: usize>(&'a mut self) -> TileCommands<'a, 'w, 's, L, N> + /// Gets [TileMapCommands] to apply commands at the tile map level. + fn tile_map<'a, const N: usize>(&'a mut self, map_id: Entity) + -> TileMapCommands<'a, 'w, 's, N>; + + /// Spawns a tile and returns a handle to the underlying entity. + /// This will despawn any tile that already exists in this coordinate + fn spawn_tile( + &mut self, + map_id: Entity, + tile_c: [isize; N], + bundle: impl Bundle, + ) -> EntityCommands<'_>; + + /// Spawns tiles from the given iterator using the given function. + /// This will despawn any tile that already exists in this coordinate + fn spawn_tile_batch( + &mut self, + map_id: Entity, + tile_cs: IC, + bundle_f: F, + ) where + F: Fn([isize; N]) -> B + Send + 'static, + B: Bundle + Send + 'static, + IC: IntoIterator + Send + 'static; + + /// Despawns a tile. + fn despawn_tile(&mut self, map_id: Entity, tile_c: [isize; N]) -> &mut Self; + + /// Despawns tiles from the given iterator. + fn despawn_tile_batch(&mut self, map_id: Entity, tile_cs: IC) where - L: TileMapLabel + 'static; + IC: IntoIterator + Send + 'static; + + /// Moves a tile from one coordinate to another, overwriting and despawning any tile in the new coordinate. + fn move_tile( + &mut self, + map_id: Entity, + old_c: [isize; N], + new_c: [isize; N], + ) -> &mut Self; + + /// Move tiles from the first coordinate to the second coordinate, despawning + /// any tile found in the second coordinate. + fn move_tile_batch(&mut self, map_id: Entity, tile_cs: IC) + where + IC: IntoIterator + Send + 'static; + + /// Swaps two tiles if both exist, or moves one tile if the other doesn't exist. + fn swap_tiles( + &mut self, + map_id: Entity, + tile_c_1: [isize; N], + tile_c_2: [isize; N], + ) -> &mut Self; + + /// Swap tiles from the first coordinate and the second coordinate + fn swap_tile_batch(&mut self, map_id: Entity, tile_cs: IC) + where + IC: IntoIterator + Send + 'static; + + /// Manually spawn a chunk entity, note that this will overwrite and despawn existing chunks at this location. + fn spawn_chunk( + &mut self, + map_id: Entity, + chunk_c: [isize; N], + bundle: impl Bundle, + ) -> EntityCommands<'_>; + + /// Spawns chunks from the given iterator using the given function. + /// This will despawn any chunks (and their tiles) that already exists in this coordinate + fn spawn_chunk_batch_with( + &mut self, + map_id: Entity, + chunk_cs: IC, + bundle_f: F, + ) where + F: Fn([isize; N]) -> B + Send + 'static, + B: Bundle + Send + 'static, + IC: IntoIterator + Send + 'static; + + /// Recursively despawn a chunk and all it's tiles. + fn despawn_chunk(&mut self, map_id: Entity, chunk_c: [isize; N]) -> &mut Self; + + /// Despawns chunks (and their tiles) from the given iterator. + fn despawn_chunk_batch(&mut self, map_id: Entity, chunk_cs: IC) + where + IC: IntoIterator + Send + 'static; + + /// Spawn a new map. + fn spawn_map( + &mut self, + chunk_size: usize, + bundle: impl Bundle, + ) -> TileMapCommands<'_, 'w, 's, N>; + + /// Recursively despawns a map and all it's chunks and tiles. + fn despawn_map(&mut self, map_id: Entity) -> &mut Self; } impl<'w, 's> TileCommandExt<'w, 's> for Commands<'w, 's> { - fn tiles(&mut self) -> TileCommands<'_, 'w, 's, L, N> - where - L: TileMapLabel + 'static, - { - TileCommands { + fn tile_map(&mut self, map_id: Entity) -> TileMapCommands<'_, 'w, 's, N> { + TileMapCommands { commands: self, - phantom: PhantomData, + map_id, } } -} -impl<'a, 'w, 's, L, const N: usize> TileCommands<'a, 'w, 's, L, N> -where - L: TileMapLabel + 'static, -{ /// Spawns a tile and returns a handle to the underlying entity. /// This will despawn any tile that already exists in this coordinate - pub fn spawn_tile(&mut self, tile_c: [isize; N], bundle: T) -> EntityCommands<'w, 's, '_> - where - T: Bundle + 'static, - { + fn spawn_tile( + &mut self, + map_id: Entity, + tile_c: [isize; N], + bundle: impl Bundle, + ) -> EntityCommands<'_> { let tile_id = self.spawn(bundle).id(); - self.add(SpawnTile:: { + self.add(SpawnTile:: { + map_id, tile_c, tile_id, - label: std::marker::PhantomData, }); self.entity(tile_id) } /// Spawns tiles from the given iterator using the given function. /// This will despawn any tile that already exists in this coordinate - pub fn spawn_tile_batch(&mut self, tile_cs: IC, bundle_f: F) - where + fn spawn_tile_batch( + &mut self, + map_id: Entity, + tile_cs: IC, + bundle_f: F, + ) where F: Fn([isize; N]) -> B + Send + 'static, B: Bundle + Send + 'static, IC: IntoIterator + Send + 'static, { - self.add(SpawnTileBatch:: { + self.add(SpawnTileBatch:: { + map_id, tile_cs, bundle_f, - label: std::marker::PhantomData, }); } /// Despawns a tile. - pub fn despawn_tile(&mut self, tile_c: [isize; N]) -> &mut Self { - self.add(DespawnTile:: { - tile_c, - label: PhantomData, - }); + fn despawn_tile(&mut self, map_id: Entity, tile_c: [isize; N]) -> &mut Self { + self.add(DespawnTile:: { map_id, tile_c }); self } /// Despawns tiles from the given iterator. - pub fn despawn_tile_batch(&mut self, tile_cs: IC) + fn despawn_tile_batch(&mut self, map_id: Entity, tile_cs: IC) where IC: IntoIterator + Send + 'static, { - self.add(DespawnTileBatch:: { - tile_cs, - label: std::marker::PhantomData, - }); + self.add(DespawnTileBatch:: { map_id, tile_cs }); } /// Moves a tile from one coordinate to another, overwriting and despawning any tile in the new coordinate. - pub fn move_tile(&mut self, old_c: [isize; N], new_c: [isize; N]) -> &mut Self { - self.add(MoveTile:: { + fn move_tile( + &mut self, + map_id: Entity, + old_c: [isize; N], + new_c: [isize; N], + ) -> &mut Self { + self.add(MoveTile:: { + map_id, old_c, new_c, - label: PhantomData, }); self } /// Move tiles from the first coordinate to the second coordinate, despawning /// any tile found in the second coordinate. - pub fn move_tile_batch(&mut self, tile_cs: IC) + fn move_tile_batch(&mut self, map_id: Entity, tile_cs: IC) where IC: IntoIterator + Send + 'static, { - self.add(MoveTileBatch:: { - tile_cs, - label: std::marker::PhantomData, - }); + self.add(MoveTileBatch:: { map_id, tile_cs }); } - /// Swaps two tiles if both exist, or just moves one tile if the other doesn't exist. - pub fn swap_tiles(&mut self, tile_c_1: [isize; N], tile_c_2: [isize; N]) -> &mut Self { - self.add(SwapTile:: { + /// Swaps two tiles if both exist, or moves one tile if the other doesn't exist. + fn swap_tiles( + &mut self, + map_id: Entity, + tile_c_1: [isize; N], + tile_c_2: [isize; N], + ) -> &mut Self { + self.add(SwapTile:: { + map_id, tile_c_1, tile_c_2, - label: PhantomData, }); self } /// Swap tiles from the first coordinate and the second coordinate - pub fn swap_tile_batch(&mut self, tile_cs: IC) + fn swap_tile_batch(&mut self, map_id: Entity, tile_cs: IC) where IC: IntoIterator + Send + 'static, { - self.add(SwapTileBatch:: { - tile_cs, - label: std::marker::PhantomData, - }); + self.add(SwapTileBatch:: { map_id, tile_cs }); } /// Manually spawn a chunk entity, note that this will overwrite and despawn existing chunks at this location. - pub fn spawn_chunk(&mut self, chunk_c: [isize; N], bundle: T) -> EntityCommands<'w, 's, '_> - where - T: Bundle + 'static, - { + fn spawn_chunk( + &mut self, + map_id: Entity, + chunk_c: [isize; N], + bundle: impl Bundle, + ) -> EntityCommands<'_> { let chunk_id = self.spawn(bundle).id(); - self.add(SpawnChunk:: { + self.add(SpawnChunk:: { + map_id, chunk_c, chunk_id, - label: std::marker::PhantomData, }); self.entity(chunk_id) } /// Spawns chunks from the given iterator using the given function. /// This will despawn any chunks (and their tiles) that already exists in this coordinate - pub fn spawn_chunk_batch_with(&mut self, chunk_cs: IC, bundle_f: F) - where + fn spawn_chunk_batch_with( + &mut self, + map_id: Entity, + chunk_cs: IC, + bundle_f: F, + ) where F: Fn([isize; N]) -> B + Send + 'static, B: Bundle + Send + 'static, IC: IntoIterator + Send + 'static, { - self.add(SpawnChunkBatch:: { + self.add(SpawnChunkBatch:: { + map_id, chunk_cs, bundle_f, - label: std::marker::PhantomData, }); } /// Recursively despawn a chunk and all it's tiles. - pub fn despawn_chunk(&mut self, chunk_c: [isize; N]) -> &mut Self { - self.add(DespawnChunk:: { - chunk_c, - label: std::marker::PhantomData, - }); + fn despawn_chunk(&mut self, map_id: Entity, chunk_c: [isize; N]) -> &mut Self { + self.add(DespawnChunk:: { map_id, chunk_c }); self } /// Despawns chunks (and their tiles) from the given iterator. - pub fn despawn_chunk_batch(&mut self, chunk_cs: IC) + fn despawn_chunk_batch(&mut self, map_id: Entity, chunk_cs: IC) where IC: IntoIterator + Send + 'static, { - self.add(DespawnChunkBatch:: { - chunk_cs, - label: std::marker::PhantomData, - }); + self.add(DespawnChunkBatch:: { map_id, chunk_cs }); } - /// Spawn a new map, overwriting any old maps found. - pub fn spawn_map(&mut self, bundle: T) -> EntityCommands<'w, 's, '_> - where - T: Bundle + 'static, - { + /// Spawn a new map. + fn spawn_map( + &mut self, + chunk_size: usize, + bundle: impl Bundle, + ) -> TileMapCommands<'_, 'w, 's, N> { let map_id = self.spawn(bundle).id(); - self.add(SpawnMap:: { + self.add(SpawnMap:: { map_id, chunk_size }); + TileMapCommands { map_id, - label: PhantomData, - }); - self.entity(map_id) + commands: self, + } } /// Recursively despawns a map and all it's chunks and tiles. - pub fn despawn_map(&mut self) -> &mut Self { - self.add(DespawnMap:: { label: PhantomData }); + fn despawn_map(&mut self, map_id: Entity) -> &mut Self { + self.add(DespawnMap:: { map_id }); self } } @@ -247,27 +426,19 @@ where /// Spawns a chunk in the world if needed, inserts the info into the map, and returns /// and id for reinsertion #[inline] -fn spawn_or_remove_chunk( +fn spawn_or_remove_chunk( world: &mut World, map: &mut TileMap, map_id: Entity, chunk_c: [isize; N], -) -> (Entity, Chunk) -where - L: TileMapLabel + Send + 'static, -{ +) -> (Entity, Chunk) { if let Some(chunk_info) = remove_chunk::(world, map, chunk_c) { chunk_info } else { - let chunk_id = world - .spawn(( - ChunkCoord::from(chunk_c), - MapLabel::::default(), - InMap(map_id), - )) - .id(); - map.chunks.insert(chunk_c.into(), chunk_id); - (chunk_id, Chunk::new(L::CHUNK_SIZE.pow(N as u32))) + let chunk_c = ChunkCoord(chunk_c); + let chunk_id = world.spawn((chunk_c, InMap(map_id))).id(); + map.get_chunks_mut().insert(chunk_c, chunk_id); + (chunk_id, Chunk::new(map.get_chunk_size().pow(N as u32))) } } @@ -278,112 +449,88 @@ fn remove_chunk( map: &mut TileMap, chunk_c: [isize; N], ) -> Option<(Entity, Chunk)> { - map.chunks - .get::>(&chunk_c.into()) + map.get_chunks_mut() + .get::>(&ChunkCoord(chunk_c)) .cloned() .and_then(|chunk_id| world.get_entity_mut(chunk_id)) .map(|mut chunk_e| (chunk_e.id(), chunk_e.take::().unwrap())) } -/// Takes the map out of the world or spawns a new one and returns the entity id to return the map to. -#[inline] -fn spawn_or_remove_map(world: &mut World) -> (Entity, TileMap) -where - L: TileMapLabel + Send + 'static, -{ - let map_info = remove_map::(world); - if let Some(map_info) = map_info { - map_info - } else { - ( - world.spawn(MapLabel::::default()).id(), - TileMap::::with_chunk_size(L::CHUNK_SIZE), - ) - } -} - /// Takes the map out of the world if it exists. #[inline] -fn remove_map(world: &mut World) -> Option<(Entity, TileMap)> -where - L: TileMapLabel + Send + 'static, -{ +fn remove_map(world: &mut World, map_id: Entity) -> Option> { world - .query_filtered::>, With>)>() - .get_single_mut(world) - .ok() - .map(|map_id| { - ( - map_id, - world - .get_entity_mut(map_id) - .unwrap() - .take::>() - .unwrap(), - ) - }) + .get_entity_mut(map_id) + .and_then(|mut map_e| map_e.take::>()) } -/// Inserts a tile into the world -pub fn insert_tile(world: &mut World, tile_c: [isize; N], tile_id: Entity) -where - L: TileMapLabel + Send + 'static, -{ - // Take the map out and get the id to reinsert it - let (map_id, mut map) = spawn_or_remove_map::(world); +/// Inserts a tile into the given map. +pub fn insert_tile_into_map( + world: &mut World, + map: &mut TileMap, + map_id: Entity, + tile_c: [isize; N], + tile_id: Entity, +) { + let chunk_size = map.get_chunk_size(); // Take the chunk out and get the id to reinsert it - let chunk_c = calculate_chunk_coordinate(tile_c, L::CHUNK_SIZE); - let (chunk_id, mut chunk) = spawn_or_remove_chunk::(world, &mut map, map_id, chunk_c); + let chunk_c = calculate_chunk_coordinate(tile_c, chunk_size); + let (chunk_id, mut chunk) = spawn_or_remove_chunk::(world, map, map_id, chunk_c); // Insert the tile - let tile_i = calculate_tile_index(tile_c, L::CHUNK_SIZE); + let tile_i = calculate_tile_index(tile_c, chunk_size); - if let Some(tile) = chunk.tiles.get_mut(tile_i) { + if let Some(tile) = chunk.0.get_mut(tile_i) { if let Some(old_tile_id) = tile.replace(tile_id) { world.despawn(old_tile_id); } } world.get_entity_mut(tile_id).unwrap().insert(( - TileIndex::from(tile_i), - TileCoord::::new(tile_c), - MapLabel::::default(), + TileIndex(tile_i), + TileCoord::(tile_c), InChunk(chunk_id), )); world.get_entity_mut(chunk_id).unwrap().insert(chunk); - world.get_entity_mut(map_id).unwrap().insert(map); } -/// Take a tile from the world. -pub fn take_tile(world: &mut World, tile_c: [isize; N]) -> Option -where - L: TileMapLabel + Send + 'static, -{ - // Get the map or return - let (map_id, mut map) = remove_map::(world)?; +/// Inserts a tile into the world. +pub fn insert_tile( + world: &mut World, + map_id: Entity, + tile_c: [isize; N], + tile_id: Entity, +) { + // Take the map out and get the id to reinsert it + let mut map = remove_map::(world, map_id) + .unwrap_or_else(|| panic!("Could not find tile map with id '{:?}'", map_id)); + insert_tile_into_map(world, &mut map, map_id, tile_c, tile_id); + world.get_entity_mut(map_id).unwrap().insert(map); +} +/// Removes a tile from the given map. +pub fn take_tile_from_map( + world: &mut World, + map: &mut TileMap, + tile_c: [isize; N], +) -> Option { + let chunk_size = map.get_chunk_size(); // Get the old chunk or return - let chunk_c = calculate_chunk_coordinate(tile_c, L::CHUNK_SIZE); - let (chunk_id, mut chunk) = - if let Some(chunk_info) = remove_chunk::(world, &mut map, chunk_c) { - chunk_info - } else { - world.get_entity_mut(map_id).unwrap().insert(map); - return None; - }; + let chunk_c = calculate_chunk_coordinate(tile_c, chunk_size); + let (chunk_id, mut chunk) = remove_chunk::(world, map, chunk_c)?; // Remove the old entity or return if the old entity is already deleted - let tile_i = calculate_tile_index(tile_c, L::CHUNK_SIZE); + let tile_i = calculate_tile_index(tile_c, chunk_size); let tile = if let Some(mut tile_e) = chunk - .tiles + .0 .get_mut(tile_i) .and_then(|tile| tile.take()) .and_then(|tile_id| world.get_entity_mut(tile_id)) { - tile_e.remove::<(TileIndex, TileCoord, MapLabel, InChunk)>(); + tile_e.remove::<(TileIndex, TileCoord, InChunk)>(); let tile_id = tile_e.id(); Some(tile_id) } else { @@ -391,44 +538,57 @@ where }; world.get_entity_mut(chunk_id).unwrap().insert(chunk); + tile +} + +/// Take a tile from the world. +pub fn take_tile( + world: &mut World, + map_id: Entity, + tile_c: [isize; N], +) -> Option { + // Get the map or return + let mut map = remove_map::(world, map_id)?; + let tile = take_tile_from_map(world, &mut map, tile_c); world.get_entity_mut(map_id).unwrap().insert(map); tile } /// Inserts a list of entities into the corresponding tiles of a given tile map -pub fn insert_tile_batch( +pub fn insert_tile_batch( world: &mut World, + map_id: Entity, tiles: impl IntoIterator, -) where - L: TileMapLabel + Send + 'static, -{ +) { + // Remove the map, or spawn an entity to hold the map, then create an empty map + let mut map = remove_map::(world, map_id) + .unwrap_or_else(|| panic!("Could not find tile map with id '{:?}'", map_id)); + + let chunk_size = map.get_chunk_size(); + let chunked_tiles = tiles .into_iter() - .group_by(|(tile_c, _)| calculate_chunk_coordinate(*tile_c, L::CHUNK_SIZE)); - - // Remove the map, or spawn an entity to hold the map, then create an empty map - let (map_id, mut map) = spawn_or_remove_map::(world); + .group_by(|(tile_c, _)| calculate_chunk_coordinate(*tile_c, chunk_size)); // Get the chunks and entities from the map let tiles_with_chunk = Vec::from_iter(chunked_tiles.into_iter().map(|(chunk_c, tiles)| { - let (chunk_id, chunk) = spawn_or_remove_chunk::(world, &mut map, map_id, chunk_c); + let (chunk_id, chunk) = spawn_or_remove_chunk::(world, &mut map, map_id, chunk_c); (chunk_id, chunk, tiles) })); for (chunk_id, mut chunk, tiles) in tiles_with_chunk { for (tile_c, tile_id) in tiles { - let tile_i = calculate_tile_index(tile_c, L::CHUNK_SIZE); + let tile_i = calculate_tile_index(tile_c, chunk_size); - if let Some(tile) = chunk.tiles.get_mut(tile_i) { + if let Some(tile) = chunk.0.get_mut(tile_i) { if let Some(old_tile_id) = tile.replace(tile_id) { world.despawn(old_tile_id); } } world.get_entity_mut(tile_id).unwrap().insert(( - TileIndex::from(tile_i), - TileCoord::::new(tile_c), - MapLabel::::default(), + TileIndex(tile_i), + TileCoord::(tile_c), InChunk(chunk_id), )); } @@ -440,25 +600,23 @@ pub fn insert_tile_batch( } /// Removes the tiles from the tile map, returning the tile coordinates removed and their corresponding entities. -pub fn take_tile_batch( +pub fn take_tile_batch( world: &mut World, + map_id: Entity, tiles: impl IntoIterator, -) -> Vec<([isize; N], Entity)> -where - L: TileMapLabel + Send + 'static, -{ - // Group tiles by chunk - let chunked_tiles = tiles - .into_iter() - .group_by(|tile_c| calculate_chunk_coordinate(*tile_c, L::CHUNK_SIZE)); - +) -> Vec<([isize; N], Entity)> { // Remove the map, or return if it doesn't exist - let (map_id, mut map) = if let Some(map_info) = remove_map::(world) { - map_info - } else { + let Some(mut map) = remove_map::(world, map_id) else { return Vec::new(); }; + let chunk_size = map.get_chunk_size(); + + // Group tiles by chunk + let chunked_tiles = tiles + .into_iter() + .group_by(|tile_c| calculate_chunk_coordinate(*tile_c, chunk_size)); + // Get the chunks and entities from the map let tiles_with_chunk = chunked_tiles .into_iter() @@ -478,15 +636,15 @@ where let mut tile_ids = Vec::new(); for (chunk_id, mut chunk, tiles) in tiles_with_chunk { for tile_c in tiles { - let tile_i = calculate_tile_index(tile_c, L::CHUNK_SIZE); + let tile_i = calculate_tile_index(tile_c, chunk_size); if let Some(mut tile_e) = chunk - .tiles + .0 .get_mut(tile_i) .and_then(|tile| tile.take()) .and_then(|tile_id| world.get_entity_mut(tile_id)) { - tile_e.remove::<(TileIndex, TileCoord, MapLabel, InChunk)>(); + tile_e.remove::<(TileIndex, TileCoord, InChunk)>(); let tile_id = tile_e.id(); tile_ids.push((tile_c, tile_id)); } @@ -500,24 +658,29 @@ where } /// Insert the given entity into the map and have it treated as a chunk -pub fn insert_chunk(world: &mut World, chunk_c: [isize; N], chunk_id: Entity) -where - L: TileMapLabel + Send + 'static, -{ - let (map_id, mut map) = spawn_or_remove_map::(world); +pub fn insert_chunk( + world: &mut World, + map_id: Entity, + chunk_c: [isize; N], + chunk_id: Entity, +) { + let mut map = remove_map::(world, map_id) + .unwrap_or_else(|| panic!("Could not find tile map with id '{:?}'", map_id)); + + let chunk_size = map.get_chunk_size(); // Despawn the chunk if it exists - if let Some(old_chunk) = take_chunk_despawn_tiles_inner::(world, chunk_c, &mut map) { + if let Some(old_chunk) = take_chunk_despawn_tiles_inner::(world, &mut map, chunk_c) { world.despawn(old_chunk); } + let chunk_c = ChunkCoord(chunk_c); world.get_entity_mut(chunk_id).unwrap().insert(( - Chunk::new(L::CHUNK_SIZE.pow(N as u32)), - ChunkCoord::from(chunk_c), - MapLabel::::default(), + Chunk::new(chunk_size.pow(N as u32)), + chunk_c, InMap(map_id), )); - map.chunks.insert(chunk_c.into(), chunk_id); + map.get_chunks_mut().insert(chunk_c, chunk_id); world.entity_mut(map_id).insert(map); } @@ -526,24 +689,23 @@ where /// # Note /// This does not despawn or remove the tile entities, and reinsertion of this entity will not recreate the link to the chunk's tiles. /// If you wish to take the chunk and delete it's underlying tiles, use (take_chunk_despawn_tiles)[`take_chunk_despawn_tiles`] -pub fn take_chunk(world: &mut World, chunk_c: [isize; N]) -> Option -where - L: TileMapLabel + Send + 'static, -{ +pub fn take_chunk( + world: &mut World, + map_id: Entity, + chunk_c: [isize; N], +) -> Option { // Get the map or return - let (map_id, mut map) = remove_map::(world)?; + let mut map = remove_map::(world, map_id)?; // Get the old chunk or return let chunk_id = if let Some(mut chunk_e) = map - .chunks - .remove::>(&chunk_c.into()) + .get_chunks_mut() + .remove::>(&ChunkCoord(chunk_c)) .and_then(|chunk_id| world.get_entity_mut(chunk_id)) { - let (chunk, _, _, _) = chunk_e - .take::<(Chunk, ChunkCoord, MapLabel, InMap)>() - .unwrap(); + let (chunk, _, _) = chunk_e.take::<(Chunk, ChunkCoord, InMap)>().unwrap(); let chunk_id = chunk_e.id(); - for tile_id in chunk.tiles.into_iter().flatten() { + for tile_id in chunk.0.into_iter().flatten() { if let Some(mut tile) = world.get_entity_mut(tile_id) { tile.remove::(); } @@ -559,42 +721,36 @@ where } /// Remove the chunk from the map without despawning it and despawns the tiles in the chunk. -pub fn take_chunk_despawn_tiles( +pub fn take_chunk_despawn_tiles( world: &mut World, + map_id: Entity, chunk_c: [isize; N], -) -> Option -where - L: TileMapLabel + Send + 'static, -{ +) -> Option { // Get the map or return - let (map_id, mut map) = remove_map::(world)?; + let mut map = remove_map::(world, map_id)?; - let chunk_id = take_chunk_despawn_tiles_inner::(world, chunk_c, &mut map); + let chunk_id = take_chunk_despawn_tiles_inner::(world, &mut map, chunk_c); world.entity_mut(map_id).insert(map); chunk_id } -pub(crate) fn take_chunk_despawn_tiles_inner( +pub(crate) fn take_chunk_despawn_tiles_inner( world: &mut World, + map: &mut TileMap, chunk_c: [isize; N], - mut map: &mut TileMap, -) -> Option -where - L: TileMapLabel + Send + 'static, -{ +) -> Option { // Get the old chunk or return + let chunk_c = ChunkCoord(chunk_c); let chunk_id = if let Some(mut chunk_e) = map - .chunks - .remove::>(&chunk_c.into()) + .get_chunks_mut() + .remove::>(&chunk_c) .and_then(|chunk_id| world.get_entity_mut(chunk_id)) { - let (chunk, _, _, _) = chunk_e - .take::<(Chunk, ChunkCoord, MapLabel, InMap)>() - .unwrap(); + let (chunk, _, _) = chunk_e.take::<(Chunk, ChunkCoord, InMap)>().unwrap(); let chunk_id = chunk_e.id(); - for tile_id in chunk.tiles.into_iter().flatten() { + for tile_id in chunk.0.into_iter().flatten() { world.despawn(tile_id); } Some(chunk_id) @@ -605,28 +761,30 @@ where } /// Inserts a list of entities into map and treats them as chunks -pub fn insert_chunk_batch( +pub fn insert_chunk_batch( world: &mut World, + map_id: Entity, chunks: impl IntoIterator, -) where - L: TileMapLabel + Send + 'static, -{ +) { // Remove the map, or spawn an entity to hold the map, then create an empty map - let (map_id, mut map) = spawn_or_remove_map::(world); + let mut map = remove_map::(world, map_id) + .unwrap_or_else(|| panic!("Could not find tile map with id '{:?}'", map_id)); + + let chunk_size = map.get_chunk_size(); // Get the chunks and entities from the map for (chunk_c, chunk_id) in chunks.into_iter() { - if let Some(old_chunk) = take_chunk_despawn_tiles_inner::(world, chunk_c, &mut map) { + if let Some(old_chunk) = take_chunk_despawn_tiles_inner::(world, &mut map, chunk_c) { world.despawn(old_chunk); } + let chunk_c = ChunkCoord(chunk_c); world.get_entity_mut(chunk_id).unwrap().insert(( - Chunk::new(L::CHUNK_SIZE.pow(N as u32)), - ChunkCoord::from(chunk_c), - MapLabel::::default(), + Chunk::new(chunk_size.pow(N as u32)), + chunk_c, InMap(map_id), )); - map.chunks.insert(chunk_c.into(), chunk_id); + map.get_chunks_mut().insert(chunk_c, chunk_id); } world.get_entity_mut(map_id).unwrap().insert(map); @@ -636,15 +794,13 @@ pub fn insert_chunk_batch( /// # Note /// This does not despawn or remove the tile entities, and reinsertion of this entity will not recreate the link to the chunk's tiles. /// If you wish to take the chunk and delete it's underlying tiles, use (take_chunk_batch_despawn_tiles)[`take_chunk_batch_despawn_tiles`] -pub fn take_chunk_batch( +pub fn take_chunk_batch( world: &mut World, + map_id: Entity, chunks: impl IntoIterator, -) -> Vec<([isize; N], Entity)> -where - L: TileMapLabel + Send + 'static, -{ +) -> Vec<([isize; N], Entity)> { // Remove the map, or return if it doesn't exist - let (map_id, mut map) = if let Some(map_info) = remove_map::(world) { + let mut map = if let Some(map_info) = remove_map::(world, map_id) { map_info } else { return Vec::new(); @@ -655,15 +811,13 @@ where for chunk_c in chunks.into_iter() { // Get the old chunk or return if let Some(mut chunk_e) = map - .chunks - .remove::>(&chunk_c.into()) + .get_chunks_mut() + .remove::>(&ChunkCoord(chunk_c)) .and_then(|chunk_id| world.get_entity_mut(chunk_id)) { - let (chunk, _, _, _) = chunk_e - .take::<(Chunk, ChunkCoord, MapLabel, InMap)>() - .unwrap(); + let (chunk, _, _) = chunk_e.take::<(Chunk, ChunkCoord, InMap)>().unwrap(); let chunk_id = chunk_e.id(); - for tile_id in chunk.tiles.into_iter().flatten() { + for tile_id in chunk.0.into_iter().flatten() { if let Some(mut tile) = world.get_entity_mut(tile_id) { tile.remove::(); } @@ -678,15 +832,13 @@ where /// Removes the chunks from the tile map, returning the chunk coordinates removed and their corresponding entities. /// Also despawns all tiles in all the removed chunks. -pub fn take_chunk_batch_despawn_tiles( +pub fn take_chunk_batch_despawn_tiles( world: &mut World, + map_id: Entity, chunks: impl IntoIterator, -) -> Vec<([isize; N], Entity)> -where - L: TileMapLabel + Send + 'static, -{ +) -> Vec<([isize; N], Entity)> { // Remove the map, or return if it doesn't exist - let (map_id, mut map) = if let Some(map_info) = remove_map::(world) { + let mut map = if let Some(map_info) = remove_map::(world, map_id) { map_info } else { return Vec::new(); @@ -697,15 +849,13 @@ where for chunk_c in chunks.into_iter() { // Get the old chunk or return if let Some(mut chunk_e) = map - .chunks - .remove::>(&chunk_c.into()) + .get_chunks_mut() + .remove::>(&ChunkCoord(chunk_c)) .and_then(|chunk_id| world.get_entity_mut(chunk_id)) { - let (chunk, _, _, _) = chunk_e - .take::<(Chunk, ChunkCoord, MapLabel, InMap)>() - .unwrap(); + let (chunk, _, _) = chunk_e.take::<(Chunk, ChunkCoord, InMap)>().unwrap(); let chunk_id = chunk_e.id(); - for tile_id in chunk.tiles.into_iter().flatten() { + for tile_id in chunk.0.into_iter().flatten() { world.despawn(tile_id); } chunk_ids.push((chunk_c, chunk_id)); @@ -717,18 +867,23 @@ where } /// Insert the given entity and have it be treated as the given map. -/// # Note -/// This will despawn any existing map with this label. -pub fn insert_map(world: &mut World, map_id: Entity) -where - L: TileMapLabel + Send + 'static, -{ - let map_info = remove_map::(world); - DespawnMap::::default().apply(world); - world.entity_mut(map_id).insert(( - MapLabel::::default(), - TileMap::::with_chunk_size(L::CHUNK_SIZE), - )); +pub fn insert_map(world: &mut World, map_id: Entity, chunk_size: usize) { + if let Some(mut map) = remove_map::(world, map_id) { + despawn_children::(world, &mut map); + } + world + .entity_mut(map_id) + .insert(TileMap::::with_chunk_size(chunk_size)); +} + +/// Despawns all the chunks and tiles in a given map +pub fn despawn_children(world: &mut World, map: &mut TileMap) { + let chunks: Vec> = map.get_chunks().keys().cloned().collect(); + for chunk_c in chunks { + if let Some(old_chunk) = take_chunk_despawn_tiles_inner::(world, map, *chunk_c) { + world.despawn(old_chunk); + } + } } trait GroupBy: Iterator { diff --git a/crates/bevy_tiles/src/commands/chunk_batch.rs b/crates/bevy_tiles/src/commands/chunk_batch.rs index def1d95..19d643b 100644 --- a/crates/bevy_tiles/src/commands/chunk_batch.rs +++ b/crates/bevy_tiles/src/commands/chunk_batch.rs @@ -1,24 +1,20 @@ use bevy::ecs::{bundle::Bundle, entity::Entity, system::Command, world::World}; -use crate::prelude::TileMapLabel; - use super::{insert_chunk_batch, take_chunk_batch_despawn_tiles}; -pub struct SpawnChunkBatch +pub struct SpawnChunkBatch where - L: TileMapLabel + Send + 'static, F: Fn([isize; N]) -> B + Send + 'static, B: Bundle + Send + 'static, IC: IntoIterator + Send + 'static, { + pub map_id: Entity, pub chunk_cs: IC, pub bundle_f: F, - pub label: std::marker::PhantomData, } -impl Command for SpawnChunkBatch +impl Command for SpawnChunkBatch where - L: TileMapLabel + Send + 'static, F: Fn([isize; N]) -> B + Send + 'static, B: Bundle + Send + 'static, IC: IntoIterator + Send + 'static, @@ -35,26 +31,24 @@ where .zip(world.spawn_batch(bundles)) .collect::>(); - insert_chunk_batch::(world, chunks); + insert_chunk_batch::(world, self.map_id, chunks); } } -pub struct DespawnChunkBatch +pub struct DespawnChunkBatch where - L: TileMapLabel + Send + 'static, IC: IntoIterator + Send + 'static, { + pub map_id: Entity, pub chunk_cs: IC, - pub label: std::marker::PhantomData, } -impl Command for DespawnChunkBatch +impl Command for DespawnChunkBatch where - L: TileMapLabel + Send + 'static, IC: IntoIterator + Send + 'static, { fn apply(self, world: &mut World) { - for (_, tile_id) in take_chunk_batch_despawn_tiles::(world, self.chunk_cs) { + for (_, tile_id) in take_chunk_batch_despawn_tiles::(world, self.map_id, self.chunk_cs) { world.despawn(tile_id); } } diff --git a/crates/bevy_tiles/src/commands/chunk_single.rs b/crates/bevy_tiles/src/commands/chunk_single.rs index faab7f4..9834fdb 100644 --- a/crates/bevy_tiles/src/commands/chunk_single.rs +++ b/crates/bevy_tiles/src/commands/chunk_single.rs @@ -1,35 +1,27 @@ use bevy::ecs::{entity::Entity, system::Command, world::World}; -use crate::prelude::TileMapLabel; - use super::{insert_chunk, take_chunk_despawn_tiles}; -pub struct SpawnChunk { +pub struct SpawnChunk { + pub map_id: Entity, pub chunk_c: [isize; N], pub chunk_id: Entity, - pub label: std::marker::PhantomData, } -impl Command for SpawnChunk -where - L: TileMapLabel + Send + 'static, -{ +impl Command for SpawnChunk { fn apply(self, world: &mut World) { - insert_chunk::(world, self.chunk_c, self.chunk_id) + insert_chunk::(world, self.map_id, self.chunk_c, self.chunk_id) } } -pub struct DespawnChunk { +pub struct DespawnChunk { + pub map_id: Entity, pub chunk_c: [isize; N], - pub label: std::marker::PhantomData, } -impl Command for DespawnChunk -where - L: TileMapLabel + Send + 'static, -{ +impl Command for DespawnChunk { fn apply(self, world: &mut World) { - let tile_id = take_chunk_despawn_tiles::(world, self.chunk_c); + let tile_id = take_chunk_despawn_tiles::(world, self.map_id, self.chunk_c); if let Some(id) = tile_id { world.despawn(id); } diff --git a/crates/bevy_tiles/src/commands/map.rs b/crates/bevy_tiles/src/commands/map.rs index 8f2ef35..2c30b73 100644 --- a/crates/bevy_tiles/src/commands/map.rs +++ b/crates/bevy_tiles/src/commands/map.rs @@ -1,63 +1,26 @@ -use std::ops::Deref; +use bevy::ecs::{entity::Entity, system::Command, world::World}; -use bevy::ecs::{entity::Entity, query::With, system::Command, world::World}; +use super::{despawn_children, insert_map, remove_map}; -use crate::{ - maps::{MapLabel, TileMap}, - prelude::{ChunkCoord, TileMapLabel}, -}; - -use super::{insert_map, take_chunk_despawn_tiles_inner}; - -pub struct SpawnMap { +pub struct SpawnMap { pub map_id: Entity, - pub label: std::marker::PhantomData, + pub chunk_size: usize, } -impl Command for SpawnMap -where - L: TileMapLabel + 'static, -{ +impl Command for SpawnMap { fn apply(self, world: &mut World) { - insert_map::(world, self.map_id) + insert_map::(world, self.map_id, self.chunk_size) } } -pub struct DespawnMap { - pub label: std::marker::PhantomData, -} - -impl Default for DespawnMap { - fn default() -> Self { - Self { - label: Default::default(), - } - } +pub struct DespawnMap { + pub map_id: Entity, } -impl Command for DespawnMap -where - L: TileMapLabel + 'static, -{ +impl Command for DespawnMap { fn apply(self, world: &mut World) { - if let Ok((map_id)) = world - .query_filtered::>, With>)>() - .get_single_mut(world) - { - let mut map = world - .get_entity_mut(map_id) - .unwrap() - .take::>() - .unwrap(); - let chunks: Vec> = map.chunks.keys().cloned().collect(); - for chunk_c in chunks { - if let Some(old_chunk) = - take_chunk_despawn_tiles_inner::(world, *chunk_c, &mut map) - { - world.despawn(old_chunk); - } - } - world.despawn(map_id); - } + let mut map = remove_map::(world, self.map_id).unwrap(); + despawn_children::(world, &mut map); + world.despawn(self.map_id); } } diff --git a/crates/bevy_tiles/src/commands/tile_batch.rs b/crates/bevy_tiles/src/commands/tile_batch.rs index b2483b3..0a030d2 100644 --- a/crates/bevy_tiles/src/commands/tile_batch.rs +++ b/crates/bevy_tiles/src/commands/tile_batch.rs @@ -4,25 +4,21 @@ use bevy::{ }; use bimap::BiMap; -use crate::prelude::TileMapLabel; - use super::{insert_tile_batch, take_tile_batch}; -pub struct SpawnTileBatch +pub struct SpawnTileBatch where - L: TileMapLabel + Send + 'static, F: Fn([isize; N]) -> B + Send + 'static, B: Bundle + Send + 'static, IC: IntoIterator + Send + 'static, { + pub map_id: Entity, pub tile_cs: IC, pub bundle_f: F, - pub label: std::marker::PhantomData, } -impl Command for SpawnTileBatch +impl Command for SpawnTileBatch where - L: TileMapLabel + Send + 'static, F: Fn([isize; N]) -> B + Send + 'static, B: Bundle + Send + 'static, IC: IntoIterator + Send + 'static, @@ -39,43 +35,39 @@ where .zip(world.spawn_batch(bundles)) .collect::>(); - insert_tile_batch::(world, tiles); + insert_tile_batch::(world, self.map_id, tiles); } } -pub struct DespawnTileBatch +pub struct DespawnTileBatch where - L: TileMapLabel + Send + 'static, IC: IntoIterator + Send + 'static, { + pub map_id: Entity, pub tile_cs: IC, - pub label: std::marker::PhantomData, } -impl Command for DespawnTileBatch +impl Command for DespawnTileBatch where - L: TileMapLabel + Send + 'static, IC: IntoIterator + Send + 'static, { fn apply(self, world: &mut World) { - for (_, tile_id) in take_tile_batch::(world, self.tile_cs) { + for (_, tile_id) in take_tile_batch::(world, self.map_id, self.tile_cs) { world.despawn(tile_id); } } } -pub struct MoveTileBatch +pub struct MoveTileBatch where - L: TileMapLabel + Send + 'static, IC: IntoIterator + Send + 'static, { + pub map_id: Entity, pub tile_cs: IC, - pub label: std::marker::PhantomData, } -impl Command for MoveTileBatch +impl Command for MoveTileBatch where - L: TileMapLabel + Send + 'static, IC: IntoIterator + Send + 'static, { fn apply(self, world: &mut World) { @@ -87,27 +79,28 @@ where .into_iter() .collect::>(); - let removed = - take_tile_batch::(world, tile_cs.keys().cloned().collect::>()) - .into_iter() - .map(|(tile_c, tile_id)| (tile_cs.remove(&tile_c).expect(ERR_MESSAGE), tile_id)); + let removed = take_tile_batch::( + world, + self.map_id, + tile_cs.keys().cloned().collect::>(), + ) + .into_iter() + .map(|(tile_c, tile_id)| (tile_cs.remove(&tile_c).expect(ERR_MESSAGE), tile_id)); - insert_tile_batch::(world, removed); + insert_tile_batch::(world, self.map_id, removed); } } -pub struct SwapTileBatch +pub struct SwapTileBatch where - L: TileMapLabel + Send + 'static, IC: IntoIterator + Send + 'static, { + pub map_id: Entity, pub tile_cs: IC, - pub label: std::marker::PhantomData, } -impl Command for SwapTileBatch +impl Command for SwapTileBatch where - L: TileMapLabel + Send + 'static, IC: IntoIterator + Send + 'static, { fn apply(self, world: &mut World) { @@ -119,20 +112,22 @@ where .into_iter() .collect::>(); - let removed_left = take_tile_batch::( + let removed_left = take_tile_batch::( world, + self.map_id, tile_cs.left_values().cloned().collect::>(), ) .into_iter() .map(|(tile_c, tile_id)| (*tile_cs.get_by_left(&tile_c).expect(ERR_MESSAGE), tile_id)); - let removed_right = take_tile_batch::( + let removed_right = take_tile_batch::( world, + self.map_id, tile_cs.right_values().cloned().collect::>(), ) .into_iter() .map(|(tile_c, tile_id)| (*tile_cs.get_by_right(&tile_c).expect(ERR_MESSAGE), tile_id)); - insert_tile_batch::(world, removed_left.chain(removed_right)); + insert_tile_batch::(world, self.map_id, removed_left.chain(removed_right)); } } diff --git a/crates/bevy_tiles/src/commands/tile_single.rs b/crates/bevy_tiles/src/commands/tile_single.rs index ffd8fc3..004e724 100644 --- a/crates/bevy_tiles/src/commands/tile_single.rs +++ b/crates/bevy_tiles/src/commands/tile_single.rs @@ -1,104 +1,87 @@ use bevy::ecs::{entity::Entity, system::Command, world::World}; -use crate::prelude::TileMapLabel; +use super::{insert_tile, insert_tile_into_map, remove_map, take_tile, take_tile_from_map}; -use super::{insert_tile, take_tile}; - -pub struct SpawnTile { +pub struct SpawnTile { + pub map_id: Entity, pub tile_c: [isize; N], pub tile_id: Entity, - pub label: std::marker::PhantomData, } -impl Command for SpawnTile -where - L: TileMapLabel + Send + 'static, -{ +impl Command for SpawnTile { fn apply(self, world: &mut World) { - insert_tile::(world, self.tile_c, self.tile_id) + insert_tile::(world, self.map_id, self.tile_c, self.tile_id) } } -pub struct DespawnTile { +pub struct DespawnTile { + pub map_id: Entity, pub tile_c: [isize; N], - pub label: std::marker::PhantomData, } -impl Command for DespawnTile -where - L: TileMapLabel + Send + 'static, -{ +impl Command for DespawnTile { fn apply(self, world: &mut World) { - let tile_id = take_tile::(world, self.tile_c); + let tile_id = take_tile::(world, self.map_id, self.tile_c); if let Some(id) = tile_id { world.despawn(id); } } } -pub struct SwapTile { +pub struct SwapTile { + pub map_id: Entity, pub tile_c_1: [isize; N], pub tile_c_2: [isize; N], - pub label: std::marker::PhantomData, } -impl Command for SwapTile -where - L: TileMapLabel + Send + 'static, -{ +impl Command for SwapTile { fn apply(self, world: &mut World) { if self.tile_c_1 == self.tile_c_2 { return; } - let tile_id_1 = take_tile::(world, self.tile_c_1); + let Some(mut map) = remove_map::(world, self.map_id) else { + return; + }; + + let tile_id_1 = take_tile_from_map::(world, &mut map, self.tile_c_1); - let tile_id_2 = take_tile::(world, self.tile_c_2); + let tile_id_2 = take_tile_from_map::(world, &mut map, self.tile_c_2); if let Some(tile_id) = tile_id_1 { - SpawnTile:: { - tile_c: self.tile_c_2, - tile_id, - label: self.label, - } - .apply(world); + insert_tile_into_map(world, &mut map, self.map_id, self.tile_c_2, tile_id); } if let Some(tile_id) = tile_id_2 { - SpawnTile:: { - tile_c: self.tile_c_1, - tile_id, - label: self.label, - } - .apply(world); + insert_tile_into_map(world, &mut map, self.map_id, self.tile_c_1, tile_id); } + + world.get_entity_mut(self.map_id).unwrap().insert(map); } } -pub struct MoveTile { +pub struct MoveTile { + pub map_id: Entity, pub old_c: [isize; N], pub new_c: [isize; N], - pub label: std::marker::PhantomData, } -impl Command for MoveTile -where - L: TileMapLabel + Send + 'static, -{ +impl Command for MoveTile { fn apply(self, world: &mut World) { if self.old_c == self.new_c { return; } - let old_tile_id = take_tile::(world, self.old_c); + let Some(mut map) = remove_map::(world, self.map_id) else { + return; + }; + + let tile_id = take_tile_from_map::(world, &mut map, self.old_c); - if let Some(old_tile_id) = old_tile_id { - SpawnTile:: { - tile_c: self.new_c, - tile_id: old_tile_id, - label: self.label, - } - .apply(world); + if let Some(tile_id) = tile_id { + insert_tile_into_map(world, &mut map, self.map_id, self.new_c, tile_id); } + + world.get_entity_mut(self.map_id).unwrap().insert(map); } } diff --git a/crates/bevy_tiles/src/coords.rs b/crates/bevy_tiles/src/coords.rs index a956f8b..61972f7 100644 --- a/crates/bevy_tiles/src/coords.rs +++ b/crates/bevy_tiles/src/coords.rs @@ -1,5 +1,3 @@ -use bevy::log::debug; - /// Calculate the coordinate of a chunk from a given tile coordinate and chunk size #[inline] pub fn calculate_chunk_coordinate( diff --git a/crates/bevy_tiles/src/lib.rs b/crates/bevy_tiles/src/lib.rs index c7e3fc0..80ec0a0 100644 --- a/crates/bevy_tiles/src/lib.rs +++ b/crates/bevy_tiles/src/lib.rs @@ -22,7 +22,7 @@ pub mod tiles; /// Provides most of what you need to get started. pub mod prelude { - pub use crate::commands::{TileCommandExt, TileCommands}; + pub use crate::commands::{TileCommandExt, TileMapCommands}; pub use crate::chunks::*; pub use crate::coords::*; @@ -32,12 +32,8 @@ pub mod prelude { } /// Adds Tiles dependencies to the App. -/// # Note -/// If you are using [Aery](https://crates.io/crates/aery), add it to the App before this plugin, or just add this plugin. -/// This plugin will add Aery if it's not in the app, since it is a unique plugin, -/// having multiple will panic. pub struct TilesPlugin; impl Plugin for TilesPlugin { - fn build(&self, app: &mut bevy::prelude::App) {} + fn build(&self, _app: &mut bevy::prelude::App) {} } diff --git a/crates/bevy_tiles/src/maps.rs b/crates/bevy_tiles/src/maps.rs index 05b0a50..ef1f7e4 100644 --- a/crates/bevy_tiles/src/maps.rs +++ b/crates/bevy_tiles/src/maps.rs @@ -1,30 +1,9 @@ -use std::marker::PhantomData; - use bevy::{ ecs::{component::Component, entity::Entity}, utils::HashMap, }; -use crate::chunks::ChunkCoord; - -/// Adds type level info on how a Tile Map should be treated. -pub trait TileMapLabel: Send + Sync + 'static { - /// How many tiles per dimension a chunk in this map extends. - const CHUNK_SIZE: usize; -} - -/// Marks an entity as being part of the tilemap. -/// # Note -/// Manually updating this value, adding it, or removing it from an entity may -/// cause issues, please only mutate map information via commands. -#[derive(Component)] -pub struct MapLabel(PhantomData); - -impl Default for MapLabel { - fn default() -> Self { - Self(Default::default()) - } -} +use crate::{chunks::ChunkCoord, prelude::calculate_chunk_coordinate, tiles::TileCoord}; /// Holds handles to all the chunks in a map. /// # Note @@ -32,9 +11,9 @@ impl Default for MapLabel { /// cause issues, please only mutate map information via commands. #[derive(Component)] pub struct TileMap { - pub(crate) chunks: HashMap, Entity>, + chunks: HashMap, Entity>, /// The size of a chunk in one direction. - pub chunk_size: usize, + chunk_size: usize, } impl TileMap { @@ -45,8 +24,30 @@ impl TileMap { } } - /// Get readonly access to the chunk table + /// Gets the chunk entity from a tile coordinate. + pub fn get_from_tile(&self, tile_c: TileCoord) -> Option { + let chunk_c = calculate_chunk_coordinate(tile_c.0, self.chunk_size); + self.chunks + .get::>(&ChunkCoord::(chunk_c)) + .cloned() + } + + /// Gets the chunk entity from a chunk coordinate. + pub fn get_from_chunk(&self, chunk_c: ChunkCoord) -> Option { + self.chunks.get::>(&chunk_c).cloned() + } + + /// Get readonly access to the chunk table. pub fn get_chunks(&self) -> &HashMap, Entity> { &self.chunks } + + pub(crate) fn get_chunks_mut(&mut self) -> &mut HashMap, Entity> { + &mut self.chunks + } + + /// Get the size of chunks in this tilemap. + pub fn get_chunk_size(&self) -> usize { + self.chunk_size + } } diff --git a/crates/bevy_tiles/src/tiles.rs b/crates/bevy_tiles/src/tiles.rs index e5d5e6c..bf34a0a 100644 --- a/crates/bevy_tiles/src/tiles.rs +++ b/crates/bevy_tiles/src/tiles.rs @@ -1,65 +1,17 @@ use bevy::prelude::*; -use std::ops::Deref; mod tile_query; pub use tile_query::*; /// The index of a tile in a given chunk. -/// # Note -/// Manually updating this value, adding it, or removing it from an entity may -/// cause issues, please only mutate tile information via commands. -#[derive(Component, Debug)] -pub struct TileIndex(usize); - -impl From for TileIndex { - fn from(value: usize) -> Self { - Self(value) - } -} - -impl Deref for TileIndex { - type Target = usize; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} +#[derive(Component, Deref, Debug)] +pub struct TileIndex(pub(crate) usize); /// The coordinate of a tile in a given map. -/// # Note -/// Manually updating this value, adding it, or removing it from an entity may -/// cause issues, please only mutate tile information via commands. -#[derive(Component, Debug)] -pub struct TileCoord([isize; N]); - -impl TileCoord { - pub(crate) fn new(value: [isize; N]) -> Self { - Self(value) - } -} - -impl From<[isize; N]> for TileCoord { - fn from(value: [isize; N]) -> Self { - Self(value) - } -} - -impl Deref for TileCoord { - type Target = [isize; N]; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} +#[derive(Component, Deref, Debug)] +pub struct TileCoord(pub(crate) [isize; N]); /// A relation on tiles that point towards the chunk they are a part of. -#[derive(Component)] +#[derive(Component, Deref, Debug)] pub struct InChunk(pub(crate) Entity); - -impl InChunk { - /// Get the referenced chunk entity. - pub fn get(&self) -> Entity { - self.0 - } -} diff --git a/crates/bevy_tiles/src/tiles/tile_query.rs b/crates/bevy_tiles/src/tiles/tile_query.rs index b6e810b..b18e320 100644 --- a/crates/bevy_tiles/src/tiles/tile_query.rs +++ b/crates/bevy_tiles/src/tiles/tile_query.rs @@ -1,114 +1,181 @@ -use std::ops::{Deref, DerefMut}; +use std::{ + marker::PhantomData, + ops::{Deref, DerefMut}, +}; use bevy::{ ecs::{ - query::{ReadOnlyWorldQuery, With, WorldQuery}, + entity::Entity, + query::{QueryData, QueryFilter, With, WorldQuery}, system::SystemParam, }, prelude::Query, }; use crate::{ - chunks::{Chunk, ChunkCoord, InMap}, - maps::{MapLabel, TileMap, TileMapLabel}, - prelude::{ - calculate_chunk_coordinate, calculate_tile_coordinate, calculate_tile_index, - max_tile_index, CoordIterator, - }, + chunks::{Chunk, InMap}, + maps::TileMap, + prelude::{calculate_tile_coordinate, calculate_tile_index, max_tile_index, CoordIterator}, }; -use super::InChunk; +use super::{InChunk, TileCoord}; + +/// Borrowed types from a [TileMapQuery] needed to construct a [TileQuery] +pub struct BorrowedTileQueries<'a, 'w: 'a, 's: 'a, Q, F, const N: usize> +where + Q: QueryData + 'static, + F: QueryFilter + 'static, +{ + phantom: PhantomData<(&'a Q, &'w F, &'s Q)>, +} + +impl<'a, 'w: 'a, 's: 'a, Q, F, const N: usize> BorrowedTileQueryTypes<'a> + for BorrowedTileQueries<'a, 'w, 's, Q, F, N> +where + Q: QueryData + 'static, + F: QueryFilter + 'static, +{ + type TileQuery = &'a Query<'w, 's, Q, (F, With)>; + + type ChunkQuery = &'a Query<'w, 's, &'static Chunk, With>; + + type Map = &'a TileMap; +} + +/// Mutable borrowed types from a [TileMapQuery] needed to construct a mutable [TileQuery] +pub struct MutableBorrowedTileQueries<'a, 'w: 'a, 's: 'a, Q, F, const N: usize> +where + Q: QueryData + 'static, + F: QueryFilter + 'static, +{ + phantom: PhantomData<(&'a Q, &'w F, &'s Q)>, +} + +impl<'a, 'w: 'a, 's: 'a, Q, F, const N: usize> BorrowedTileQueryTypes<'a> + for MutableBorrowedTileQueries<'a, 'w, 's, Q, F, N> +where + Q: QueryData + 'static, + F: QueryFilter + 'static, +{ + type TileQuery = &'a mut Query<'w, 's, Q, (F, With)>; + + type ChunkQuery = &'a mut Query<'w, 's, &'static Chunk, With>; + + type Map = &'a TileMap; +} + +/// Describes the types used to construct a query, mainly needed to reduce code duplication. +pub trait BorrowedTileQueryTypes<'a> { + /// Query for tiles. + type TileQuery; + /// Query for chunks. + type ChunkQuery; + /// The map used. + type Map; +} /// Used to query individual tiles from a tile map. /// This query also implicitly queries chunks and maps /// in order to properly resolve tiles. #[derive(SystemParam)] -pub struct TileQuery<'w, 's, L, Q, F = (), const N: usize = 2> +pub struct TileMapQuery<'w, 's, Q, F = (), const N: usize = 2> where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, + Q: QueryData + 'static, + F: QueryFilter + 'static, { - tile_q: Query<'w, 's, Q, (F, With, With>)>, - chunk_q: Query<'w, 's, &'static Chunk, (With, With>)>, - map_q: Query<'w, 's, &'static TileMap, With>>, + tile_q: Query<'w, 's, Q, (F, With)>, + chunk_q: Query<'w, 's, &'static Chunk, With>, + map_q: Query<'w, 's, &'static TileMap>, } -impl<'w, 's, L, Q, F, const N: usize> Deref for TileQuery<'w, 's, L, Q, F, N> +impl<'w, 's, Q, F, const N: usize> TileMapQuery<'w, 's, Q, F, N> where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, + Q: QueryData + 'static, + F: QueryFilter + 'static, { - type Target = Query<'w, 's, Q, (F, With, With>)>; + /// Gets the query for a given map. + pub fn get_map( + &self, + map_id: Entity, + ) -> Option< + TileQuery< + &'_ Query<'w, 's, Q, (F, With)>, + &'_ Query<'w, 's, &'static Chunk, With>, + N, + >, + > { + let map = self.map_q.get(map_id).ok()?; + + Some(TileQuery { + tile_q: &self.tile_q, + chunk_q: &self.chunk_q, + map, + }) + } - fn deref(&self) -> &Self::Target { - &self.tile_q + /// Gets the query for a given map. + pub fn get_map_mut( + &mut self, + map_id: Entity, + ) -> Option< + TileQuery< + &'_ mut Query<'w, 's, Q, (F, With)>, + &'_ mut Query<'w, 's, &'static Chunk, With>, + N, + >, + > { + let map = self.map_q.get(map_id).ok()?; + + Some(TileQuery { + tile_q: &mut self.tile_q, + chunk_q: &mut self.chunk_q, + map, + }) } } -impl<'w, 's, L, Q, F, const N: usize> DerefMut for TileQuery<'w, 's, L, Q, F, N> -where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, -{ - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.tile_q - } +/// Queries a particular tilemap. +pub struct TileQuery<'a, T, C, const N: usize> { + tile_q: T, + chunk_q: C, + map: &'a TileMap, } -impl<'w, 's, L, Q, F, const N: usize> TileQuery<'w, 's, L, Q, F, N> +impl<'a, 'w: 'a, 's: 'a, Q, F, T, C, const N: usize> TileQuery<'a, T, C, N> where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, + T: Deref)>>, + C: Deref>>, + Q: QueryData + 'static, + F: QueryFilter + 'static, { - /// Get's the readonly query item for the given tile. - pub fn get_at( - &self, - tile_c: [isize; N], - ) -> Option<<::ReadOnly as WorldQuery>::Item<'_>> { - let map = self.map_q.get_single().ok()?; - let chunk_c = calculate_chunk_coordinate(tile_c, L::CHUNK_SIZE); - let chunk_e = map.chunks.get::>(&chunk_c.into())?; + fn get_tile_entity(&self, tile_c: [isize; N]) -> Option { + let chunk_size = self.map.get_chunk_size(); + let chunk_id = self.map.get_from_tile(TileCoord::(tile_c))?; - let chunk = self.chunk_q.get(*chunk_e).ok()?; - let tile_index = calculate_tile_index(tile_c, L::CHUNK_SIZE); - let tile_e = chunk.tiles.get(tile_index)?.as_ref()?; + let chunk = self.chunk_q.get(chunk_id).ok()?; + let tile_index = calculate_tile_index(tile_c, chunk_size); - self.tile_q.get(*tile_e).ok() + chunk.get(tile_index) } - /// Get's the query item for the given tile. - pub fn get_at_mut(&mut self, tile_c: [isize; N]) -> Option<::Item<'_>> { - let map = self.map_q.get_single().ok()?; - let chunk_c = calculate_chunk_coordinate(tile_c, L::CHUNK_SIZE); - let chunk_e = map.chunks.get::>(&chunk_c.into())?; - - let chunk = self.chunk_q.get(*chunk_e).ok()?; - let tile_i = calculate_tile_index(tile_c, L::CHUNK_SIZE); - let tile_e = chunk.tiles.get(tile_i)?.as_ref()?; - - self.tile_q.get_mut(*tile_e).ok() + /// Gets the readonly query item for the given tile. + pub fn get_at( + &self, + tile_c: [isize; N], + ) -> Option<<::ReadOnly as WorldQuery>::Item<'_>> { + let tile_e = self.get_tile_entity(tile_c)?; + self.tile_q.get(tile_e).ok() } - /// Get's the query item for the given tile. + /// Gets the query item for the given tile. /// # Safety /// This function makes it possible to violate Rust's aliasing guarantees: please use responsibly. pub unsafe fn get_at_unchecked( &self, tile_c: [isize; N], ) -> Option<::Item<'_>> { - let map = self.map_q.get_single().ok()?; - let chunk_c = calculate_chunk_coordinate(tile_c, L::CHUNK_SIZE); - let chunk_e = map.chunks.get::>(&chunk_c.into())?; - - let chunk = self.chunk_q.get(*chunk_e).ok()?; - let tile_i = calculate_tile_index(tile_c, L::CHUNK_SIZE); - let tile_e = chunk.tiles.get(tile_i)?.as_ref()?; - - self.tile_q.get_unchecked(*tile_e).ok() + let tile_e = self.get_tile_entity(tile_c)?; + self.tile_q.get_unchecked(tile_e).ok() } /// Iterate over all the tiles in a given space, starting at `corner_1` @@ -117,62 +184,23 @@ where &self, corner_1: [isize; N], corner_2: [isize; N], - ) -> TileQueryIter<'_, 's, L, Q, F, N> { + ) -> TileQueryIter<'_, 'a, T, C, N> { TileQueryIter::new(self, corner_1, corner_2) } - /// Iterate over all the tiles in a given space, starting at `corner_1` - /// inclusive over `corner_2` - pub fn iter_in_mut( - &mut self, - corner_1: [isize; N], - corner_2: [isize; N], - ) -> TileQueryIterMut<'_, 's, L, Q, F, N> { - // SAFETY: Use case is safe since this is the mut version and the function signature - // stops us from borrowing this mutably twice - unsafe { TileQueryIterMut::new(self, corner_1, corner_2) } - } - - /// Get the readonly version of this query. - pub fn to_readonly( - &self, - ) -> TileQuery<'_, 's, L, ::ReadOnly, ::ReadOnly, N> { - TileQuery::::ReadOnly, ::ReadOnly, N> { - tile_q: self.tile_q.to_readonly(), - chunk_q: self.chunk_q.to_readonly(), - map_q: self.map_q.to_readonly(), - } - } - /// Iter all tiles in a given chunk. /// # Note /// The coordinates for this function are givne in chunk coordinates. - pub fn iter_in_chunk(&self, chunk_c: [isize; N]) -> TileQueryIter<'_, 's, L, Q, F, N> { + pub fn iter_in_chunk(&self, chunk_c: [isize; N]) -> TileQueryIter<'_, 'a, T, C, N> { + let chunk_size = self.map.get_chunk_size(); // Get corners of chunk - let corner_1 = calculate_tile_coordinate(chunk_c, 0, L::CHUNK_SIZE); + let corner_1 = calculate_tile_coordinate(chunk_c, 0, chunk_size); let corner_2 = - calculate_tile_coordinate(chunk_c, max_tile_index::(L::CHUNK_SIZE), L::CHUNK_SIZE); + calculate_tile_coordinate(chunk_c, max_tile_index::(chunk_size), chunk_size); // Create tile iter TileQueryIter::new(self, corner_1, corner_2) } - /// Iter all tiles in a given chunk. - /// # Note - /// The coordinates for this function are givne in chunk coordinates. - pub fn iter_in_chunk_mut( - &mut self, - chunk_c: [isize; N], - ) -> TileQueryIterMut<'_, 's, L, Q, F, N> { - // Get corners of chunk - let corner_1 = calculate_tile_coordinate(chunk_c, 0, L::CHUNK_SIZE); - let corner_2 = - calculate_tile_coordinate(chunk_c, max_tile_index::(L::CHUNK_SIZE), L::CHUNK_SIZE); - - // SAFETY: Use case is safe since this is the mut version and the function signature - // stops us from borrowing this mutably twice - unsafe { TileQueryIterMut::new(self, corner_1, corner_2) } - } - /// Iter all tiles in the chunks in the given range. /// # Note /// The coordinates for this function are givne in chunk coordinates. @@ -180,14 +208,29 @@ where &mut self, chunk_c_1: [isize; N], chunk_c_2: [isize; N], - ) -> TileQueryIter<'_, 's, L, Q, F, N> { + ) -> TileQueryIter<'_, 'a, T, C, N> { + let chunk_size = self.map.get_chunk_size(); // Get corners of chunk - let corner_1 = calculate_tile_coordinate(chunk_c_1, 0, L::CHUNK_SIZE); + let corner_1 = calculate_tile_coordinate(chunk_c_1, 0, chunk_size); let corner_2 = - calculate_tile_coordinate(chunk_c_2, max_tile_index::(L::CHUNK_SIZE), L::CHUNK_SIZE); + calculate_tile_coordinate(chunk_c_2, max_tile_index::(chunk_size), chunk_size); // Create tile iter TileQueryIter::new(self, corner_1, corner_2) } +} + +impl<'a, 'w: 'a, 's: 'a, Q, F, T, C, const N: usize> TileQuery<'a, T, C, N> +where + T: DerefMut)>>, + C: DerefMut>>, + Q: QueryData + 'static, + F: QueryFilter + 'static, +{ + /// Gets the query item for the given tile. + pub fn get_at_mut(&mut self, tile_c: [isize; N]) -> Option<::Item<'_>> { + let tile_e = self.get_tile_entity(tile_c)?; + self.tile_q.get_mut(tile_e).ok() + } /// Iter all tiles in the chunks in the given range. /// # Note @@ -196,44 +239,48 @@ where &mut self, chunk_c_1: [isize; N], chunk_c_2: [isize; N], - ) -> TileQueryIterMut<'_, 's, L, Q, F, N> { + ) -> TileQueryIterMut<'_, 'a, T, C, N> { + let chunk_size = self.map.get_chunk_size(); + // Get corners of chunk + let corner_1 = calculate_tile_coordinate(chunk_c_1, 0, chunk_size); + let corner_2 = + calculate_tile_coordinate(chunk_c_2, max_tile_index::(chunk_size), chunk_size); + + TileQueryIterMut::new(self, corner_1, corner_2) + } + + /// Iter all tiles in a given chunk. + /// # Note + /// The coordinates for this function are givne in chunk coordinates. + pub fn iter_in_chunk_mut(&mut self, chunk_c: [isize; N]) -> TileQueryIterMut<'_, 'a, T, C, N> { + let chunk_size = self.map.get_chunk_size(); // Get corners of chunk - let corner_1 = calculate_tile_coordinate(chunk_c_1, 0, L::CHUNK_SIZE); + let corner_1 = calculate_tile_coordinate(chunk_c, 0, chunk_size); let corner_2 = - calculate_tile_coordinate(chunk_c_2, max_tile_index::(L::CHUNK_SIZE), L::CHUNK_SIZE); + calculate_tile_coordinate(chunk_c, max_tile_index::(chunk_size), chunk_size); - // SAFETY: Use case is safe since this is the mut version and the function signature - // stops us from borrowing this mutably twice - unsafe { TileQueryIterMut::new(self, corner_1, corner_2) } + TileQueryIterMut::new(self, corner_1, corner_2) + } + + /// Iterate over all the tiles in a given space, starting at `corner_1` + /// inclusive over `corner_2` + pub fn iter_in_mut( + &mut self, + corner_1: [isize; N], + corner_2: [isize; N], + ) -> TileQueryIterMut<'_, 'a, T, C, N> { + TileQueryIterMut::new(self, corner_1, corner_2) } } /// Iterates over all the tiles in a region. -pub struct TileQueryIter<'w, 's, L, Q, F, const N: usize> -where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, -{ +pub struct TileQueryIter<'i, 'a, T, C, const N: usize> { coord_iter: CoordIterator, - tile_q: &'w TileQuery<'w, 's, L, Q, F, N>, + tile_q: &'i TileQuery<'a, T, C, N>, } -impl<'w, 's, L, Q, F, const N: usize> TileQueryIter<'w, 's, L, Q, F, N> -where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, -{ - /// # Safety - /// This iterator uses unchecked get's to get around some lifetime issue I don't understand yet. - /// Due to this, you should only call this constructor from a context where the query is actually - /// borrowed mutabley. - fn new( - tile_q: &'w TileQuery<'w, 's, L, Q, F, N>, - corner_1: [isize; N], - corner_2: [isize; N], - ) -> Self { +impl<'i, 'a: 'i, T, C, const N: usize> TileQueryIter<'i, 'a, T, C, N> { + fn new(tile_q: &'i TileQuery<'a, T, C, N>, corner_1: [isize; N], corner_2: [isize; N]) -> Self { Self { tile_q, coord_iter: CoordIterator::new(corner_1, corner_2), @@ -241,18 +288,19 @@ where } } -impl<'w, 's, L, Q, F, const N: usize> Iterator for TileQueryIter<'w, 's, L, Q, F, N> +impl<'i, 'a: 'i, 'w: 'a, 's: 'a, Q, F, T, C, const N: usize> Iterator + for TileQueryIter<'i, 'a, T, C, N> where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, + T: Deref)>>, + C: Deref>>, + Q: QueryData + 'static, + F: QueryFilter + 'static, { - type Item = <::ReadOnly as WorldQuery>::Item<'w>; + type Item = <::ReadOnly as WorldQuery>::Item<'i>; #[allow(clippy::while_let_on_iterator)] fn next(&mut self) -> Option { while let Some(target) = self.coord_iter.next() { - // This fixes some lifetime issue that I'm not sure I understand quite yet, will do testing let tile = self.tile_q.get_at(target); if tile.is_some() { return tile; @@ -272,28 +320,15 @@ where ///# let _ = iter_2.next(); ///# } /// ``` -pub struct TileQueryIterMut<'w, 's, L, Q, F, const N: usize> -where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, -{ +/// Iterates over all the tiles in a region. +pub struct TileQueryIterMut<'i, 'a, T, C, const N: usize> { coord_iter: CoordIterator, - tile_q: &'w TileQuery<'w, 's, L, Q, F, N>, + tile_q: &'i TileQuery<'a, T, C, N>, } -impl<'w, 's, L, Q, F, const N: usize> TileQueryIterMut<'w, 's, L, Q, F, N> -where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, -{ - /// # Safety - /// This iterator uses unchecked get's to get around some lifetime issue I don't understand yet. - /// Due to this, you should only call this constructor from a context where the query is actually - /// borrowed mutabley. - unsafe fn new( - tile_q: &'w TileQuery<'w, 's, L, Q, F, N>, +impl<'i, 'a: 'i, T, C, const N: usize> TileQueryIterMut<'i, 'a, T, C, N> { + fn new( + tile_q: &'i mut TileQuery<'a, T, C, N>, corner_1: [isize; N], corner_2: [isize; N], ) -> Self { @@ -304,18 +339,20 @@ where } } -impl<'w, 's, L, Q, F, const N: usize> Iterator for TileQueryIterMut<'w, 's, L, Q, F, N> +impl<'i, 'a: 'i, 'w: 'a, 's: 'a, Q, F, T, C, const N: usize> Iterator + for TileQueryIterMut<'i, 'a, T, C, N> where - L: TileMapLabel + 'static, - Q: WorldQuery + 'static, - F: ReadOnlyWorldQuery + 'static, + T: DerefMut)>>, + C: Deref>>, + Q: QueryData + 'static, + F: QueryFilter + 'static, { - type Item = ::Item<'w>; + type Item = ::Item<'i>; #[allow(clippy::while_let_on_iterator)] fn next(&mut self) -> Option { while let Some(target) = self.coord_iter.next() { - // SAFETY: This fixes some lifetime issue that I'm not sure I understand quite yet, will do testing + // SAFETY: This is safe as long as new always requires a mutable reference let tile = unsafe { self.tile_q.get_at_unchecked(target) }; if tile.is_some() { return tile; diff --git a/crates/bevy_tiles_render/Cargo.toml b/crates/bevy_tiles_render/Cargo.toml deleted file mode 100644 index 20f1f21..0000000 --- a/crates/bevy_tiles_render/Cargo.toml +++ /dev/null @@ -1,38 +0,0 @@ -[package] -name = "bevy_tiles_render" -version = "0.1.0" -edition = "2021" -authors = ["James Bell "] -license = "MIT" -license-file = "LICENSE-MIT" -description = "Bevy library for working with entities in grids." -repository = "https://github.com/OxidizedGames/bevy_bevy_tiles_render" -homepage = "https://github.com/OxidizedGames/bevy_bevy_tiles_render" - -[features] -atlas = [] - -[profile.dev] -opt-level = 1 - -[profile.dev.package."*"] -opt-level = 3 - -[dependencies] -bevy = { workspace = true, features = [ - "bevy_core_pipeline", - "bevy_render", - "bevy_asset", - "bevy_sprite", -] } -bevy_tiles = {path = "../bevy_tiles"} -crossbeam = {workspace = true} -dashmap = {workspace = true} - -[dev-dependencies] -rstest = {workspace = true} -bevy = {workspace = true, default-features = true} -rand = {workspace = true} - -[lints] -workspace = true \ No newline at end of file diff --git a/crates/bevy_tiles_render/README.md b/crates/bevy_tiles_render/README.md deleted file mode 100644 index 1d51892..0000000 --- a/crates/bevy_tiles_render/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# `bevy_tiles_render` - -Rendering plugin for the bevy game engine, built on top of `bevy_tiles`. - -# Features - -Supports: -* Square Tilemaps. -* Isometric Tilemaps. -* Hex Tilemaps. -* Tile animation. - -# How it Works - -In `bevy_tiles`, each tile is automatically part of a chunk. Each frame, if a tile in a chunk has changed, -we can regenerate the render mesh for all the tiles in a chunk, stick it on the chunk, then send it to the render app. -This allows for more efficient rendering, and has the added benefit of letting you remove a chunk from the map, but keeping -the render mesh, allowing for higher performance in large static chunk scenarios. - -# Why use this over X? - -The goal of the `bevy_tiles` project is to be the most erganomic and natural to use tile solution in the bevy game engine. -Querying for a tile or group of tiles should look as similar as possible to querying for a non tiled entity, and should -look almost native to bevy from a code perspective. - -# Why not use this over X? - -This is a relatively new bundle of crates, and probably has some rough edges or missing features. I (we, I'd love some help) will -get to a lot of features in the future, but it will take time and effort! \ No newline at end of file diff --git a/crates/bevy_tiles_render/assets/block.png b/crates/bevy_tiles_render/assets/block.png deleted file mode 100644 index 72700d39ddb87dc804dfb183aaa76055dcfb73db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|nmt_{Lo9le zQxXz>oOfVMNK8mb=&=9YqH~tJH&uZxW{yq&!5h1#shq9vnP+4G0uxhBg%TXaEvmOj zu4gNmo+Png{_GT4Akg`E=0>Q$+98H%#g{B{4^N9) r`JB~BQ$Y5Gw5lQ4Fr$DOa~Ut~l(_Q$#k8eB=P-D>`njxgN@xNA(g#KJ diff --git a/crates/bevy_tiles_render/assets/character.png b/crates/bevy_tiles_render/assets/character.png deleted file mode 100644 index b78bec7d9a981bc0f093401b615090d583fabb5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 265 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|4tu&dhFJ6_ zCrEs15S-q^B7eWWWTW_eyTld8vl@WB|LMn{C3JX4E=`a)jg75Md+tLCy~73! zcinPw7V#>uJuqdssl8*5YoWrXgv)EpZ#Nx$tW_p`k+Dl$<;RbI_En$T61^XYwdIS? zFcitZxj{x*%pit=`HuU3BLf*%;hX~@?SgDVH8uag^72UN#qDTN;uAhRO)Ajjzm@Ly z|JO5j{y*V2^}*xc{}h diff --git a/crates/bevy_tiles_render/examples/hello_tile.rs b/crates/bevy_tiles_render/examples/hello_tile.rs deleted file mode 100644 index 2e7d5ec..0000000 --- a/crates/bevy_tiles_render/examples/hello_tile.rs +++ /dev/null @@ -1,80 +0,0 @@ -use std::iter::repeat_with; - -use bevy::{ - app::{App, Startup, Update}, - core_pipeline::core_2d::Camera2dBundle, - diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, - ecs::system::Commands, - math::{Quat, Vec3}, - render::camera::OrthographicProjection, - transform::{ - components::{GlobalTransform, Transform}, - TransformBundle, - }, - DefaultPlugins, -}; -use bevy_tiles::{ - commands::TileCommandExt, coords::CoordIterator, maps::TileMapLabel, TilesPlugin, -}; -use bevy_tiles_render::{ - maps::{TileGridSize, TileMapRenderer, TileMapRenderingBundle, TileSize}, - TilesRenderPlugin, -}; -use rand::Rng; - -fn main() { - App::new() - .add_plugins(( - DefaultPlugins, - FrameTimeDiagnosticsPlugin, - LogDiagnosticsPlugin::default(), - )) - .add_plugins((TilesPlugin, TilesRenderPlugin)) - .add_systems(Startup, spawn) - .add_systems(Update, change_map) - .run(); -} - -struct GameLayer; - -impl TileMapLabel for GameLayer { - const CHUNK_SIZE: usize = 128; -} - -fn spawn(mut commands: Commands) { - let mut tile_commands = commands.tiles::(); - tile_commands.spawn_map(TileMapRenderingBundle { - tile_size: TileSize(16.0), - grid_size: TileGridSize(18.0), - tile_map_renderer: TileMapRenderer { batch_size: 512 }, - ..Default::default() - }); - - commands.spawn(Camera2dBundle { - projection: OrthographicProjection { - scale: 10.0, - far: 1000.0, - near: -1000.0, - ..Default::default() - }, - ..Default::default() - }); -} - -fn change_map(mut commands: Commands) { - let mut rng = rand::thread_rng(); - let changes = rng.gen_range(500..1000); - let mut tile_commands = commands.tiles::(); - - let spawn = rng.gen_bool(0.5); - - let tiles = Vec::from_iter( - repeat_with(|| [rng.gen_range(-1000..1000), rng.gen_range(-1000..1000)]).take(changes), - ); - - if spawn { - tile_commands.spawn_tile_batch(tiles, |_| ()) - } else { - tile_commands.despawn_tile_batch(tiles) - } -} diff --git a/crates/bevy_tiles_render/src/bindings.rs b/crates/bevy_tiles_render/src/bindings.rs deleted file mode 100644 index 060d9c8..0000000 --- a/crates/bevy_tiles_render/src/bindings.rs +++ /dev/null @@ -1,262 +0,0 @@ -use std::num::NonZeroU64; - -use bevy::{ - ecs::{component::Component, world::FromWorld}, - log::debug, - math::{Affine3, Vec2, Vec4}, - render::{ - render_resource::{ - BindGroup, BindGroupEntries, BindGroupLayout, BindGroupLayoutDescriptor, - BindGroupLayoutEntry, BindingType, Buffer, BufferAddress, BufferBindingType, - BufferDescriptor, BufferInitDescriptor, BufferUsages, CommandEncoder, ShaderSize, - ShaderStages, ShaderType, StorageBuffer, UniformBuffer, - }, - renderer::{RenderDevice, RenderQueue}, - }, - transform::components::GlobalTransform, -}; - -use crate::{ - buffer_helpers::*, - chunk::{self, internal::ChunkUniforms}, - maps::internal::MapInfo, -}; - -#[derive(Component)] -pub struct ChunkBatchBindGroups { - pub map_bind_group: BindGroup, - pub chunk_bind_group: BindGroup, -} - -/// Contains all the data for an individual chunk that can be -/// consolidated into the batch buffers. -#[derive(Component)] -pub struct ChunkBuffer { - pub chunk_offset: Vec2, - pub tile_instances: GpuStorageBuffer, -} - -impl ChunkBuffer { - pub fn new(chunk_uniforms: &mut ChunkUniforms) -> Self { - Self { - chunk_offset: Vec2::from(&chunk_uniforms.chunk_coord), - tile_instances: GpuStorageBuffer::::from( - chunk_uniforms - .tile_instances - .take() - .expect("Couldn't find TileInstances"), - ), - } - } - - pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) { - self.tile_instances.write_buffer(device, queue); - } -} - -#[derive(Component)] -pub struct ChunkBatchBuffer { - total_chunk_size: u64, - batch_size: u64, - pub chunk_offsets: GpuStorageBuffer, - pub tile_instances: Buffer, -} - -impl ChunkBatchBuffer { - pub fn with_size_no_default_values( - batch_size: usize, - chunk_size: usize, - device: &RenderDevice, - ) -> Self { - let total_chunk_size = chunk_size as u64 * chunk_size as u64; - Self { - total_chunk_size, - batch_size: batch_size as u64, - chunk_offsets: GpuStorageBuffer::::default(), - tile_instances: device.create_buffer(&BufferDescriptor { - label: None, - size: total_chunk_size * batch_size as u64 * u32::SHADER_SIZE.get(), - usage: BufferUsages::COPY_DST | BufferUsages::STORAGE, - mapped_at_creation: false, - }), - } - } - - /// # Note - /// after call push, write_buffer needs to be called as well as using the commands - /// from the command encoders to finish the copying. - pub fn push(&mut self, command_encoder: &mut CommandEncoder, chunk_buffer: &ChunkBuffer) { - let index = self.chunk_offsets.push(chunk_buffer.chunk_offset); - command_encoder.copy_buffer_to_buffer( - chunk_buffer.tile_instances.gpu_buffer().unwrap(), - 0, - &self.tile_instances, - index.get() as u64 * self.total_chunk_size * u32::SHADER_SIZE.get(), - self.total_chunk_size * u32::SHADER_SIZE.get(), - ) - } - - pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) { - self.chunk_offsets.write_buffer(device, queue); - } - - pub fn bindings(&self) -> BindGroupEntries<2> { - BindGroupEntries::with_indices(( - (0, self.chunk_offsets.binding().unwrap()), - (1, self.tile_instances.as_entire_binding()), - )) - } - - pub fn layout_entries() -> Vec { - vec![ - // off_sets - GpuStorageBuffer::::binding_layout(0, ShaderStages::VERTEX_FRAGMENT), - BindGroupLayoutEntry { - binding: 1, - visibility: ShaderStages::VERTEX_FRAGMENT, - ty: BindingType::Buffer { - ty: BufferBindingType::Storage { read_only: true }, - has_dynamic_offset: false, - min_binding_size: Some(u32::min_size()), - }, - count: None, - }, - ] - } -} - -#[derive(Component)] -pub struct MapBatchBuffer { - chunk_size: UniformBuffer, - tile_size: UniformBuffer, - grid_size: UniformBuffer, - transform: UniformBuffer, -} - -impl MapBatchBuffer { - pub fn new(map_info: &MapInfo) -> Self { - Self { - chunk_size: map_info.chunk_size.into(), - tile_size: map_info.tile_size.0.into(), - grid_size: map_info.grid_size.0.into(), - transform: MapTransformUniform::from(&map_info.transform).into(), - } - } - - pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) { - self.chunk_size.write_buffer(device, queue); - self.transform.write_buffer(device, queue); - self.tile_size.write_buffer(device, queue); - self.grid_size.write_buffer(device, queue); - } - - pub fn bindings(&self) -> BindGroupEntries<4> { - BindGroupEntries::with_indices(( - (0, self.transform.binding().unwrap()), - (1, self.chunk_size.binding().unwrap()), - (2, self.tile_size.binding().unwrap()), - (3, self.grid_size.binding().unwrap()), - )) - } - - pub fn layout_entries() -> Vec { - vec![ - // transform - BindGroupLayoutEntry { - binding: 0, - visibility: ShaderStages::VERTEX_FRAGMENT, - ty: BindingType::Buffer { - ty: BufferBindingType::Uniform, - has_dynamic_offset: false, - min_binding_size: Some(MapTransformUniform::SHADER_SIZE), - }, - count: None, - }, - // chunk_size - BindGroupLayoutEntry { - binding: 1, - visibility: ShaderStages::VERTEX_FRAGMENT, - ty: BindingType::Buffer { - ty: BufferBindingType::Uniform, - has_dynamic_offset: false, - min_binding_size: Some(u32::SHADER_SIZE), - }, - count: None, - }, - // tile_size - BindGroupLayoutEntry { - binding: 2, - visibility: ShaderStages::VERTEX_FRAGMENT, - ty: BindingType::Buffer { - ty: BufferBindingType::Uniform, - has_dynamic_offset: false, - min_binding_size: Some(f32::SHADER_SIZE), - }, - count: None, - }, - // grid_size - BindGroupLayoutEntry { - binding: 3, - visibility: ShaderStages::VERTEX_FRAGMENT, - ty: BindingType::Buffer { - ty: BufferBindingType::Uniform, - has_dynamic_offset: false, - min_binding_size: Some(f32::SHADER_SIZE), - }, - count: None, - }, - ] - } -} - -#[derive(ShaderType, Clone, Default)] -pub struct MapTransformUniform { - // Affine 4x3 matrix transposed to 3x4 - pub transform: [Vec4; 3], - // 3x3 matrix packed in mat2x4 and f32 as: - // [0].xyz, [1].x, - // [1].yz, [2].xy - // [2].z - pub inverse_transpose_model_a: [Vec4; 2], - pub inverse_transpose_model_b: f32, -} - -impl From<&GlobalTransform> for MapTransformUniform { - fn from(value: &GlobalTransform) -> Self { - let affine = Affine3::from(&value.affine()); - let (inverse_transpose_model_a, inverse_transpose_model_b) = affine.inverse_transpose_3x3(); - Self { - transform: affine.to_transpose(), - inverse_transpose_model_a, - inverse_transpose_model_b, - } - } -} - -pub struct ChunkBatchBindGroupLayouts { - pub map_layouts: BindGroupLayout, - pub chunk_layouts: BindGroupLayout, -} - -impl FromWorld for ChunkBatchBindGroupLayouts { - fn from_world(world: &mut bevy::prelude::World) -> Self { - let device = world - .get_resource::() - .expect("No render device found!"); - - let map_layouts = device.create_bind_group_layout(&BindGroupLayoutDescriptor { - label: Some("bevy_tiles_map_bind_group"), - entries: &MapBatchBuffer::layout_entries(), - }); - - let chunk_layouts = device.create_bind_group_layout(&BindGroupLayoutDescriptor { - label: Some("bevy_tiles_chunk_bind_group"), - entries: &ChunkBatchBuffer::layout_entries(), - }); - - Self { - map_layouts, - chunk_layouts, - } - } -} diff --git a/crates/bevy_tiles_render/src/buffer_helpers/gpu_storage_buffer.rs b/crates/bevy_tiles_render/src/buffer_helpers/gpu_storage_buffer.rs deleted file mode 100644 index b07df95..0000000 --- a/crates/bevy_tiles_render/src/buffer_helpers/gpu_storage_buffer.rs +++ /dev/null @@ -1,104 +0,0 @@ -use std::{marker::PhantomData, mem}; - -use bevy::{ - ecs::{component::Component, system::Resource, world::FromWorld}, - render::{ - render_resource::{ - BindGroupLayoutEntry, BindingResource, BindingType, Buffer, BufferBindingType, - BufferUsages, GpuArrayBufferable, ShaderStages, StorageBuffer, - }, - renderer::{RenderDevice, RenderQueue}, - }, - utils::nonmax::NonMaxU32, -}; - -/// Stores an array of elements to be transferred to the GPU and made accessible to shaders as a read-only array. -/// This is modified from bevy's GpuArrayBuffer -pub struct GpuStorageBuffer { - gpu_buffer: StorageBuffer>, - buffer: Vec, -} - -impl From> for GpuStorageBuffer { - fn from(value: Vec) -> Self { - let mut gpu_buffer: StorageBuffer> = Default::default(); - gpu_buffer.add_usages(BufferUsages::COPY_SRC); - Self { - gpu_buffer, - buffer: value, - } - } -} - -impl Default for GpuStorageBuffer { - fn default() -> Self { - let mut gpu_buffer: StorageBuffer> = Default::default(); - gpu_buffer.add_usages(BufferUsages::COPY_SRC); - Self { - gpu_buffer, - buffer: Default::default(), - } - } -} - -impl GpuStorageBuffer { - pub fn clear(&mut self) { - self.buffer.clear() - } - - pub fn gpu_buffer(&self) -> Option<&Buffer> { - self.gpu_buffer.buffer() - } - - pub fn push(&mut self, value: T) -> NonMaxU32 { - let index = NonMaxU32::new(self.buffer.len() as u32).unwrap(); - self.buffer.push(value); - index - } - - pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) { - self.gpu_buffer.set(mem::take(&mut self.buffer)); - self.gpu_buffer.write_buffer(device, queue); - } - - pub fn binding_layout(binding: u32, visibility: ShaderStages) -> BindGroupLayoutEntry { - BindGroupLayoutEntry { - binding, - visibility, - ty: BindingType::Buffer { - ty: BufferBindingType::Storage { read_only: true }, - has_dynamic_offset: false, - min_binding_size: Some(T::min_size()), - }, - count: None, - } - } - - pub fn binding(&self) -> Option { - self.gpu_buffer.binding() - } - pub fn insert(&mut self, index: usize, value: T) { - *self.buffer.get_mut(index).unwrap() = value; - } - - // Fails if used on the wrong size buffer - /// SAFETY: Use carefully, this is to allow for parallel writes to sections of a buffer. - pub unsafe fn raw_insert(&self, index: usize, value: T) { - let spot: *const T = self.buffer.get(index).unwrap(); - let spot: *mut T = spot as *mut T; - *spot = value; - } -} - -impl GpuStorageBuffer -where - T: Default, -{ - /// Creates a buffer of the given size filled with default values - pub fn with_size(size: usize) -> Self { - Self { - buffer: vec![T::default(); size], - gpu_buffer: Default::default(), - } - } -} diff --git a/crates/bevy_tiles_render/src/buffer_helpers/mod.rs b/crates/bevy_tiles_render/src/buffer_helpers/mod.rs deleted file mode 100644 index 0ad7685..0000000 --- a/crates/bevy_tiles_render/src/buffer_helpers/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod gpu_storage_buffer; - -pub use gpu_storage_buffer::*; diff --git a/crates/bevy_tiles_render/src/chunk/internal.rs b/crates/bevy_tiles_render/src/chunk/internal.rs deleted file mode 100644 index d8c42d6..0000000 --- a/crates/bevy_tiles_render/src/chunk/internal.rs +++ /dev/null @@ -1,27 +0,0 @@ -use bevy::{ - ecs::{component::Component, entity::Entity, system::Resource}, - prelude::{Deref, DerefMut}, -}; -use bevy_tiles::chunks::ChunkCoord; -use dashmap::DashMap; - -use crate::bindings::ChunkBuffer; - -#[derive(Default, Resource, Deref, DerefMut)] -pub struct SavedChunks(DashMap); - -#[derive(Component, Deref)] -pub struct BatchSize(pub u32); - -/// Holds a reference to the batch this chunk is in -#[derive(Component, Deref, Clone)] -pub struct ChunkBatch(pub Entity); - -/// Data needed to render a chunk in the batched chunk rendering pipeline. -/// This needs to be able to be instantiated in the extract stage and should -/// not have knowledge of the batch it's in. -#[derive(Debug, Component)] -pub struct ChunkUniforms { - pub chunk_coord: ChunkCoord, - pub tile_instances: Option>, -} diff --git a/crates/bevy_tiles_render/src/chunk/mod.rs b/crates/bevy_tiles_render/src/chunk/mod.rs deleted file mode 100644 index ef77e6c..0000000 --- a/crates/bevy_tiles_render/src/chunk/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! Components that can affect chunk rendering - -/// Components used by rendering pipeline -pub(crate) mod internal; diff --git a/crates/bevy_tiles_render/src/cleanup.rs b/crates/bevy_tiles_render/src/cleanup.rs deleted file mode 100644 index 7dd5900..0000000 --- a/crates/bevy_tiles_render/src/cleanup.rs +++ /dev/null @@ -1,38 +0,0 @@ -use bevy::ecs::{entity::Entity, query::With, system::ResMut, world::World}; - -use crate::{ - bindings::ChunkBuffer, - chunk::internal::SavedChunks, - maps::internal::{MapInfo, SavedMaps}, -}; - -pub fn save_chunks(mut world: &mut World) { - // Get the map id's we need - let map_ids: Vec = world - .query_filtered::>() - .iter(world) - .collect(); - - // Get the chunk id's we need - let chunk_ids: Vec = world - .query_filtered::>() - .iter(world) - .collect(); - - // Remove the map entities and put them into our hashmap - let mut saved_maps = SavedMaps::default(); - for map_id in map_ids.into_iter() { - let mut map = world.entity_mut(map_id); - saved_maps.insert(map_id, map.take::().unwrap()); - } - - // Remove the chunk entities and put them into our hashmap - let mut saved_chunks = SavedChunks::default(); - for chunk_id in chunk_ids.into_iter() { - let mut chunk = world.entity_mut(chunk_id); - saved_chunks.insert(chunk_id, chunk.take::().unwrap()); - } - - world.insert_resource(saved_maps); - world.insert_resource(saved_chunks); -} diff --git a/crates/bevy_tiles_render/src/draw.rs b/crates/bevy_tiles_render/src/draw.rs deleted file mode 100644 index 5b4caeb..0000000 --- a/crates/bevy_tiles_render/src/draw.rs +++ /dev/null @@ -1,120 +0,0 @@ -//! Contains commands given to the Transparent2D render step -//! to draw tiles. -//! -//! In order to batch draw calls of batched chunk draws (used for larger scenes if for lower memory situations) -//! the draw commands consist of copying individual chunk buffers to the various instance buffers before -//! issuing a draw call for a given batch of chunks. -use bevy::{ - core_pipeline::core_2d::Transparent2d, - ecs::{ - query::ROQueryItem, - system::{lifetimeless::Read, SystemParamItem}, - }, - log::debug, - render::render_phase::{ - PhaseItem, RenderCommand, RenderCommandResult, SetItemPipeline, TrackedRenderPass, - }, - sprite::SetMesh2dViewBindGroup, -}; - -use crate::{bindings::ChunkBatchBindGroups, chunk::internal::BatchSize, maps::internal::MapInfo}; - -pub type DrawChunks = ( - SetItemPipeline, - SetMesh2dViewBindGroup<0>, - SetMapBindGroup<1>, - SetChunkBindGroup<2>, - DrawChunkBatch, -); - -pub struct SetMapBindGroup; -impl RenderCommand for SetMapBindGroup { - type Param = (); - - type ViewWorldQuery = (); - - type ItemWorldQuery = Read; - - #[inline] - fn render<'w>( - item: &Transparent2d, - _view: (), - bind_groups: ROQueryItem<'w, Self::ItemWorldQuery>, - _: SystemParamItem<'w, '_, Self::Param>, - pass: &mut TrackedRenderPass<'w>, - ) -> RenderCommandResult { - debug!("Setting Chunk Map Level Bind Groups"); - - let mut dynamic_offsets: [u32; 1] = Default::default(); - let mut offset_count = 0; - if let Some(dynamic_offset) = item.dynamic_offset() { - dynamic_offsets[offset_count] = dynamic_offset.get(); - offset_count += 1; - } - - pass.set_bind_group( - I, - &bind_groups.map_bind_group, - &dynamic_offsets[..offset_count], - ); - RenderCommandResult::Success - } -} - -pub struct SetChunkBindGroup; -impl RenderCommand for SetChunkBindGroup { - type Param = (); - - type ViewWorldQuery = (); - - type ItemWorldQuery = Read; - - #[inline] - fn render<'w>( - item: &Transparent2d, - _view: (), - bind_groups: ROQueryItem<'w, Self::ItemWorldQuery>, - _: SystemParamItem<'w, '_, Self::Param>, - pass: &mut TrackedRenderPass<'w>, - ) -> RenderCommandResult { - debug!("Setting Chunk Level Bind Groups"); - - let mut dynamic_offsets: [u32; 1] = Default::default(); - let mut offset_count = 0; - if let Some(dynamic_offset) = item.dynamic_offset() { - dynamic_offsets[offset_count] = dynamic_offset.get(); - offset_count += 1; - } - - pass.set_bind_group( - I, - &bind_groups.chunk_bind_group, - &dynamic_offsets[..offset_count], - ); - RenderCommandResult::Success - } -} - -pub struct DrawChunkBatch; -impl RenderCommand for DrawChunkBatch { - type Param = (); - - type ViewWorldQuery = (); - - type ItemWorldQuery = (Read, Read); - - #[inline] - fn render<'w>( - item: &Transparent2d, - _view: ROQueryItem<'w, Self::ViewWorldQuery>, - (map_info, batch_size): ROQueryItem<'w, Self::ItemWorldQuery>, - _: SystemParamItem<'w, '_, Self::Param>, - pass: &mut TrackedRenderPass<'w>, - ) -> RenderCommandResult { - pass.draw( - 0..(map_info.chunk_size * map_info.chunk_size * 6), - 0..**batch_size, - ); - RenderCommandResult::Success - } -} diff --git a/crates/bevy_tiles_render/src/extract.rs b/crates/bevy_tiles_render/src/extract.rs deleted file mode 100644 index ba8d2ce..0000000 --- a/crates/bevy_tiles_render/src/extract.rs +++ /dev/null @@ -1,136 +0,0 @@ -use bevy::{ - ecs::{ - entity::Entity, - query::{Changed, With}, - system::{Commands, Query, ResMut}, - }, - render::Extract, - transform::components::GlobalTransform, - utils::hashbrown::HashMap, -}; -use bevy_tiles::{ - chunks::{Chunk, ChunkCoord, InMap}, - maps::TileMap, - tiles::{InChunk, TileIndex}, -}; -use crossbeam::queue::ArrayQueue; - -use crate::{ - chunk::internal::{ChunkUniforms, SavedChunks}, - maps::{ - internal::{MapChunks, MapInfo, SavedMaps}, - TileGridSize, TileMapRenderer, TileSize, - }, -}; - -pub fn extract_chunks( - mut commands: Commands, - mut saved_maps: ResMut, - mut saved_chunks: ResMut, - maps: Extract< - Query<( - Entity, - &TileMap, - &TileMapRenderer, - Option<&GlobalTransform>, - Option<&TileSize>, - Option<&TileGridSize>, - )>, - >, - changed_maps: Extract< - Query< - (), - ( - Changed, - Changed, - Changed, - Changed, - Changed, - ), - >, - >, - chunks: Extract>, - changed_chunks: Extract, Changed, Changed)>>, - tiles: Extract>>, - changed_tiles: Extract>>, -) { - let maps_iter = maps.iter(); - let mut extracted_maps = Vec::with_capacity(maps_iter.len()); - let mut map_chunks: HashMap<_, _> = - HashMap::::with_capacity(maps_iter.len()); - - for (map_id, map, renderer, transform, tile_size, grid_size) in maps_iter { - map_chunks.insert(map_id, MapChunks::default()); - if let Some(saved_map) = saved_maps.remove(&map_id) { - if !changed_maps.contains(map_id) { - extracted_maps.push(saved_map); - continue; - } - } - let transform = transform.cloned().unwrap_or_default(); - let tile_size = tile_size.cloned().unwrap_or_default(); - let grid_size = grid_size.cloned().unwrap_or_default(); - extracted_maps.push(( - map_id, - MapInfo { - chunk_size: map.chunk_size as u32, - tile_map_renderer: renderer.clone(), - tile_size, - grid_size, - transform, - }, - )); - } - commands.insert_or_spawn_batch(extracted_maps); - - let chunks_len = chunks.iter().len(); - if chunks_len == 0 { - return; - } - let extracted_chunks = ArrayQueue::new(chunks_len); - let extracted_saved_chunks = ArrayQueue::new(chunks_len); - let chunk_edges = ArrayQueue::new(chunks_len); - - changed_tiles.iter().for_each(|in_chunk| { - saved_chunks.remove(&in_chunk.get()); - }); - - chunks - .par_iter() - .for_each(|(chunk_id, in_map, chunk, chunk_coord)| { - map_chunks.get(&in_map.get()).unwrap().push(chunk_id); - chunk_edges.push((chunk_id, in_map.clone())); - - // TODO: Check if it's changed - if let Some(chunk) = saved_chunks.remove(&chunk_id) { - if !changed_chunks.contains(chunk_id) { - extracted_saved_chunks.push(chunk); - return; - } - } - - let mut extracted_tile_instances = Vec::with_capacity(chunk.total_size()); - - for tile in chunk.get_tiles() { - if tile.and_then(|tile_id| tiles.get(tile_id).ok()).is_some() { - extracted_tile_instances.push(1); - } else { - extracted_tile_instances.push(0); - } - } - - extracted_chunks - .push(( - chunk_id, - ChunkUniforms { - chunk_coord: *chunk_coord, - tile_instances: Some(extracted_tile_instances), - }, - )) - .expect("Failed to extract chunk: {:?}"); - }); - - commands.insert_or_spawn_batch(extracted_saved_chunks); - commands.insert_or_spawn_batch(extracted_chunks); - commands.insert_or_spawn_batch(map_chunks); -} diff --git a/crates/bevy_tiles_render/src/lib.rs b/crates/bevy_tiles_render/src/lib.rs deleted file mode 100644 index 4e40e16..0000000 --- a/crates/bevy_tiles_render/src/lib.rs +++ /dev/null @@ -1,93 +0,0 @@ -use bevy::{ - app::Plugin, - asset::{load_internal_asset, Handle}, - core_pipeline::core_2d::Transparent2d, - ecs::schedule::{apply_deferred, IntoSystemConfigs}, - render::{ - render_phase::AddRenderCommand, - render_resource::{Shader, SpecializedRenderPipelines}, - ExtractSchedule, Render, RenderApp, RenderSet, - }, -}; - -use chunk::internal::SavedChunks; -use cleanup::save_chunks; -use extract::extract_chunks; -use maps::internal::SavedMaps; -use prepare::{create_bind_groups, prepare_chunk_batch, prepare_chunks}; -use queue::{create_chunk_batches, queue_chunks}; - -use crate::{draw::DrawChunks, pipeline::TilesChunkPipeline}; - -mod bindings; -mod buffer_helpers; -pub mod chunk; -mod cleanup; -mod draw; -mod extract; -pub mod maps; -mod pipeline; -mod prepare; -mod queue; -pub mod tiles; - -const TILES_VERT: Handle = Handle::weak_from_u128(163058266501073814892310220797241232500); -const TILES_FRAG: Handle = Handle::weak_from_u128(163058266501073814892310220797241232501); - -pub struct TilesRenderPlugin; - -impl Plugin for TilesRenderPlugin { - fn build(&self, app: &mut bevy::prelude::App) { - let render_app = app.get_sub_app_mut(RenderApp).expect("No RenderApp found!"); - - render_app.init_resource::(); - render_app.init_resource::(); - - // Respawn chunks that we saved from the last frame - // Copy over tile data - render_app - .add_systems(ExtractSchedule, extract_chunks) - .add_systems( - Render, - (create_chunk_batches, apply_deferred, queue_chunks) - .chain() - .in_set(RenderSet::Queue), - ) - .add_systems( - Render, - ( - prepare_chunks, - apply_deferred, - prepare_chunk_batch, - apply_deferred, - create_bind_groups, - ) - .chain() - .in_set(RenderSet::Prepare), - ) - .add_systems(Render, (save_chunks).in_set(RenderSet::Cleanup)); - } - - fn finish(&self, app: &mut bevy::prelude::App) { - let render_app = app.get_sub_app_mut(RenderApp).expect("No RenderApp found!"); - - render_app.add_render_command::(); - render_app - .init_resource::() - .init_resource::>(); - - load_internal_asset!( - app, - TILES_FRAG, - "shaders/tiles_frag.wgsl", - Shader::from_wgsl - ); - - load_internal_asset!( - app, - TILES_VERT, - "shaders/tiles_vert.wgsl", - Shader::from_wgsl - ); - } -} diff --git a/crates/bevy_tiles_render/src/maps/internal.rs b/crates/bevy_tiles_render/src/maps/internal.rs deleted file mode 100644 index 0edf1ce..0000000 --- a/crates/bevy_tiles_render/src/maps/internal.rs +++ /dev/null @@ -1,24 +0,0 @@ -use bevy::{ - ecs::{component::Component, entity::Entity, system::Resource}, - prelude::{Deref, DerefMut}, - transform::components::GlobalTransform, -}; -use crossbeam::queue::SegQueue; -use dashmap::DashMap; - -use super::{TileGridSize, TileMapRenderer, TileSize}; - -#[derive(Default, Resource, Deref, DerefMut)] -pub struct SavedMaps(DashMap); - -#[derive(Default, Component, Deref, DerefMut)] -pub struct MapChunks(SegQueue); - -#[derive(Clone, Component)] -pub struct MapInfo { - pub chunk_size: u32, - pub tile_map_renderer: TileMapRenderer, - pub tile_size: TileSize, - pub grid_size: TileGridSize, - pub transform: GlobalTransform, -} diff --git a/crates/bevy_tiles_render/src/maps/mod.rs b/crates/bevy_tiles_render/src/maps/mod.rs deleted file mode 100644 index 0f2f879..0000000 --- a/crates/bevy_tiles_render/src/maps/mod.rs +++ /dev/null @@ -1,54 +0,0 @@ -//! Components that can affect map rendering - -use bevy::{ - ecs::{bundle::Bundle, component::Component}, - prelude::Deref, - transform::components::{GlobalTransform, Transform}, -}; - -pub(crate) mod internal; - -#[derive(Bundle, Default)] -pub struct TileMapRenderingBundle { - pub tile_map_renderer: TileMapRenderer, - pub tile_size: TileSize, - pub grid_size: TileGridSize, - pub transform: Transform, - pub global_transform: GlobalTransform, -} - -/// Marks a tilemap as renderable, without this it cannot be rendered. -#[derive(Clone, Component)] -pub struct TileMapRenderer { - pub batch_size: u32, -} - -impl Default for TileMapRenderer { - fn default() -> Self { - Self { batch_size: 128 } - } -} - -/// The size of a tile in pixels. -#[derive(Clone, Deref, Component)] -pub struct TileSize(pub f32); - -/// Defaults to 16 pixels -impl Default for TileSize { - fn default() -> Self { - Self(16.0) - } -} -/// The size of a tile grid in pixels. -/// # Example -/// A [`TileSize`] of 16 with a [`GridSize`] of 18 would lead to a 2 pixel gap between tiles. -/// A [`TileSize`] of 16 with a [`GridSize`] of 14 would lead to a 2 pixel overlap between tiles. -#[derive(Clone, Deref, Component)] -pub struct TileGridSize(pub f32); - -/// Defaults to 16 pixels -impl Default for TileGridSize { - fn default() -> Self { - Self(16.0) - } -} diff --git a/crates/bevy_tiles_render/src/pipeline.rs b/crates/bevy_tiles_render/src/pipeline.rs deleted file mode 100644 index 30cdb0d..0000000 --- a/crates/bevy_tiles_render/src/pipeline.rs +++ /dev/null @@ -1,101 +0,0 @@ -use bevy::{ - ecs::{ - system::Resource, - world::{FromWorld, World}, - }, - render::{ - render_resource::{ - BindGroupLayout, BlendState, ColorTargetState, ColorWrites, Face, FragmentState, - FrontFace, MultisampleState, PolygonMode, PrimitiveState, PrimitiveTopology, - RenderPipelineDescriptor, SpecializedRenderPipeline, TextureFormat, VertexBufferLayout, - VertexFormat, VertexState, VertexStepMode, - }, - renderer::RenderDevice, - texture::BevyDefault, - view::ViewTarget, - }, - sprite::{Mesh2dPipeline, Mesh2dPipelineKey}, -}; - -use crate::{ - bindings::{ChunkBatchBindGroupLayouts, MapTransformUniform}, - TILES_FRAG, TILES_VERT, -}; - -#[derive(Resource)] -pub struct TilesChunkPipeline { - pub mesh2d_pipeline: Mesh2dPipeline, - pub chunk_batch_bind_groups: ChunkBatchBindGroupLayouts, -} - -impl FromWorld for TilesChunkPipeline { - fn from_world(world: &mut World) -> Self { - Self { - mesh2d_pipeline: Mesh2dPipeline::from_world(world), - chunk_batch_bind_groups: ChunkBatchBindGroupLayouts::from_world(world), - } - } -} - -impl SpecializedRenderPipeline for TilesChunkPipeline { - type Key = Mesh2dPipelineKey; - - fn specialize( - &self, - key: Self::Key, - ) -> bevy::render::render_resource::RenderPipelineDescriptor { - let format = match key.contains(Mesh2dPipelineKey::HDR) { - true => ViewTarget::TEXTURE_FORMAT_HDR, - false => TextureFormat::bevy_default(), - }; - - let shader_defs = Vec::new(); - - RenderPipelineDescriptor { - vertex: VertexState { - shader: TILES_VERT, - entry_point: "vs_main".into(), - shader_defs: shader_defs.clone(), - // We generate clip space triangles on the fly based on the implicit index buffer - buffers: vec![], - }, - fragment: Some(FragmentState { - // Use our custom shader - shader: TILES_FRAG, - shader_defs, - entry_point: "fs_main".into(), - targets: vec![Some(ColorTargetState { - format, - blend: Some(BlendState::ALPHA_BLENDING), - write_mask: ColorWrites::ALL, - })], - }), - // Use the two standard uniforms for 2d meshes - layout: vec![ - // Bind group 0 is the view uniform - self.mesh2d_pipeline.view_layout.clone(), - // Bind group 1 are the map components - self.chunk_batch_bind_groups.map_layouts.clone(), - // Bind group 2 are the chunk components - self.chunk_batch_bind_groups.chunk_layouts.clone(), - ], - push_constant_ranges: Vec::new(), - primitive: PrimitiveState { - front_face: FrontFace::Ccw, - cull_mode: Some(Face::Back), - unclipped_depth: false, - polygon_mode: PolygonMode::Fill, - conservative: false, - topology: PrimitiveTopology::TriangleList, - strip_index_format: None, - }, - depth_stencil: None, - multisample: MultisampleState { - count: key.msaa_samples(), - mask: !0, - alpha_to_coverage_enabled: false, - }, - label: Some("tiles_pipeline".into()), - } - } -} diff --git a/crates/bevy_tiles_render/src/prepare.rs b/crates/bevy_tiles_render/src/prepare.rs deleted file mode 100644 index fb6b2f8..0000000 --- a/crates/bevy_tiles_render/src/prepare.rs +++ /dev/null @@ -1,138 +0,0 @@ -use bevy::{ - ecs::{ - entity::Entity, - system::{Commands, ParallelCommands, Query, Res}, - }, - log::debug, - render::{ - render_resource::CommandEncoderDescriptor, - renderer::{RenderDevice, RenderQueue}, - }, - utils::hashbrown::HashMap, -}; -use bevy_tiles::chunks::ChunkCoord; -use crossbeam::queue::ArrayQueue; - -use crate::{ - bindings::{ChunkBatchBindGroups, ChunkBatchBuffer, ChunkBuffer, MapBatchBuffer}, - chunk::internal::{BatchSize, ChunkBatch, ChunkUniforms}, - maps::internal::MapInfo, - pipeline::TilesChunkPipeline, -}; - -// Write individual chunk data to the GPU before consolidation -pub fn prepare_chunks( - mut commands: Commands, - device: Res, - queue: Res, - mut chunks: Query<(Entity, &mut ChunkUniforms)>, -) { - let size = chunks.iter().len(); - if size == 0 { - return; - } - let uniform_buffers = ArrayQueue::new(size); - chunks - .par_iter_mut() - .for_each(|(chunk_id, mut chunk_uniform)| { - let mut buffer = ChunkBuffer::new(&mut chunk_uniform); - buffer.write_buffer(&device, &queue); - let _ = uniform_buffers.push((chunk_id, buffer)); - }); - commands.insert_or_spawn_batch(uniform_buffers); -} - -// Consolidate individual chunk information into the batch entities -pub fn prepare_chunk_batch( - mut commands: Commands, - device: Res, - queue: Res, - chunks: Query<(&ChunkBatch, &ChunkBuffer)>, - chunk_batches: Query<(Entity, &BatchSize, &MapInfo)>, -) { - let batch_iter = chunk_batches.iter(); - let batch_count = batch_iter.len(); - - let mut instance_indices = HashMap::with_capacity(batch_count); - let mut chunk_batch_buffers = HashMap::with_capacity(batch_count); - let mut global_uniform_buffers = Vec::with_capacity(batch_count); - - if batch_iter.len() == 0 { - return; - } - - for (batch_id, batch_size, map_info) in batch_iter { - debug!( - "Preparing batch {:?} with size {:?}", - batch_id, **batch_size - ); - - // Create all our instance buffers before we start iterating over chunks - instance_indices.insert(batch_id, 0); - chunk_batch_buffers.insert( - batch_id, - ChunkBatchBuffer::with_size_no_default_values( - **batch_size as usize, - map_info.chunk_size as usize, - &device, - ), - ); - - // Create all our global uniforms for the batches - let mut map_buffers = MapBatchBuffer::new(map_info); - - map_buffers.write_buffer(&device, &queue); - - global_uniform_buffers.push((batch_id, (map_buffers))); - } - - let mut command_encoder = device.create_command_encoder(&CommandEncoderDescriptor { - label: Some("bevy_tiles_render::batch_buffer_copies"), - }); - - for (batch_id, chunk_buffer) in chunks.iter() { - let chunk_batch_buffer = chunk_batch_buffers.get_mut(&**batch_id).unwrap(); - chunk_batch_buffer.push(&mut command_encoder, chunk_buffer); - } - - for (_, buffer) in chunk_batch_buffers.iter_mut() { - buffer.write_buffer(&device, &queue) - } - - queue.submit([command_encoder.finish()]); - - commands.insert_or_spawn_batch(global_uniform_buffers); - commands.insert_or_spawn_batch(chunk_batch_buffers); -} - -pub fn create_bind_groups( - mut commands: Commands, - device: Res, - chunk_pipeline: Res, - chunk_batches: Query<(Entity, &MapBatchBuffer, &ChunkBatchBuffer)>, -) { - // Create bind groups - debug!( - "Creating bind group for {} batches", - chunk_batches.iter().len() - ); - for (batch_id, map_buffers, chunk_offsets) in chunk_batches.iter() { - let map_bind_group = device.create_bind_group( - "batch_map_bind_group", - &chunk_pipeline.chunk_batch_bind_groups.map_layouts, - &map_buffers.bindings(), - ); - - let chunk_bind_group = device.create_bind_group( - "batch_chunk_bind_group", - &chunk_pipeline.chunk_batch_bind_groups.chunk_layouts, - &chunk_offsets.bindings(), - ); - - debug!("Adding bind groups to batch {:?}", batch_id); - commands.entity(batch_id).insert(ChunkBatchBindGroups { - map_bind_group, - chunk_bind_group, - }); - } -} diff --git a/crates/bevy_tiles_render/src/queue.rs b/crates/bevy_tiles_render/src/queue.rs deleted file mode 100644 index a32e50a..0000000 --- a/crates/bevy_tiles_render/src/queue.rs +++ /dev/null @@ -1,118 +0,0 @@ -use bevy::{ - core_pipeline::core_2d::Transparent2d, - ecs::{ - entity::Entity, - query::{Or, With}, - system::{Commands, ParallelCommands, Query, Res, ResMut}, - }, - log::debug, - render::{ - render_phase::{DrawFunctions, RenderPhase}, - render_resource::{PipelineCache, PrimitiveTopology, SpecializedRenderPipelines}, - renderer::RenderDevice, - view::{ExtractedView, Msaa}, - }, - sprite::Mesh2dPipelineKey, - utils::FloatOrd, -}; -use bevy_tiles::{chunks::InMap, maps::TileMap}; - -use crate::{ - bindings::ChunkBuffer, - chunk::internal::{BatchSize, ChunkBatch, ChunkUniforms}, - draw::DrawChunks, - maps::internal::{MapChunks, MapInfo}, - pipeline::TilesChunkPipeline, -}; - -pub fn create_chunk_batches( - commands: ParallelCommands, - maps: Query<(&MapInfo, &MapChunks)>, - chunks: Query, With)>>, -) { - maps.par_iter().for_each(|(map_info, map_chunks)| { - commands.command_scope(|mut commands| { - let max_batch_size = map_info.tile_map_renderer.batch_size; - let chunk_count = chunks.iter().len(); - let batch_count = chunk_count / max_batch_size as usize - + if (chunk_count % max_batch_size as usize) > 0 { - 1 - } else { - 0 - }; - - if batch_count == 0 { - return; - } - - let mut batches = Vec::with_capacity(batch_count); - let mut batched_chunks = Vec::with_capacity(chunk_count); - - let mut batch_size = 0; - let mut current_batch = ChunkBatch(commands.spawn_empty().id()); - - while let Some(chunk_id) = map_chunks.pop() { - if chunks.get(chunk_id).is_ok() { - if batch_size == max_batch_size { - batches.push((*current_batch, (BatchSize(batch_size), map_info.clone()))); - batch_size = 0; - current_batch = ChunkBatch(commands.spawn_empty().id()); - } - batched_chunks.push((chunk_id, current_batch.clone())); - batch_size += 1; - } - } - - if batch_size > 0 { - batches.push((*current_batch, (BatchSize(batch_size), map_info.clone()))); - } - - commands.insert_or_spawn_batch(batches); - commands.insert_or_spawn_batch(batched_chunks); - }); - }); -} - -pub fn queue_chunks( - mut commands: Commands, - mut pipelines: ResMut>, - device: Res, - chunk_pipeline: Res, - pipeline_cache: Res, - msaa: Res, - transparent_draw_functions: Res>, - mut views: Query<(&mut RenderPhase, &ExtractedView)>, - chunk_batches: Query<(Entity, &BatchSize)>, -) { - for (mut transparent_phase, view) in &mut views { - let chunk_batch_iter = chunk_batches.iter(); - if chunk_batch_iter.len() == 0 { - continue; - } - - let mesh_key = Mesh2dPipelineKey::from_msaa_samples(msaa.samples()) - | Mesh2dPipelineKey::from_hdr(view.hdr) - | Mesh2dPipelineKey::from_primitive_topology(PrimitiveTopology::TriangleList); - let pipeline_id = pipelines.specialize(&pipeline_cache, &chunk_pipeline, mesh_key); - - let draw_chunks = transparent_draw_functions.read().id::(); - - for (batch_id, batch_size) in chunk_batch_iter { - debug!("Queuing draw call for batch: {:?}", batch_id); - transparent_phase.add(Transparent2d { - entity: batch_id, - draw_function: draw_chunks, - pipeline: pipeline_id, - sort_key: FloatOrd(0.0), - // Ignore this, we do our own batching - batch_range: 0..1, - dynamic_offset: None, - }); - } - - debug!( - "Queued {:?} Chunk Batches for Drawing", - chunk_batches.iter().len() - ); - } -} diff --git a/crates/bevy_tiles_render/src/shaders/tiles_frag.wgsl b/crates/bevy_tiles_render/src/shaders/tiles_frag.wgsl deleted file mode 100644 index 0f2eca6..0000000 --- a/crates/bevy_tiles_render/src/shaders/tiles_frag.wgsl +++ /dev/null @@ -1,18 +0,0 @@ - -@group(1) @binding(1) var chunk_size: u32; -@group(2) @binding(1) var tile_instances: array; - -struct FragIn { - @location(0) tile_index: u32, - @location(1) chunk_index: u32, -}; - -/// Entry point for the fragment shader -@fragment -fn fs_main(in: FragIn) -> @location(0) vec4 { - let global_tile_index = in.chunk_index * chunk_size * chunk_size + in.tile_index; - if tile_instances[global_tile_index] == 0u{ - discard; - } - return vec4(1.0, 1.0, 1.0, 1.0); -} \ No newline at end of file diff --git a/crates/bevy_tiles_render/src/shaders/tiles_vert.wgsl b/crates/bevy_tiles_render/src/shaders/tiles_vert.wgsl deleted file mode 100644 index 5d3a24e..0000000 --- a/crates/bevy_tiles_render/src/shaders/tiles_vert.wgsl +++ /dev/null @@ -1,105 +0,0 @@ -#define_import_path bevy_tiles::vert -// Import the standard 2d mesh uniforms and set their bind groups -#import bevy_render::view::View -#import bevy_render::globals::Globals -#import bevy_render::{ - instance_index::get_instance_index, - maths::{affine_to_square, mat2x4_f32_to_mat3x3_unpack}, -} - -@group(0) @binding(0) var view: View; - -@group(0) @binding(1) var globals: Globals; - -// Map level uniforms -@group(1) @binding(0) var mesh: Mesh2d; -@group(1) @binding(1) var chunk_size: u32; -@group(1) @binding(2) var tile_size: f32; -@group(1) @binding(3) var grid_size: f32; - -// Chunk level uniforms -@group(2) @binding(0) var chunk_offsets: array>; - -// The structure of the vertex buffer is as specified in `specialize()` -struct VertIn { - @builtin(vertex_index) vertex_index: u32, - @builtin(instance_index) instance_index: u32, -}; - -struct VertOut { - @builtin(position) clip_position: vec4, - @location(0) tile_index: u32, - @location(1) chunk_index: u32, -}; - -// LUT for quad verts -var positions: array, 6> = array, 6>( - vec2(0.0, 0.0), - vec2(1.0, 0.0), - vec2(1.0, 1.0), - vec2(1.0, 1.0), - vec2(0.0, 1.0), - vec2(0.0, 0.0), -); - -/// Entry point for the vertex shader -@vertex -fn vs_main(v: VertIn) -> VertOut { - let tile_index = v.vertex_index / 6u; - let chunk_index = v.instance_index; - let tile_offset = vec2( - f32(tile_index % chunk_size), - f32((tile_index / chunk_size) % chunk_size) - ); - let grid_offset = grid_size - tile_size; - let chunk_offset = f32(chunk_size) * chunk_offsets[chunk_index]; - let vertex_position = - // Base tile position - tile_size * (positions[v.vertex_index % 6u] + tile_offset + chunk_offset) + - // Account for grid size - (grid_offset) * (tile_offset + chunk_offset) + vec2(grid_offset / 2.0); - - let model = affine_to_square(mesh.model); - let clip_position = mesh2d_position_local_to_clip(model, vec4(vertex_position, 1.0, 1.0)); - - var out: VertOut; - out.clip_position = clip_position; - out.tile_index = tile_index; - out.chunk_index = chunk_index; - return out; -} - -struct Mesh2d { - model: mat3x4, - inverse_transpose_model_a: mat2x4, - inverse_transpose_model_b: f32, - flags: u32, -}; - - -fn mesh2d_position_local_to_world(model: mat4x4, vertex_position: vec4) -> vec4 { - return model * vertex_position; -} - -fn mesh2d_position_world_to_clip(world_position: vec4) -> vec4 { - return view.view_proj * world_position; -} - -// NOTE: The intermediate world_position assignment is important -// for precision purposes when using the 'equals' depth comparison -// function. -fn mesh2d_position_local_to_clip(model: mat4x4, vertex_position: vec4) -> vec4 { - let world_position = mesh2d_position_local_to_world(model, vertex_position); - return mesh2d_position_world_to_clip(world_position); -} - -fn mesh2d_tangent_local_to_world(model: mat4x4, vertex_tangent: vec4) -> vec4 { - return vec4( - mat3x3( - model[0].xyz, - model[1].xyz, - model[2].xyz - ) * vertex_tangent.xyz, - vertex_tangent.w - ); -} \ No newline at end of file diff --git a/crates/bevy_tiles_render/src/tiles.rs b/crates/bevy_tiles_render/src/tiles.rs deleted file mode 100644 index f14141e..0000000 --- a/crates/bevy_tiles_render/src/tiles.rs +++ /dev/null @@ -1 +0,0 @@ -use bevy::ecs::component::Component;