idanarye / bevy-yoleck

Your Own Level Editor Creation Kit
Other
172 stars 11 forks source link

Exclusive input mode for edit systems #22

Open idanarye opened 1 year ago

idanarye commented 1 year ago

Example usecase - #21. When an entity refers to another entity, we want the first entity to click the second entity, we want to be able to do this by editing the target entity, doing something to indicate that we want to pick an entity to refer to, and then click on the other entity.

For this, we need to be able to send an edit system to an "exclusive input mode". In that mode:

idanarye commented 1 year ago

I imagine the syntax as something like this:

fn edit_system_with_exclusive_mode(
    mut ui: ResMut<YoleckUi>,
    mut edit: YoleckEdit<&mut OtherEntityUuid>,
    mut exclusive: YoleckExclusive, // this captures the system (like `YoleckMarking` does)
    uuid_query: Query<&VpeolUuid>,
) {
    let Ok(mut other_entity_uuid) = edit.get_single_mut() else { return };

    if let Some(exclusive) = exclusive.exclusive() {
        // Or maybe this should use passed-data?
        if let Some(clicked_entity) = exclusive.get_clicked() {
            if let Ok(uuid) = uuid_query.get(clicked_entity) {
                other_entity_uuid.0 = uuid.0;
                exclusive.finish();
            }
        }
    } else {
        if ui.button("Pick Other Entity").clicked() {
            exclusive.start();
        }
    }
}
idanarye commented 1 year ago

Alternatively, maybe this can be combined with #20's mechanism?

fn edit_system_that_initiates_the_exclusive_mode(
    mut ui: ResMut<YoleckUi>,
    mut edit: YoleckEdit<With<&OtherEntityUuid>>,
    mut exclusive: YoleckExclusive,
    uuid_query: Query<&VpeolUuid>,
) {
    let Ok(_) = edit.get_single_mut() else { return };

    if ui.button("Pick Other Entity").clicked() {
        exclusive.enqueue(edit_system_for_the_exclusive_mode);
    }
}

fn edit_system_for_the_exclusive_mode(
    mut exclusive_input: Res<YoleckExclusiveInput>,
    mut edit: YoleckEdit<&mut OtherEntityUuid>,
) -> Option<YoleckExclusiveVeredict> {
    let mut other_entity_uuid = edit.get_single_mut()?;
    if let Some(clicked_entity) = exclusive_input.get_clicked() {
        if let Ok(uuid) = uuid_query.get(clicked_entity) {
            other_entity_uuid.0 = uuid.0;
            return Some(YoleckExclusiveVeredict::Done);
        }
    }
    None
}