Skip to content

Instantly share code, notes, and snippets.

@sum-catnip
Created May 2, 2025 13:25
Show Gist options
  • Save sum-catnip/dcaf3f1fd09015336d95b2c040fa1f39 to your computer and use it in GitHub Desktop.
Save sum-catnip/dcaf3f1fd09015336d95b2c040fa1f39 to your computer and use it in GitHub Desktop.
bevy "effectbundle"
use bevy::{
ecs::{
bundle::{BundleEffect, DynamicBundle},
component::{
ComponentId, Components, ComponentsRegistrator, RequiredComponents, StorageType,
},
},
prelude::*,
ptr::OwningPtr,
};
pub struct EffectBundleFn(Box<dyn FnOnce(&mut EntityWorldMut) + Sync + Send + 'static>);
impl EffectBundleFn {
pub fn new<F: FnOnce(&mut EntityWorldMut) + Sync + Send + 'static>(f: F) -> Self {
Self(Box::new(f))
}
}
unsafe impl Bundle for EffectBundleFn {
fn get_component_ids(components: &Components, ids: &mut impl FnMut(Option<ComponentId>)) {
<() as Bundle>::get_component_ids(components, ids);
}
fn register_required_components(
components: &mut ComponentsRegistrator,
required_components: &mut RequiredComponents,
) {
<() as Bundle>::register_required_components(components, required_components);
}
fn component_ids(components: &mut ComponentsRegistrator, ids: &mut impl FnMut(ComponentId)) {
<() as Bundle>::component_ids(components, ids);
}
}
impl DynamicBundle for EffectBundleFn {
type Effect = Self;
fn get_components(self, func: &mut impl FnMut(StorageType, OwningPtr<'_>)) -> Self::Effect {
<() as DynamicBundle>::get_components((), func);
self
}
}
impl BundleEffect for EffectBundleFn {
fn apply(self, entity: &mut EntityWorldMut) {
(self.0)(entity)
}
}
@sum-catnip
Copy link
Author

For the second question i have no idea but there is an open github discussion about bsn so maybe ask there or in the ui channel on discord

@DylanRJohnston
Copy link

@sum-catnip I think you need to be careful with this because you report to the ECS system that the bundle contains no components

fn get_component_ids(components: &Components, ids: &mut impl FnMut(Option<ComponentId>)) {
    <() as Bundle>::get_component_ids(components, ids);
}

but then in your type erased example demonstrate how EffectBundleFn can be used to insert components, does this lead to undefined behavior? Or is the insertion of components in the BundleEffect completely separate from the logic of Bundle?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment