diff --git a/src/app/entity_app_ext.rs b/src/app/entity_app_ext.rs new file mode 100644 index 00000000..5ee425dc --- /dev/null +++ b/src/app/entity_app_ext.rs @@ -0,0 +1,180 @@ +//! Provides [LdtkEntityAppExt] for registering bundles to spawn for given LDtk Entity identifiers. +use crate::app::ldtk_entity::*; +use bevy::prelude::*; + +/// [Bundle]: bevy::prelude::Bundle +/// [App]: bevy::prelude::App +/// +/// Provides functions to register [Bundle]s to bevy's [App] for particular LDtk layer and entity +/// identifiers. +/// +/// After being registered, entities will be spawned with these [Bundle]s when some entity in LDtk +/// meets the criteria you specify. +/// +/// Not intended for custom implementations on your own types. +pub trait LdtkEntityAppExt { + /// Used internally by all the other LDtk entity registration functions. + /// + /// Similar to [LdtkEntityAppExt::register_ldtk_entity_for_layer], except it provides + /// defaulting functionality: + /// - Setting `layer_identifier` to [None] will make the registration apply to any Entity layer. + /// - Setting `entity_identifier` to [None] will make the registration apply to any LDtk entity. + /// + /// This defaulting functionality means that a particular instance of an LDtk entity may match + /// multiple registrations. + /// In these cases, registrations are prioritized in order of most to least specific: + /// 1. `layer_identifier` and `entity_identifier` are specified + /// 2. Just `entity_identifier` is specified + /// 3. Just `layer_identifier` is specified + /// 4. Neither `entity_identifier` nor `layer_identifier` are specified + fn register_ldtk_entity_for_layer_optional( + &mut self, + layer_identifier: Option, + entity_identifier: Option, + ) -> &mut Self; + + /// Registers [LdtkEntity] types to be spawned for a given Entity identifier and layer + /// identifier in an LDtk file. + /// + /// This example lets the plugin know that it should spawn a MyBundle when it encounters a + /// "my_entity_identifier" entity on a "MyLayerIdentifier" layer. + /// ```no_run + /// use bevy::prelude::*; + /// use bevy_ecs_ldtk::prelude::*; + /// + /// fn main() { + /// App::empty() + /// .add_plugin(LdtkPlugin) + /// .register_ldtk_entity_for_layer::("MyLayerIdentifier", "my_entity_identifier") + /// // add other systems, plugins, resources... + /// .run(); + /// } + /// + /// # #[derive(Component, Default)] + /// # struct ComponentA; + /// # #[derive(Component, Default)] + /// # struct ComponentB; + /// # #[derive(Component, Default)] + /// # struct ComponentC; + /// #[derive(Bundle, LdtkEntity)] + /// pub struct MyBundle { + /// a: ComponentA, + /// b: ComponentB, + /// c: ComponentC, + /// } + /// ``` + /// + /// You can find more details on the `#[derive(LdtkEntity)]` macro at [LdtkEntity]. + fn register_ldtk_entity_for_layer( + &mut self, + layer_identifier: &str, + entity_identifier: &str, + ) -> &mut Self { + self.register_ldtk_entity_for_layer_optional::( + Some(layer_identifier.to_string()), + Some(entity_identifier.to_string()), + ) + } + + /// Similar to [LdtkEntityAppExt::register_ldtk_entity_for_layer], except it applies the + /// registration to all layers. + fn register_ldtk_entity( + &mut self, + entity_identifier: &str, + ) -> &mut Self { + self.register_ldtk_entity_for_layer_optional::(None, Some(entity_identifier.to_string())) + } + + /// Similar to [LdtkEntityAppExt::register_ldtk_entity_for_layer], except it applies the + /// registration to all entities on the given layer. + fn register_default_ldtk_entity_for_layer( + &mut self, + layer_identifier: &str, + ) -> &mut Self { + self.register_ldtk_entity_for_layer_optional::(Some(layer_identifier.to_string()), None) + } + + /// Similar to [LdtkEntityAppExt::register_ldtk_entity_for_layer], except it applies the + /// registration to any entity and any layer. + fn register_default_ldtk_entity(&mut self) -> &mut Self { + self.register_ldtk_entity_for_layer_optional::(None, None) + } +} + +impl LdtkEntityAppExt for App { + fn register_ldtk_entity_for_layer_optional( + &mut self, + layer_identifier: Option, + entity_identifier: Option, + ) -> &mut Self { + let new_entry = Box::new(PhantomLdtkEntity::::new()); + match self.world.get_non_send_resource_mut::() { + Some(mut entries) => { + entries.insert((layer_identifier, entity_identifier), new_entry); + } + None => { + let mut bundle_map = LdtkEntityMap::new(); + bundle_map.insert((layer_identifier, entity_identifier), new_entry); + self.world + .insert_non_send_resource::(bundle_map); + } + } + self + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + components::EntityInstance, + ldtk::{LayerInstance, TilesetDefinition}, + }; + + #[derive(Default, Component, Debug)] + struct ComponentA; + + #[derive(Default, Component, Debug)] + struct ComponentB; + + #[derive(Default, Bundle, Debug)] + struct LdtkEntityBundle { + a: ComponentA, + b: ComponentB, + } + + impl LdtkEntity for LdtkEntityBundle { + fn bundle_entity( + _: &EntityInstance, + _: &LayerInstance, + _: Option<&Handle>, + _: Option<&TilesetDefinition>, + _: &AssetServer, + _: &mut Assets, + ) -> LdtkEntityBundle { + LdtkEntityBundle::default() + } + } + + #[test] + fn test_ldtk_entity_registrations() { + let mut app = App::new(); + app.register_ldtk_entity_for_layer::("layer", "entity_for_layer") + .register_ldtk_entity::("entity") + .register_default_ldtk_entity_for_layer::("default_entity_for_layer") + .register_default_ldtk_entity::(); + + let ldtk_entity_map = app.world.get_non_send_resource::().unwrap(); + + assert!(ldtk_entity_map.contains_key(&( + Some("layer".to_string()), + Some("entity_for_layer".to_string()) + ))); + + assert!(ldtk_entity_map.contains_key(&(None, Some("entity".to_string())))); + + assert!(ldtk_entity_map.contains_key(&(Some("default_entity_for_layer".to_string()), None))); + + assert!(ldtk_entity_map.contains_key(&(None, None))); + } +} diff --git a/src/app/int_cell_app_ext.rs b/src/app/int_cell_app_ext.rs new file mode 100644 index 00000000..6efe7e14 --- /dev/null +++ b/src/app/int_cell_app_ext.rs @@ -0,0 +1,171 @@ +//! Provides [LdtkIntCellAppExt] for registering bundles to spawn for given IntGrid values. +use crate::app::ldtk_int_cell::*; +use bevy::prelude::*; + +/// [Bundle]: bevy::prelude::Bundle +/// [App]: bevy::prelude::App +/// +/// Provides functions to register [Bundle]s to bevy's [App] for particular LDtk layer and IntGrid +/// values. +/// +/// After being registered, entities will be spawned with these [Bundle]s when some IntGrid cell in +/// LDtk meets the criteria you specify. +/// +/// Not intended for custom implementations on your own types. +pub trait LdtkIntCellAppExt { + /// Used internally by all the other LDtk int cell registration functions. + /// + /// Similar to [LdtkIntCellAppExt::register_ldtk_int_cell_for_layer], except it provides + /// defaulting functionality: + /// - Setting `layer_identifier` to [None] will make the registration apply to any IntGrid layer. + /// - Setting `value` to [None] will make the registration apply to any IntGrid tile. + /// + /// This defaulting functionality means that a particular LDtk IntGrid tile may match multiple + /// registrations. + /// In these cases, registrations are prioritized in order of most to least specific: + /// 1. `layer_identifier` and `value` are specified + /// 2. Just `value` is specified + /// 3. Just `layer_identifier` is specified + /// 4. Neither `value` nor `layer_identifier` are specified + fn register_ldtk_int_cell_for_layer_optional( + &mut self, + layer_identifier: Option, + value: Option, + ) -> &mut Self; + + /// Registers [LdtkIntCell] types to be inserted for a given IntGrid value and layer identifier + /// in an LDtk file. + /// + /// This example lets the plugin know that it should spawn a MyBundle when it encounters an + /// IntGrid tile whose value is `1` on a "MyLayerIdentifier" layer. + /// ```no_run + /// use bevy::prelude::*; + /// use bevy_ecs_ldtk::prelude::*; + /// + /// fn main() { + /// App::empty() + /// .add_plugin(LdtkPlugin) + /// .register_ldtk_int_cell_for_layer::("MyLayerIdentifier", 1) + /// // add other systems, plugins, resources... + /// .run(); + /// } + /// + /// # #[derive(Component, Default)] + /// # struct ComponentA; + /// # #[derive(Component, Default)] + /// # struct ComponentB; + /// # #[derive(Component, Default)] + /// # struct ComponentC; + /// #[derive(Bundle, LdtkIntCell)] + /// pub struct MyBundle { + /// a: ComponentA, + /// b: ComponentB, + /// c: ComponentC, + /// } + /// ``` + /// + /// You can find more details on the `#[derive(LdtkIntCell)]` macro at [LdtkIntCell]. + fn register_ldtk_int_cell_for_layer( + &mut self, + layer_identifier: &str, + value: i32, + ) -> &mut Self { + self.register_ldtk_int_cell_for_layer_optional::( + Some(layer_identifier.to_string()), + Some(value), + ) + } + + /// Similar to [LdtkIntCellAppExt::register_ldtk_int_cell_for_layer], except it applies the + /// registration to all layers. + fn register_ldtk_int_cell(&mut self, value: i32) -> &mut Self { + self.register_ldtk_int_cell_for_layer_optional::(None, Some(value)) + } + + /// Similar to [LdtkIntCellAppExt::register_ldtk_int_cell_for_layer], except it applies the + /// registration to all tiles on the given layer. + fn register_default_ldtk_int_cell_for_layer( + &mut self, + layer_identifier: &str, + ) -> &mut Self { + self.register_ldtk_int_cell_for_layer_optional::( + Some(layer_identifier.to_string()), + None, + ) + } + + /// Similar to [LdtkIntCellAppExt::register_ldtk_int_cell_for_layer], except it applies the + /// registration to any tile and any layer. + fn register_default_ldtk_int_cell(&mut self) -> &mut Self { + self.register_ldtk_int_cell_for_layer_optional::(None, None) + } +} + +impl LdtkIntCellAppExt for App { + fn register_ldtk_int_cell_for_layer_optional( + &mut self, + layer_identifier: Option, + value: Option, + ) -> &mut Self { + let new_entry = Box::new(PhantomLdtkIntCell::::new()); + match self.world.get_non_send_resource_mut::() { + Some(mut entries) => { + entries.insert((layer_identifier, value), new_entry); + } + None => { + let mut bundle_map = LdtkIntCellMap::new(); + bundle_map.insert((layer_identifier, value), new_entry); + self.world + .insert_non_send_resource::(bundle_map); + } + } + self + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{components::IntGridCell, ldtk::LayerInstance}; + + #[derive(Default, Component, Debug)] + struct ComponentA; + + #[derive(Default, Component, Debug)] + struct ComponentB; + + #[derive(Default, Bundle)] + struct LdtkIntCellBundle { + a: ComponentA, + b: ComponentB, + } + + impl LdtkIntCell for LdtkIntCellBundle { + fn bundle_int_cell(_: IntGridCell, _: &LayerInstance) -> LdtkIntCellBundle { + LdtkIntCellBundle::default() + } + } + + #[test] + fn test_ldtk_int_cell_registrations() { + let mut app = App::new(); + app.register_ldtk_int_cell_for_layer::("layer", 1) + .register_ldtk_int_cell::(2) + .register_default_ldtk_int_cell_for_layer::( + "default_int_cell_for_layer", + ) + .register_default_ldtk_int_cell::(); + + let ldtk_int_cell_map = app.world.get_non_send_resource::().unwrap(); + + assert!(ldtk_int_cell_map.contains_key(&(Some("layer".to_string()), Some(1)))); + + assert!(ldtk_int_cell_map.contains_key(&(None, Some(2)))); + + assert!( + ldtk_int_cell_map.contains_key(&(Some("default_int_cell_for_layer".to_string()), None)) + ); + + assert!(ldtk_int_cell_map.contains_key(&(None, None))); + } +} diff --git a/src/app/ldtk_entity.rs b/src/app/ldtk_entity.rs index d6f1b93c..ed4aa9a1 100644 --- a/src/app/ldtk_entity.rs +++ b/src/app/ldtk_entity.rs @@ -6,9 +6,7 @@ use crate::{ use bevy::{ecs::system::EntityCommands, prelude::*}; use std::{collections::HashMap, marker::PhantomData}; -#[allow(unused_imports)] -use crate::app::register_ldtk_objects::RegisterLdtkObjects; - +/// [LdtkEntityAppExt]: super::LdtkEntityAppExt /// [Bundle]: bevy::prelude::Bundle /// [App]: bevy::prelude::App /// [Component]: bevy::prelude::Component @@ -16,7 +14,7 @@ use crate::app::register_ldtk_objects::RegisterLdtkObjects; /// Provides a constructor which can be used for spawning entities from an LDtk file. /// /// After implementing this trait on a [Bundle], you can register it to spawn automatically for a -/// given identifier via [RegisterLdtkObjects] functions on your [App]. +/// given identifier via [LdtkEntityAppExt] functions on your [App]. /// /// For common use cases, you'll want to use derive-macro `#[derive(LdtkEntity)]`, but you can also /// provide a custom implementation. @@ -30,7 +28,7 @@ use crate::app::register_ldtk_objects::RegisterLdtkObjects; /// /// ## Derive macro usage /// Using `#[derive(LdtkEntity)]` on a [Bundle] struct will allow the type to be registered to the -/// [App] via [RegisterLdtkObjects] functions: +/// [App] via [LdtkEntityAppExt] functions: /// ```no_run /// use bevy::prelude::*; /// use bevy_ecs_ldtk::prelude::*; @@ -427,5 +425,5 @@ impl PhantomLdtkEntityTrait for PhantomLdtkEntity { } } -/// Used by [RegisterLdtkObjects] to associate Ldtk entity identifiers with [LdtkEntity]s. +/// Used by [LdtkEntityAppExt](super::LdtkEntityAppExt) to associate Ldtk entity identifiers with [LdtkEntity]s. pub type LdtkEntityMap = HashMap<(Option, Option), Box>; diff --git a/src/app/ldtk_int_cell.rs b/src/app/ldtk_int_cell.rs index 9471d3e0..ee725bb8 100644 --- a/src/app/ldtk_int_cell.rs +++ b/src/app/ldtk_int_cell.rs @@ -5,6 +5,7 @@ use crate::{ use bevy::{ecs::system::EntityCommands, prelude::*}; use std::{collections::HashMap, marker::PhantomData}; +/// [LdtkIntCellAppExt]: super::LdtkIntCellAppExt /// [Bundle]: bevy::prelude::Bundle /// [App]: bevy::prelude::App /// [Component]: bevy::prelude::Component @@ -12,7 +13,7 @@ use std::{collections::HashMap, marker::PhantomData}; /// Provides a constructor which can be used for spawning additional components on IntGrid tiles. /// /// After implementing this trait on a [Bundle], you can register it to spawn automatically for a -/// given int grid value via [RegisterLdtkObjects] on your [App]. +/// given int grid value via [LdtkIntCellAppExt] on your [App]. /// /// For common use cases, you'll want to use derive-macro `#[derive(LdtkIntCell)]`, but you can /// also provide a custom implementation. @@ -26,7 +27,7 @@ use std::{collections::HashMap, marker::PhantomData}; /// /// ## Derive macro usage /// Using `#[derive(LdtkIntCell)]` on a [Bundle] struct will allow the type to be registered to the -/// [App] via [RegisterLdtkObjects] functions: +/// [App] via [LdtkIntCellAppExt] functions: /// ```no_run /// use bevy::prelude::*; /// use bevy_ecs_ldtk::prelude::*; @@ -180,5 +181,5 @@ impl PhantomLdtkIntCellTrait for PhantomLdtkIntCell } } -/// Used by [RegisterLdtkObjects] to associate Ldtk IntGrid values with [LdtkIntCell]s. +/// Used by [LdtkIntCellAppExt](super::LdtkIntCellAppExt) to associate Ldtk IntGrid values with [LdtkIntCell]s. pub type LdtkIntCellMap = HashMap<(Option, Option), Box>; diff --git a/src/app/mod.rs b/src/app/mod.rs index ff13c858..446d7fd1 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -1,9 +1,11 @@ //! Types and traits for hooking into the ldtk loading process via [bevy::app::App]. +mod entity_app_ext; +mod int_cell_app_ext; mod ldtk_entity; mod ldtk_int_cell; -mod register_ldtk_objects; +pub use entity_app_ext::*; +pub use int_cell_app_ext::*; pub use ldtk_entity::*; pub use ldtk_int_cell::*; -pub use register_ldtk_objects::*; diff --git a/src/app/register_ldtk_objects.rs b/src/app/register_ldtk_objects.rs deleted file mode 100644 index b50811ee..00000000 --- a/src/app/register_ldtk_objects.rs +++ /dev/null @@ -1,318 +0,0 @@ -use crate::{app::ldtk_entity::*, app::ldtk_int_cell::*}; -use bevy::prelude::*; - -/// Provides functions to register [Bundle]s to bevy's [App] for particular LDtk layer identifiers, -/// entity identifiers, and IntGrid values. -/// -/// After being registered, [Entity]s will be spawned with these bundles when some IntGrid tile or -/// entity meets the criteria you specify. -/// -/// Not necessarily intended for custom implementations on your own types. -pub trait RegisterLdtkObjects { - /// Used internally by all the other LDtk entity registration functions. - /// - /// Similar to [RegisterLdtkObjects::register_ldtk_entity_for_layer], except it provides - /// defaulting functionality: - /// - Setting `layer_identifier` to [None] will make the registration apply to any Entity layer. - /// - Setting `entity_identifier` to [None] will make the registration apply to any LDtk entity. - /// - /// This defaulting functionality means that a particular instance of an LDtk entity may match - /// multiple registrations. - /// In these cases, registrations are prioritized in order of most to least specific: - /// 1. `layer_identifier` and `entity_identifier` are specified - /// 2. Just `entity_identifier` is specified - /// 3. Just `layer_identifier` is specified - /// 4. Neither `entity_identifier` nor `layer_identifier` are specified - fn register_ldtk_entity_for_layer_optional( - &mut self, - layer_identifier: Option, - entity_identifier: Option, - ) -> &mut Self; - - /// Registers [LdtkEntity] types to be spawned for a given Entity identifier and layer - /// identifier in an LDtk file. - /// - /// This example lets the plugin know that it should spawn a MyBundle when it encounters a - /// "my_entity_identifier" entity on a "MyLayerIdentifier" layer. - /// ```no_run - /// use bevy::prelude::*; - /// use bevy_ecs_ldtk::prelude::*; - /// - /// fn main() { - /// App::empty() - /// .add_plugin(LdtkPlugin) - /// .register_ldtk_entity_for_layer::("MyLayerIdentifier", "my_entity_identifier") - /// // add other systems, plugins, resources... - /// .run(); - /// } - /// - /// # #[derive(Component, Default)] - /// # struct ComponentA; - /// # #[derive(Component, Default)] - /// # struct ComponentB; - /// # #[derive(Component, Default)] - /// # struct ComponentC; - /// #[derive(Bundle, LdtkEntity)] - /// pub struct MyBundle { - /// a: ComponentA, - /// b: ComponentB, - /// c: ComponentC, - /// } - /// ``` - /// - /// You can find more details on the `#[derive(LdtkEntity)]` macro at [LdtkEntity]. - fn register_ldtk_entity_for_layer( - &mut self, - layer_identifier: &str, - entity_identifier: &str, - ) -> &mut Self { - self.register_ldtk_entity_for_layer_optional::( - Some(layer_identifier.to_string()), - Some(entity_identifier.to_string()), - ) - } - - /// Similar to [RegisterLdtkObjects::register_ldtk_entity_for_layer], except it applies the - /// registration to all layers. - fn register_ldtk_entity( - &mut self, - entity_identifier: &str, - ) -> &mut Self { - self.register_ldtk_entity_for_layer_optional::(None, Some(entity_identifier.to_string())) - } - - /// Similar to [RegisterLdtkObjects::register_ldtk_entity_for_layer], except it applies the - /// registration to all entities on the given layer. - fn register_default_ldtk_entity_for_layer( - &mut self, - layer_identifier: &str, - ) -> &mut Self { - self.register_ldtk_entity_for_layer_optional::(Some(layer_identifier.to_string()), None) - } - - /// Similar to [RegisterLdtkObjects::register_ldtk_entity_for_layer], except it applies the - /// registration to any entity and any layer. - fn register_default_ldtk_entity(&mut self) -> &mut Self { - self.register_ldtk_entity_for_layer_optional::(None, None) - } - - /// Used internally by all the other LDtk int cell registration functions. - /// - /// Similar to [RegisterLdtkObjects::register_ldtk_int_cell_for_layer], except it provides - /// defaulting functionality: - /// - Setting `layer_identifier` to [None] will make the registration apply to any IntGrid layer. - /// - Setting `value` to [None] will make the registration apply to any IntGrid tile. - /// - /// This defaulting functionality means that a particular LDtk IntGrid tile may match multiple - /// registrations. - /// In these cases, registrations are prioritized in order of most to least specific: - /// 1. `layer_identifier` and `value` are specified - /// 2. Just `value` is specified - /// 3. Just `layer_identifier` is specified - /// 4. Neither `value` nor `layer_identifier` are specified - fn register_ldtk_int_cell_for_layer_optional( - &mut self, - layer_identifier: Option, - value: Option, - ) -> &mut Self; - - /// Registers [LdtkIntCell] types to be inserted for a given IntGrid value and layer identifier - /// in an LDtk file. - /// - /// This example lets the plugin know that it should spawn a MyBundle when it encounters an - /// IntGrid tile whose value is `1` on a "MyLayerIdentifier" layer. - /// ```no_run - /// use bevy::prelude::*; - /// use bevy_ecs_ldtk::prelude::*; - /// - /// fn main() { - /// App::empty() - /// .add_plugin(LdtkPlugin) - /// .register_ldtk_int_cell_for_layer::("MyLayerIdentifier", 1) - /// // add other systems, plugins, resources... - /// .run(); - /// } - /// - /// # #[derive(Component, Default)] - /// # struct ComponentA; - /// # #[derive(Component, Default)] - /// # struct ComponentB; - /// # #[derive(Component, Default)] - /// # struct ComponentC; - /// #[derive(Bundle, LdtkIntCell)] - /// pub struct MyBundle { - /// a: ComponentA, - /// b: ComponentB, - /// c: ComponentC, - /// } - /// ``` - /// - /// You can find more details on the `#[derive(LdtkIntCell)]` macro at [LdtkIntCell]. - fn register_ldtk_int_cell_for_layer( - &mut self, - layer_identifier: &str, - value: i32, - ) -> &mut Self { - self.register_ldtk_int_cell_for_layer_optional::( - Some(layer_identifier.to_string()), - Some(value), - ) - } - - /// Similar to [RegisterLdtkObjects::register_ldtk_int_cell_for_layer], except it applies the - /// registration to all layers. - fn register_ldtk_int_cell(&mut self, value: i32) -> &mut Self { - self.register_ldtk_int_cell_for_layer_optional::(None, Some(value)) - } - - /// Similar to [RegisterLdtkObjects::register_ldtk_int_cell_for_layer], except it applies the - /// registration to all tiles on the given layer. - fn register_default_ldtk_int_cell_for_layer( - &mut self, - layer_identifier: &str, - ) -> &mut Self { - self.register_ldtk_int_cell_for_layer_optional::( - Some(layer_identifier.to_string()), - None, - ) - } - - /// Similar to [RegisterLdtkObjects::register_ldtk_int_cell_for_layer], except it applies the - /// registration to any tile and any layer. - fn register_default_ldtk_int_cell(&mut self) -> &mut Self { - self.register_ldtk_int_cell_for_layer_optional::(None, None) - } -} - -impl RegisterLdtkObjects for App { - fn register_ldtk_entity_for_layer_optional( - &mut self, - layer_identifier: Option, - entity_identifier: Option, - ) -> &mut Self { - let new_entry = Box::new(PhantomLdtkEntity::::new()); - match self.world.get_non_send_resource_mut::() { - Some(mut entries) => { - entries.insert((layer_identifier, entity_identifier), new_entry); - } - None => { - let mut bundle_map = LdtkEntityMap::new(); - bundle_map.insert((layer_identifier, entity_identifier), new_entry); - self.world - .insert_non_send_resource::(bundle_map); - } - } - self - } - - fn register_ldtk_int_cell_for_layer_optional( - &mut self, - layer_identifier: Option, - value: Option, - ) -> &mut Self { - let new_entry = Box::new(PhantomLdtkIntCell::::new()); - match self.world.get_non_send_resource_mut::() { - Some(mut entries) => { - entries.insert((layer_identifier, value), new_entry); - } - None => { - let mut bundle_map = LdtkIntCellMap::new(); - bundle_map.insert((layer_identifier, value), new_entry); - self.world - .insert_non_send_resource::(bundle_map); - } - } - self - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::{ - components::{EntityInstance, IntGridCell}, - ldtk::{LayerInstance, TilesetDefinition}, - }; - - #[derive(Default, Component, Debug)] - struct ComponentA; - - #[derive(Default, Component, Debug)] - struct ComponentB; - - #[derive(Default, Bundle, Debug)] - struct LdtkEntityBundle { - a: ComponentA, - b: ComponentB, - } - - impl LdtkEntity for LdtkEntityBundle { - fn bundle_entity( - _: &EntityInstance, - _: &LayerInstance, - _: Option<&Handle>, - _: Option<&TilesetDefinition>, - _: &AssetServer, - _: &mut Assets, - ) -> LdtkEntityBundle { - LdtkEntityBundle::default() - } - } - - #[derive(Default, Bundle)] - struct LdtkIntCellBundle { - a: ComponentA, - b: ComponentB, - } - - impl LdtkIntCell for LdtkIntCellBundle { - fn bundle_int_cell(_: IntGridCell, _: &LayerInstance) -> LdtkIntCellBundle { - LdtkIntCellBundle::default() - } - } - - #[test] - fn test_ldtk_entity_registrations() { - let mut app = App::new(); - app.register_ldtk_entity_for_layer::("layer", "entity_for_layer") - .register_ldtk_entity::("entity") - .register_default_ldtk_entity_for_layer::("default_entity_for_layer") - .register_default_ldtk_entity::(); - - let ldtk_entity_map = app.world.get_non_send_resource::().unwrap(); - - assert!(ldtk_entity_map.contains_key(&( - Some("layer".to_string()), - Some("entity_for_layer".to_string()) - ))); - - assert!(ldtk_entity_map.contains_key(&(None, Some("entity".to_string())))); - - assert!(ldtk_entity_map.contains_key(&(Some("default_entity_for_layer".to_string()), None))); - - assert!(ldtk_entity_map.contains_key(&(None, None))); - } - - #[test] - fn test_ldtk_int_cell_registrations() { - let mut app = App::new(); - app.register_ldtk_int_cell_for_layer::("layer", 1) - .register_ldtk_int_cell::(2) - .register_default_ldtk_int_cell_for_layer::( - "default_int_cell_for_layer", - ) - .register_default_ldtk_int_cell::(); - - let ldtk_int_cell_map = app.world.get_non_send_resource::().unwrap(); - - assert!(ldtk_int_cell_map.contains_key(&(Some("layer".to_string()), Some(1)))); - - assert!(ldtk_int_cell_map.contains_key(&(None, Some(2)))); - - assert!( - ldtk_int_cell_map.contains_key(&(Some("default_int_cell_for_layer".to_string()), None)) - ); - - assert!(ldtk_int_cell_map.contains_key(&(None, None))); - } -} diff --git a/src/lib.rs b/src/lib.rs index 9b3fb2a8..104e6939 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -219,7 +219,7 @@ pub mod prelude { //! `use bevy_ecs_ldtk::prelude::*;` to import commonly used items. pub use crate::{ - app::{LdtkEntity, LdtkIntCell, RegisterLdtkObjects}, + app::{LdtkEntity, LdtkEntityAppExt, LdtkIntCell, LdtkIntCellAppExt}, assets::{LdtkAsset, LdtkLevel}, components::{ EntityInstance, GridCoords, IntGridCell, LayerMetadata, LdtkWorldBundle, LevelSet, diff --git a/src/utils.rs b/src/utils.rs index a67bacba..8b4f6d23 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -268,7 +268,7 @@ pub(crate) fn set_all_tiles_with_func( /// 3. Some, None /// 4. None, None /// -/// Used for the defaulting functionality of [bevy_ecs_ldtk::app::RegisterLdtkObjects] +/// Used for the defaulting functionality of the `AppExt` traits in [bevy_ecs_ldtk::app]. pub(crate) fn try_each_optional_permutation( a: A, b: B, @@ -287,7 +287,7 @@ where /// The "get" function used on [bevy_ecs_ldtk::app::LdtkEntityMap] and /// [bevy_ecs_ldtk::app::LdtkIntCellMap]. /// -/// Due to the defaulting functionality of [bevy_ecs_ldtk::app::RegisterLdtkObjects], a single +/// Due to the defaulting functionality of the `AppExt` traits in [bevy_ecs_ldtk::app], a single /// instance of an LDtk entity or int grid tile may match multiple registrations. /// This function is responsible for picking the correct registration while spawning these /// entities/tiles.