An experimental, status effects-as-entities system for Bevy.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Rename `EffectBundle` to `Effect`. It is now only used during related spawning.

+49 -49
+3 -3
benches/insert_mode.rs
··· 1 1 //! Benchmarks for applying insert-mode effects. 2 2 3 - use bevy_alchemy::{AlchemyPlugin, EffectBundle, EffectCommandsExt, EffectMode, EffectedBy}; 3 + use bevy_alchemy::{AlchemyPlugin, Effect, EffectCommandsExt, EffectMode, EffectedBy}; 4 4 use bevy_app::App; 5 5 use bevy_ecs::name::Name; 6 6 use bevy_ecs::prelude::{Component, Entity, SpawnRelated}; ··· 17 17 .world_mut() 18 18 .spawn(( 19 19 Name::new("Target"), 20 - EffectedBy::spawn(EffectBundle(( 20 + EffectedBy::spawn(Effect(( 21 21 Name::new("Effect"), 22 22 EffectMode::Insert, 23 23 BenchEffect, ··· 51 51 app.world_mut() 52 52 .commands() 53 53 .entity(entity) 54 - .insert(EffectedBy::spawn(EffectBundle(( 54 + .insert(EffectedBy::spawn(Effect(( 55 55 Name::new("Effect"), 56 56 EffectMode::Insert, 57 57 BenchEffect,
+2 -2
benches/stack_mode.rs
··· 1 1 //! Benchmarks for applying stack-mode effects. 2 2 3 - use bevy_alchemy::{AlchemyPlugin, EffectBundle, EffectCommandsExt, EffectMode, EffectedBy}; 3 + use bevy_alchemy::{AlchemyPlugin, Effect, EffectCommandsExt, EffectMode, EffectedBy}; 4 4 use bevy_app::App; 5 5 use bevy_ecs::name::Name; 6 6 use bevy_ecs::prelude::{Component, Entity, SpawnRelated}; ··· 41 41 app.world_mut() 42 42 .commands() 43 43 .entity(entity) 44 - .insert(EffectedBy::spawn(EffectBundle(( 44 + .insert(EffectedBy::spawn(Effect(( 45 45 Name::new("Effect"), 46 46 EffectMode::Stack, 47 47 BenchEffect,
+1 -1
docs/effected_by_spawn_example.md
··· 12 12 commands.spawn(( 13 13 Name::new("Target"), 14 14 EffectedBy::spawn( 15 - EffectBundle((Name::new("Effect"), MyEffect)) 15 + Effect((Name::new("Effect"), MyEffect)) 16 16 ), 17 17 )); 18 18 # }
-16
src/bundle.rs
··· 1 - use bevy_ecs::prelude::*; 2 - 3 - /// A "bundle" of components/settings used when applying an effect. 4 - /// Due to technical limitations, this doesn't actually implement [`Bundle`]. 5 - /// Instead, purpose build commands ([`with_effect`](crate::command::EffectCommandsExt::with_effect)) 6 - /// or related spawners ([`EffectedBy::spawn`](SpawnRelated::spawn)) should be used. 7 - /// 8 - /// # Examples 9 - /// ### [`with_effect`](crate::command::EffectCommandsExt::with_effect) 10 - #[doc = include_str!("../docs/with_effect_example.md")] 11 - /// ### [`with_effects`](crate::command::EffectCommandsExt::with_effects) + [`EffectSpawner`](crate::command::EffectSpawner) 12 - #[doc = include_str!("../docs/with_effects_example.md")] 13 - /// ### [`EffectedBy::spawn`](SpawnRelated::spawn) 14 - #[doc = include_str!("../docs/effected_by_spawn_example.md")] 15 - #[derive(Default)] 16 - pub struct EffectBundle<B: Bundle>(pub B);
-18
src/command.rs
··· 1 - use crate::bundle::EffectBundle; 2 1 use crate::bundle_inspector::BundleInspector; 3 2 use crate::registry::{EffectMergeFn, EffectMergeRegistry}; 4 3 use crate::{EffectMode, EffectedBy, Effecting}; 5 4 use bevy_ecs::entity_disabling::Disabled; 6 5 use bevy_ecs::prelude::*; 7 - use bevy_ecs::ptr::MovingPtr; 8 - use bevy_ecs::spawn::SpawnableList; 9 6 use bevy_log::warn_once; 10 7 use std::any::TypeId; 11 8 ··· 139 136 } 140 137 EffectMode::Merge => self.merge(world, old_entity), 141 138 } 142 - } 143 - } 144 - 145 - // Todo This is probably bad practice/has larger performance cost. 146 - impl<B: Bundle + Clone> SpawnableList<Effecting> for EffectBundle<B> { 147 - fn spawn(this: MovingPtr<'_, Self>, world: &mut World, target: Entity) { 148 - let bundle = this.read(); 149 - world.commands().queue(AddEffectCommand { 150 - target, 151 - bundle: bundle.0, 152 - }); 153 - } 154 - 155 - fn size_hint(&self) -> usize { 156 - 0 157 139 } 158 140 } 159 141
+2 -2
src/lib.rs
··· 1 1 #![doc = include_str!("../README.md")] 2 2 3 - mod bundle; 4 3 mod bundle_inspector; 5 4 mod command; 6 5 mod component; 7 6 mod registry; 8 7 mod relation; 8 + mod spawnable_list; 9 9 10 10 use bevy_app::{App, Plugin}; 11 11 use bevy_ecs::prelude::*; ··· 13 13 use bevy_reflect::prelude::ReflectDefault; 14 14 15 15 use crate::bundle_inspector::BundleInspector; 16 - pub use bundle::*; 17 16 pub use command::*; 18 17 pub use component::*; 19 18 pub use registry::*; 20 19 pub use relation::*; 20 + pub use spawnable_list::*; 21 21 22 22 /// Setup required types and systems for `bevy_alchemy`. 23 23 pub struct AlchemyPlugin;
+34
src/spawnable_list.rs
··· 1 + use crate::{AddEffectCommand, Effecting}; 2 + use bevy_ecs::prelude::*; 3 + use bevy_ecs::ptr::MovingPtr; 4 + use bevy_ecs::spawn::SpawnableList; 5 + 6 + /// A "bundle" of components/settings used when applying an effect. 7 + /// Due to technical limitations, this doesn't actually implement [`Bundle`]. 8 + /// Instead, purpose build commands ([`with_effect`](crate::command::EffectCommandsExt::with_effect)) 9 + /// or related spawners ([`EffectedBy::spawn`](SpawnRelated::spawn)) should be used. 10 + /// 11 + /// # Examples 12 + /// ### [`with_effect`](crate::command::EffectCommandsExt::with_effect) 13 + #[doc = include_str!("../docs/with_effect_example.md")] 14 + /// ### [`with_effects`](crate::command::EffectCommandsExt::with_effects) + [`EffectSpawner`](crate::command::EffectSpawner) 15 + #[doc = include_str!("../docs/with_effects_example.md")] 16 + /// ### [`EffectedBy::spawn`](SpawnRelated::spawn) 17 + #[doc = include_str!("../docs/effected_by_spawn_example.md")] 18 + #[derive(Default)] 19 + pub struct Effect<B: Bundle>(pub B); 20 + 21 + // Todo This is probably bad practice/has larger performance cost. 22 + impl<B: Bundle + Clone> SpawnableList<Effecting> for Effect<B> { 23 + fn spawn(this: MovingPtr<'_, Self>, world: &mut World, target: Entity) { 24 + let bundle = this.read(); 25 + world.commands().queue(AddEffectCommand { 26 + target, 27 + bundle: bundle.0, 28 + }); 29 + } 30 + 31 + fn size_hint(&self) -> usize { 32 + 0 33 + } 34 + }
+7 -7
tests/spawn_syntax.rs
··· 12 12 13 13 world.spawn(( 14 14 Name::new("Target"), 15 - EffectedBy::spawn((EffectBundle(MyEffect(0)), EffectBundle(MyEffect(1)))), 15 + EffectedBy::spawn((Effect(MyEffect(0)), Effect(MyEffect(1)))), 16 16 )); 17 17 18 18 world.flush(); ··· 34 34 world.spawn(( 35 35 Name::new("Target"), 36 36 EffectedBy::spawn(( 37 - EffectBundle((EffectMode::Insert, MyEffect(0))), 38 - EffectBundle((EffectMode::Insert, MyEffect(1))), 37 + Effect((EffectMode::Insert, MyEffect(0))), 38 + Effect((EffectMode::Insert, MyEffect(1))), 39 39 )), 40 40 )); 41 41 ··· 58 58 world.spawn(( 59 59 Name::new("Target"), 60 60 EffectedBy::spawn(( 61 - EffectBundle(MyEffect(0)), 62 - EffectBundle(MyEffect(1)), 63 - EffectBundle((EffectMode::Insert, MyEffect(2))), 64 - EffectBundle((EffectMode::Insert, MyEffect(3))), 61 + Effect(MyEffect(0)), 62 + Effect(MyEffect(1)), 63 + Effect((EffectMode::Insert, MyEffect(2))), 64 + Effect((EffectMode::Insert, MyEffect(3))), 65 65 )), 66 66 )); 67 67