diff --git a/Cargo.lock b/Cargo.lock index aa21e00e91c0dd6ab1e984682c784470969547a4..efe43717b4a900c2d06bf47202bce7b4983235d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,24 +4,24 @@ version = 3 [[package]] name = "accesskit" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c98a5d094590335462354da402d754fe2cb78f0e6ce5024611c28ed539c1de" +checksum = "ca8410747ed85a17c4a1e9ed3f5a74d3e7bdcc876cf9a18ff40ae21d645997b2" [[package]] name = "accesskit_consumer" -version = "0.15.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca541e0fdb600916d196a940228df99b86d804fd2e6ef13894d7814f2799db43" +checksum = "8c17cca53c09fbd7288667b22a201274b9becaa27f0b91bf52a526db95de45e6" dependencies = [ "accesskit", ] [[package]] name = "accesskit_macos" -version = "0.7.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4baea9413f0daf1cd4aab199bc09f8139cd726ce7673d523c27d186b8b878325" +checksum = "cd3b6ae1eabbfbced10e840fd3fce8a93ae84f174b3e4ba892ab7bcb42e477a7" dependencies = [ "accesskit", "accesskit_consumer", @@ -31,23 +31,23 @@ dependencies = [ [[package]] name = "accesskit_windows" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e11c7f177739f23bd19bb856e4a64fdd96eb8638ec0a6a6dde9a7019a9e91c53" +checksum = "afcae27ec0974fc7c3b0b318783be89fd1b2e66dd702179fe600166a38ff4a0b" dependencies = [ "accesskit", "accesskit_consumer", - "arrayvec", "once_cell", "paste", - "windows", + "static_assertions", + "windows 0.48.0", ] [[package]] name = "accesskit_winit" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f1bd64cd0b480cafb7bdd91eb489a1ff50f0f5702437b9efa32a25b8bb82a1" +checksum = "88e39fcec2e10971e188730b7a76bab60647dacc973d4591855ebebcadfaa738" dependencies = [ "accesskit", "accesskit_macos", @@ -162,21 +162,37 @@ dependencies = [ "num-traits", ] +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "ash" -version = "0.37.2+1.3.238" +version = "0.37.3+1.3.251" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28bf19c1f0a470be5fbf7522a308a05df06610252c5bcf5143e1b23f629a9a03" +checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a" dependencies = [ "libloading 0.7.4", ] +[[package]] +name = "async-broadcast" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b" +dependencies = [ + "event-listener", + "futures-core", +] + [[package]] name = "async-channel" version = "1.8.0" @@ -197,16 +213,28 @@ dependencies = [ "async-lock", "async-task", "concurrent-queue", - "fastrand", + "fastrand 1.9.0", "futures-lite", "slab", ] +[[package]] +name = "async-fs" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +dependencies = [ + "async-lock", + "autocfg", + "blocking", + "futures-lite", +] + [[package]] name = "async-lock" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" dependencies = [ "event-listener", ] @@ -217,6 +245,12 @@ version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.1.0" @@ -246,18 +280,18 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "bevy" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04a90fe8e9c03fa2d30acf39a5178a48526df00c1ccea2fc43fa6d9ca4d8a168" +checksum = "329e344f835f5a9a4c46a6d1d57371f726aa2c482d1bd669b2b9c4eb1ee91fd7" dependencies = [ "bevy_internal", ] [[package]] name = "bevy_a11y" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f758f437d9d862bf10a8e3a0f76b426095c19a87d118c945dcb935358d856076" +checksum = "271b812e5734f5056a400f7d64592dd82d6c0e6179389c2f066f433ab8bc7692" dependencies = [ "accesskit", "bevy_app", @@ -267,9 +301,9 @@ dependencies = [ [[package]] name = "bevy_app" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1817e8d5b1146ea9e7730a7264d3470394840e0754d15abded26473f867967a0" +checksum = "172d532ea812e5954fa814dae003c207f2a0b20c6e50431787c94a7159677ece" dependencies = [ "bevy_derive", "bevy_ecs", @@ -283,24 +317,29 @@ dependencies = [ [[package]] name = "bevy_asset" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e12f951d4af2ad4ad230cd7bcb05248149c415eec17c34bf26731c4cd8b897f" +checksum = "ccb2b67984088b23e223cfe9ec1befd89a110665a679acb06839bc4334ed37d6" dependencies = [ - "anyhow", + "async-broadcast", + "async-fs", + "async-lock", "bevy_app", - "bevy_diagnostic", + "bevy_asset_macros", "bevy_ecs", "bevy_log", "bevy_reflect", "bevy_tasks", "bevy_utils", "bevy_winit", + "blake3", "crossbeam-channel", "downcast-rs", - "fastrand", + "futures-io", + "futures-lite", "js-sys", "parking_lot", + "ron", "serde", "thiserror", "wasm-bindgen", @@ -308,11 +347,23 @@ dependencies = [ "web-sys", ] +[[package]] +name = "bevy_asset_macros" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b3245193e90fc8abcf1059a467cb224501dcda083d114c67c10ac66b7171e3a" +dependencies = [ + "bevy_macro_utils", + "proc-macro2 1.0.56", + "quote 1.0.26", + "syn 2.0.15", +] + [[package]] name = "bevy_core" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "263b6a943ecba176c8390a1100615021f61a3b2d7a87e8eecf4009b6ed4457e0" +checksum = "025e6800b73048092a55c3611e9327ad4c4c17b60517ec1c0086bb40b4b19ea8" dependencies = [ "bevy_app", "bevy_ecs", @@ -325,15 +376,16 @@ dependencies = [ [[package]] name = "bevy_core_pipeline" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c70113b5c4106855b888f96d8574697eb9082713f976c9b6487c1f5ab28589" +checksum = "2e4b08a2d53ba62d9ec1fca3f7f4e0f556e9f59e1c8e63a4b7c2a18c0701152c" dependencies = [ "bevy_app", "bevy_asset", "bevy_core", "bevy_derive", "bevy_ecs", + "bevy_log", "bevy_math", "bevy_reflect", "bevy_render", @@ -346,9 +398,9 @@ dependencies = [ [[package]] name = "bevy_derive" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1477347b17df781756ba0dfd677e2975e57e930752cd3cd42e6cdd8fdaa3223" +checksum = "24bf40259be12a1a24d9fd536f5ff18d31eeb5665b77e2732899783be6edc5d6" dependencies = [ "bevy_macro_utils", "quote 1.0.26", @@ -357,9 +409,9 @@ dependencies = [ [[package]] name = "bevy_diagnostic" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a594f970c261007cdd3edeccd61651c2cb4513de3d0b8b35d93f5d9c32c059" +checksum = "41b5a99a9fb6cd7d1eb1714fad193944a0317f0887a15cccb8309c8d37951132" dependencies = [ "bevy_app", "bevy_core", @@ -372,9 +424,9 @@ dependencies = [ [[package]] name = "bevy_ecs" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "032c81ba7d919c1004b0abc33cc6c588c8f896a4d7c55a7c7aa1e46382242f43" +checksum = "ae11a1f467c372b50e9d4b55e78370f5420c9db7416200cc441cc84f08174dd3" dependencies = [ "async-channel", "bevy_ecs_macros", @@ -393,9 +445,9 @@ dependencies = [ [[package]] name = "bevy_ecs_macros" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15ff7fcafdb8fe464ddd300b4860a76d5c6f9d684472e4bf21852d6f0ff3991" +checksum = "f642c2b67c4d0daf8edf15074f6351457eb487a34b3de1290c760d8f3ac9ec16" dependencies = [ "bevy_macro_utils", "proc-macro2 1.0.56", @@ -405,9 +457,9 @@ dependencies = [ [[package]] name = "bevy_encase_derive" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdf808dbdc68a0c519e09026c627bda85250205a40ac02794866bff254d6b56" +checksum = "65b9fb5a62c4e3ab70caaa839470d35fa932001b1b34b08bc7f7f1909bd2b3a7" dependencies = [ "bevy_macro_utils", "encase_derive_impl", @@ -415,9 +467,9 @@ dependencies = [ [[package]] name = "bevy_gizmos" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7938b43b4bdf9d039b7d3b310f871ed5ffa5a185e861a9c85731c40182019f8d" +checksum = "87d1cc978b91f416b23eb16f00e69f95c3a04582021827d8082e92d4725cc510" dependencies = [ "bevy_app", "bevy_asset", @@ -434,9 +486,9 @@ dependencies = [ [[package]] name = "bevy_hierarchy" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba41e1bb0c367b31e59b53ab858de56764c78bee87c121843c1ff033efa0086c" +checksum = "64fa240011fce8ee23f9b46e5a26a628a31d7860d6d2e4e0e361bb3ea6d5a703" dependencies = [ "bevy_app", "bevy_core", @@ -449,9 +501,9 @@ dependencies = [ [[package]] name = "bevy_input" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7221091c7b219a63a1f3f019512e8b72bed673230b97c3fcbca37ba566b1cffb" +checksum = "9e86e241b3a10b79f65a69205552546723b855d3d4c1bd8261637c076144d32f" dependencies = [ "bevy_app", "bevy_ecs", @@ -463,9 +515,9 @@ dependencies = [ [[package]] name = "bevy_internal" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f232e7bd2566abd05656789e3c6278a5ca2a24f1232dff525e5b0233a99a610" +checksum = "55124e486814c4d3632d5cfad9c4f4e46d052c028593ec46fef5bfbfb0f840b1" dependencies = [ "bevy_a11y", "bevy_app", @@ -494,9 +546,9 @@ dependencies = [ [[package]] name = "bevy_log" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487dfd1fc75fada8f3f2f4773addf3fbba53a2a91cb913616e6dc6c26dd62995" +checksum = "011417debf7868b45932bb97fc0d5bfdeaf9304e324aa94840e2f1e6deeed69d" dependencies = [ "android_log-sys", "bevy_app", @@ -510,21 +562,22 @@ dependencies = [ [[package]] name = "bevy_macro_utils" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3868e555723249fde3786891f35893b3001b2be4efb51f431467cb7fc378cd" +checksum = "cf6fba87c6d069fcbcd8a48625ca8ab4392ad40d2b260863ce7d641a0f42986d" dependencies = [ + "proc-macro2 1.0.56", "quote 1.0.26", "rustc-hash", "syn 2.0.15", - "toml_edit", + "toml_edit 0.20.7", ] [[package]] name = "bevy_math" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25088c6598fe0b8ded992c781dc49e613993c7a4e6a731c0f2ab0408add6afdb" +checksum = "752764558a1f429c20704c3b836a019fa308961c43fdfef4f08e339d456c96be" dependencies = [ "glam", "serde", @@ -532,24 +585,24 @@ dependencies = [ [[package]] name = "bevy_mikktspace" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99dde80034660f7dbb473141c31f0a746acc7229f5a06ce769aba5f16fd592ab" +checksum = "b596c41a56f2268ec7cde560edc588bc7b5886e4b49c8b27c4dcc9f7c743424c" dependencies = [ "glam", ] [[package]] name = "bevy_ptr" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c74fcf37593a0053f539c3b088f34f268cbefed031d8eb8ff0fb10d175160242" +checksum = "308a02679f6ce21ef71de20fae6d6a2016c07baa21d8e8d0558e6b7851e8adf2" [[package]] name = "bevy_reflect" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "362492a6b66f676176705cc06017b012320fa260a9cf4baf3513387e9c05693e" +checksum = "cdd56914a8ad57621d7a1a099f7e6b1f7482c9c76cedc9c3d4c175a203939c5d" dependencies = [ "bevy_math", "bevy_ptr", @@ -558,8 +611,6 @@ dependencies = [ "downcast-rs", "erased-serde", "glam", - "once_cell", - "parking_lot", "serde", "smallvec", "smol_str", @@ -568,12 +619,11 @@ dependencies = [ [[package]] name = "bevy_reflect_derive" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e974d78eaf1b45e1b4146711b5c16e37c24234e12f3a52f5f2e28332c969d3c" +checksum = "25f627907c40ac552f798423447fc331fc1ddacd94c5f7a2a70942eb06bc8447" dependencies = [ "bevy_macro_utils", - "bit-set", "proc-macro2 1.0.56", "quote 1.0.26", "syn 2.0.15", @@ -582,11 +632,10 @@ dependencies = [ [[package]] name = "bevy_render" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46e4b6a82c3a2be1c0d0cbecf62debb8251b72c0ae76285f66265aabc5bf2d37" +checksum = "90d777f4c51bd58e9e40777c6cb8dde0778df7e2c5298b3f9e3455bd12a9856c" dependencies = [ - "anyhow", "async-channel", "bevy_app", "bevy_asset", @@ -616,8 +665,6 @@ dependencies = [ "js-sys", "naga", "naga_oil", - "parking_lot", - "regex", "serde", "smallvec", "thiserror", @@ -625,14 +672,13 @@ dependencies = [ "wasm-bindgen", "web-sys", "wgpu", - "wgpu-hal", ] [[package]] name = "bevy_render_macros" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07c4d937f966644f5e1e3c9157736acdd36286bcce06142ff9ad25cd71348c09" +checksum = "35b00c3d0abff94a729460fc9aa95c2ceac71b49b3041166bb5ba3098e9657e7" dependencies = [ "bevy_macro_utils", "proc-macro2 1.0.56", @@ -642,11 +688,10 @@ dependencies = [ [[package]] name = "bevy_scene" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1e00eb30e2053d9fff0802b2f557350b4e66bac58d531de30882048b4e3232" +checksum = "ba6294396a6375f0b14341d8003408c10aa040e3f833ac8bd49677170ec55d73" dependencies = [ - "anyhow", "bevy_app", "bevy_asset", "bevy_derive", @@ -664,9 +709,9 @@ dependencies = [ [[package]] name = "bevy_sprite" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03f64119444ef9788dcdd05012a60f0fa3b7ddb396d434ebcfc3edefd76c91b5" +checksum = "b4f7d1f88a6e5497fdafd95c20984a1d1b5517bc39d51600b4988cd60c51837a" dependencies = [ "bevy_app", "bevy_asset", @@ -683,15 +728,16 @@ dependencies = [ "bytemuck", "fixedbitset", "guillotiere", + "radsort", "rectangle-pack", "thiserror", ] [[package]] name = "bevy_tasks" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faab904296a3d6976bb8a12bc0f42f6c98fb6cd87a96244e0151d359f684ec2d" +checksum = "3a45be906618192515bc613e46546150089adbb4a82178dc462045acd1e89e92" dependencies = [ "async-channel", "async-executor", @@ -703,9 +749,9 @@ dependencies = [ [[package]] name = "bevy_time" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d09225ad2ffef14da000080143730b36ba225844ae479e4791cdb9d08066d06a" +checksum = "b29709cadf22d318a0b7c79f763e9c5ac414292bd0e850066fa935959021b276" dependencies = [ "bevy_app", "bevy_ecs", @@ -717,28 +763,30 @@ dependencies = [ [[package]] name = "bevy_transform" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da8a0cd3780e120e20be333cc48d41cb74620d798dc61bc18eb2a82d3545e184" +checksum = "70262c51e915b6224129206d23823364e650cf5eb5f4b6ce3ee379f608c180d2" dependencies = [ "bevy_app", "bevy_ecs", "bevy_hierarchy", "bevy_math", "bevy_reflect", + "thiserror", ] [[package]] name = "bevy_utils" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10bfde141f0cdd15e07bca72f4439a9db80877c283738f581d061972ef483b1b" +checksum = "c8e75d4a34ef0b15dffd1ee9079ef1f0f5139527e192b9d5708b3e158777c753" dependencies = [ "ahash 0.8.3", "bevy_utils_proc_macros", "getrandom", "hashbrown 0.14.0", "instant", + "nonmax", "petgraph", "thiserror", "tracing", @@ -747,9 +795,9 @@ dependencies = [ [[package]] name = "bevy_utils_proc_macros" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e37f2e885b0e8af59dc19871c313d3cf2a2495db35bb4d4ae0a61b3f87d5401" +checksum = "f7dfd3735a61a1b681ed1e176afe4eae731bbb03e51ad871e9eb39e76a2d170e" dependencies = [ "proc-macro2 1.0.56", "quote 1.0.26", @@ -758,10 +806,11 @@ dependencies = [ [[package]] name = "bevy_window" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0528832361e3d942df287c90537ef6fafb726c4934468a7c3a5d53d659bfbf54" +checksum = "e60d1830b3fbd7db5bfea7ac9fcd0f5e1d1af88c91ab469e697ab176d8b3140b" dependencies = [ + "bevy_a11y", "bevy_app", "bevy_ecs", "bevy_input", @@ -773,9 +822,9 @@ dependencies = [ [[package]] name = "bevy_winit" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24c6709dc70cfee1eb94d5f125d29612c4a9345dfc1a70dd3189af927b2fd503" +checksum = "7f8294e78c6a1f9c34d36501a377c5d20bf0fa23a0958187bb270187741448ba" dependencies = [ "accesskit_winit", "approx", @@ -823,6 +872,19 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +[[package]] +name = "blake3" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0231f06152bf547e9c2b5194f247cd97aacf6dcd8b15d8e5ec0663f64580da87" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + [[package]] name = "block" version = "0.1.6" @@ -848,6 +910,22 @@ dependencies = [ "objc2-encode", ] +[[package]] +name = "blocking" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c36a4d0d48574b3dd360b4b7d95cc651d2b6557b6402848a27d4b228a473e2a" +dependencies = [ + "async-channel", + "async-lock", + "async-task", + "fastrand 2.0.1", + "futures-io", + "futures-lite", + "piper", + "tracing", +] + [[package]] name = "bumpalo" version = "3.12.1" @@ -954,6 +1032,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87ca1caa64ef4ed453e68bb3db612e51cf1b2f5b871337f0fcab1c8f87cc3dff" +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + [[package]] name = "constgebra" version = "0.1.3" @@ -988,7 +1072,7 @@ dependencies = [ "bitflags 1.3.2", "core-foundation", "core-graphics-types", - "foreign-types", + "foreign-types 0.3.2", "libc", ] @@ -1000,7 +1084,7 @@ checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" dependencies = [ "bitflags 1.3.2", "core-foundation", - "foreign-types", + "foreign-types 0.3.2", "libc", ] @@ -1025,12 +1109,12 @@ dependencies = [ [[package]] name = "d3d12" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8f0de2f5a8e7bd4a9eec0e3c781992a4ce1724f68aec7d7a3715344de8b39da" +checksum = "e16e44ab292b1dddfdaf7be62cfd8877df52f2f3fde5858d95bab606be259f20" dependencies = [ - "bitflags 1.3.2", - "libloading 0.7.4", + "bitflags 2.3.3", + "libloading 0.8.0", "winapi", ] @@ -1144,6 +1228,12 @@ dependencies = [ "syn 2.0.15", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "erased-serde" version = "0.3.25" @@ -1177,6 +1267,12 @@ dependencies = [ "instant", ] +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + [[package]] name = "fixedbitset" version = "0.4.2" @@ -1195,7 +1291,28 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "foreign-types-shared", + "foreign-types-shared 0.1.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.1", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2 1.0.56", + "quote 1.0.26", + "syn 2.0.15", ] [[package]] @@ -1204,6 +1321,12 @@ 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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + [[package]] name = "futures-core" version = "0.3.28" @@ -1222,7 +1345,7 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" dependencies = [ - "fastrand", + "fastrand 1.9.0", "futures-core", "futures-io", "memchr", @@ -1262,9 +1385,9 @@ dependencies = [ [[package]] name = "glow" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e007a07a24de5ecae94160f141029e9a347282cfe25d1d58d85d845cf3130f1" +checksum = "ca0fe580e4b60a8ab24a868bc08e2f03cbcb20d3d676601fa909386713333728" dependencies = [ "js-sys", "slotmap", @@ -1274,21 +1397,21 @@ dependencies = [ [[package]] name = "gpu-alloc" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22beaafc29b38204457ea030f6fb7a84c9e4dd1b86e311ba0542533453d87f62" +checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.3.3", "gpu-alloc-types", ] [[package]] name = "gpu-alloc-types" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54804d0d6bc9d7f26db4eaec1ad10def69b599315f487d32c334a80d1efe67a5" +checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.3.3", ] [[package]] @@ -1301,7 +1424,7 @@ dependencies = [ "log", "thiserror", "winapi", - "windows", + "windows 0.44.0", ] [[package]] @@ -1414,6 +1537,16 @@ dependencies = [ "hashbrown 0.12.3", ] +[[package]] +name = "indexmap" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad227c3af19d4914570ad36d30409928b75967c298feb9ea1969db3a610bb14e" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", +] + [[package]] name = "instant" version = "0.1.12" @@ -1449,9 +1582,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.61" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] @@ -1544,16 +1677,17 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "metal" -version = "0.24.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de11355d1f6781482d027a3b4d4de7825dcedb197bf573e0596d00008402d060" +checksum = "623b5e6cefd76e58f774bd3cc0c6f5c7615c58c03a97815245a25c3c9bdee318" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.3.3", "block", "core-graphics-types", - "foreign-types", + "foreign-types 0.5.0", "log", "objc", + "paste", ] [[package]] @@ -1562,7 +1696,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78eda07db196df5c028f17242e7f5e9fd26efadf83d1e10d4927b56754155996" dependencies = [ - "fastrand", + "fastrand 1.9.0", ] [[package]] @@ -1591,15 +1725,15 @@ dependencies = [ [[package]] name = "naga" -version = "0.12.3" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbcc2e0513220fd2b598e6068608d4462db20322c0e77e47f6f488dfcfc279cb" +checksum = "c1ceaaa4eedaece7e4ec08c55c640ba03dbb73fb812a6570a59bcf1930d0f70e" dependencies = [ "bit-set", - "bitflags 1.3.2", + "bitflags 2.3.3", "codespan-reporting", "hexf-parse", - "indexmap", + "indexmap 1.9.3", "log", "num-traits", "pp-rs", @@ -1612,18 +1746,18 @@ dependencies = [ [[package]] name = "naga_oil" -version = "0.8.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9c27fc9c84580434af75123d13ad98d9a56e16d033b16dcfa6940728c8c225" +checksum = "a1fa9518ff79ae8a98c3abe3897d873a85561d1b5642981c2245c1c4b9b2429d" dependencies = [ "bit-set", "codespan-reporting", "data-encoding", - "indexmap", + "indexmap 1.9.3", "naga", "once_cell", "regex", - "regex-syntax 0.6.29", + "regex-syntax 0.7.1", "rustc-hash", "thiserror", "tracing", @@ -1659,6 +1793,12 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "nonmax" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99756f5493e135528f0cd660ac67b4c3a542bb65a3565efe92bb2c2317eb3669" + [[package]] name = "ntapi" version = "0.4.1" @@ -1904,7 +2044,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" dependencies = [ "fixedbitset", - "indexmap", + "indexmap 1.9.3", ] [[package]] @@ -1913,6 +2053,17 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +[[package]] +name = "piper" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +dependencies = [ + "atomic-waker", + "fastrand 2.0.1", + "futures-io", +] + [[package]] name = "pkg-config" version = "0.3.27" @@ -1935,7 +2086,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit", + "toml_edit 0.19.8", ] [[package]] @@ -2297,9 +2448,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.1" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" [[package]] name = "toml_edit" @@ -2307,9 +2458,20 @@ version = "0.19.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" dependencies = [ - "indexmap", + "indexmap 1.9.3", + "toml_datetime", + "winnow 0.4.6", +] + +[[package]] +name = "toml_edit" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap 2.0.1", "toml_datetime", - "winnow", + "winnow 0.5.19", ] [[package]] @@ -2445,9 +2607,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2455,16 +2617,16 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2 1.0.56", "quote 1.0.26", - "syn 1.0.109", + "syn 2.0.15", "wasm-bindgen-shared", ] @@ -2482,9 +2644,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote 1.0.26", "wasm-bindgen-macro-support", @@ -2492,22 +2654,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2 1.0.56", "quote 1.0.26", - "syn 1.0.109", + "syn 2.0.15", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "wayland-scanner" @@ -2522,9 +2684,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.61" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" dependencies = [ "js-sys", "wasm-bindgen", @@ -2532,9 +2694,9 @@ dependencies = [ [[package]] name = "wgpu" -version = "0.16.3" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "480c965c9306872eb6255fa55e4b4953be55a8b64d57e61d7ff840d3dcc051cd" +checksum = "ed547920565c56c7a29afb4538ac5ae5048865a5d2f05bff3ad4fbeb921a9a2c" dependencies = [ "arrayvec", "cfg-if", @@ -2556,9 +2718,9 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "0.16.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f478237b4bf0d5b70a39898a66fa67ca3a007d79f2520485b8b0c3dfc46f8c2" +checksum = "0f8a44dd301a30ceeed3c27d8c0090433d3da04d7b2a4042738095a424d12ae7" dependencies = [ "arrayvec", "bit-vec", @@ -2579,9 +2741,9 @@ dependencies = [ [[package]] name = "wgpu-hal" -version = "0.16.2" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecb3258078e936deee14fd4e0febe1cfe9bbb5ffef165cb60218d2ee5eb4448" +checksum = "9a80bf0e3c77399bb52850cb0830af9bad073d5cfcb9dd8253bef8125c42db17" dependencies = [ "android_system_properties", "arrayvec", @@ -2591,7 +2753,6 @@ dependencies = [ "block", "core-graphics-types", "d3d12", - "foreign-types", "glow", "gpu-alloc", "gpu-allocator", @@ -2621,9 +2782,9 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "0.16.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c153280bb108c2979eb5c7391cb18c56642dd3c072e55f52065e13e2a1252a" +checksum = "ee64d7398d0c2f9ca48922c902ef69c42d000c759f3db41e355f4a570b052b67" dependencies = [ "bitflags 2.3.3", "js-sys", @@ -2672,17 +2833,26 @@ 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.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ "windows-implement", "windows-interface", - "windows-targets 0.42.2", + "windows-targets 0.48.0", ] [[package]] name = "windows-implement" -version = "0.44.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce87ca8e3417b02dc2a8a22769306658670ec92d78f1bd420d6310a67c245c6" +checksum = "5e2ee588991b9e7e6c8338edf3333fbe4da35dc72092643958ebb43f0ab2c49c" dependencies = [ "proc-macro2 1.0.56", "quote 1.0.26", @@ -2691,9 +2861,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.44.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "853f69a591ecd4f810d29f17e902d40e349fb05b0b11fff63b08b826bfe39c7f" +checksum = "e6fb8df20c9bcaa8ad6ab513f7b40104840c8867d5751126e4df3b08388d0cc7" dependencies = [ "proc-macro2 1.0.56", "quote 1.0.26", @@ -2834,9 +3004,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winit" -version = "0.28.5" +version = "0.28.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94c9651471cd576737671fbf7081edfea43de3e06846dd9bd4e49ea803c9f55f" +checksum = "9596d90b45384f5281384ab204224876e8e8bf7d58366d9b795ad99aa9894b94" dependencies = [ "android-activity", "bitflags 1.3.2", @@ -2868,6 +3038,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" +dependencies = [ + "memchr", +] + [[package]] name = "xml-rs" version = "0.8.7" diff --git a/Cargo.toml b/Cargo.toml index c46f91f073c28767bba590862fa37b95af2a6459..f1e750d51d941ac90229a80069a4ac9871c5b337 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ autotile = ["micro_autotile"] no_panic = [] [dependencies] -bevy = { version = "0.11", default-features = false, features = ["bevy_render", "bevy_sprite", "bevy_asset"] } +bevy = { version = "0.12", default-features = false, features = ["bevy_render", "bevy_sprite", "bevy_asset"] } anyhow = "1.0" thiserror = "1.0" diff --git a/README.md b/README.md index 872653af9e1261d5c2afb3def7bb99c9f1240992..f581f7d78326284db1f70975eb5d0c3ad375dda6 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ select the schema version you need: ```toml [dependencies] -micro_ldtk = { version = "0.7.0", default-features = false, features = ["ldtk_1_3_0", "autotile"] } +micro_ldtk = { version = "0.8.0", default-features = false, features = ["ldtk_1_3_0", "autotile"] } ``` ### Features diff --git a/src/assets/asset_events.rs b/src/assets/asset_events.rs index c7acc8ae2a88c5a5baa2a2b54c17083e6165a3dc..f4d4aa00df8e24c75284ef1be37fb17f508a4cf4 100644 --- a/src/assets/asset_events.rs +++ b/src/assets/asset_events.rs @@ -13,9 +13,10 @@ pub fn handle_ldtk_project_events( mut tilset_index: ResMut<TilesetIndex>, mut update_events: EventWriter<LevelDataUpdated>, ) { - for event in events.iter() { + for event in events.read() { match event { - AssetEvent::Created { handle } | AssetEvent::Modified { handle } => { + AssetEvent::Added { id } | AssetEvent::Modified { id } => { + let handle = Handle::Weak(*id); if let Some(project) = assets.get(handle) { for level in project.get_all_levels() { if level.external_rel_path.is_none() { @@ -50,7 +51,8 @@ pub fn handle_ldtk_level_events( ) { for event in events.iter() { match event { - AssetEvent::Created { handle } | AssetEvent::Modified { handle } => { + AssetEvent::Added { id } | AssetEvent::Modified { id } => { + let handle = Handle::Weak(*id); if let Some(level) = assets.get(handle) { level_index.insert(level.identifier.clone(), LdtkLevel::from(level.clone())); update_events.send(LevelDataUpdated(level.identifier.clone())); diff --git a/src/ldtk/data_1_4_0.rs b/src/ldtk/data_1_4_0.rs new file mode 100644 index 0000000000000000000000000000000000000000..f78ed5cb114aa39be2871fcf5a3eefa17e64ba13 --- /dev/null +++ b/src/ldtk/data_1_4_0.rs @@ -0,0 +1,1650 @@ +// Example code that deserializes and serializes the model. +// extern crate serde; +// #[macro_use] +// extern crate serde_derive; +// extern crate serde_json; +// +// use generated_module::Project; +// +// fn main() { +// let json = r#"{"answer": 42}"#; +// let model: Project = serde_json::from_str(&json).unwrap(); +// } + +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// This file is a JSON schema of files created by LDtk level editor (https://ldtk.io). +/// +/// This is the root of any Project JSON file. It contains: - the project settings, - an +/// array of levels, - a group of definitions (that can probably be safely ignored for most +/// users). +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Project { + /// This object is not actually used by LDtk. It ONLY exists to force explicit references to + /// all types, to make sure QuickType finds them and integrate all of them. Otherwise, + /// Quicktype will drop types that are not explicitely used. + #[serde(rename = "__FORCED_REFS")] + pub forced_refs: Option<ForcedRefs>, + + /// LDtk application build identifier.<br/> This is only used to identify the LDtk version + /// that generated this particular project file, which can be useful for specific bug fixing. + /// Note that the build identifier is just the date of the release, so it's not unique to + /// each user (one single global ID per LDtk public release), and as a result, completely + /// anonymous. + pub app_build_id: f64, + + /// Number of backup files to keep, if the `backupOnSave` is TRUE + pub backup_limit: i64, + + /// If TRUE, an extra copy of the project will be created in a sub folder, when saving. + pub backup_on_save: bool, + + /// Target relative path to store backup files + pub backup_rel_path: Option<String>, + + /// Project background color + pub bg_color: String, + + /// An array of command lines that can be ran manually by the user + pub custom_commands: Vec<LdtkCustomCommand>, + + /// Default height for new entities + pub default_entity_height: i64, + + /// Default width for new entities + pub default_entity_width: i64, + + /// Default grid size for new layers + pub default_grid_size: i64, + + /// Default background color of levels + pub default_level_bg_color: String, + + /// **WARNING**: this field will move to the `worlds` array after the "multi-worlds" update. + /// It will then be `null`. You can enable the Multi-worlds advanced project option to enable + /// the change immediately.<br/><br/> Default new level height + pub default_level_height: Option<i64>, + + /// **WARNING**: this field will move to the `worlds` array after the "multi-worlds" update. + /// It will then be `null`. You can enable the Multi-worlds advanced project option to enable + /// the change immediately.<br/><br/> Default new level width + pub default_level_width: Option<i64>, + + /// Default X pivot (0 to 1) for new entities + pub default_pivot_x: f64, + + /// Default Y pivot (0 to 1) for new entities + pub default_pivot_y: f64, + + /// A structure containing all the definitions of this project + pub defs: Definitions, + + /// If the project isn't in MultiWorlds mode, this is the IID of the internal "dummy" World. + pub dummy_world_iid: String, + + /// If TRUE, the exported PNGs will include the level background (color or image). + pub export_level_bg: bool, + + /// **WARNING**: this deprecated value is no longer exported since version 0.9.3 Replaced + /// by: `imageExportMode` + pub export_png: Option<bool>, + + /// If TRUE, a Tiled compatible file will also be generated along with the LDtk JSON file + /// (default is FALSE) + pub export_tiled: bool, + + /// If TRUE, one file will be saved for the project (incl. all its definitions) and one file + /// in a sub-folder for each level. + pub external_levels: bool, + + /// An array containing various advanced flags (ie. options or other states). Possible + /// values: `DiscardPreCsvIntGrid`, `ExportPreCsvIntGridFormat`, `IgnoreBackupSuggest`, + /// `PrependIndexToLevelFileNames`, `MultiWorlds`, `UseMultilinesType` + pub flags: Vec<Flag>, + + /// Naming convention for Identifiers (first-letter uppercase, full uppercase etc.) Possible + /// values: `Capitalize`, `Uppercase`, `Lowercase`, `Free` + pub identifier_style: IdentifierStyle, + + /// Unique project identifier + pub iid: String, + + /// "Image export" option when saving project. Possible values: `None`, `OneImagePerLayer`, + /// `OneImagePerLevel`, `LayersAndLevels` + pub image_export_mode: ImageExportMode, + + /// File format version + pub json_version: String, + + /// The default naming convention for level identifiers. + pub level_name_pattern: String, + + /// All levels. The order of this array is only relevant in `LinearHorizontal` and + /// `linearVertical` world layouts (see `worldLayout` value).<br/> Otherwise, you should + /// refer to the `worldX`,`worldY` coordinates of each Level. + pub levels: Vec<Level>, + + /// If TRUE, the Json is partially minified (no indentation, nor line breaks, default is + /// FALSE) + pub minify_json: bool, + + /// Next Unique integer ID available + pub next_uid: i64, + + /// File naming pattern for exported PNGs + pub png_file_pattern: Option<String>, + + /// If TRUE, a very simplified will be generated on saving, for quicker & easier engine + /// integration. + pub simplified_export: bool, + + /// All instances of entities that have their `exportToToc` flag enabled are listed in this + /// array. + pub toc: Vec<LdtkTableOfContentEntry>, + + /// This optional description is used by LDtk Samples to show up some informations and + /// instructions. + pub tutorial_desc: Option<String>, + + /// **WARNING**: this field will move to the `worlds` array after the "multi-worlds" update. + /// It will then be `null`. You can enable the Multi-worlds advanced project option to enable + /// the change immediately.<br/><br/> Height of the world grid in pixels. + pub world_grid_height: Option<i64>, + + /// **WARNING**: this field will move to the `worlds` array after the "multi-worlds" update. + /// It will then be `null`. You can enable the Multi-worlds advanced project option to enable + /// the change immediately.<br/><br/> Width of the world grid in pixels. + pub world_grid_width: Option<i64>, + + /// **WARNING**: this field will move to the `worlds` array after the "multi-worlds" update. + /// It will then be `null`. You can enable the Multi-worlds advanced project option to enable + /// the change immediately.<br/><br/> An enum that describes how levels are organized in + /// this project (ie. linearly or in a 2D space). Possible values: <`null`>, `Free`, + /// `GridVania`, `LinearHorizontal`, `LinearVertical` + pub world_layout: Option<WorldLayout>, + + /// This array will be empty, unless you enable the Multi-Worlds in the project advanced + /// settings.<br/><br/> - in current version, a LDtk project file can only contain a single + /// world with multiple levels in it. In this case, levels and world layout related settings + /// are stored in the root of the JSON.<br/> - with "Multi-worlds" enabled, there will be a + /// `worlds` array in root, each world containing levels and layout settings. Basically, it's + /// pretty much only about moving the `levels` array to the `worlds` array, along with world + /// layout related values (eg. `worldGridWidth` etc).<br/><br/>If you want to start + /// supporting this future update easily, please refer to this documentation: + /// https://github.com/deepnight/ldtk/issues/231 + pub worlds: Vec<World>, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct LdtkCustomCommand { + pub command: String, + + /// Possible values: `Manual`, `AfterLoad`, `BeforeSave`, `AfterSave` + pub when: When, +} + +/// Possible values: `Manual`, `AfterLoad`, `BeforeSave`, `AfterSave` +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum When { + #[serde(rename = "AfterLoad")] + AfterLoad, + + #[serde(rename = "AfterSave")] + AfterSave, + + #[serde(rename = "BeforeSave")] + BeforeSave, + + Manual, +} + +/// If you're writing your own LDtk importer, you should probably just ignore *most* stuff in +/// the `defs` section, as it contains data that are mostly important to the editor. To keep +/// you away from the `defs` section and avoid some unnecessary JSON parsing, important data +/// from definitions is often duplicated in fields prefixed with a double underscore (eg. +/// `__identifier` or `__type`). The 2 only definition types you might need here are +/// **Tilesets** and **Enums**. +/// +/// A structure containing all the definitions of this project +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Definitions { + /// All entities definitions, including their custom fields + pub entities: Vec<EntityDefinition>, + + /// All internal enums + pub enums: Vec<EnumDefinition>, + + /// Note: external enums are exactly the same as `enums`, except they have a `relPath` to + /// point to an external source file. + pub external_enums: Vec<EnumDefinition>, + + /// All layer definitions + pub layers: Vec<LayerDefinition>, + + /// All custom fields available to all levels. + pub level_fields: Vec<FieldDefinition>, + + /// All tilesets + pub tilesets: Vec<TilesetDefinition>, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct EntityDefinition { + /// Base entity color + pub color: String, + + /// User defined documentation for this element to provide help/tips to level designers. + pub doc: Option<String>, + + /// If enabled, all instances of this entity will be listed in the project "Table of content" + /// object. + pub export_to_toc: bool, + + /// Array of field definitions + pub field_defs: Vec<FieldDefinition>, + + pub fill_opacity: f64, + + /// Pixel height + pub height: i64, + + pub hollow: bool, + + /// User defined unique identifier + pub identifier: String, + + /// Only applies to entities resizable on both X/Y. If TRUE, the entity instance width/height + /// will keep the same aspect ratio as the definition. + pub keep_aspect_ratio: bool, + + /// Possible values: `DiscardOldOnes`, `PreventAdding`, `MoveLastOne` + pub limit_behavior: LimitBehavior, + + /// If TRUE, the maxCount is a "per world" limit, if FALSE, it's a "per level". Possible + /// values: `PerLayer`, `PerLevel`, `PerWorld` + pub limit_scope: LimitScope, + + pub line_opacity: f64, + + /// Max instances count + pub max_count: i64, + + /// Max pixel height (only applies if the entity is resizable on Y) + pub max_height: Option<i64>, + + /// Max pixel width (only applies if the entity is resizable on X) + pub max_width: Option<i64>, + + /// Min pixel height (only applies if the entity is resizable on Y) + pub min_height: Option<i64>, + + /// Min pixel width (only applies if the entity is resizable on X) + pub min_width: Option<i64>, + + /// An array of 4 dimensions for the up/right/down/left borders (in this order) when using + /// 9-slice mode for `tileRenderMode`.<br/> If the tileRenderMode is not NineSlice, then + /// this array is empty.<br/> See: https://en.wikipedia.org/wiki/9-slice_scaling + pub nine_slice_borders: Vec<i64>, + + /// Pivot X coordinate (from 0 to 1.0) + pub pivot_x: f64, + + /// Pivot Y coordinate (from 0 to 1.0) + pub pivot_y: f64, + + /// Possible values: `Rectangle`, `Ellipse`, `Tile`, `Cross` + pub render_mode: RenderMode, + + /// If TRUE, the entity instances will be resizable horizontally + pub resizable_x: bool, + + /// If TRUE, the entity instances will be resizable vertically + pub resizable_y: bool, + + /// Display entity name in editor + pub show_name: bool, + + /// An array of strings that classifies this entity + pub tags: Vec<String>, + + /// **WARNING**: this deprecated value is no longer exported since version 1.2.0 Replaced + /// by: `tileRect` + pub tile_id: Option<i64>, + + pub tile_opacity: f64, + + /// An object representing a rectangle from an existing Tileset + pub tile_rect: Option<TilesetRectangle>, + + /// An enum describing how the the Entity tile is rendered inside the Entity bounds. Possible + /// values: `Cover`, `FitInside`, `Repeat`, `Stretch`, `FullSizeCropped`, + /// `FullSizeUncropped`, `NineSlice` + pub tile_render_mode: TileRenderMode, + + /// Tileset ID used for optional tile display + pub tileset_id: Option<i64>, + + /// Unique Int identifier + pub uid: i64, + + /// This tile overrides the one defined in `tileRect` in the UI + pub ui_tile_rect: Option<TilesetRectangle>, + + /// Pixel width + pub width: i64, +} + +/// This section is mostly only intended for the LDtk editor app itself. You can safely +/// ignore it. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FieldDefinition { + /// Human readable value type. Possible values: `Int, Float, String, Bool, Color, + /// ExternEnum.XXX, LocalEnum.XXX, Point, FilePath`.<br/> If the field is an array, this + /// field will look like `Array<...>` (eg. `Array<Int>`, `Array<Point>` etc.)<br/> NOTE: if + /// you enable the advanced option **Use Multilines type**, you will have "*Multilines*" + /// instead of "*String*" when relevant. + #[serde(rename = "__type")] + pub field_definition_type: String, + + /// Optional list of accepted file extensions for FilePath value type. Includes the dot: + /// `.ext` + pub accept_file_types: Option<Vec<String>>, + + /// Possible values: `Any`, `OnlySame`, `OnlyTags`, `OnlySpecificEntity` + pub allowed_refs: AllowedRefs, + + pub allowed_refs_entity_uid: Option<i64>, + + pub allowed_ref_tags: Vec<String>, + + pub allow_out_of_level_ref: bool, + + /// Array max length + pub array_max_length: Option<i64>, + + /// Array min length + pub array_min_length: Option<i64>, + + pub auto_chain_ref: bool, + + /// TRUE if the value can be null. For arrays, TRUE means it can contain null values + /// (exception: array of Points can't have null values). + pub can_be_null: bool, + + /// Default value if selected value is null or invalid. + pub default_override: Option<serde_json::Value>, + + /// User defined documentation for this field to provide help/tips to level designers about + /// accepted values. + pub doc: Option<String>, + + pub editor_always_show: bool, + + pub editor_cut_long_values: bool, + + pub editor_display_color: Option<String>, + + /// Possible values: `Hidden`, `ValueOnly`, `NameAndValue`, `EntityTile`, `LevelTile`, + /// `Points`, `PointStar`, `PointPath`, `PointPathLoop`, `RadiusPx`, `RadiusGrid`, + /// `ArrayCountWithLabel`, `ArrayCountNoLabel`, `RefLinkBetweenPivots`, + /// `RefLinkBetweenCenters` + pub editor_display_mode: EditorDisplayMode, + + /// Possible values: `Above`, `Center`, `Beneath` + pub editor_display_pos: EditorDisplayPos, + + pub editor_display_scale: f64, + + /// Possible values: `ZigZag`, `StraightArrow`, `CurvedArrow`, `ArrowsLine`, `DashedLine` + pub editor_link_style: EditorLinkStyle, + + pub editor_show_in_world: bool, + + pub editor_text_prefix: Option<String>, + + pub editor_text_suffix: Option<String>, + + /// User defined unique identifier + pub identifier: String, + + /// TRUE if the value is an array of multiple values + pub is_array: bool, + + /// Max limit for value, if applicable + pub max: Option<f64>, + + /// Min limit for value, if applicable + pub min: Option<f64>, + + /// Optional regular expression that needs to be matched to accept values. Expected format: + /// `/some_reg_ex/g`, with optional "i" flag. + pub regex: Option<String>, + + pub symmetrical_ref: bool, + + /// Possible values: <`null`>, `LangPython`, `LangRuby`, `LangJS`, `LangLua`, `LangC`, + /// `LangHaxe`, `LangMarkdown`, `LangJson`, `LangXml`, `LangLog` + pub text_language_mode: Option<TextLanguageMode>, + + /// UID of the tileset used for a Tile + pub tileset_uid: Option<i64>, + + /// Internal enum representing the possible field types. Possible values: F_Int, F_Float, + /// F_String, F_Text, F_Bool, F_Color, F_Enum(...), F_Point, F_Path, F_EntityRef, F_Tile + #[serde(rename = "type")] + pub purple_type: String, + + /// Unique Int identifier + pub uid: i64, + + /// If TRUE, the color associated with this field will override the Entity or Level default + /// color in the editor UI. For Enum fields, this would be the color associated to their + /// values. + pub use_for_smart_color: bool, +} + +/// Possible values: `Any`, `OnlySame`, `OnlyTags`, `OnlySpecificEntity` +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum AllowedRefs { + Any, + + #[serde(rename = "OnlySame")] + OnlySame, + + #[serde(rename = "OnlySpecificEntity")] + OnlySpecificEntity, + + #[serde(rename = "OnlyTags")] + OnlyTags, +} + +/// Possible values: `Hidden`, `ValueOnly`, `NameAndValue`, `EntityTile`, `LevelTile`, +/// `Points`, `PointStar`, `PointPath`, `PointPathLoop`, `RadiusPx`, `RadiusGrid`, +/// `ArrayCountWithLabel`, `ArrayCountNoLabel`, `RefLinkBetweenPivots`, +/// `RefLinkBetweenCenters` +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum EditorDisplayMode { + #[serde(rename = "ArrayCountNoLabel")] + ArrayCountNoLabel, + + #[serde(rename = "ArrayCountWithLabel")] + ArrayCountWithLabel, + + #[serde(rename = "EntityTile")] + EntityTile, + + Hidden, + + #[serde(rename = "LevelTile")] + LevelTile, + + #[serde(rename = "NameAndValue")] + NameAndValue, + + #[serde(rename = "PointPath")] + PointPath, + + #[serde(rename = "PointPathLoop")] + PointPathLoop, + + #[serde(rename = "PointStar")] + PointStar, + + Points, + + #[serde(rename = "RadiusGrid")] + RadiusGrid, + + #[serde(rename = "RadiusPx")] + RadiusPx, + + #[serde(rename = "RefLinkBetweenCenters")] + RefLinkBetweenCenters, + + #[serde(rename = "RefLinkBetweenPivots")] + RefLinkBetweenPivots, + + #[serde(rename = "ValueOnly")] + ValueOnly, +} + +/// Possible values: `Above`, `Center`, `Beneath` +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum EditorDisplayPos { + Above, + + Beneath, + + Center, +} + +/// Possible values: `ZigZag`, `StraightArrow`, `CurvedArrow`, `ArrowsLine`, `DashedLine` +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum EditorLinkStyle { + #[serde(rename = "ArrowsLine")] + ArrowsLine, + + #[serde(rename = "CurvedArrow")] + CurvedArrow, + + #[serde(rename = "DashedLine")] + DashedLine, + + #[serde(rename = "StraightArrow")] + StraightArrow, + + #[serde(rename = "ZigZag")] + ZigZag, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum TextLanguageMode { + #[serde(rename = "LangC")] + LangC, + + #[serde(rename = "LangHaxe")] + LangHaxe, + + #[serde(rename = "LangJS")] + LangJs, + + #[serde(rename = "LangJson")] + LangJson, + + #[serde(rename = "LangLog")] + LangLog, + + #[serde(rename = "LangLua")] + LangLua, + + #[serde(rename = "LangMarkdown")] + LangMarkdown, + + #[serde(rename = "LangPython")] + LangPython, + + #[serde(rename = "LangRuby")] + LangRuby, + + #[serde(rename = "LangXml")] + LangXml, +} + +/// Possible values: `DiscardOldOnes`, `PreventAdding`, `MoveLastOne` +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum LimitBehavior { + #[serde(rename = "DiscardOldOnes")] + DiscardOldOnes, + + #[serde(rename = "MoveLastOne")] + MoveLastOne, + + #[serde(rename = "PreventAdding")] + PreventAdding, +} + +/// If TRUE, the maxCount is a "per world" limit, if FALSE, it's a "per level". Possible +/// values: `PerLayer`, `PerLevel`, `PerWorld` +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum LimitScope { + #[serde(rename = "PerLayer")] + PerLayer, + + #[serde(rename = "PerLevel")] + PerLevel, + + #[serde(rename = "PerWorld")] + PerWorld, +} + +/// Possible values: `Rectangle`, `Ellipse`, `Tile`, `Cross` +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum RenderMode { + Cross, + + Ellipse, + + Rectangle, + + Tile, +} + +/// This object represents a custom sub rectangle in a Tileset image. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TilesetRectangle { + /// Height in pixels + pub h: i64, + + /// UID of the tileset + pub tileset_uid: i64, + + /// Width in pixels + pub w: i64, + + /// X pixels coordinate of the top-left corner in the Tileset image + pub x: i64, + + /// Y pixels coordinate of the top-left corner in the Tileset image + pub y: i64, +} + +/// An enum describing how the the Entity tile is rendered inside the Entity bounds. Possible +/// values: `Cover`, `FitInside`, `Repeat`, `Stretch`, `FullSizeCropped`, +/// `FullSizeUncropped`, `NineSlice` +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum TileRenderMode { + Cover, + + #[serde(rename = "FitInside")] + FitInside, + + #[serde(rename = "FullSizeCropped")] + FullSizeCropped, + + #[serde(rename = "FullSizeUncropped")] + FullSizeUncropped, + + #[serde(rename = "NineSlice")] + NineSlice, + + Repeat, + + Stretch, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct EnumDefinition { + pub external_file_checksum: Option<String>, + + /// Relative path to the external file providing this Enum + pub external_rel_path: Option<String>, + + /// Tileset UID if provided + pub icon_tileset_uid: Option<i64>, + + /// User defined unique identifier + pub identifier: String, + + /// An array of user-defined tags to organize the Enums + pub tags: Vec<String>, + + /// Unique Int identifier + pub uid: i64, + + /// All possible enum values, with their optional Tile infos. + pub values: Vec<EnumValueDefinition>, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct EnumValueDefinition { + /// **WARNING**: this deprecated value is no longer exported since version 1.4.0 Replaced + /// by: `tileRect` + #[serde(rename = "__tileSrcRect")] + pub tile_src_rect: Option<Vec<i64>>, + + /// Optional color + pub color: i64, + + /// Enum value + pub id: String, + + /// **WARNING**: this deprecated value is no longer exported since version 1.4.0 Replaced + /// by: `tileRect` + pub tile_id: Option<i64>, + + /// Optional tileset rectangle to represents this value + pub tile_rect: Option<TilesetRectangle>, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct LayerDefinition { + /// Type of the layer (*IntGrid, Entities, Tiles or AutoLayer*) + #[serde(rename = "__type")] + pub layer_definition_type: String, + + /// Contains all the auto-layer rule definitions. + pub auto_rule_groups: Vec<AutoLayerRuleGroup>, + + pub auto_source_layer_def_uid: Option<i64>, + + /// **WARNING**: this deprecated value is no longer exported since version 1.2.0 Replaced + /// by: `tilesetDefUid` + pub auto_tileset_def_uid: Option<i64>, + + /// Allow editor selections when the layer is not currently active. + pub can_select_when_inactive: bool, + + /// Opacity of the layer (0 to 1.0) + pub display_opacity: f64, + + /// User defined documentation for this element to provide help/tips to level designers. + pub doc: Option<String>, + + /// An array of tags to forbid some Entities in this layer + pub excluded_tags: Vec<String>, + + /// Width and height of the grid in pixels + pub grid_size: i64, + + /// Height of the optional "guide" grid in pixels + pub guide_grid_hei: i64, + + /// Width of the optional "guide" grid in pixels + pub guide_grid_wid: i64, + + pub hide_fields_when_inactive: bool, + + /// Hide the layer from the list on the side of the editor view. + pub hide_in_list: bool, + + /// User defined unique identifier + pub identifier: String, + + /// Alpha of this layer when it is not the active one. + pub inactive_opacity: f64, + + /// An array that defines extra optional info for each IntGrid value.<br/> WARNING: the + /// array order is not related to actual IntGrid values! As user can re-order IntGrid values + /// freely, you may value "2" before value "1" in this array. + pub int_grid_values: Vec<IntGridValueDefinition>, + + /// Group informations for IntGrid values + pub int_grid_values_groups: Vec<IntGridValueGroupDefinition>, + + /// Parallax horizontal factor (from -1 to 1, defaults to 0) which affects the scrolling + /// speed of this layer, creating a fake 3D (parallax) effect. + pub parallax_factor_x: f64, + + /// Parallax vertical factor (from -1 to 1, defaults to 0) which affects the scrolling speed + /// of this layer, creating a fake 3D (parallax) effect. + pub parallax_factor_y: f64, + + /// If true (default), a layer with a parallax factor will also be scaled up/down accordingly. + pub parallax_scaling: bool, + + /// X offset of the layer, in pixels (IMPORTANT: this should be added to the `LayerInstance` + /// optional offset) + pub px_offset_x: i64, + + /// Y offset of the layer, in pixels (IMPORTANT: this should be added to the `LayerInstance` + /// optional offset) + pub px_offset_y: i64, + + /// If TRUE, the content of this layer will be used when rendering levels in a simplified way + /// for the world view + pub render_in_world_view: bool, + + /// An array of tags to filter Entities that can be added to this layer + pub required_tags: Vec<String>, + + /// If the tiles are smaller or larger than the layer grid, the pivot value will be used to + /// position the tile relatively its grid cell. + pub tile_pivot_x: f64, + + /// If the tiles are smaller or larger than the layer grid, the pivot value will be used to + /// position the tile relatively its grid cell. + pub tile_pivot_y: f64, + + /// Reference to the default Tileset UID being used by this layer definition.<br/> + /// **WARNING**: some layer *instances* might use a different tileset. So most of the time, + /// you should probably use the `__tilesetDefUid` value found in layer instances.<br/> Note: + /// since version 1.0.0, the old `autoTilesetDefUid` was removed and merged into this value. + pub tileset_def_uid: Option<i64>, + + /// Type of the layer as Haxe Enum Possible values: `IntGrid`, `Entities`, `Tiles`, + /// `AutoLayer` + #[serde(rename = "type")] + pub purple_type: Type, + + /// User defined color for the UI + pub ui_color: Option<String>, + + /// Unique Int identifier + pub uid: i64, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AutoLayerRuleGroup { + pub active: bool, + + /// *This field was removed in 1.0.0 and should no longer be used.* + pub collapsed: Option<bool>, + + pub color: Option<String>, + + pub icon: Option<TilesetRectangle>, + + pub is_optional: bool, + + pub name: String, + + pub rules: Vec<AutoLayerRuleDefinition>, + + pub uid: i64, + + pub uses_wizard: bool, +} + +/// This complex section isn't meant to be used by game devs at all, as these rules are +/// completely resolved internally by the editor before any saving. You should just ignore +/// this part. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AutoLayerRuleDefinition { + /// If FALSE, the rule effect isn't applied, and no tiles are generated. + pub active: bool, + + pub alpha: f64, + + /// When TRUE, the rule will prevent other rules to be applied in the same cell if it matches + /// (TRUE by default). + pub break_on_match: bool, + + /// Chances for this rule to be applied (0 to 1) + pub chance: f64, + + /// Checker mode Possible values: `None`, `Horizontal`, `Vertical` + pub checker: Checker, + + /// If TRUE, allow rule to be matched by flipping its pattern horizontally + pub flip_x: bool, + + /// If TRUE, allow rule to be matched by flipping its pattern vertically + pub flip_y: bool, + + /// Default IntGrid value when checking cells outside of level bounds + pub out_of_bounds_value: Option<i64>, + + /// Rule pattern (size x size) + pub pattern: Vec<i64>, + + /// If TRUE, enable Perlin filtering to only apply rule on specific random area + pub perlin_active: bool, + + pub perlin_octaves: f64, + + pub perlin_scale: f64, + + pub perlin_seed: f64, + + /// X pivot of a tile stamp (0-1) + pub pivot_x: f64, + + /// Y pivot of a tile stamp (0-1) + pub pivot_y: f64, + + /// Pattern width & height. Should only be 1,3,5 or 7. + pub size: i64, + + /// Array of all the tile IDs. They are used randomly or as stamps, based on `tileMode` value. + pub tile_ids: Vec<i64>, + + /// Defines how tileIds array is used Possible values: `Single`, `Stamp` + pub tile_mode: TileMode, + + /// Max random offset for X tile pos + pub tile_random_x_max: i64, + + /// Min random offset for X tile pos + pub tile_random_x_min: i64, + + /// Max random offset for Y tile pos + pub tile_random_y_max: i64, + + /// Min random offset for Y tile pos + pub tile_random_y_min: i64, + + /// Tile X offset + pub tile_x_offset: i64, + + /// Tile Y offset + pub tile_y_offset: i64, + + /// Unique Int identifier + pub uid: i64, + + /// X cell coord modulo + pub x_modulo: i64, + + /// X cell start offset + pub x_offset: i64, + + /// Y cell coord modulo + pub y_modulo: i64, + + /// Y cell start offset + pub y_offset: i64, +} + +/// Checker mode Possible values: `None`, `Horizontal`, `Vertical` +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Checker { + Horizontal, + + None, + + Vertical, +} + +/// Defines how tileIds array is used Possible values: `Single`, `Stamp` +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum TileMode { + Single, + + Stamp, +} + +/// IntGrid value definition +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct IntGridValueDefinition { + pub color: String, + + /// Parent group identifier (0 if none) + pub group_uid: i64, + + /// User defined unique identifier + pub identifier: Option<String>, + + pub tile: Option<TilesetRectangle>, + + /// The IntGrid value itself + pub value: i64, +} + +/// IntGrid value group definition +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct IntGridValueGroupDefinition { + /// User defined color + pub color: Option<String>, + + /// User defined string identifier + pub identifier: Option<String>, + + /// Group unique ID + pub uid: i64, +} + +/// Type of the layer as Haxe Enum Possible values: `IntGrid`, `Entities`, `Tiles`, +/// `AutoLayer` +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Type { + #[serde(rename = "AutoLayer")] + AutoLayer, + + Entities, + + #[serde(rename = "IntGrid")] + IntGrid, + + Tiles, +} + +/// The `Tileset` definition is the most important part among project definitions. It +/// contains some extra informations about each integrated tileset. If you only had to parse +/// one definition section, that would be the one. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TilesetDefinition { + /// Grid-based height + #[serde(rename = "__cHei")] + pub c_hei: i64, + + /// Grid-based width + #[serde(rename = "__cWid")] + pub c_wid: i64, + + /// The following data is used internally for various optimizations. It's always synced with + /// source image changes. + pub cached_pixel_data: Option<HashMap<String, Option<serde_json::Value>>>, + + /// An array of custom tile metadata + pub custom_data: Vec<TileCustomMetadata>, + + /// If this value is set, then it means that this atlas uses an internal LDtk atlas image + /// instead of a loaded one. Possible values: <`null`>, `LdtkIcons` + pub embed_atlas: Option<EmbedAtlas>, + + /// Tileset tags using Enum values specified by `tagsSourceEnumId`. This array contains 1 + /// element per Enum value, which contains an array of all Tile IDs that are tagged with it. + pub enum_tags: Vec<EnumTagValue>, + + /// User defined unique identifier + pub identifier: String, + + /// Distance in pixels from image borders + pub padding: i64, + + /// Image height in pixels + pub px_hei: i64, + + /// Image width in pixels + pub px_wid: i64, + + /// Path to the source file, relative to the current project JSON file<br/> It can be null + /// if no image was provided, or when using an embed atlas. + pub rel_path: Option<String>, + + /// Array of group of tiles selections, only meant to be used in the editor + pub saved_selections: Vec<HashMap<String, Option<serde_json::Value>>>, + + /// Space in pixels between all tiles + pub spacing: i64, + + /// An array of user-defined tags to organize the Tilesets + pub tags: Vec<String>, + + /// Optional Enum definition UID used for this tileset meta-data + pub tags_source_enum_uid: Option<i64>, + + pub tile_grid_size: i64, + + /// Unique Intidentifier + pub uid: i64, +} + +/// In a tileset definition, user defined meta-data of a tile. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TileCustomMetadata { + pub data: String, + + pub tile_id: i64, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum EmbedAtlas { + #[serde(rename = "LdtkIcons")] + LdtkIcons, +} + +/// In a tileset definition, enum based tag infos +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct EnumTagValue { + pub enum_value_id: String, + + pub tile_ids: Vec<i64>, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Flag { + #[serde(rename = "DiscardPreCsvIntGrid")] + DiscardPreCsvIntGrid, + + #[serde(rename = "ExportPreCsvIntGridFormat")] + ExportPreCsvIntGridFormat, + + #[serde(rename = "IgnoreBackupSuggest")] + IgnoreBackupSuggest, + + #[serde(rename = "MultiWorlds")] + MultiWorlds, + + #[serde(rename = "PrependIndexToLevelFileNames")] + PrependIndexToLevelFileNames, + + #[serde(rename = "UseMultilinesType")] + UseMultilinesType, +} + +/// This object is not actually used by LDtk. It ONLY exists to force explicit references to +/// all types, to make sure QuickType finds them and integrate all of them. Otherwise, +/// Quicktype will drop types that are not explicitely used. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct ForcedRefs { + pub auto_layer_rule_group: Option<AutoLayerRuleGroup>, + + pub auto_rule_def: Option<AutoLayerRuleDefinition>, + + pub custom_command: Option<LdtkCustomCommand>, + + pub definitions: Option<Definitions>, + + pub entity_def: Option<EntityDefinition>, + + pub entity_instance: Option<EntityInstance>, + + pub entity_reference_infos: Option<ReferenceToAnEntityInstance>, + + pub enum_def: Option<EnumDefinition>, + + pub enum_def_values: Option<EnumValueDefinition>, + + pub enum_tag_value: Option<EnumTagValue>, + + pub field_def: Option<FieldDefinition>, + + pub field_instance: Option<FieldInstance>, + + pub grid_point: Option<GridPoint>, + + pub int_grid_value_def: Option<IntGridValueDefinition>, + + pub int_grid_value_group_def: Option<IntGridValueGroupDefinition>, + + pub int_grid_value_instance: Option<IntGridValueInstance>, + + pub layer_def: Option<LayerDefinition>, + + pub layer_instance: Option<LayerInstance>, + + pub level: Option<Level>, + + pub level_bg_pos_infos: Option<LevelBackgroundPosition>, + + pub neighbour_level: Option<NeighbourLevel>, + + pub table_of_content_entry: Option<LdtkTableOfContentEntry>, + + pub tile: Option<TileInstance>, + + pub tile_custom_metadata: Option<TileCustomMetadata>, + + pub tileset_def: Option<TilesetDefinition>, + + pub tileset_rect: Option<TilesetRectangle>, + + pub world: Option<World>, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct EntityInstance { + /// Grid-based coordinates (`[x,y]` format) + #[serde(rename = "__grid")] + pub grid: Vec<i64>, + + /// Entity definition identifier + #[serde(rename = "__identifier")] + pub identifier: String, + + /// Pivot coordinates (`[x,y]` format, values are from 0 to 1) of the Entity + #[serde(rename = "__pivot")] + pub pivot: Vec<f64>, + + /// The entity "smart" color, guessed from either Entity definition, or one its field + /// instances. + #[serde(rename = "__smartColor")] + pub smart_color: String, + + /// Array of tags defined in this Entity definition + #[serde(rename = "__tags")] + pub tags: Vec<String>, + + /// Optional TilesetRect used to display this entity (it could either be the default Entity + /// tile, or some tile provided by a field value, like an Enum). + #[serde(rename = "__tile")] + pub tile: Option<TilesetRectangle>, + + /// X world coordinate in pixels + #[serde(rename = "__worldX")] + pub world_x: i64, + + /// Y world coordinate in pixels + #[serde(rename = "__worldY")] + pub world_y: i64, + + /// Reference of the **Entity definition** UID + pub def_uid: i64, + + /// An array of all custom fields and their values. + pub field_instances: Vec<FieldInstance>, + + /// Entity height in pixels. For non-resizable entities, it will be the same as Entity + /// definition. + pub height: i64, + + /// Unique instance identifier + pub iid: String, + + /// Pixel coordinates (`[x,y]` format) in current level coordinate space. Don't forget + /// optional layer offsets, if they exist! + pub px: Vec<i64>, + + /// Entity width in pixels. For non-resizable entities, it will be the same as Entity + /// definition. + pub width: i64, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FieldInstance { + /// Field definition identifier + #[serde(rename = "__identifier")] + pub identifier: String, + + /// Optional TilesetRect used to display this field (this can be the field own Tile, or some + /// other Tile guessed from the value, like an Enum). + #[serde(rename = "__tile")] + pub tile: Option<TilesetRectangle>, + + /// Type of the field, such as `Int`, `Float`, `String`, `Enum(my_enum_name)`, `Bool`, + /// etc.<br/> NOTE: if you enable the advanced option **Use Multilines type**, you will have + /// "*Multilines*" instead of "*String*" when relevant. + #[serde(rename = "__type")] + pub field_instance_type: String, + + /// Actual value of the field instance. The value type varies, depending on `__type`:<br/> + /// - For **classic types** (ie. Integer, Float, Boolean, String, Text and FilePath), you + /// just get the actual value with the expected type.<br/> - For **Color**, the value is an + /// hexadecimal string using "#rrggbb" format.<br/> - For **Enum**, the value is a String + /// representing the selected enum value.<br/> - For **Point**, the value is a + /// [GridPoint](#ldtk-GridPoint) object.<br/> - For **Tile**, the value is a + /// [TilesetRect](#ldtk-TilesetRect) object.<br/> - For **EntityRef**, the value is an + /// [EntityReferenceInfos](#ldtk-EntityReferenceInfos) object.<br/><br/> If the field is an + /// array, then this `__value` will also be a JSON array. + #[serde(rename = "__value")] + pub value: Option<serde_json::Value>, + + /// Reference of the **Field definition** UID + pub def_uid: i64, + + /// Editor internal raw values + pub real_editor_values: Vec<Option<serde_json::Value>>, +} + +/// This object describes the "location" of an Entity instance in the project worlds. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ReferenceToAnEntityInstance { + /// IID of the refered EntityInstance + pub entity_iid: String, + + /// IID of the LayerInstance containing the refered EntityInstance + pub layer_iid: String, + + /// IID of the Level containing the refered EntityInstance + pub level_iid: String, + + /// IID of the World containing the refered EntityInstance + pub world_iid: String, +} + +/// This object is just a grid-based coordinate used in Field values. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct GridPoint { + /// X grid-based coordinate + pub cx: i64, + + /// Y grid-based coordinate + pub cy: i64, +} + +/// IntGrid value instance +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct IntGridValueInstance { + /// Coordinate ID in the layer grid + pub coord_id: i64, + + /// IntGrid value + pub v: i64, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct LayerInstance { + /// Grid-based height + #[serde(rename = "__cHei")] + pub c_hei: i64, + + /// Grid-based width + #[serde(rename = "__cWid")] + pub c_wid: i64, + + /// Grid size + #[serde(rename = "__gridSize")] + pub grid_size: i64, + + /// Layer definition identifier + #[serde(rename = "__identifier")] + pub identifier: String, + + /// Layer opacity as Float [0-1] + #[serde(rename = "__opacity")] + pub opacity: f64, + + /// Total layer X pixel offset, including both instance and definition offsets. + #[serde(rename = "__pxTotalOffsetX")] + pub px_total_offset_x: i64, + + /// Total layer Y pixel offset, including both instance and definition offsets. + #[serde(rename = "__pxTotalOffsetY")] + pub px_total_offset_y: i64, + + /// The definition UID of corresponding Tileset, if any. + #[serde(rename = "__tilesetDefUid")] + pub tileset_def_uid: Option<i64>, + + /// The relative path to corresponding Tileset, if any. + #[serde(rename = "__tilesetRelPath")] + pub tileset_rel_path: Option<String>, + + /// Layer type (possible values: IntGrid, Entities, Tiles or AutoLayer) + #[serde(rename = "__type")] + pub layer_instance_type: String, + + /// An array containing all tiles generated by Auto-layer rules. The array is already sorted + /// in display order (ie. 1st tile is beneath 2nd, which is beneath 3rd etc.).<br/><br/> + /// Note: if multiple tiles are stacked in the same cell as the result of different rules, + /// all tiles behind opaque ones will be discarded. + pub auto_layer_tiles: Vec<TileInstance>, + + pub entity_instances: Vec<EntityInstance>, + + pub grid_tiles: Vec<TileInstance>, + + /// Unique layer instance identifier + pub iid: String, + + /// **WARNING**: this deprecated value is no longer exported since version 1.0.0 Replaced + /// by: `intGridCsv` + pub int_grid: Option<Vec<IntGridValueInstance>>, + + /// A list of all values in the IntGrid layer, stored in CSV format (Comma Separated + /// Values).<br/> Order is from left to right, and top to bottom (ie. first row from left to + /// right, followed by second row, etc).<br/> `0` means "empty cell" and IntGrid values + /// start at 1.<br/> The array size is `__cWid` x `__cHei` cells. + pub int_grid_csv: Vec<i64>, + + /// Reference the Layer definition UID + pub layer_def_uid: i64, + + /// Reference to the UID of the level containing this layer instance + pub level_id: i64, + + /// An Array containing the UIDs of optional rules that were enabled in this specific layer + /// instance. + pub optional_rules: Vec<i64>, + + /// This layer can use another tileset by overriding the tileset UID here. + pub override_tileset_uid: Option<i64>, + + /// X offset in pixels to render this layer, usually 0 (IMPORTANT: this should be added to + /// the `LayerDef` optional offset, so you should probably prefer using `__pxTotalOffsetX` + /// which contains the total offset value) + pub px_offset_x: i64, + + /// Y offset in pixels to render this layer, usually 0 (IMPORTANT: this should be added to + /// the `LayerDef` optional offset, so you should probably prefer using `__pxTotalOffsetX` + /// which contains the total offset value) + pub px_offset_y: i64, + + /// Random seed used for Auto-Layers rendering + pub seed: i64, + + /// Layer instance visibility + pub visible: bool, +} + +/// This structure represents a single tile from a given Tileset. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct TileInstance { + /// Alpha/opacity of the tile (0-1, defaults to 1) + pub a: f64, + + /// Internal data used by the editor.<br/> For auto-layer tiles: `[ruleId, coordId]`.<br/> + /// For tile-layer tiles: `[coordId]`. + pub d: Vec<i64>, + + /// "Flip bits", a 2-bits integer to represent the mirror transformations of the tile.<br/> + /// - Bit 0 = X flip<br/> - Bit 1 = Y flip<br/> Examples: f=0 (no flip), f=1 (X flip + /// only), f=2 (Y flip only), f=3 (both flips) + pub f: i64, + + /// Pixel coordinates of the tile in the **layer** (`[x,y]` format). Don't forget optional + /// layer offsets, if they exist! + pub px: Vec<i64>, + + /// Pixel coordinates of the tile in the **tileset** (`[x,y]` format) + pub src: Vec<i64>, + + /// The *Tile ID* in the corresponding tileset. + pub t: i64, +} + +/// This section contains all the level data. It can be found in 2 distinct forms, depending +/// on Project current settings: - If "*Separate level files*" is **disabled** (default): +/// full level data is *embedded* inside the main Project JSON file, - If "*Separate level +/// files*" is **enabled**: level data is stored in *separate* standalone `.ldtkl` files (one +/// per level). In this case, the main Project JSON file will still contain most level data, +/// except heavy sections, like the `layerInstances` array (which will be null). The +/// `externalRelPath` string points to the `ldtkl` file. A `ldtkl` file is just a JSON file +/// containing exactly what is described below. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Level { + /// Background color of the level (same as `bgColor`, except the default value is + /// automatically used here if its value is `null`) + #[serde(rename = "__bgColor")] + pub bg_color: String, + + /// Position informations of the background image, if there is one. + #[serde(rename = "__bgPos")] + pub bg_pos: Option<LevelBackgroundPosition>, + + /// An array listing all other levels touching this one on the world map. Since 1.4.0, this + /// includes levels that overlap in the same world layer, or in nearby world layers.<br/> + /// Only relevant for world layouts where level spatial positioning is manual (ie. GridVania, + /// Free). For Horizontal and Vertical layouts, this array is always empty. + #[serde(rename = "__neighbours")] + pub neighbours: Vec<NeighbourLevel>, + + /// The "guessed" color for this level in the editor, decided using either the background + /// color or an existing custom field. + #[serde(rename = "__smartColor")] + pub smart_color: String, + + /// Background color of the level. If `null`, the project `defaultLevelBgColor` should be + /// used. + #[serde(rename = "bgColor")] + pub level_bg_color: Option<String>, + + /// Background image X pivot (0-1) + pub bg_pivot_x: f64, + + /// Background image Y pivot (0-1) + pub bg_pivot_y: f64, + + /// An enum defining the way the background image (if any) is positioned on the level. See + /// `__bgPos` for resulting position info. Possible values: <`null`>, `Unscaled`, + /// `Contain`, `Cover`, `CoverDirty`, `Repeat` + #[serde(rename = "bgPos")] + pub level_bg_pos: Option<BgPos>, + + /// The *optional* relative path to the level background image. + pub bg_rel_path: Option<String>, + + /// This value is not null if the project option "*Save levels separately*" is enabled. In + /// this case, this **relative** path points to the level Json file. + pub external_rel_path: Option<String>, + + /// An array containing this level custom field values. + pub field_instances: Vec<FieldInstance>, + + /// User defined unique identifier + pub identifier: String, + + /// Unique instance identifier + pub iid: String, + + /// An array containing all Layer instances. **IMPORTANT**: if the project option "*Save + /// levels separately*" is enabled, this field will be `null`.<br/> This array is **sorted + /// in display order**: the 1st layer is the top-most and the last is behind. + pub layer_instances: Option<Vec<LayerInstance>>, + + /// Height of the level in pixels + pub px_hei: i64, + + /// Width of the level in pixels + pub px_wid: i64, + + /// Unique Int identifier + pub uid: i64, + + /// If TRUE, the level identifier will always automatically use the naming pattern as defined + /// in `Project.levelNamePattern`. Becomes FALSE if the identifier is manually modified by + /// user. + pub use_auto_identifier: bool, + + /// Index that represents the "depth" of the level in the world. Default is 0, greater means + /// "above", lower means "below".<br/> This value is mostly used for display only and is + /// intended to make stacking of levels easier to manage. + pub world_depth: i64, + + /// World X coordinate in pixels.<br/> Only relevant for world layouts where level spatial + /// positioning is manual (ie. GridVania, Free). For Horizontal and Vertical layouts, the + /// value is always -1 here. + pub world_x: i64, + + /// World Y coordinate in pixels.<br/> Only relevant for world layouts where level spatial + /// positioning is manual (ie. GridVania, Free). For Horizontal and Vertical layouts, the + /// value is always -1 here. + pub world_y: i64, +} + +/// Level background image position info +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct LevelBackgroundPosition { + /// An array of 4 float values describing the cropped sub-rectangle of the displayed + /// background image. This cropping happens when original is larger than the level bounds. + /// Array format: `[ cropX, cropY, cropWidth, cropHeight ]` + pub crop_rect: Vec<f64>, + + /// An array containing the `[scaleX,scaleY]` values of the **cropped** background image, + /// depending on `bgPos` option. + pub scale: Vec<f64>, + + /// An array containing the `[x,y]` pixel coordinates of the top-left corner of the + /// **cropped** background image, depending on `bgPos` option. + pub top_left_px: Vec<i64>, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum BgPos { + Contain, + + Cover, + + #[serde(rename = "CoverDirty")] + CoverDirty, + + Repeat, + + Unscaled, +} + +/// Nearby level info +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct NeighbourLevel { + /// A single lowercase character tipping on the level location (`n`orth, `s`outh, `w`est, + /// `e`ast).<br/> Since 1.4.0, this character value can also be `<` (neighbour depth is + /// lower), `>` (neighbour depth is greater) or `o` (levels overlap and share the same world + /// depth). + pub dir: String, + + /// Neighbour Instance Identifier + pub level_iid: String, + + /// **WARNING**: this deprecated value is no longer exported since version 1.2.0 Replaced + /// by: `levelIid` + pub level_uid: Option<i64>, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct LdtkTableOfContentEntry { + pub identifier: String, + + pub instances: Vec<ReferenceToAnEntityInstance>, +} + +/// **IMPORTANT**: this type is available as a preview. You can rely on it to update your +/// importers, for when it will be officially available. A World contains multiple levels, +/// and it has its own layout settings. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct World { + /// Default new level height + pub default_level_height: i64, + + /// Default new level width + pub default_level_width: i64, + + /// User defined unique identifier + pub identifier: String, + + /// Unique instance identifer + pub iid: String, + + /// All levels from this world. The order of this array is only relevant in + /// `LinearHorizontal` and `linearVertical` world layouts (see `worldLayout` value). + /// Otherwise, you should refer to the `worldX`,`worldY` coordinates of each Level. + pub levels: Vec<Level>, + + /// Height of the world grid in pixels. + pub world_grid_height: i64, + + /// Width of the world grid in pixels. + pub world_grid_width: i64, + + /// An enum that describes how levels are organized in this project (ie. linearly or in a 2D + /// space). Possible values: `Free`, `GridVania`, `LinearHorizontal`, `LinearVertical`, `null` + pub world_layout: Option<WorldLayout>, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum WorldLayout { + Free, + + #[serde(rename = "GridVania")] + GridVania, + + #[serde(rename = "LinearHorizontal")] + LinearHorizontal, + + #[serde(rename = "LinearVertical")] + LinearVertical, +} + +/// Naming convention for Identifiers (first-letter uppercase, full uppercase etc.) Possible +/// values: `Capitalize`, `Uppercase`, `Lowercase`, `Free` +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum IdentifierStyle { + Capitalize, + + Free, + + Lowercase, + + Uppercase, +} + +/// "Image export" option when saving project. Possible values: `None`, `OneImagePerLayer`, +/// `OneImagePerLevel`, `LayersAndLevels` +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum ImageExportMode { + #[serde(rename = "LayersAndLevels")] + LayersAndLevels, + + None, + + #[serde(rename = "OneImagePerLayer")] + OneImagePerLayer, + + #[serde(rename = "OneImagePerLevel")] + OneImagePerLevel, +} diff --git a/src/ldtk/mod.rs b/src/ldtk/mod.rs index d7e55590b415221a8c266bd843b942e579f49050..cd212df6228775fb54ce71074a6423cd32a20ea2 100644 --- a/src/ldtk/mod.rs +++ b/src/ldtk/mod.rs @@ -14,10 +14,18 @@ mod data_1_2_4; mod data_1_2_5; #[cfg(feature = "ldtk_1_3_0")] mod data_1_3_0; - -use bevy::asset::{AssetLoader, AssetPath, BoxedFuture, LoadContext, LoadedAsset}; +#[cfg(feature = "ldtk_1_4_0")] +mod data_1_4_0; + +use bevy::asset::io::Reader; +use bevy::asset::{ + AssetLoader, AssetPath, AsyncReadExt, BoxedFuture, LoadContext, LoadedAsset, UntypedAssetId, + VisitAssetDependencies, +}; +use bevy::prelude::Asset; use bevy::reflect::{TypePath, TypeUuid, Uuid}; +use crate::{ldtk, LdtkLevel}; #[cfg(feature = "ldtk_1_0_0")] pub use data_1_0_0::*; #[cfg(any(feature = "ldtk_1_1_1", feature = "ldtk_1_1_0"))] @@ -34,6 +42,8 @@ pub use data_1_2_4::*; pub use data_1_2_5::*; #[cfg(feature = "ldtk_1_3_0")] pub use data_1_3_0::*; +#[cfg(feature = "ldtk_1_4_0")] +pub use data_1_4_0::*; use serde::Deserialize; #[derive(thiserror::Error, Debug)] @@ -91,6 +101,12 @@ impl TypePath for Project { } } +impl VisitAssetDependencies for Project { + fn visit_dependencies(&self, _visit: &mut impl FnMut(UntypedAssetId)) {} +} + +impl Asset for Project {} + impl TypeUuid for Level { const TYPE_UUID: Uuid = Uuid::from_u128(18486863672600588966868281477384349187); } @@ -105,6 +121,12 @@ impl TypePath for Level { } } +impl VisitAssetDependencies for Level { + fn visit_dependencies(&self, _visit: &mut impl FnMut(UntypedAssetId)) {} +} + +impl Asset for Level {} + impl Project { pub fn get_all_levels(&self) -> Vec<&Level> { if !self.worlds.is_empty() { @@ -134,7 +156,7 @@ impl Project { vec![] } - #[cfg(any(feature = "ldtk_1_3_0",))] + #[cfg(any(feature = "ldtk_1_3_0", feature = "ldtk_1_4_0"))] pub fn get_world_levels(&self, identifier: impl ToString) -> Vec<&Level> { let id = identifier.to_string(); self.worlds @@ -145,58 +167,56 @@ impl Project { } } +#[derive(Debug, thiserror::Error)] +pub enum LdtkLoadError { + #[error(transparent)] + Io(#[from] std::io::Error), + #[error(transparent)] + Serde(#[from] serde_json::Error), + #[error(transparent)] + Ldtk(#[from] ldtk::ParseError), +} + pub type LdtkProject = Project; #[derive(Default)] pub struct LdtkLoader; impl AssetLoader for LdtkLoader { + type Asset = Project; + type Settings = (); + type Error = LdtkLoadError; + fn load<'a>( &'a self, - bytes: &'a [u8], + reader: &'a mut Reader, + _settings: &'a Self::Settings, load_context: &'a mut LoadContext, - ) -> BoxedFuture<'a, anyhow::Result<(), anyhow::Error>> { + ) -> BoxedFuture<'a, Result<Self::Asset, Self::Error>> { Box::pin(async move { - log::debug!( - "Loading ldtk project file {}", - load_context.path().display() - ); - - let project = Project::from_bytes(bytes)?; + let mut bytes = Vec::new(); + reader.read_to_end(&mut bytes).await?; + let project = Project::from_bytes(bytes.as_slice())?; + + let mut levels = project.levels.iter().flat_map(|level| { + log::debug!( + "Checking if level is external: {} [{}]", + level.identifier, + level.external_rel_path.is_some() + ); + + level + .external_rel_path + .as_ref() + .map(|path| (level.identifier.clone(), path)) + }); + + for (id, path) in levels { + load_context.labeled_asset_scope(id, |lc| { + lc.load::<Level>(path); + }); + } - let sub_levels = project - .levels - .iter() - .flat_map(|level| { - log::debug!( - "Checking if level is external: {} [{}]", - level.identifier, - level.external_rel_path.is_some() - ); - - level - .external_rel_path - .as_ref() - .map(|rel_path| (level.identifier.clone(), rel_path.clone())) - }) - .collect::<Vec<(String, String)>>(); - - let asset = LoadedAsset::new(project).with_dependencies( - sub_levels - .into_iter() - .flat_map(|(id, path)| { - log::debug!( - "Checking for file {}", - load_context.path().parent()?.join(&path).display() - ); - - let path = load_context.path().parent()?.join(path); - Some(AssetPath::new(path, Some(id))) - }) - .collect(), - ); - - load_context.set_default_asset(asset); - Ok(()) + Ok(project) }) } @@ -204,21 +224,27 @@ impl AssetLoader for LdtkLoader { &["ldtk"] } } + #[derive(Default)] pub struct LdtkLevelLoader; impl AssetLoader for LdtkLevelLoader { + type Asset = Level; + type Settings = (); + type Error = LdtkLoadError; + fn load<'a>( &'a self, - bytes: &'a [u8], - load_context: &'a mut LoadContext, - ) -> BoxedFuture<'a, anyhow::Result<(), anyhow::Error>> { + reader: &'a mut Reader, + _settings: &'a Self::Settings, + _load_context: &'a mut LoadContext, + ) -> BoxedFuture<'a, Result<Self::Asset, Self::Error>> { Box::pin(async move { - log::debug!("Loading ldtkl level file {}", load_context.path().display()); - load_context.set_default_asset(LoadedAsset::new(Level::from_bytes(bytes)?)); - Ok(()) + let mut bytes = Vec::new(); + reader.read_to_end(&mut bytes).await?; + let level = Level::from_bytes(bytes.as_slice())?; + Ok(level) }) } - fn extensions(&self) -> &[&str] { &["ldtkl"] } diff --git a/src/lib.rs b/src/lib.rs index fb70b85650b46937e8237c264c147516a10240ae..40020d397e02a808720df13ab0ef900d1c3a0489 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,10 +74,10 @@ mod __plugin { ))] { app.add_event::<super::system::LevelDataUpdated>() - .add_asset::<super::ldtk::Project>() - .add_asset::<super::ldtk::Level>() - .add_asset_loader(super::ldtk::LdtkLoader) - .add_asset_loader(super::ldtk::LdtkLevelLoader) + .init_asset::<super::ldtk::Project>() + .init_asset::<super::ldtk::Level>() + .init_asset_loader::<super::ldtk::LdtkLoader>() + .init_asset_loader::<super::ldtk::LdtkLevelLoader>() .init_resource::<super::assets::TilesetIndex>() .init_resource::<super::assets::LevelIndex>() .add_systems(Update, super::assets::handle_ldtk_project_events)