Skip to content

Commit

Permalink
delete scenarios
Browse files Browse the repository at this point in the history
Signed-off-by: Reuben Thomas <reubenthomas123@gmail.com>
  • Loading branch information
reuben-thomas committed Aug 1, 2024
1 parent 94ccc5c commit 4b413a2
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 18 deletions.
1 change: 1 addition & 0 deletions rmf_site_editor/src/site/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ fn generate_site_entities(
.insert(Dependents(dependents));
}

// let mut model_description_dependents = HashMap::<Entity, HashSet<Entity>>::new();
for (scenario_id, scenario_bundle) in &site_data.scenarios {
let parent = match scenario_bundle.scenario.parent_scenario.0 {
Some(parent_id) => *id_to_entity.get(&parent_id).unwrap_or(&site_id),
Expand Down
6 changes: 4 additions & 2 deletions rmf_site_editor/src/site/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ impl Plugin for SitePlugin {
.add_event::<ImportNavGraphs>()
.add_event::<ChangeCurrentSite>()
.add_event::<ChangeCurrentScenario>()
.add_event::<RemoveScenario>()
.add_event::<RemoveInstance>()
.add_event::<SaveSite>()
.add_event::<SaveNavGraphs>()
Expand Down Expand Up @@ -372,9 +373,10 @@ impl Plugin for SitePlugin {
add_location_visuals,
add_fiducial_visuals,
update_level_visibility,
update_current_scenario.before(update_scenario_properties),
update_scenario_properties,
remove_instances,
handle_remove_scenarios.before(update_current_scenario),
update_current_scenario.before(update_scenario_properties),
handle_remove_instances,
update_changed_lane,
update_lane_for_moved_anchor,
)
Expand Down
82 changes: 78 additions & 4 deletions rmf_site_editor/src/site/scenario.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@

use crate::{
interaction::Selection,
site::{CurrentScenario, Delete, InstanceMarker, Pending, Pose, Scenario, SiteParent},
site::{
CurrentScenario, Delete, Dependents, InstanceMarker, Pending, Pose, Scenario,
ScenarioBundle, ScenarioMarker, SiteParent,
},
CurrentWorkspace,
};
use bevy::prelude::*;
Expand All @@ -26,6 +29,7 @@ use std::collections::HashMap;
#[derive(Clone, Copy, Debug, Event)]
pub struct ChangeCurrentScenario(pub Entity);

/// Handles changes to the current scenario
pub fn update_current_scenario(
mut commands: Commands,
mut selection: ResMut<Selection>,
Expand Down Expand Up @@ -169,21 +173,91 @@ pub fn update_scenario_properties(
}
}

#[derive(Debug, Clone, Copy, Event)]
pub struct RemoveScenario(pub Entity);

/// When a scenario is removed, all child scenarios are removed as well
pub fn handle_remove_scenarios(
mut commands: Commands,
mut remove_scenario_requests: EventReader<RemoveScenario>,
mut change_current_scenario: EventWriter<ChangeCurrentScenario>,
mut delete: EventWriter<Delete>,
mut current_scenario: ResMut<CurrentScenario>,
current_workspace: Res<CurrentWorkspace>,
mut scenarios: Query<
(Entity, &Scenario<Entity>, Option<&mut Dependents>),
With<ScenarioMarker>,
>,
children: Query<&Children>,
) {
for request in remove_scenario_requests.read() {
// Any child scenarios or instances added within the subtree are considered dependents
// to be deleted
let mut subtree_dependents = std::collections::HashSet::<Entity>::new();
let mut queue = vec![request.0];
while let Some(scenario_entity) = queue.pop() {
if let Ok((_, scenario, _)) = scenarios.get(scenario_entity) {
scenario.added_instances.iter().for_each(|(e, _)| {
subtree_dependents.insert(*e);
});
}
if let Ok(children) = children.get(scenario_entity) {
children.iter().for_each(|e| {
subtree_dependents.insert(*e);
queue.push(*e);
});
}
}

// Change to parent scenario, else root, else create an empty scenario and switch to it
if let Some(parent_scenario_entity) = scenarios
.get(request.0)
.map(|(_, s, _)| s.parent_scenario.0)
.ok()
.flatten()
{
change_current_scenario.send(ChangeCurrentScenario(parent_scenario_entity));
} else if let Some((root_scenario_entity, _, _)) = scenarios
.iter()
.filter(|(e, s, _)| request.0 != *e && s.parent_scenario.0.is_none())
.next()
{
change_current_scenario.send(ChangeCurrentScenario(root_scenario_entity));
} else {
let new_scenario_entity = commands
.spawn(ScenarioBundle::<Entity>::default())
.set_parent(current_workspace.root.expect("No current site"))
.id();
*current_scenario = CurrentScenario(Some(new_scenario_entity));
}

// Delete with dependents
if let Ok((_, _, Some(mut depenedents))) = scenarios.get_mut(request.0) {
depenedents.extend(subtree_dependents.iter());
} else {
commands
.entity(request.0)
.insert(Dependents(subtree_dependents));
}
delete.send(Delete::new(request.0).and_dependents());
}
}

#[derive(Debug, Clone, Copy, Event)]
pub struct RemoveInstance(pub Entity);

/// Handle requests to remove model instances. If an instance was added in this scenario, or if
/// the scenario is root, the InstanceMarker is removed, allowing it to be permanently deleted.
/// Otherwise, it is only temporarily removed.
pub fn remove_instances(
pub fn handle_remove_instances(
mut commands: Commands,
mut scenarios: Query<&mut Scenario<Entity>>,
current_scenario: ResMut<CurrentScenario>,
mut change_current_scenario: EventWriter<ChangeCurrentScenario>,
mut removals: EventReader<RemoveInstance>,
mut remove_requests: EventReader<RemoveInstance>,
mut delete: EventWriter<Delete>,
) {
for removal in removals.read() {
for removal in remove_requests.read() {
let Some(current_scenario_entity) = current_scenario.0 else {
delete.send(Delete::new(removal.0));
return;
Expand Down
46 changes: 36 additions & 10 deletions rmf_site_editor/src/widgets/creation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{
widgets::{prelude::*, AssetGalleryStatus},
AppState, CurrentWorkspace,
};
use bevy::{ecs::system::SystemParam, prelude::*};
use bevy::{audio::Source, ecs::system::SystemParam, prelude::*};
use bevy_egui::egui::{CollapsingHeader, ComboBox, Grid, Ui};

use rmf_site_format::{
Expand Down Expand Up @@ -236,7 +236,6 @@ impl<'w, 's> Creation<'w, 's> {
_ => return,
};

ui.label("Properties");
ui.horizontal(|ui| {
ui.label("Description Name");
let mut new_name = pending_model.name.clone();
Expand Down Expand Up @@ -266,7 +265,7 @@ impl<'w, 's> Creation<'w, 's> {
pending_model.scale = new_scale;
}

ui.add_space(5.0);
ui.separator();
if let Some(asset_gallery) = &mut self.asset_gallery {
match self.app_state.get() {
AppState::MainMenu
Expand Down Expand Up @@ -346,15 +345,20 @@ impl<'w, 's> Creation<'w, 's> {
ui.text_edit_singleline(&mut pending_model.instance_name);
}
});

ui.add_space(3.0);
if ui.button("Browse fuel").clicked() {
asset_gallery.show = true;
if ui
.selectable_label(asset_gallery.show, "Browse Fuel")
.clicked()
{
asset_gallery.show = !asset_gallery.show;
}
}
AppState::WorkcellEditor => {
if ui.button("Browse fuel").clicked() {
asset_gallery.show = true;
if ui
.selectable_label(asset_gallery.show, "Browse Fuel")
.clicked()
{
asset_gallery.show = !asset_gallery.show;
}
if ui.button("Spawn visual").clicked() {
let workcell_model = WorkcellModel {
Expand Down Expand Up @@ -507,13 +511,22 @@ struct PendingDrawing {
pub recall_source: RecallAssetSource,
}

#[derive(Clone, Default)]
#[derive(Clone)]
struct PendingModelInstance {
pub description_entity: Option<Entity>,
pub instance_name: String,
}

#[derive(Clone, Default)]
impl Default for PendingModelInstance {
fn default() -> Self {
Self {
description_entity: None,
instance_name: "<Unnamed Instance>".to_string(),
}
}
}

#[derive(Clone)]
struct PendingModelDescription {
pub name: String,
pub source: AssetSource,
Expand All @@ -522,3 +535,16 @@ struct PendingModelDescription {
pub spawn_instance: bool,
pub instance_name: String,
}

impl Default for PendingModelDescription {
fn default() -> Self {
Self {
name: "<Unnamed Description>".to_string(),
source: AssetSource::default(),
recall_source: RecallAssetSource::default(),
scale: Scale::default(),
spawn_instance: true,
instance_name: " <Unnamed Instance>".to_string(),
}
}
}
13 changes: 11 additions & 2 deletions rmf_site_editor/src/widgets/view_scenarios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
use crate::{
interaction::{Select, Selection},
site::{
Category, Change, ChangeCurrentScenario, CurrentScenario, Delete, NameInSite, Scenario,
ScenarioMarker,
Category, Change, ChangeCurrentScenario, CurrentScenario, Delete, NameInSite,
RemoveScenario, Scenario, ScenarioMarker,
},
widgets::prelude::*,
Icons,
Expand Down Expand Up @@ -53,6 +53,7 @@ pub struct ViewScenarios<'w, 's> {
>,
change_name: EventWriter<'w, Change<NameInSite>>,
change_current_scenario: EventWriter<'w, ChangeCurrentScenario>,
remove_scenario: EventWriter<'w, RemoveScenario>,
display_scenarios: ResMut<'w, ScenarioDisplay>,
current_scenario: ResMut<'w, CurrentScenario>,
instances: Query<
Expand Down Expand Up @@ -95,6 +96,14 @@ impl<'w, 's> ViewScenarios<'w, 's> {
self.change_name
.send(Change::new(NameInSite(new_name), current_scenario_entity));
}
if ui
.button("❌")
.on_hover_text("Delete this scenario and all its child scenarios")
.clicked()
{
self.remove_scenario
.send(RemoveScenario(current_scenario_entity));
}
});
ui.label("From Previous:");
// Added
Expand Down

0 comments on commit 4b413a2

Please sign in to comment.