From d6ab6659763bb19b740d48f16a40d7a39b15440f Mon Sep 17 00:00:00 2001 From: Franklin Date: Sun, 24 Mar 2024 11:58:35 +0100 Subject: [PATCH] Finished crate logic. On to testing and writing doc --- Cargo.lock | 438 ++++++++++++++++++++++++++++++++++++++- Cargo.toml | 3 +- Readme.md | 4 +- src/clone_entity_tree.rs | 62 ------ src/created_icons.rs | 11 + src/image_ext.rs | 32 +++ src/lib.rs | 8 +- src/markers.rs | 40 +++- src/plugin.rs | 12 +- src/register_types.rs | 24 +++ src/set_image_on_load.rs | 5 + src/setup.rs | 4 +- src/state.rs | 5 +- src/update.rs | 113 ++++++++++ src/utils.rs | 35 ++++ 15 files changed, 707 insertions(+), 89 deletions(-) delete mode 100644 src/clone_entity_tree.rs create mode 100644 src/created_icons.rs create mode 100644 src/image_ext.rs create mode 100644 src/register_types.rs create mode 100644 src/set_image_on_load.rs create mode 100644 src/utils.rs diff --git a/Cargo.lock b/Cargo.lock index d459662..64608f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,7 +68,7 @@ dependencies = [ "accesskit", "accesskit_macos", "accesskit_windows", - "raw-window-handle", + "raw-window-handle 0.6.0", "winit", ] @@ -178,6 +178,25 @@ dependencies = [ "num-traits", ] +[[package]] +name = "arboard" +version = "3.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2041f1943049c7978768d84e6d0fd95de98b76d6c4727b09e78ec253d29fa58" +dependencies = [ + "clipboard-win", + "core-graphics", + "image", + "log", + "objc", + "objc-foundation", + "objc_id", + "parking_lot", + "thiserror", + "windows-sys 0.48.0", + "x11rb", +] + [[package]] name = "arrayref" version = "0.3.7" @@ -297,6 +316,46 @@ dependencies = [ "bevy_internal", ] +[[package]] +name = "bevy-inspector-egui" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb36c3adb02afa4496085250d437217b2a5280d8dd464937c6c5b21bc88830c0" +dependencies = [ + "bevy-inspector-egui-derive", + "bevy_app", + "bevy_asset", + "bevy_core", + "bevy_core_pipeline", + "bevy_ecs", + "bevy_egui", + "bevy_hierarchy", + "bevy_log", + "bevy_math", + "bevy_pbr", + "bevy_reflect", + "bevy_render", + "bevy_time", + "bevy_utils", + "bevy_window", + "egui", + "image", + "once_cell", + "pretty-type-name", + "smallvec", +] + +[[package]] +name = "bevy-inspector-egui-derive" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3c488161a04a123e10273e16d4533945943fcfcf345f066242790e8977aee2d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.53", +] + [[package]] name = "bevy_a11y" version = "0.13.1" @@ -502,6 +561,61 @@ dependencies = [ "syn 2.0.53", ] +[[package]] +name = "bevy_editor_pls" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d08e119d7983670a41690d60ef0e4730f0c02719118b8e6dd42b13f90a0348c0" +dependencies = [ + "bevy", + "bevy_editor_pls_core", + "bevy_editor_pls_default_windows", + "egui", + "egui-gizmo", +] + +[[package]] +name = "bevy_editor_pls_core" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84de9dc9204638e9eabaef4f1426a73280570a98ab3cf750e473d89e8d49e1f4" +dependencies = [ + "bevy", + "bevy-inspector-egui", + "egui_dock", + "indexmap", +] + +[[package]] +name = "bevy_editor_pls_default_windows" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d12a4a8a762b6dd1212700dd4a82a6f16ed8cab1d6313c242a23fb53610ce1d" +dependencies = [ + "bevy", + "bevy-inspector-egui", + "bevy_editor_pls_core", + "bevy_mod_debugdump", + "egui-gizmo", + "indexmap", + "opener", + "pretty-type-name", +] + +[[package]] +name = "bevy_egui" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b84bfb8d4104a1467910cf2090bc6a6d394ebde39c0dbc02397b45aa9ef88e80" +dependencies = [ + "arboard", + "bevy", + "egui", + "thread_local", + "web-sys", + "webbrowser", +] + [[package]] name = "bevy_encase_derive" version = "0.13.1" @@ -611,6 +725,7 @@ name = "bevy_icon_creator" version = "0.1.0" dependencies = [ "bevy", + "bevy_editor_pls", ] [[package]] @@ -715,6 +830,21 @@ dependencies = [ "glam", ] +[[package]] +name = "bevy_mod_debugdump" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d39eb6372d6af22b209d68c10e3b742938b450117281387c94ce3f9f51902b76" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_render", + "bevy_utils", + "once_cell", + "petgraph", + "pretty-type-name", +] + [[package]] name = "bevy_pbr" version = "0.13.1" @@ -1015,7 +1145,7 @@ dependencies = [ "bevy_math", "bevy_reflect", "bevy_utils", - "raw-window-handle", + "raw-window-handle 0.6.0", "smol_str", ] @@ -1038,7 +1168,7 @@ dependencies = [ "bevy_utils", "bevy_window", "crossbeam-channel", - "raw-window-handle", + "raw-window-handle 0.6.0", "wasm-bindgen", "web-sys", "winit", @@ -1167,6 +1297,17 @@ dependencies = [ "tracing", ] +[[package]] +name = "bstr" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +dependencies = [ + "memchr", + "regex-automata 0.4.6", + "serde", +] + [[package]] name = "bumpalo" version = "3.15.4" @@ -1267,6 +1408,15 @@ dependencies = [ "libloading 0.8.3", ] +[[package]] +name = "clipboard-win" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d517d4b86184dbb111d3556a10f1c8a04da7428d2987bf1081602bf11c3aa9ee" +dependencies = [ + "error-code", +] + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -1544,12 +1694,73 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +[[package]] +name = "duplicate" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de78e66ac9061e030587b2a2e75cc88f22304913c907b11307bca737141230cb" +dependencies = [ + "heck", + "proc-macro-error", +] + +[[package]] +name = "ecolor" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03cfe80b1890e1a8cdbffc6044d6872e814aaf6011835a2a5e2db0e5c5c4ef4e" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "egui" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180f595432a5b615fc6b74afef3955249b86cfea72607b40740a4cd60d5297d0" +dependencies = [ + "ahash", + "epaint", + "nohash-hasher", +] + +[[package]] +name = "egui-gizmo" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65371711037f6f256024371f21fd8f8c5fa2ce5221469a5fb1efc670f205f740" +dependencies = [ + "egui", + "glam", + "mint", +] + +[[package]] +name = "egui_dock" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a062ac200c9f3ddf120ffcc5582f9fbd5d8fbd046d2eed215ed5426f56513d0" +dependencies = [ + "duplicate", + "egui", + "paste", +] + [[package]] name = "either" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +[[package]] +name = "emath" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6916301ecf80448f786cdf3eb51d9dbdd831538732229d49119e2d4312eaaf09" +dependencies = [ + "bytemuck", +] + [[package]] name = "encase" version = "0.7.0" @@ -1582,6 +1793,21 @@ dependencies = [ "syn 2.0.53", ] +[[package]] +name = "epaint" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77b9fdf617dd7f58b0c8e6e9e4a1281f730cde0831d40547da446b2bb76a47af" +dependencies = [ + "ab_glyph", + "ahash", + "bytemuck", + "ecolor", + "emath", + "nohash-hasher", + "parking_lot", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -1607,6 +1833,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "error-code" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b" + [[package]] name = "euclid" version = "0.22.9" @@ -1728,6 +1960,15 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" +[[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 = "futures-core" version = "0.3.30" @@ -1828,6 +2069,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3" dependencies = [ "bytemuck", + "mint", "serde", ] @@ -1999,6 +2241,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hexasphere" version = "10.0.0" @@ -2015,6 +2263,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "icrate" version = "0.0.4" @@ -2026,6 +2283,16 @@ dependencies = [ "objc2 0.4.1", ] +[[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 = "image" version = "0.24.9" @@ -2037,6 +2304,7 @@ dependencies = [ "color_quant", "num-traits", "png", + "tiff", ] [[package]] @@ -2131,6 +2399,12 @@ dependencies = [ "libc", ] +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" + [[package]] name = "js-sys" version = "0.3.69" @@ -2322,6 +2596,12 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "mint" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e53debba6bda7a793e5f99b8dacf19e626084f525f7829104ba9898f367d85ff" + [[package]] name = "naga" version = "0.19.2" @@ -2374,7 +2654,7 @@ dependencies = [ "log", "ndk-sys", "num_enum", - "raw-window-handle", + "raw-window-handle 0.6.0", "thiserror", ] @@ -2405,6 +2685,12 @@ dependencies = [ "libc", ] +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + [[package]] name = "nom" version = "7.1.3" @@ -2421,6 +2707,15 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "610a5acd306ec67f907abe5567859a3c693fb9886eb1f012ab8f2a47bef3db51" +[[package]] +name = "normpath" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5831952a9476f2fed74b77d74182fa5ddc4d21c72ec45a333b250e3ed0272804" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "ntapi" version = "0.4.1" @@ -2491,6 +2786,17 @@ dependencies = [ "objc_exception", ] +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + [[package]] name = "objc-sys" version = "0.2.0-beta.2" @@ -2548,6 +2854,15 @@ dependencies = [ "cc", ] +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + [[package]] name = "oboe" version = "0.6.1" @@ -2586,6 +2901,17 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "opener" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c62dcb6174f9cb326eac248f07e955d5d559c272730b6c03e396b443b562788" +dependencies = [ + "bstr", + "normpath", + "winapi", +] + [[package]] name = "orbclient" version = "0.3.47" @@ -2726,6 +3052,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" +[[package]] +name = "pretty-type-name" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f73cdaf19b52e6143685c3606206e114a4dfa969d6b14ec3894c88eb38bd4b" + [[package]] name = "proc-macro-crate" version = "3.1.0" @@ -2735,6 +3067,30 @@ dependencies = [ "toml_edit", ] +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.79" @@ -2771,6 +3127,12 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8a99fddc9f0ba0a85884b8d14e3592853e787d581ca1816c91349b10e4eeab" +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + [[package]] name = "raw-window-handle" version = "0.6.0" @@ -3120,6 +3482,17 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -3251,12 +3624,27 @@ dependencies = [ "static_assertions", ] +[[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.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-segmentation" version = "1.11.0" @@ -3275,6 +3663,17 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + [[package]] name = "uuid" version = "1.8.0" @@ -3405,6 +3804,29 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webbrowser" +version = "0.8.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1b04c569c83a9bb971dd47ec6fd48753315f4bf989b9b04a2e7ca4d7f0dc950" +dependencies = [ + "core-foundation", + "home", + "jni", + "log", + "ndk-context", + "objc", + "raw-window-handle 0.5.2", + "url", + "web-sys", +] + +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + [[package]] name = "wgpu" version = "0.19.3" @@ -3419,7 +3841,7 @@ dependencies = [ "naga", "parking_lot", "profiling", - "raw-window-handle", + "raw-window-handle 0.6.0", "smallvec", "static_assertions", "wasm-bindgen", @@ -3447,7 +3869,7 @@ dependencies = [ "once_cell", "parking_lot", "profiling", - "raw-window-handle", + "raw-window-handle 0.6.0", "rustc-hash", "smallvec", "thiserror", @@ -3490,7 +3912,7 @@ dependencies = [ "parking_lot", "profiling", "range-alloc", - "raw-window-handle", + "raw-window-handle 0.6.0", "renderdoc-sys", "rustc-hash", "smallvec", @@ -3853,7 +4275,7 @@ dependencies = [ "once_cell", "orbclient", "percent-encoding", - "raw-window-handle", + "raw-window-handle 0.6.0", "redox_syscall 0.3.5", "rustix", "smol_str", diff --git a/Cargo.toml b/Cargo.toml index ec5944c..91af75d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,4 +10,5 @@ readme = "README.md" [lib] [dependencies] -bevy = { version = "0.13.1" } \ No newline at end of file +bevy = { version = "0.13.1" } +bevy_editor_pls = "0.8" \ No newline at end of file diff --git a/Readme.md b/Readme.md index 65ca27e..6db749b 100644 --- a/Readme.md +++ b/Readme.md @@ -2,4 +2,6 @@ by Franklin E. Blanco -## A +## Usage + +#### diff --git a/src/clone_entity_tree.rs b/src/clone_entity_tree.rs deleted file mode 100644 index 286c1e7..0000000 --- a/src/clone_entity_tree.rs +++ /dev/null @@ -1,62 +0,0 @@ -use bevy::{ecs::{query::QueryEntityError, system::Command}, prelude::*}; -use std::sync::Arc; - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct EntityTreeNode { - pub source: Entity, - pub destination: Entity, - pub children: Vec, -} - -impl EntityTreeNode { - pub fn from_entity_recursive( - commands: &mut Commands, - from_entity: Entity, - q_children: &Query<&Children>, - ) -> EntityTreeNode { - let children = match q_children.get(from_entity) { - Ok(children) => children - .iter() - .map(|&child| { - EntityTreeNode::from_entity_recursive( - commands, child, q_children, - ) - }) - .collect::>(), - Err(QueryEntityError::QueryDoesNotMatch(_)) => vec![], - Err(e) => panic!("{}", e), - }; - EntityTreeNode { - source: from_entity, - destination: commands.spawn_empty().id(), - children, - } - } - - pub fn iter(&self) -> impl Iterator { - self.children.iter() - } -} - -pub fn clone_entity_tree( - world: &mut World, - EntityTreeNode { - source, - destination, - children, - }: &EntityTreeNode, -) { - //clone_entity_components(world, *source, *destination); - for node in children { - clone_entity_tree(world, node); - let mut destination = world.get_entity_mut(*destination).unwrap(); - destination.add_child(node.destination); - } -} -// uses arc to prevent cloning the whole tree. -pub struct CloneEntityTree(Arc); -impl Command for CloneEntityTree { - fn apply(self, world: &mut World) { - clone_entity_tree(world, &self.0); - } -} \ No newline at end of file diff --git a/src/created_icons.rs b/src/created_icons.rs new file mode 100644 index 0000000..90f8a73 --- /dev/null +++ b/src/created_icons.rs @@ -0,0 +1,11 @@ +use bevy::{asset::Handle, ecs::{reflect::ReflectResource, system::Resource}, reflect::Reflect, render::texture::Image, utils::{HashMap, Uuid}}; + +#[derive(Resource, Default, Clone, Debug, Reflect)] +#[reflect(Resource)] +pub struct CreatedIcons(pub(crate) HashMap>); + +impl CreatedIcons { + pub fn get_image_handle(&self, uuid: &Uuid) -> Option> { + self.0.get(uuid).cloned() + } +} \ No newline at end of file diff --git a/src/image_ext.rs b/src/image_ext.rs new file mode 100644 index 0000000..09db3d5 --- /dev/null +++ b/src/image_ext.rs @@ -0,0 +1,32 @@ +use bevy::{prelude::default, render::{render_resource::{Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages}, texture::Image}}; + +pub trait ImageExt { + fn get_blank_image(width: u32, height: u32) -> Self; +} + +impl ImageExt for Image { + fn get_blank_image(width: u32, height: u32) -> Self { + let size = Extent3d { + width, + height, + ..default() + }; + let mut image = Image { + texture_descriptor: TextureDescriptor { + label: None, + size, + dimension: TextureDimension::D2, + format: TextureFormat::Bgra8UnormSrgb, + mip_level_count: 1, + sample_count: 1, + usage: TextureUsages::TEXTURE_BINDING + | TextureUsages::COPY_DST + | TextureUsages::RENDER_ATTACHMENT, + view_formats: &[], + }, + ..default() + }; + image.resize(size); + image + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index fae8dd2..cc04de4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,11 @@ mod markers; mod update; mod setup; mod state; -mod clone_entity_tree; +mod utils; +mod set_image_on_load; +mod register_types; +pub mod image_ext; pub mod plugin; -pub mod needs_icon_marker; \ No newline at end of file +pub mod needs_icon_marker; +pub mod created_icons; \ No newline at end of file diff --git a/src/markers.rs b/src/markers.rs index 38a28f5..d1306f7 100644 --- a/src/markers.rs +++ b/src/markers.rs @@ -1,21 +1,43 @@ -use bevy::ecs::component::Component; +use bevy::{ecs::{component::Component, reflect::ReflectComponent}, reflect::Reflect, utils::Uuid}; /// The root of all the scenes that will be generated from this plugin. -#[derive(Component, Debug)] +#[derive(Component, Debug, Reflect, Default, Clone)] +#[reflect(Component)] pub struct IconCreatorRootMarker; -#[derive(Component, Debug)] -pub struct IconCreatorSceneRootMarker; +/// u8 is for frames_elapsed +#[derive(Component, Debug, Reflect, Default, Clone)] +#[reflect(Component)] +pub struct IconCreatorSceneRootMarker(pub(crate) u8); -#[derive(Component, Debug)] +#[derive(Component, Debug, Reflect, Default, Clone)] +#[reflect(Component)] pub struct IconCreatorCameraMarker; -#[derive(Component, Debug)] +#[derive(Component, Debug, Reflect, Default, Clone)] +#[reflect(Component)] pub struct IconCreatorLightMarker; -#[derive(Component, Debug)] +#[derive(Component, Debug, Reflect, Default, Clone)] +#[reflect(Component)] pub struct IconCreatorEntityParentMarker; +#[derive(Component, Debug, Reflect, Default, Clone)] +#[reflect(Component)] +pub struct IconCreatorEntityChildMarker; + /// Everything inside a scene should contain this marker with the scene's id. -#[derive(Component, Debug)] -pub struct InIconCreatorSceneMarker(pub u8); \ No newline at end of file +#[derive(Component, Debug, Reflect, Default, Clone, Copy)] +#[reflect(Component)] +pub struct InIconCreatorSceneMarker(pub(crate) u8); + +#[derive(Component, Debug, Reflect, Default, Clone, Copy)] +#[reflect(Component)] +pub struct EntityGettingIconMarker { + pub(crate) extra_frames: Option, + pub(crate) id: Uuid, +} + +#[derive(Component, Debug, Reflect, Default, Clone)] +#[reflect(Component)] +pub struct SceneOccupiedMarker; \ No newline at end of file diff --git a/src/plugin.rs b/src/plugin.rs index a323b12..9d368dc 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -1,6 +1,6 @@ -use bevy::{app::{Plugin, Startup}, math::Vec3}; +use bevy::{app::{Plugin, Startup, Update}, math::Vec3}; -use crate::{setup::setup_icon_creation_scenes, state::IconCreatorState}; +use crate::{created_icons::CreatedIcons, register_types::RegisterTypesPlugin, setup::setup_icon_creation_scenes, state::IconCreatorState, update::{update_give_work_to_scenes, update_icon_creator_scenes, update_replace_images_on_ui_images, update_set_render_layers_recursively}}; const DEFAULT_SCENES_AMOUNT: u8 = 1; const DEFAULT_WORLD_POSITION_FOR_ROOT: Vec3 = Vec3 { x: 0.0, y: -300.0, z: 0.0 }; @@ -29,9 +29,17 @@ pub struct IconCreatorPlugin { impl Plugin for IconCreatorPlugin { fn build(&self, app: &mut bevy::prelude::App) { + app.add_plugins(RegisterTypesPlugin); app.insert_resource(IconCreatorState::new(self.scenes, self.world_pos, self.render_layer, self.light_intensity)); + app.insert_resource(CreatedIcons::default()); app.add_systems(Startup, setup_icon_creation_scenes); + app.add_systems(Update, ( + update_set_render_layers_recursively, + update_give_work_to_scenes, + update_icon_creator_scenes, + update_replace_images_on_ui_images, + )); } } diff --git a/src/register_types.rs b/src/register_types.rs new file mode 100644 index 0000000..1c4ea6a --- /dev/null +++ b/src/register_types.rs @@ -0,0 +1,24 @@ +use bevy::app::Plugin; + +use crate::{created_icons::CreatedIcons, markers::*, set_image_on_load::SetImageOnLoadMarker, state::IconCreatorState}; + +pub struct RegisterTypesPlugin; + +impl Plugin for RegisterTypesPlugin { + fn build(&self, app: &mut bevy::prelude::App) { + app + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + ; + } +} \ No newline at end of file diff --git a/src/set_image_on_load.rs b/src/set_image_on_load.rs new file mode 100644 index 0000000..94069ef --- /dev/null +++ b/src/set_image_on_load.rs @@ -0,0 +1,5 @@ +use bevy::{ecs::{component::Component, reflect::ReflectComponent}, reflect::Reflect, utils::Uuid}; + +#[derive(Component, Debug, Default, Clone, Reflect)] +#[reflect(Component)] +pub struct SetImageOnLoadMarker(pub Uuid); \ No newline at end of file diff --git a/src/setup.rs b/src/setup.rs index 3447a06..1f3038d 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -17,9 +17,9 @@ pub fn setup_icon_creation_scenes( // Scene Root let scene_root_entity = commands .spawn(( - IconCreatorSceneRootMarker, + IconCreatorSceneRootMarker(0), InIconCreatorSceneMarker(scene_id), - TransformBundle::default(), + TransformBundle::from_transform(Transform::from_translation(Vec3::X * 5.0 * scene_id as f32)), VisibilityBundle::default(), RenderLayers::layer(icon_creator_state.render_layer), Name::new(format!("Scene Root with id: {scene_id}")), diff --git a/src/state.rs b/src/state.rs index 3966317..e072ec1 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,6 +1,7 @@ -use bevy::{ecs::system::Resource, math::Vec3}; +use bevy::{ecs::{reflect::ReflectResource, system::Resource}, math::Vec3, reflect::Reflect}; -#[derive(Resource, Debug)] +#[derive(Resource, Debug, Reflect, Default, Clone)] +#[reflect(Resource)] pub struct IconCreatorState { pub(crate) scenes: u8, pub(crate) world_pos: Vec3, diff --git a/src/update.rs b/src/update.rs index e69de29..2e2fbc1 100644 --- a/src/update.rs +++ b/src/update.rs @@ -0,0 +1,113 @@ +use bevy::{prelude::*, render::{camera::RenderTarget, view::RenderLayers}, utils::petgraph::matrix_graph::Zero}; + +use crate::{created_icons::CreatedIcons, image_ext::ImageExt, markers::{EntityGettingIconMarker, IconCreatorCameraMarker, IconCreatorEntityChildMarker, IconCreatorEntityParentMarker, IconCreatorSceneRootMarker, InIconCreatorSceneMarker, SceneOccupiedMarker}, needs_icon_marker::NeedsIconMarker, set_image_on_load::SetImageOnLoadMarker, utils::mark_all_children_with_component}; + +const MIN_FRAMES_TO_RENDER: u8 = 3; + +/// In this update system the scenes will do the work of rendering to an image. +/// +/// It should keep track of the amount of frames. +pub fn update_icon_creator_scenes( + mut commands: Commands, + mut scene_query: Query<(&InIconCreatorSceneMarker, &mut Visibility, &mut IconCreatorSceneRootMarker), With>, + mut scene_camera_query: Query<(&mut Camera, &InIconCreatorSceneMarker), With>, + scene_entity_parent_query: Query<(Entity, &InIconCreatorSceneMarker), With>, + scene_child_query: Query<(&Parent, &InIconCreatorSceneMarker, &EntityGettingIconMarker), With>, + mut images: ResMut>, + mut created_icons: ResMut, +) { + for (scene_marker, mut scene_root_visibility, mut scene_root_marker) in scene_query.iter_mut() { + for (mut scene_camera, in_scene) in scene_camera_query.iter_mut() { + if scene_marker.0 != in_scene.0 { continue; } + for (scene_parent_entity, in_scene) in scene_entity_parent_query.iter() { + if scene_marker.0 != in_scene.0 { continue; } + for (scene_child_parent, in_scene, entity_getting_icon_marker) in scene_child_query.iter() { + if scene_child_parent.get() == scene_parent_entity && scene_marker.0 == in_scene.0 { + if scene_root_marker.0.is_zero() { // if it's the first frame + scene_camera.is_active = true; + *scene_root_visibility = Visibility::Visible; + // Create image + let camera_target_image_handle = if let Some(existing_image_handle) = created_icons.0.get(&entity_getting_icon_marker.id) { + existing_image_handle.clone() + } else { + let handle = images.add(Image::get_blank_image(512, 512)); + created_icons.0.insert(entity_getting_icon_marker.id, handle.clone()); + handle + }; + scene_camera.target = RenderTarget::Image(camera_target_image_handle); + } else if scene_root_marker.0 >= MIN_FRAMES_TO_RENDER + entity_getting_icon_marker.extra_frames.unwrap_or(0) { + // Unoccupy + if let Some(mut entity_commands) = commands.get_entity(scene_parent_entity) { + entity_commands.remove::(); + scene_camera.is_active = false; + *scene_root_visibility = Visibility::Hidden; + scene_camera.target = RenderTarget::default(); + } + } + } + } + } + } + scene_root_marker.0 += 1; + } +} + +#[allow(clippy::type_complexity)] +pub fn update_give_work_to_scenes( + mut commands: Commands, + needs_icon_query: Query<(Entity, &NeedsIconMarker)>, + mut scene_query: Query<(Entity, &InIconCreatorSceneMarker, &RenderLayers), (With, Without)>, + scene_entity_parent_query: Query<(Entity, &InIconCreatorSceneMarker), With>, +) { + for (needs_icon_entity, needs_icon_marker) in needs_icon_query.iter() { + // move this entity to any unoccupied scene. + // Then set the scene to occupied (Visibility::Visible & Camera.active = true & Occupied component) + for (scene_entity, scene_marker, scene_render_layer) in scene_query.iter_mut() { + for (scene_entity_parent, in_scene_marker) in scene_entity_parent_query.iter() { + if scene_marker.0 == in_scene_marker.0 { // Is inside the scene root + if let Some(mut entity_commands) = commands.get_entity(needs_icon_entity) { + entity_commands + .set_parent(scene_entity_parent) + .insert(needs_icon_marker.transform.unwrap_or_default()) + .insert(*scene_render_layer) + .insert(*in_scene_marker) + .insert(EntityGettingIconMarker { + extra_frames: needs_icon_marker.extra_frames, + id: needs_icon_marker.id, + }) + .insert(IconCreatorEntityChildMarker) + .insert(VisibilityBundle::default()) + .remove::(); + commands.entity(scene_entity).insert(SceneOccupiedMarker); + } + } + } + } + } +} + +#[allow(clippy::type_complexity)] +pub fn update_set_render_layers_recursively( + mut commands: Commands, + in_scene_but_no_render_layers_query: Query<(Entity, &RenderLayers, &InIconCreatorSceneMarker), (Added, Added)>, + children_query: Query<&Children>, +) { + for (in_scene_entity, render_layers, in_icon_creator_scene_marker) in in_scene_but_no_render_layers_query.iter() { + mark_all_children_with_component(&mut commands, in_scene_entity, &children_query, (*render_layers, VisibilityBundle::default(), *in_icon_creator_scene_marker), false); + } +} + +pub fn update_replace_images_on_ui_images( + mut commands: Commands, + mut marked_ui_images_query: Query<(Entity, &SetImageOnLoadMarker, &mut UiImage)>, + created_icons: Res, +) { + for (entity, set_image_on_load_marker, mut ui_image) in marked_ui_images_query.iter_mut() { + if let Some(image_handle) = created_icons.get_image_handle(&set_image_on_load_marker.0) { + ui_image.texture = image_handle; + if let Some(mut entity_commands) = commands.get_entity(entity) { + entity_commands.remove::(); + } + } + } +} \ No newline at end of file diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..1a9fe20 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,35 @@ +use bevy::prelude::*; + +pub fn mark_all_children_with_component( + commands: &mut Commands, + entity: Entity, + children_query: &Query<&Children>, + bundle: T, + mark_parent: bool, +) { + if mark_parent { + if let Some(mut entity_commands) = commands.get_entity(entity) { + entity_commands.insert(bundle.clone()); + } + } + mark_all_children_with_component_recursive(commands, entity, children_query, bundle, true); +} + +fn mark_all_children_with_component_recursive( + commands: &mut Commands, + entity: Entity, + children_query: &Query<&Children>, + bundle: T, + first_time: bool, +) { + if let Ok(new_children) = children_query.get(entity) { + for child in new_children.iter() { + mark_all_children_with_component_recursive(commands, *child, children_query, bundle.clone(), false); + } + } + if !first_time { + if let Some(mut entity_commands) = commands.get_entity(entity) { + entity_commands.insert(bundle); + } + } +} \ No newline at end of file