#How do i read an event reader and for each event, call a fn using &mut world ?

19 messages · Page 1 of 1 (latest)

soft vault
#

is this valid

#[derive(Resource)]
pub struct ApplyInstantEffectsEventReaderState {
event_state: SystemState<EventReader<'static, 'static, ApplyInstantEffectEvent>>,

}

fn init_apply_instant_effects_reader_state(
world: &mut World,

){

// Create and store a system state once
let mut world = World::new();
world.init_resource::<Events<ApplyInstantEffectEvent>>();
let initial_state: SystemState<EventReader<ApplyInstantEffectEvent>> = SystemState::new(&mut world);

// The system state is cached in a resource
world.insert_resource(ApplyInstantEffectsEventReaderState {
    event_state: initial_state,
});

}

fn apply_instant_effects(
world: &mut World,
mut apply_instant_effects_reader_state: ResMut<ApplyInstantEffectsEventReaderState>

) {



   // Step 1: Collect all events first
    let mut effects_to_apply = Vec::new();
    {
        // Create a scope to limit the mutable borrow of `world`
        let mut event_reader = apply_instant_effects_reader_state.event_state.get_mut(world);
        for event in event_reader.read() {
            effects_to_apply.push(event.clone());
        }
    } // `event_reader` goes out of scope here, releasing the mutable borrow on `world`


     for evt in effects_to_apply {

        let effect_application = evt.effect_application.clone();
        let source = evt.source_entity;
        let target = evt.target_entity;
        let contact_position = evt.contact_position; 

        effect_application.apply_to_world(source, target, contact_position, &mut world);
    }

}

#

its giving me tons of illegal borrow errors 😦

#

OK i think i got it !! my event just didnt impl clone

#

i think im good

tardy swan
#

why are you wrapping the EventReader?

#
fn apply_instant_effect(world: &mut World, mut apply_instant_effects_reader_state: EventReader<AplyInstantEffectsEvent> {
    todo!();
}
#

code blocks start with 3 back ticks and ends with 3 back ticks

\`\`\`rust
let my_value = 32;
\`\`\`
thorn plover
#

EventReader isn't ExclusiveSystemParam, so it must be wrapped in a SystemState to be used in an exclusive system

tardy swan
#

hmm

thorn plover
#

Instead of cloning events, another approach you can do is take Events<T> instead of EventReader<T>

#

You can resource_scope it directly

#

Or drain the events to get them as owned (this will prevent future readers from seeing them) without cloning

tardy swan
#

are you using the whole of bevy, or just bevy_ecs?

#
fn init_apply_instant_effects_reader_state(
      world: &mut World,
 ){
    // Create and store a system state once
    let mut world = World::new();
    world.init_resource::<Events<ApplyInstantEffectEvent>>();
    let initial_state: SystemState<EventReader<ApplyInstantEffectEvent>> = SystemState::new(&mut world);

    // The system state is cached in a resource
    world.insert_resource(ApplyInstantEffectsEventReaderState {
        event_state: initial_state,
    });
}

seeing this makes me thing that you are using bevy, so i ask if you are registering the event with app.add_event::<ApplyInstantEffectEvent>(), and why you are creating a new world when you already have the app world as a param for the system

#
// Step 1: Collect all events first
let mut effects_to_apply = {
    // Create a scope to limit the mutable borrow of world
    let mut event_reader = apply_instant_effects_reader_state.event_state.get_mut(world);
    event_reader.read().collect::<Vec<_>>()
};

this one is just a me thing

soft vault
#

Oh yeah im not creating a new world anymore i fixed that

#

Also not initting the event anymore. Those were cruft i copied from the example

#

Anyways i got it to work i figured it out

#

Now i can read events and pass mut World to something for each one !!