diff --git a/lib/deferred_loader/.gitignore b/lib/deferred_loader/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/lib/deferred_loader/.gitignore @@ -0,0 +1 @@ +/target diff --git a/lib/deferred_loader/Cargo.lock b/lib/deferred_loader/Cargo.lock new file mode 100644 index 0000000..cc09efd --- /dev/null +++ b/lib/deferred_loader/Cargo.lock @@ -0,0 +1,802 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "approx" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278" +dependencies = [ + "num-traits", +] + +[[package]] +name = "array-init" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" + +[[package]] +name = "binrw" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f36b7cb3ab9ff6a2858650d8dc360e783a5d14dc29594db48c56a3c233cc265" +dependencies = [ + "array-init", + "binrw_derive", + "bytemuck", +] + +[[package]] +name = "binrw_derive" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20ea7a8c5c8eeffffac6d54d172444e15beffac6f817fac714460a9a9aa88da3" +dependencies = [ + "either", + "owo-colors", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bnum" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50202def95bf36cb7d1d7a7962cea1c36a3f8ad42425e5d2b71d7acb8041b5b8" + +[[package]] +name = "bv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" +dependencies = [ + "feature-probe", +] + +[[package]] +name = "bytemuck" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" + +[[package]] +name = "byteorder" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cgmath" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a98d30140e3296250832bbaaff83b27dcd6fa3cc70fb6f1f3e5c9c0023b5317" +dependencies = [ + "approx", + "num-traits", +] + +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + +[[package]] +name = "fixed_wide" +version = "0.1.1" +source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/" +checksum = "d9c2cf115b3785ede870fada07e8b1aeba3378345b4ca86fe3c772ecabc05c0f" +dependencies = [ + "arrayvec", + "bnum", + "paste", + "ratio_ops", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "glam" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "779ae4bf7e8421cf91c0b3b64e7e8b40b862fba4d393f59150042de7c4965a94" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "id" +version = "0.1.0" +source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/" +checksum = "2337e7a6c273082b672e377e159d7a168fb51438461b7c4033c79a515dd7a25a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" + +[[package]] +name = "linear_ops" +version = "0.1.0" +source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/" +checksum = "b2e6977ac24f47086d8a7a2d4ae1c720e86dfdc8407cf5e34c18bfa01053c456" +dependencies = [ + "fixed_wide", + "paste", + "ratio_ops", +] + +[[package]] +name = "logos" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c6b6e02facda28ca5fb8dbe4b152496ba3b1bd5a4b40bb2b1b2d8ad74e0f39b" +dependencies = [ + "logos-derive", +] + +[[package]] +name = "logos-codegen" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b32eb6b5f26efacd015b000bfc562186472cd9b34bdba3f6b264e2a052676d10" +dependencies = [ + "beef", + "fnv", + "lazy_static", + "proc-macro2", + "quote", + "regex-syntax", + "syn 2.0.79", +] + +[[package]] +name = "logos-derive" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e5d0c5463c911ef55624739fc353238b4e310f0144be1f875dc42fec6bfd5ec" +dependencies = [ + "logos-codegen", +] + +[[package]] +name = "lzma" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "782ba3f542e8bc1349386c15e9dc3119ae6da96479f96b3863cc7a88bbdfd4e4" +dependencies = [ + "byteorder 0.5.3", +] + +[[package]] +name = "lzma-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" +dependencies = [ + "byteorder 1.5.0", + "crc", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "miette" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4edc8853320c2a0dab800fbda86253c8938f6ea88510dc92c5f1ed20e794afc1" +dependencies = [ + "cfg-if", + "miette-derive", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette-derive" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "once_cell" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "parse-display" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914a1c2265c98e2446911282c6ac86d8524f495792c38c5bd884f80499c7538a" +dependencies = [ + "parse-display-derive", + "regex", + "regex-syntax", +] + +[[package]] +name = "parse-display-derive" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ae7800a4c974efd12df917266338e79a7a74415173caf7e70aa0a0707345281" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "regex-syntax", + "structmeta", + "syn 2.0.79", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "portable-atomic" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ratio_ops" +version = "0.1.0" +source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/" +checksum = "01239195d6afe0509e7e3511b716c0540251dfe7ece0a9a5a27116afb766c42c" + +[[package]] +name = "regex" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "serde" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strafesnet_common" +version = "0.5.1" +source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/" +checksum = "eaf0b69648e1b6b61b6f05868a5fc5496bc90b0586cfc69533b5cd7a3c006f86" +dependencies = [ + "arrayvec", + "bitflags", + "fixed_wide", + "glam", + "id", + "linear_ops", + "ratio_ops", +] + +[[package]] +name = "strafesnet_deferred_loader" +version = "0.4.1" +dependencies = [ + "strafesnet_common", + "url", + "vbsp", +] + +[[package]] +name = "structmeta" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e1575d8d40908d70f6fd05537266b90ae71b15dbbe7a8b7dffa2b759306d329" +dependencies = [ + "proc-macro2", + "quote", + "structmeta-derive", + "syn 2.0.79", +] + +[[package]] +name = "structmeta-derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "vbsp" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f14a5685e0bb386aac9b9c6046a05152a46a0bc58d53afb3fbe577f1a1c2bb05" +dependencies = [ + "ahash", + "arrayvec", + "binrw", + "bitflags", + "bv", + "cgmath", + "itertools", + "lzma-rs", + "num_enum", + "serde", + "static_assertions", + "thiserror", + "vdf-reader", + "zip-lzma", +] + +[[package]] +name = "vdf-reader" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "543945fdc3d51b20e3e0f5fd845ddeca4a270e56522035cf152105bc144ffd65" +dependencies = [ + "logos", + "miette", + "parse-display", + "serde", + "thiserror", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "zip-lzma" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b480cb31fccfb2786565c0e0712865fd6f1ea0ea850c50316f643c3948196e63" +dependencies = [ + "byteorder 1.5.0", + "crc32fast", + "crossbeam-utils", + "lzma", +] diff --git a/lib/deferred_loader/Cargo.toml b/lib/deferred_loader/Cargo.toml new file mode 100644 index 0000000..a9939f5 --- /dev/null +++ b/lib/deferred_loader/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "strafesnet_deferred_loader" +version = "0.4.1" +edition = "2021" +repository = "https://git.itzana.me/StrafesNET/deferred_loader" +license = "MIT OR Apache-2.0" +description = "Acquire IDs for objects before loading them in bulk." +authors = ["Rhys Lloyd "] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[features] +default = ["legacy"] +legacy = ["dep:url","dep:vbsp"] +#roblox = ["dep:lazy-regex"] +#source = ["dep:vbsp"] + +[dependencies] +strafesnet_common = { version = "0.5.1", registry = "strafesnet" } +url = { version = "2.5.2", optional = true } +vbsp = { version = "0.6.0", optional = true } diff --git a/lib/deferred_loader/LICENSE-APACHE b/lib/deferred_loader/LICENSE-APACHE new file mode 100644 index 0000000..a7e77cb --- /dev/null +++ b/lib/deferred_loader/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/lib/deferred_loader/LICENSE-MIT b/lib/deferred_loader/LICENSE-MIT new file mode 100644 index 0000000..468cd79 --- /dev/null +++ b/lib/deferred_loader/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/lib/deferred_loader/README.md b/lib/deferred_loader/README.md new file mode 100644 index 0000000..f33b955 --- /dev/null +++ b/lib/deferred_loader/README.md @@ -0,0 +1,19 @@ +Texture Loader +============== + +## Texture loader, designed to be used in conjunction with rbx_loader, bsp_loader or Strafe Client + +#### License + + +Licensed under either of Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. + \ No newline at end of file diff --git a/lib/deferred_loader/src/lib.rs b/lib/deferred_loader/src/lib.rs new file mode 100644 index 0000000..767528a --- /dev/null +++ b/lib/deferred_loader/src/lib.rs @@ -0,0 +1,34 @@ +#[cfg(feature="legacy")] +mod roblox_legacy; +#[cfg(feature="legacy")] +mod source_legacy; +#[cfg(feature="roblox")] +mod roblox; +#[cfg(feature="source")] +mod source; + +#[cfg(any(feature="roblox",feature="legacy"))] +pub mod rbxassetid; + +pub mod texture; +#[cfg(any(feature="source",feature="legacy"))] +pub mod valve_mesh; +#[cfg(any(feature="roblox",feature="legacy"))] +pub mod roblox_mesh; + +#[cfg(feature="legacy")] +pub fn roblox_legacy()->roblox_legacy::Loader{ + roblox_legacy::Loader::new() +} +#[cfg(feature="legacy")] +pub fn source_legacy()->source_legacy::Loader{ + source_legacy::Loader::new() +} +#[cfg(feature="roblox")] +pub fn roblox()->roblox::Loader{ + roblox::Loader::new() +} +#[cfg(feature="source")] +pub fn source()->source::Loader{ + source::Loader::new() +} diff --git a/lib/deferred_loader/src/rbxassetid.rs b/lib/deferred_loader/src/rbxassetid.rs new file mode 100644 index 0000000..2cf43d7 --- /dev/null +++ b/lib/deferred_loader/src/rbxassetid.rs @@ -0,0 +1,48 @@ +#[derive(Hash,Eq,PartialEq)] +pub struct RobloxAssetId(pub u64); +#[derive(Debug)] +#[allow(dead_code)] +pub struct StringWithError{ + string:String, + error:RobloxAssetIdParseErr, +} +impl std::fmt::Display for StringWithError{ + fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ + write!(f,"{self:?}") + } +} +impl std::error::Error for StringWithError{} +impl StringWithError{ + const fn new( + string:String, + error:RobloxAssetIdParseErr, + )->Self{ + Self{string,error} + } +} +#[derive(Debug)] +pub enum RobloxAssetIdParseErr{ + Url(url::ParseError), + UnknownScheme, + ParseInt(std::num::ParseIntError), + MissingAssetId, +} +impl std::str::FromStr for RobloxAssetId{ + type Err=StringWithError; + fn from_str(s:&str)->Result{ + let url=url::Url::parse(s).map_err(|e|StringWithError::new(s.to_owned(),RobloxAssetIdParseErr::Url(e)))?; + let parsed_asset_id=match url.scheme(){ + "rbxassetid"=>url.domain().ok_or_else(||StringWithError::new(s.to_owned(),RobloxAssetIdParseErr::MissingAssetId))?.parse(), + "http"|"https"=>{ + let (_,asset_id)=url.query_pairs() + .find(|(id,_)|match id.as_ref(){ + "ID"|"id"|"Id"|"iD"=>true, + _=>false, + }).ok_or_else(||StringWithError::new(s.to_owned(),RobloxAssetIdParseErr::MissingAssetId))?; + asset_id.parse() + }, + _=>Err(StringWithError::new(s.to_owned(),RobloxAssetIdParseErr::UnknownScheme))?, + }; + Ok(Self(parsed_asset_id.map_err(|e|StringWithError::new(s.to_owned(),RobloxAssetIdParseErr::ParseInt(e)))?)) + } +} diff --git a/lib/deferred_loader/src/roblox.rs b/lib/deferred_loader/src/roblox.rs new file mode 100644 index 0000000..e69de29 diff --git a/lib/deferred_loader/src/roblox_legacy.rs b/lib/deferred_loader/src/roblox_legacy.rs new file mode 100644 index 0000000..a6480fe --- /dev/null +++ b/lib/deferred_loader/src/roblox_legacy.rs @@ -0,0 +1,112 @@ +use std::io::Read; +use std::collections::HashMap; +use crate::roblox_mesh; +use crate::texture::{RenderConfigs,Texture}; +use strafesnet_common::model::{MeshId,RenderConfig,RenderConfigId,TextureId}; +use crate::rbxassetid::RobloxAssetId; + +#[derive(Default)] +pub struct RenderConfigLoader{ + texture_count:u32, + render_configs:Vec, + render_config_id_from_asset_id:HashMap,RenderConfigId>, +} + +impl RenderConfigLoader{ + pub fn acquire_render_config_id(&mut self,name:Option<&str>)->RenderConfigId{ + let render_id=RenderConfigId::new(self.render_config_id_from_asset_id.len() as u32); + let index=name.and_then(|name|{ + match name.parse::(){ + Ok(asset_id)=>Some(asset_id), + Err(e)=>{ + println!("Failed to parse AssetId: {e}"); + None + }, + } + }); + *self.render_config_id_from_asset_id.entry(index).or_insert_with(||{ + //create the render config. + let render_config=if name.is_some(){ + let render_config=RenderConfig::texture(TextureId::new(self.texture_count)); + self.texture_count+=1; + render_config + }else{ + RenderConfig::default() + }; + self.render_configs.push(render_config); + render_id + }) + } +} + +#[derive(Default)] +pub struct MeshLoader{ + mesh_id_from_asset_id:HashMap,MeshId>, +} + +impl MeshLoader{ + pub fn acquire_mesh_id(&mut self,name:&str)->MeshId{ + let mesh_id=MeshId::new(self.mesh_id_from_asset_id.len() as u32); + let index=match name.parse::(){ + Ok(asset_id)=>Some(asset_id), + Err(e)=>{ + println!("Failed to parse AssetId: {e}"); + None + }, + }; + *self.mesh_id_from_asset_id.entry(index).or_insert(mesh_id) + } + pub fn load_meshes(&mut self)->Result{ + let mut mesh_data=vec![None;self.mesh_id_from_asset_id.len()]; + for (asset_id_option,mesh_id) in &self.mesh_id_from_asset_id{ + if let Some(asset_id)=asset_id_option{ + if let Ok(mut file)=std::fs::File::open(format!("meshes/{}",asset_id.0)){ + //TODO: parallel + let mut data=Vec::::new(); + file.read_to_end(&mut data)?; + mesh_data[mesh_id.get() as usize]=Some(roblox_mesh::RobloxMeshData::new(data)); + }else{ + println!("[roblox_legacy] no mesh name={}",asset_id.0); + } + } + } + Ok(roblox_mesh::Meshes::new(mesh_data)) + } +} + +pub struct Loader{ + render_config_loader:RenderConfigLoader, + mesh_loader:MeshLoader, +} +impl Loader{ + pub fn new()->Self{ + Self{ + render_config_loader:RenderConfigLoader::default(), + mesh_loader:MeshLoader::default(), + } + } + pub fn get_inner_mut(&mut self)->(&mut RenderConfigLoader,&mut MeshLoader){ + (&mut self.render_config_loader,&mut self.mesh_loader) + } + pub fn into_render_configs(mut self)->Result{ + let mut sorted_textures=vec![None;self.render_config_loader.texture_count as usize]; + for (asset_id_option,render_config_id) in self.render_config_loader.render_config_id_from_asset_id{ + let render_config=self.render_config_loader.render_configs.get_mut(render_config_id.get() as usize).unwrap(); + if let (Some(asset_id),Some(texture_id))=(asset_id_option,render_config.texture){ + if let Ok(mut file)=std::fs::File::open(format!("textures/{}.dds",asset_id.0)){ + //TODO: parallel + let mut data=Vec::::new(); + file.read_to_end(&mut data)?; + sorted_textures[texture_id.get() as usize]=Some(Texture::ImageDDS(data)); + }else{ + //texture failed to load + render_config.texture=None; + } + } + } + Ok(RenderConfigs::new( + sorted_textures, + self.render_config_loader.render_configs, + )) + } +} diff --git a/lib/deferred_loader/src/roblox_mesh.rs b/lib/deferred_loader/src/roblox_mesh.rs new file mode 100644 index 0000000..cdb545f --- /dev/null +++ b/lib/deferred_loader/src/roblox_mesh.rs @@ -0,0 +1,30 @@ +use strafesnet_common::model::MeshId; + +#[derive(Clone)] +pub struct RobloxMeshData(Vec); +impl RobloxMeshData{ + pub(crate) fn new(data:Vec)->Self{ + Self(data) + } + pub fn get(self)->Vec{ + self.0 + } +} +pub struct Meshes{ + meshes:Vec>, +} +impl Meshes{ + pub(crate) const fn new(meshes:Vec>)->Self{ + Self{ + meshes, + } + } + pub fn get_texture(&self,texture_id:MeshId)->Option<&RobloxMeshData>{ + self.meshes.get(texture_id.get() as usize)?.as_ref() + } + pub fn into_iter(self)->impl Iterator{ + self.meshes.into_iter().enumerate().filter_map(|(mesh_id,maybe_mesh)| + maybe_mesh.map(|mesh|(MeshId::new(mesh_id as u32),mesh)) + ) + } +} \ No newline at end of file diff --git a/lib/deferred_loader/src/source_legacy.rs b/lib/deferred_loader/src/source_legacy.rs new file mode 100644 index 0000000..fc1474e --- /dev/null +++ b/lib/deferred_loader/src/source_legacy.rs @@ -0,0 +1,102 @@ +use std::io::Read; +use std::collections::HashMap; +use crate::valve_mesh; +use crate::texture::{Texture,RenderConfigs}; +use strafesnet_common::model::{MeshId,TextureId,RenderConfig,RenderConfigId}; + +pub struct RenderConfigLoader{ + texture_count:u32, + render_configs:Vec, + texture_paths:HashMap>,RenderConfigId>, +} +impl RenderConfigLoader{ + pub fn acquire_render_config_id(&mut self,name:Option<&str>)->RenderConfigId{ + let render_id=RenderConfigId::new(self.texture_paths.len() as u32); + *self.texture_paths.entry(name.map(Into::into)).or_insert_with(||{ + //create the render config. + let render_config=if name.is_some(){ + let render_config=RenderConfig::texture(TextureId::new(self.texture_count)); + self.texture_count+=1; + render_config + }else{ + RenderConfig::default() + }; + self.render_configs.push(render_config); + render_id + }) + } +} +pub struct MeshLoader{ + mesh_paths:HashMap,MeshId>, +} +impl MeshLoader{ + pub fn acquire_mesh_id(&mut self,name:&str)->MeshId{ + let mesh_id=MeshId::new(self.mesh_paths.len() as u32); + *self.mesh_paths.entry(name.into()).or_insert(mesh_id) + } + //load_meshes should look like load_textures + pub fn load_meshes(&mut self,bsp:&vbsp::Bsp)->valve_mesh::Meshes{ + let mut mesh_data=vec![None;self.mesh_paths.len()]; + for (mesh_path,mesh_id) in &self.mesh_paths{ + let mesh_path_lower=mesh_path.to_lowercase(); + //.mdl, .vvd, .dx90.vtx + let path=std::path::PathBuf::from(mesh_path_lower.as_str()); + let mut vvd_path=path.clone(); + let mut vtx_path=path.clone(); + vvd_path.set_extension("vvd"); + vtx_path.set_extension("dx90.vtx"); + match (bsp.pack.get(mesh_path_lower.as_str()),bsp.pack.get(vvd_path.as_os_str().to_str().unwrap()),bsp.pack.get(vtx_path.as_os_str().to_str().unwrap())){ + (Ok(Some(mdl_file)),Ok(Some(vvd_file)),Ok(Some(vtx_file)))=>{ + mesh_data[mesh_id.get() as usize]=Some(valve_mesh::ModelData{ + mdl:valve_mesh::MdlData::new(mdl_file), + vtx:valve_mesh::VtxData::new(vtx_file), + vvd:valve_mesh::VvdData::new(vvd_file), + }); + }, + _=>println!("no model name={}",mesh_path), + } + } + valve_mesh::Meshes::new(mesh_data) + } +} + +pub struct Loader{ + render_config_loader:RenderConfigLoader, + mesh_loader:MeshLoader, +} +impl Loader{ + pub fn new()->Self{ + Self{ + render_config_loader:RenderConfigLoader{ + texture_count:0, + texture_paths:HashMap::new(), + render_configs:Vec::new(), + }, + mesh_loader:MeshLoader{mesh_paths:HashMap::new()}, + } + } + pub fn get_inner_mut(&mut self)->(&mut RenderConfigLoader,&mut MeshLoader){ + (&mut self.render_config_loader,&mut self.mesh_loader) + } + pub fn into_render_configs(mut self)->Result{ + let mut sorted_textures=vec![None;self.render_config_loader.texture_count as usize]; + for (texture_path,render_config_id) in self.render_config_loader.texture_paths{ + let render_config=self.render_config_loader.render_configs.get_mut(render_config_id.get() as usize).unwrap(); + if let (Some(texture_path),Some(texture_id))=(texture_path,render_config.texture){ + if let Ok(mut file)=std::fs::File::open(format!("textures/{}.dds",texture_path)){ + //TODO: parallel + let mut data=Vec::::new(); + file.read_to_end(&mut data)?; + sorted_textures[texture_id.get() as usize]=Some(Texture::ImageDDS(data)); + }else{ + //texture failed to load + render_config.texture=None; + } + } + } + Ok(RenderConfigs::new( + sorted_textures, + self.render_config_loader.render_configs, + )) + } +} diff --git a/lib/deferred_loader/src/texture.rs b/lib/deferred_loader/src/texture.rs new file mode 100644 index 0000000..d737618 --- /dev/null +++ b/lib/deferred_loader/src/texture.rs @@ -0,0 +1,39 @@ +use strafesnet_common::model::{TextureId,RenderConfigId,RenderConfig}; + +#[derive(Clone)] +pub enum Texture{ + ImageDDS(Vec), +} +impl AsRef<[u8]> for Texture{ + fn as_ref(&self)->&[u8]{ + match self{ + Texture::ImageDDS(data)=>data.as_ref(), + } + } +} + +pub struct RenderConfigs{ + textures:Vec>, + render_configs:Vec, +} +impl RenderConfigs{ + pub(crate) const fn new(textures:Vec>,render_configs:Vec)->Self{ + Self{ + textures, + render_configs, + } + } + pub fn consume(self)->( + impl Iterator, + impl Iterator + ){ + ( + self.textures.into_iter().enumerate().filter_map(|(texture_id,maybe_texture)| + maybe_texture.map(|texture|(TextureId::new(texture_id as u32),texture)) + ), + self.render_configs.into_iter().enumerate().map(|(render_id,render)| + (RenderConfigId::new(render_id as u32),render) + ), + ) + } +} \ No newline at end of file diff --git a/lib/deferred_loader/src/valve_mesh.rs b/lib/deferred_loader/src/valve_mesh.rs new file mode 100644 index 0000000..15d7f40 --- /dev/null +++ b/lib/deferred_loader/src/valve_mesh.rs @@ -0,0 +1,60 @@ +use strafesnet_common::model::MeshId; + +//duplicate this code for now +#[derive(Clone)] +pub struct MdlData(Vec); +impl MdlData{ + pub const fn new(value:Vec)->Self{ + Self(value) + } + pub fn get(self)->Vec{ + self.0 + } +} +#[derive(Clone)] +pub struct VtxData(Vec); +impl VtxData{ + pub const fn new(value:Vec)->Self{ + Self(value) + } + pub fn get(self)->Vec{ + self.0 + } +} +#[derive(Clone)] +pub struct VvdData(Vec); +impl VvdData{ + pub const fn new(value:Vec)->Self{ + Self(value) + } + pub fn get(self)->Vec{ + self.0 + } +} + +#[derive(Clone)] +pub struct ModelData{ + pub mdl:MdlData, + pub vtx:VtxData, + pub vvd:VvdData, +} + +//meshes is more prone to failure +pub struct Meshes{ + meshes:Vec>, +} +impl Meshes{ + pub(crate) const fn new(meshes:Vec>)->Self{ + Self{ + meshes, + } + } + pub fn get_texture(&self,texture_id:MeshId)->Option<&ModelData>{ + self.meshes.get(texture_id.get() as usize)?.as_ref() + } + pub fn into_iter(self)->impl Iterator{ + self.meshes.into_iter().enumerate().filter_map(|(mesh_id,maybe_mesh)| + maybe_mesh.map(|mesh|(MeshId::new(mesh_id as u32),mesh)) + ) + } +} \ No newline at end of file