-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Description
What problem does this solve or what need does it fill?
Problem is when the required component should be initialized using the data from the World.
What alternative(s) have you considered?
You can have the required component first be created with a placeholder value and then use a system or on_add component hook to initialize it correctly.
Additional context
Currently I am writing a rollback plugin, I want to use the disabling components to "virtualy" despawn an entity so that it can be put back when time is rolled back to a point when the entity was supposed to still exist. Currently I have this:
/// put this marker disabling component on a rollback entity to virtualy despawn it
#[derive(Component)]
#[require(DespawnedSince(Frame(u64::MAX)))] //the u64::MAX is placeholder value until the correct value is loaded from World
pub struct Despawn;
/// when the entity is virtualy despawed for too long (until snapshot storage length)
/// it will despawn properly as the other data needed to restore it is not stored anymore
/// and its assumed that rolling back too far will not happen/will not be needed
#[derive(Component)]
pub struct DespawnedSince(pub Frame);
pub struct RollbackDespawnPlugin;
impl Plugin for RollbackDespawnPlugin {
fn build(&self, app: &mut App) {
// currently I have to modify the component after its created by required component
app.world_mut().register_component_hooks::<DespawnedSince>()
.on_add(|mut world, context| {
let Some(&frame) = world.get_resource::<Frame>() else{
warn!("can not initialize DespawnedSince component, the Frame resource does not exist");
return
};
world.entity_mut(context.entity).get_mut::<DespawnedSince>().unwrap().0 = frame;
});
....
}
What solution would you like?
the world.register_required_components_with(constructor_function) should take a function that takes &World (or maybe DeferredWorld) so that the constructor can initialize the component using world data.
world.register_required_components could instead of taking a component that implements Default, take component that implements FromWorld, as FromWorld is automatically implemented for any type implementing Default, it should work nice. And then it would internally call the world.register_required_components_with using that FromWorld::from_world() implementation instead of Default::default().
The try_ versions should be also changed the same way.
Then I could specify that the DespawnedSince required component is initialized correctly from the begining and I would not need to first have it be made with a placeholder and then overwritten, it seems logical to me that it should be possible when a costructor function is passed in already, it should allow taking arguments for initialization.