Skip to content

Commit

Permalink
Fix modules remaining in world if cycling through modules too fast
Browse files Browse the repository at this point in the history
  • Loading branch information
hukasu committed May 17, 2024
1 parent 476f05b commit 6006e8d
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 38 deletions.
11 changes: 5 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ fn spawn_text(mut commands: Commands, asset_server: Res<AssetServer>) {
"Cycle through heads with Q and W\n\
Cycle through bodies with E and R\n\
Cycle through heads with T and Y\n\
Cycle through heads with U and I\n\
Do not press the buttons too fast",
Cycle through heads with U and I",
TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 24.,
Expand All @@ -85,22 +84,22 @@ fn spawn_modular(
Name::new("Modular"),
ModularCharacterHead {
id: 0,
instance_id: scene_spawner.spawn(asset_server.load(modular::HEADS[0])),
instance_id: Some(scene_spawner.spawn(asset_server.load(modular::HEADS[0]))),
entities: vec![],
},
ModularCharacterBody {
id: 0,
instance_id: scene_spawner.spawn(asset_server.load(modular::BODIES[0])),
instance_id: Some(scene_spawner.spawn(asset_server.load(modular::BODIES[0]))),
entities: vec![],
},
ModularCharacterLegs {
id: 0,
instance_id: scene_spawner.spawn(asset_server.load(modular::LEGS[0])),
instance_id: Some(scene_spawner.spawn(asset_server.load(modular::LEGS[0]))),
entities: vec![],
},
ModularCharacterFeet {
id: 0,
instance_id: scene_spawner.spawn(asset_server.load(modular::FEET[0])),
instance_id: Some(scene_spawner.spawn(asset_server.load(modular::FEET[0]))),
entities: vec![],
},
))
Expand Down
12 changes: 6 additions & 6 deletions src/modular/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use bevy::{

pub trait ModularCharacter: Component {
fn id_mut(&mut self) -> &mut usize;
fn instance_id_mut(&mut self) -> &mut InstanceId;
fn instance_id_mut(&mut self) -> &mut Option<InstanceId>;
fn entities_mut(&mut self) -> &mut Vec<Entity>;
fn id(&self) -> &usize;
fn instance_id(&self) -> &InstanceId;
fn instance_id(&self) -> Option<&InstanceId>;
fn entities(&self) -> &Vec<Entity>;
}

Expand All @@ -18,15 +18,15 @@ macro_rules! create_modular_segment {
#[derive(Debug, Component)]
pub struct [<ModularCharacter $name>] {
pub id: usize,
pub instance_id: InstanceId,
pub instance_id: Option<InstanceId>,
pub entities: Vec<Entity>,
}
impl ModularCharacter for [<ModularCharacter $name>] {
fn id_mut(&mut self) -> &mut usize {
&mut self.id
}

fn instance_id_mut(&mut self) -> &mut InstanceId {
fn instance_id_mut(&mut self) -> &mut Option<InstanceId> {
&mut self.instance_id
}

Expand All @@ -38,8 +38,8 @@ macro_rules! create_modular_segment {
&self.id
}

fn instance_id(&self) -> &InstanceId {
&self.instance_id
fn instance_id(&self) -> Option<&InstanceId> {
self.instance_id.as_ref()
}

fn entities(&self) -> &Vec<Entity> {
Expand Down
89 changes: 63 additions & 26 deletions src/modular/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use bevy::{
entity::Entity,
event::{EventReader, EventWriter},
query::Changed,
schedule::IntoSystemConfigs,
system::{Commands, Query, Res, ResMut},
},
hierarchy::{BuildChildren, Children, DespawnRecursiveExt, HierarchyQueryExt, Parent},
Expand Down Expand Up @@ -70,14 +71,46 @@ impl Plugin for ModularPlugin {
.add_systems(Update, update_modular::<ModularCharacterBody>)
.add_systems(Update, update_modular::<ModularCharacterLegs>)
.add_systems(Update, update_modular::<ModularCharacterFeet>)
.add_systems(Update, cycle_modular_segment::<ModularCharacterHead, 0>)
.add_systems(Update, cycle_modular_segment::<ModularCharacterBody, 1>)
.add_systems(Update, cycle_modular_segment::<ModularCharacterLegs, 2>)
.add_systems(Update, cycle_modular_segment::<ModularCharacterFeet, 3>)
.add_systems(Update, reset_changed::<ModularCharacterHead>)
.add_systems(Update, reset_changed::<ModularCharacterBody>)
.add_systems(Update, reset_changed::<ModularCharacterLegs>)
.add_systems(Update, reset_changed::<ModularCharacterFeet>);
.add_systems(
Update,
cycle_modular_segment::<ModularCharacterHead, 0>
.after(update_modular::<ModularCharacterHead>),
)
.add_systems(
Update,
cycle_modular_segment::<ModularCharacterBody, 1>
.after(update_modular::<ModularCharacterBody>),
)
.add_systems(
Update,
cycle_modular_segment::<ModularCharacterLegs, 2>
.after(update_modular::<ModularCharacterLegs>),
)
.add_systems(
Update,
cycle_modular_segment::<ModularCharacterFeet, 3>
.after(update_modular::<ModularCharacterFeet>),
)
.add_systems(
Update,
reset_changed::<ModularCharacterHead>
.after(cycle_modular_segment::<ModularCharacterHead, 0>),
)
.add_systems(
Update,
reset_changed::<ModularCharacterBody>
.after(cycle_modular_segment::<ModularCharacterBody, 1>),
)
.add_systems(
Update,
reset_changed::<ModularCharacterLegs>
.after(cycle_modular_segment::<ModularCharacterLegs, 2>),
)
.add_systems(
Update,
reset_changed::<ModularCharacterFeet>
.after(cycle_modular_segment::<ModularCharacterFeet, 3>),
);
}
}

Expand All @@ -100,7 +133,10 @@ fn update_modular<T: components::ModularCharacter>(
mut writer: EventWriter<ResetChanged>,
) {
for (entity, mut modular) in &mut changed_modular {
if scene_spawner.instance_is_ready(*modular.instance_id()) {
let Some(scene_instance) = modular.instance_id().copied() else {
continue;
};
if scene_spawner.instance_is_ready(scene_instance) {
// Delete old
bevy::log::trace!("Deleting old modular segment.");
if !modular.entities().is_empty() {
Expand All @@ -112,7 +148,7 @@ fn update_modular<T: components::ModularCharacter>(

// Get MeshPrimitives
let mesh_primitives = scene_spawner
.iter_instance_entities(*modular.instance_id())
.iter_instance_entities(scene_instance)
.filter(|node| mesh_primitives_query.contains(*node))
.collect::<Vec<_>>();

Expand Down Expand Up @@ -198,8 +234,9 @@ fn update_modular<T: components::ModularCharacter>(
modular.entities_mut().push(mesh_entity);
commands.entity(entity).add_child(mesh_entity);
}

scene_spawner.despawn_instance(*modular.instance_id());
if let Some(instance) = modular.instance_id_mut().take() {
scene_spawner.despawn_instance(instance);
}
} else {
writer.send(ResetChanged(entity));
}
Expand All @@ -219,22 +256,22 @@ fn cycle_modular_segment<T: ModularCharacter, const ID: usize>(
(KeyCode::KeyU, KeyCode::KeyI),
];
const MODULES: [&[&str]; 4] = [&HEADS, &BODIES, &LEGS, &FEET];
if key_input.just_pressed(KEYS[ID].0) {
let Ok(mut module) = modular.get_single_mut() else {
bevy::log::error!("Couldn't get single Head.");
return;
};
*module.id_mut() = module.id().wrapping_sub(1).min(MODULES[ID].len() - 1);
*module.instance_id_mut() =
scene_spawner.spawn(asset_server.load(MODULES[ID][*module.id()]));
let Ok(mut module) = modular.get_single_mut() else {
bevy::log::error!("Couldn't get single module.");
return;
};
*module.id_mut() = if key_input.just_pressed(KEYS[ID].0) {
module.id().wrapping_sub(1).min(MODULES[ID].len() - 1)
} else if key_input.just_pressed(KEYS[ID].1) {
let Ok(mut head) = modular.get_single_mut() else {
bevy::log::error!("Couldn't get single Head.");
return;
};
*head.id_mut() = (head.id() + 1) % MODULES[ID].len();
*head.instance_id_mut() = scene_spawner.spawn(asset_server.load(MODULES[ID][*head.id()]));
(module.id() + 1) % MODULES[ID].len()
} else {
return;
};
if let Some(instance) = module.instance_id() {
scene_spawner.despawn_instance(*instance);
}
*module.instance_id_mut() =
Some(scene_spawner.spawn(asset_server.load(MODULES[ID][*module.id()])));
}

fn reset_changed<T: ModularCharacter>(
Expand Down

0 comments on commit 6006e8d

Please sign in to comment.