moving code around

Next I might make each part of the editor a plugin

I know code moving is toil, but I'm kinda braindead and this is on my
todo list...
main
Elijah Voigt 2 years ago
parent 0a56361168
commit 3b75fed684

File diff suppressed because it is too large Load Diff

@ -0,0 +1,155 @@
use crate::editor::prelude::*;
#[derive(Debug, Component, Default)]
pub struct AnimationWidget;
#[derive(Debug, Component)]
pub struct AnimationPlayAll;
pub fn init_animations_ui(events: Query<Entity, Added<AnimationWidget>>, mut commands: Commands) {
events.iter().for_each(|entity| {
commands.entity(entity).with_children(|parent| {
parent.spawn((
AnimationPlayAll,
ButtonBundle {
style: Style {
border: UiRect::all(Val::Px(1.0)),
margin: UiRect::all(Val::Px(1.0)),
padding: UiRect::all(Val::Px(1.0)),
..default()
},
border_color: Color::BLACK.into(),
..default()
},
ui::Title {
text: "Play All".into(),
..default()
},
));
});
})
}
/// When a new scene is loaded, add any newly compatible animations
/// TODO: Add target entity(s) too
pub fn add_animations_ui(
player_spawned: Query<&Name, Added<AnimationPlayer>>,
widget: Query<Entity, With<AnimationWidget>>,
mut commands: Commands,
gltfs: Res<Assets<Gltf>>,
clips: Res<Assets<AnimationClip>>,
) {
player_spawned.iter().for_each(|player_name| {
gltfs
.iter()
.flat_map(|(_, gltf)| gltf.named_animations.iter())
.filter_map(|(clip_name, handle)| {
clips.get(&handle).map(|clip| (clip_name, handle, clip))
})
.filter(|(_, _, clip)| clip.compatible_with(player_name))
.for_each(|(clip_name, handle, _)| {
create_asset_button(
&widget,
&mut commands,
ui::TargetAsset {
handle: handle.clone(),
},
clip_name.clone(),
None,
);
});
});
}
// When a scene is de-selected, remove any outdated animation options
pub fn remove_animations_ui(
mut removed_players: RemovedComponents<Handle<Scene>>,
current: Query<(Entity, &ui::TargetAsset<AnimationClip>)>,
clips: Res<Assets<AnimationClip>>,
targets: Query<(&AnimationPlayer, &Name)>,
mut commands: Commands,
) {
// For each removed scene
removed_players.iter().for_each(|_| {
// Iterate over the current animation buttons
current
.iter()
.filter(|(_, ui::TargetAsset { handle })| {
// Check if this clip is compatible with any remaining entities
// NOTE: We are checking this is *not* compatible with any entities
clips
.get(handle)
.map(|clip| !(targets.iter().any(|(_, name)| clip.compatible_with(name))))
.unwrap_or(true)
})
.for_each(|(_, ui::TargetAsset { handle })| {
// Destroy the buton if it is so
destroy_asset_button(
&current,
&mut commands,
&ui::TargetAsset {
handle: handle.clone(),
},
);
});
});
}
pub fn play_all_animations(
start: Query<Entity, (With<Button>, Added<ui::Active>)>,
mut stop: RemovedComponents<ui::Active>,
play_all_btn: Query<Entity, With<AnimationPlayAll>>,
clip_btns: Query<Entity, With<ui::TargetAsset<AnimationClip>>>,
mut commands: Commands,
) {
stop.iter()
.filter(|&entity| play_all_btn.contains(entity))
.for_each(|_| {
clip_btns.iter().for_each(|entity| {
commands.entity(entity).remove::<ui::Active>();
})
});
start
.iter()
.filter(|&entity| play_all_btn.contains(entity))
.for_each(|_| {
clip_btns.iter().for_each(|entity| {
commands.entity(entity).insert(ui::Active);
})
});
}
pub fn play_animation(
start: Query<Entity, (With<Button>, Added<ui::Active>)>,
mut stop: RemovedComponents<ui::Active>,
clip_refs: Query<&ui::TargetAsset<AnimationClip>>,
mut targets: Query<(&mut AnimationPlayer, &Name), With<Transform>>,
clips: Res<Assets<AnimationClip>>,
) {
stop.iter().for_each(|entity| {
if let Ok(ui::TargetAsset { handle }) = clip_refs.get(entity) {
let clip = clips.get(&handle).expect("Load animation clip");
targets
.iter_mut()
.filter(|(_, name)| clip.compatible_with(name))
.for_each(|(mut player, _)| {
player.pause();
})
}
});
start.iter().for_each(|entity| {
if let Ok(ui::TargetAsset { handle }) = clip_refs.get(entity) {
let clip = clips.get(&handle).expect("Load animation clip");
targets
.iter_mut()
.filter(|(_, name)| clip.compatible_with(name))
.for_each(|(mut player, _)| {
if player.is_paused() {
player.resume();
} else {
player.play(handle.clone()).repeat();
}
})
}
});
}

@ -0,0 +1,55 @@
use crate::editor::prelude::*;
// This sets buttons to active when their associated handle is spawned
pub fn sync_asset_buttons<T: Asset>(
events: Query<&Handle<T>, Added<Handle<T>>>,
buttons: Query<(Entity, &ui::TargetAsset<T>)>,
mut commands: Commands,
) {
events.iter().for_each(|this_handle| {
info!("Syncing {:?}", this_handle);
buttons
.iter()
.find_map(|(entity, ui::TargetAsset { handle })| {
if handle == this_handle {
Some(entity)
} else {
None
}
})
.iter()
.for_each(|&entity| {
commands.entity(entity).insert(ui::Active);
});
});
}
// Remove active when handle is despawned?
// ONLY IF there are no instances of that handle [!any(*)]
pub fn sync_remove_asset_buttons<T: Asset>(
mut events: RemovedComponents<Handle<T>>,
asset_entities: Query<&Handle<T>>,
buttons: Query<(Entity, &ui::TargetAsset<T>)>,
mut commands: Commands,
) {
events
.iter()
.find_map(|this_asset_entity| asset_entities.get(this_asset_entity).ok())
.iter()
.for_each(|this_handle| {
info!("Syncing removal of {:?}", this_handle);
buttons
.iter()
.find_map(|(entity, ui::TargetAsset { handle })| {
if handle == *this_handle {
Some(entity)
} else {
None
}
})
.iter()
.for_each(|&entity| {
commands.entity(entity).remove::<ui::Active>();
});
});
}

@ -1,5 +1,4 @@
use crate::ui;
use bevy::{asset::Asset, prelude::*};
use crate::editor::prelude::*;
#[derive(Resource, Default)]
pub struct AssetRegistry(pub Vec<HandleUntyped>);

@ -1,5 +1,5 @@
use crate::{editor::assets::*, ui};
use bevy::{audio::PlaybackMode, prelude::*};
use crate::editor::prelude::*;
use bevy::audio::PlaybackMode;
#[derive(Debug, Component, Reflect, Default)]
#[reflect(Component)]

@ -0,0 +1,66 @@
use crate::editor::prelude::*;
#[derive(Debug, Component)]
pub struct EditorCamera;
#[derive(Debug, Component, Default)]
pub struct CameraWidget;
pub fn cameras_ui(
mut added: Query<(Entity, &mut Camera, &Name), Added<Camera>>,
mut removed: RemovedComponents<Camera>,
editor_camera: Query<Entity, With<EditorCamera>>,
widget: Query<Entity, With<CameraWidget>>,
current: Query<(Entity, &ui::TargetEntity)>,
mut commands: Commands,
) {
removed.iter().for_each(|entity| {
info!("Destroy button for {:?}", entity);
destroy_entity_button(&current, &mut commands, &ui::TargetEntity { entity });
});
added.iter_mut().for_each(|(entity, mut camera, name)| {
info!("Camera added {:?} {:?}", entity, name);
create_entity_button(
&widget,
&mut commands,
ui::TargetEntity { entity },
name.as_str().into(),
);
camera.is_active = entity == editor_camera.single();
});
}
/// Set the camera active component based on button clicks
pub fn manage_active_camera(
events: Query<&ui::TargetEntity, Added<ui::Active>>,
mut cameras: Query<(Entity, &mut Camera)>,
) {
events.iter().for_each(|ui::TargetEntity { entity }| {
cameras.iter_mut().for_each(|(this_entity, mut camera)| {
if this_entity == *entity {
info!("Marking {:?} as active camera", entity);
camera.is_active = true;
} else {
info!("Marking {:?} as inactive camera", entity);
camera.is_active = false;
}
});
});
}
// In the event that an active camera is despawned, fall back to the editor camera
pub fn fallback_camera(
modified: Query<Entity, (Changed<Camera>, Without<EditorCamera>)>,
mut removed: RemovedComponents<Camera>,
other_cameras: Query<&Camera, Without<EditorCamera>>,
mut editor_camera: Query<&mut Camera, With<EditorCamera>>,
) {
// Any time a camera is modified
modified.iter().chain(removed.iter()).for_each(|_| {
// If no other cameras are active
if !other_cameras.iter().any(|camera| camera.is_active) {
// Make the editor camera active
editor_camera.single_mut().is_active = true;
}
})
}

@ -1,5 +1,4 @@
use crate::{editor::assets::*, ui};
use bevy::prelude::*;
use crate::editor::prelude::*;
#[derive(Debug, Component, Default)]
pub struct FontWidget;

@ -0,0 +1,68 @@
use crate::editor::prelude::*;
#[derive(Debug, Component, Default)]
pub struct GltfWidget;
pub fn gltf_ui(
mut events: EventReader<AssetEvent<Gltf>>,
mut commands: Commands,
widget: Query<Entity, With<GltfWidget>>,
current: Query<(Entity, &ui::TargetAsset<Gltf>)>,
server: Res<AssetServer>,
) {
events.iter().for_each(|event| match event {
AssetEvent::Created { handle } => {
info!("Asset created! {:?}", event);
create_asset_button(
&widget,
&mut commands,
ui::TargetAsset {
handle: handle.clone(),
},
get_asset_name(&server, handle.clone()),
None,
);
}
AssetEvent::Removed { handle } => {
info!("Asset removed! {:?}", event);
destroy_asset_button(
&current,
&mut commands,
&ui::TargetAsset {
handle: handle.clone(),
},
);
}
AssetEvent::Modified { handle } => {
info!("Asset modified! {:?}", event);
destroy_asset_button(
&current,
&mut commands,
&ui::TargetAsset {
handle: handle.clone(),
},
);
create_asset_button(
&widget,
&mut commands,
ui::TargetAsset {
handle: handle.clone(),
},
get_asset_name(&server, handle.clone()),
None,
);
}
});
}
pub fn control_active_gltf(
events: Query<Entity, (With<ui::TargetAsset<Gltf>>, Added<ui::Active>)>,
root: Query<Entity, With<LevelRoot>>,
mut commands: Commands,
) {
events.iter().for_each(|_| {
root.iter().for_each(|entity| {
commands.entity(entity).despawn_descendants();
});
});
}

@ -0,0 +1,167 @@
use crate::editor::prelude::*;
use bevy::tasks::IoTaskPool;
#[derive(Debug, Component, Reflect, Default)]
#[reflect(Component)]
pub struct LevelRoot;
pub type Level = DynamicScene;
#[derive(Debug, Component, Default)]
pub struct LevelWidget;
#[derive(Debug, Component)]
pub struct ExportLevel;
pub fn level_ui(
mut events: EventReader<AssetEvent<Level>>,
mut commands: Commands,
widget: Query<Entity, With<LevelWidget>>,
current: Query<(Entity, &ui::TargetAsset<Level>)>,
server: Res<AssetServer>,
) {
events.iter().for_each(|event| match event {
AssetEvent::Created { handle } => {
info!("Asset created! {:?}", event);
create_asset_button(
&widget,
&mut commands,
ui::TargetAsset {
handle: handle.clone(),
},
get_asset_name(&server, handle.clone()),
None,
);
}
AssetEvent::Removed { handle } => {
info!("Asset removed! {:?}", event);
destroy_asset_button(
&current,
&mut commands,
&ui::TargetAsset {
handle: handle.clone(),
},
);
}
AssetEvent::Modified { handle } => {
info!("Asset modified! {:?}", event);
destroy_asset_button(
&current,
&mut commands,
&ui::TargetAsset {
handle: handle.clone(),
},
);
create_asset_button(
&widget,
&mut commands,
ui::TargetAsset {
handle: handle.clone(),
},
get_asset_name(&server, handle.clone()),
None,
);
}
});
}
pub fn load_level(
events: Query<
&ui::TargetAsset<DynamicScene>,
(Added<ui::Active>, With<ui::TargetAsset<DynamicScene>>),
>,
root: Query<Entity, With<LevelRoot>>,
mut commands: Commands,
) {
events.iter().for_each(|ui::TargetAsset { handle }| {
root.iter().for_each(|entity| {
commands.entity(entity).despawn_recursive();
});
commands.spawn(DynamicSceneBundle {
scene: handle.clone(),
..default()
});
});
}
pub fn export_level(
level_root: Query<Entity, With<LevelRoot>>,
audio_root: Query<Entity, With<AudioRoot>>,
children: Query<&Children>,
world: &World,
) {
let app_type_registry = world.resource::<AppTypeRegistry>().clone();
let mut builder = DynamicSceneBuilder::from_world(world.clone());
builder.deny_all_resources();
// Exclude computed visibility
builder.deny_all();
// Level administrivia
builder.allow::<LevelRoot>();
builder.allow::<AudioRoot>();
// TODO: Serialize Timeline
// Scene components
builder.allow::<Handle<Scene>>();
// Spatial components
builder.allow::<Transform>();
builder.allow::<GlobalTransform>();
builder.allow::<Visibility>();
// Audio components
builder.allow::<Handle<AudioSource>>();
builder.allow::<PlaybackSettings>();
// Text components
builder.allow::<Handle<Font>>();
builder.allow::<Handle<Monologue>>();
level_root.iter().for_each(|level| {
// Extract the level root
builder.extract_entity(level);
if let Ok(kids) = children.get(level) {
builder.extract_entities(kids.into_iter().map(|&e| e));
} else {
warn!("Level is empty!");
}
});
audio_root.iter().for_each(|audio| {
// Extract the level root
builder.extract_entity(audio);
if let Ok(kids) = children.get(audio) {
builder.extract_entities(kids.into_iter().map(|&e| e));
} else {
warn!("Audio is empty!");
}
});
let scene = builder.build();
let serialized = scene
.serialize_ron(&app_type_registry)
.expect("Serialize scene");
IoTaskPool::get()
.spawn(async move {
// Write the scene RON data to file
std::fs::write(format!("assets/output.scn.ron"), serialized.as_bytes())
.expect("Error while writing scene to file");
})
.detach();
}
pub fn rehydrate_level<W: Component, WO: Component + Default>(
events: Query<Entity, (Added<W>, Without<WO>)>,
mut commands: Commands,
) {
events.iter().for_each(|entity| {
commands.entity(entity).insert(WO::default());
});
}

@ -0,0 +1,21 @@
use crate::editor::prelude::*;
pub fn spot_light_force_shadows(mut spot_lights: Query<&mut SpotLight, Added<SpotLight>>) {
spot_lights.iter_mut().for_each(|mut light| {
light.shadows_enabled = true;
})
}
pub fn directional_light_force_shadows(
mut directional_lights: Query<&mut DirectionalLight, Added<DirectionalLight>>,
) {
directional_lights.iter_mut().for_each(|mut light| {
light.shadows_enabled = true;
})
}
pub fn point_light_force_shadows(mut point_lights: Query<&mut PointLight, Added<PointLight>>) {
point_lights.iter_mut().for_each(|mut light| {
light.shadows_enabled = true;
})
}

@ -1,10 +1,18 @@
pub mod audio;
pub mod animation;
pub mod asset_sync;
pub mod assets;
pub mod monologue;
pub mod audio;
pub mod camera;
pub mod font;
pub mod gltf;
pub mod level;
pub mod lighting;
pub mod monologue;
mod prelude;
pub mod quit;
pub mod reset;
pub mod scene;
pub mod timeline;
use crate::ui;
use bevy::{asset::Asset, prelude::*};

@ -1,10 +1,6 @@
use crate::{
editor::{assets::*, font::*},
ui,
};
use crate::editor::prelude::*;
use bevy::{
asset::{AssetLoader, LoadContext, LoadedAsset},
prelude::*,
reflect::{TypePath, TypeUuid},
ui::FocusPolicy,
utils::BoxedFuture,

@ -0,0 +1,8 @@
pub use crate::{
editor::{
animation::*, asset_sync::*, assets::*, audio::*, camera::*, font::*, gltf::*, level::*,
lighting::*, monologue::*, quit::*, reset::*, scene::*, timeline::*, *,
},
ui,
};
pub use bevy::{gltf::Gltf, prelude::*};

@ -0,0 +1,10 @@
use crate::editor::prelude::*;
use bevy::app::AppExit;
#[derive(Debug, Component, Default)]
pub struct QuitAction;
pub fn quit(mut exit: EventWriter<AppExit>) {
exit.send(AppExit);
}

@ -0,0 +1,69 @@
use crate::editor::prelude::*;
#[derive(Debug, Component)]
pub struct ClearLevel;
pub fn clear_level(
events: Query<Entity, (With<ClearLevel>, Added<ui::Active>)>,
actives: Query<
Entity,
(
With<ui::Active>,
Or<(
With<ui::TargetEntity>,
With<ui::TargetAsset<Gltf>>,
With<ui::TargetAsset<Scene>>,
With<ui::TargetAsset<AnimationClip>>,
With<ui::TargetAsset<AudioSource>>,
With<ui::TargetAsset<Monologue>>,
With<ui::TargetAsset<Font>>,
)>,
),
>,
root: Query<Entity, With<LevelRoot>>,
mut commands: Commands,
) {
events.iter().for_each(|_| {
actives.iter().for_each(|entity| {
commands.entity(entity).remove::<ui::Active>();
});
root.iter().for_each(|entity| {
commands.entity(entity).despawn_descendants();
});
})
}
#[derive(Debug, Component)]
pub struct ClearAssets;
pub fn clear_assets(
asset_holders: Query<
Entity,
Or<(
With<ui::TargetAsset<Gltf>>,
With<Handle<Gltf>>,
With<ui::TargetAsset<Scene>>,
With<Handle<Scene>>,
With<ui::TargetAsset<AnimationClip>>,
With<Handle<AnimationClip>>,
With<ui::TargetAsset<AudioSource>>,
With<Handle<AudioSource>>,
With<ui::TargetAsset<Monologue>>,
With<Handle<Monologue>>,
With<ui::TargetAsset<Font>>,
With<Handle<Font>>,
)>,
>,
mut registry: ResMut<AssetRegistry>,
mut commands: Commands,
) {
info!("Clearing assets");
// Clear buttons holding asset references
asset_holders
.iter()
.for_each(|entity| commands.entity(entity).despawn_recursive());
// Empty asset registry
registry.0.clear();
}

@ -0,0 +1,93 @@
use crate::editor::prelude::*;
#[derive(Debug, Component, Default)]
pub struct SceneWidget;
pub fn add_scenes_ui(
gltf_selected: Query<&ui::TargetAsset<Gltf>, Added<ui::Active>>,
mut commands: Commands,
gltfs: Res<Assets<Gltf>>,
widget: Query<Entity, With<SceneWidget>>,
) {
gltf_selected.iter().for_each(|ui::TargetAsset { handle }| {
if let Some(gltf) = gltfs.get(&handle.clone()) {
gltf.named_scenes.iter().for_each(|(name, handle)| {
create_asset_button(
&widget,
&mut commands,
ui::TargetAsset {
handle: handle.clone(),
},
name.clone(),
None,
);
})
}
});
}
pub fn remove_scenes_ui(
mut gltf_unselected: RemovedComponents<ui::Active>,
target_assets: Query<&ui::TargetAsset<Gltf>>,
current: Query<(Entity, &ui::TargetAsset<Scene>)>,
gltfs: Res<Assets<Gltf>>,
mut commands: Commands,
) {
gltf_unselected
.iter()
.filter_map(|entity| target_assets.get(entity).ok())
.filter_map(|ui::TargetAsset { handle }| gltfs.get(handle))
.for_each(|gltf| {
gltf.scenes.iter().for_each(|handle| {
destroy_asset_button(
&current,
&mut commands,
&ui::TargetAsset {
handle: handle.clone(),
},
);
});
});
}
pub fn control_active_scenes(
added: Query<Entity, (With<Button>, Added<ui::Active>)>,
mut removed: RemovedComponents<ui::Active>,
scene_refs: Query<&ui::TargetAsset<Scene>>,
scenes: Query<(Entity, &Handle<Scene>)>,
level_root: Query<Entity, With<LevelRoot>>,
mut commands: Commands,
) {
// A scene button was marked inactive
removed.iter().for_each(|entity| {
// Get the handle associated with that button
scene_refs
.get(entity)
.iter()
.for_each(|ui::TargetAsset { handle }| {
scenes
.iter()
.find_map(|(entity, this_handle)| (this_handle == handle).then_some(entity))
.iter()
.for_each(|&entity| {
commands.entity(entity).despawn_recursive();
});
});
});
added.iter().for_each(|entity| {
scene_refs
.get(entity)
.iter()
.for_each(|ui::TargetAsset { handle }| {
info!("Spawning Scene {:?}", handle);
commands
.entity(level_root.single())
.with_children(|parent| {
parent.spawn(SceneBundle {
scene: handle.clone(),
..default()
});
});
});
});
}

@ -0,0 +1,325 @@
use crate::editor::prelude::*;
/// Timeline widget marker
#[derive(Debug, Component)]
pub struct TimelineWidget;
/// Add Epoch component, used on a button to trigger a new epoch addition
#[derive(Debug, Component)]
pub struct AddEpoch;
/// Epoch ID Component
#[derive(Debug, Reflect, Component, Clone)]
pub struct EpochId {
id: usize,
}
/// Epoch GLTF Component
#[derive(Debug, Reflect, Component, Clone)]
pub struct EpochGltf {
gltf: Handle<Gltf>,
}
/// Epoch Scene Component
#[derive(Debug, Reflect, Component, Clone)]
pub struct EpochScene {
scene: Handle<Scene>,
}
/// Epoch Camera Component, marking the current camera
#[derive(Debug, Reflect, Component, Clone)]
pub struct EpochCamera {
camera: Entity,
}
/// Epoch music component, marking the opening track for this epoch
#[derive(Debug, Reflect, Default, Component, Clone)]
pub struct EpochMusic {
music: Handle<AudioSource>,
}
/// Epoch monologue, marking the dialog spoken this epoch
#[derive(Debug, Reflect, Component, Clone)]
pub struct EpochMonologue {
monologue: Handle<Monologue>,
}
/// Epoch font, marking the font used for this epoch's monologue
#[derive(Debug, Reflect, Component, Clone)]
pub struct EpochFont {
font: Handle<Font>,
}
/// A vector of audios looping this epoch as background tracks
#[derive(Debug, Reflect, Component, Clone)]
pub struct EpochSfx {
sfx: Vec<Handle<AudioSource>>,
}
/// Epoch animations, looping this epoch
#[derive(Debug, Reflect, Component, Clone)]
pub struct EpochAnimations {
animations: Vec<Handle<AnimationClip>>,
}
/// System for adding an epoch to the level's timeline
/// Triggered when a button with the AddEpoch marker is Active
pub fn add_timeline_epoch(
root: Query<(Entity, &Children), With<TimelineWidget>>,
mut commands: Commands,
) {
info!("Adding timeline epoch");
root.iter().for_each(|(entity, children)| {
let id = children.iter().len();
let name = format!("{}", id);
commands.entity(entity).with_children(|parent| {
parent.spawn((
ButtonBundle {
style: Style {
border: UiRect::all(Val::Px(1.0)),
margin: UiRect::all(Val::Px(1.0)),
padding: UiRect::all(Val::Px(1.0)),
..default()
},
border_color: Color::BLACK.into(),
..default()
},
ui::Title {
text: name,
..default()
},
EpochId { id },
));
});
});
}
/// Set the GLTF for the current epoch
pub fn set_epoch_gltf(
events: Query<&ui::TargetAsset<Gltf>, Added<ui::Active>>,
active_epoch: Query<Entity, (With<ui::Active>, With<EpochId>)>,
mut commands: Commands,
) {
// Each time a GLTF is selected in the editor
events.iter().for_each(|ui::TargetAsset { handle }| {
// Iterate over all (0 or 1) active epochs
active_epoch.iter().for_each(|entity| {
// Set the GLTF (overwrite existing GLTF selections)
commands.entity(entity).insert(EpochGltf {
gltf: handle.clone(),
});
// TODO: Unset Scene, Camera, Animations
});
});
}
pub fn load_epoch_gltf(events: Query<Option<&EpochGltf>, (Added<ui::Active>, With<EpochId>)>) {
events.iter().for_each(|epoch_gltf| {
warn!("TODO: Load epoch GLTF!");
})
}
pub fn set_epoch_scene(
events: Query<&ui::TargetAsset<Scene>, Added<ui::Active>>,
active_epoch: Query<Entity, (With<ui::Active>, With<EpochId>)>,
mut commands: Commands,
) {
// Each time a Scene is selected in the editor
events.iter().for_each(|ui::TargetAsset { handle }| {
// Iterate over all (0 or 1) active epochs
active_epoch.iter().for_each(|entity| {
// Set the Scene (overwrite existing Scene selections)
commands.entity(entity).insert(EpochScene {
scene: handle.clone(),
});
});
});
}
pub fn load_epoch_scene(events: Query<Option<&EpochScene>, (Added<ui::Active>, With<EpochId>)>) {
events.iter().for_each(|epoch_scene| {
warn!("TODO: Load epoch Scene!");
})
}
pub fn set_epoch_camera(
events: Query<&ui::TargetEntity, Added<ui::Active>>,
active_epoch: Query<Entity, (With<ui::Active>, With<EpochId>)>,
mut commands: Commands,
) {
// Each time a Scene is selected in the editor
events.iter().for_each(|ui::TargetEntity { entity }| {
// Iterate over all (0 or 1) active epochs
active_epoch.iter().for_each(|this_entity| {
// Set the Scene (overwrite existing Scene selections)
commands
.entity(this_entity)
.insert(EpochCamera { camera: *entity });
});
});
}
pub fn load_epoch_camera(events: Query<Option<&EpochCamera>, (Added<ui::Active>, With<EpochId>)>) {
events.iter().for_each(|epoch_camera| {
warn!("TODO: Load epoch Camera");
})
}
pub fn set_epoch_music(
events: Query<&ui::TargetAsset<AudioSource>, Added<ui::Active>>,
active_epoch: Query<Entity, (With<ui::Active>, With<EpochId>)>,
mut commands: Commands,
) {
// Each time a Scene is selected in the editor
events.iter().for_each(|ui::TargetAsset { handle }| {
info!("TODO: Select scene music");
// // Iterate over all (0 or 1) active epochs
// active_epoch.iter().for_each(|entity| {
// // Set the Scene (overwrite existing Scene selections)
// commands.entity(entity).insert(EpochMusic { music: handle.clone() });
// });
});
}
pub fn load_epoch_music(events: Query<Option<&EpochMusic>, (Added<ui::Active>, With<EpochId>)>) {
events.iter().for_each(|epoch_music| {
warn!("TODO: Load epoch music!");
})
}
pub fn set_epoch_monologue(
events: Query<&ui::TargetAsset<Monologue>, Added<ui::Active>>,
active_epoch: Query<Entity, (With<ui::Active>, With<EpochId>)>,
mut commands: Commands,
) {
// Each time a Scene is selected in the editor
events.iter().for_each(|ui::TargetAsset { handle }| {
// Iterate over all (0 or 1) active epochs
active_epoch.iter().for_each(|entity| {
// Set the Scene (overwrite existing Scene selections)
commands.entity(entity).insert(EpochMonologue {
monologue: handle.clone(),
});
});
});
}
pub fn load_epoch_monologue(
events: Query<Option<&EpochMonologue>, (Added<ui::Active>, With<EpochId>)>,
) {
events.iter().for_each(|epoch_monologue| {
warn!("TODO: unset epoch Monologue!");
epoch_monologue
.iter()
.for_each(|EpochMonologue { monologue }| {
warn!("TODO: Set level epoch");
});
});
}
pub fn set_epoch_font(
events: Query<&ui::TargetAsset<Font>, Added<ui::Active>>,
active_epoch: Query<Entity, (With<ui::Active>, With<EpochId>)>,
mut commands: Commands,
) {
// Each time a Scene is selected in the editor
events.iter().for_each(|ui::TargetAsset { handle }| {
// Iterate over all (0 or 1) active epochs
active_epoch.iter().for_each(|entity| {
// Set the Scene (overwrite existing Scene selections)
commands.entity(entity).insert(EpochFont {
font: handle.clone(),
});
});
});
}
pub fn load_epoch_font(
events: Query<Option<&EpochFont>, (Added<ui::Active>, With<EpochId>)>,
mut font_info: ResMut<FontInfo>,
) {
events.iter().for_each(|epoch_font| {
font_info.default = epoch_font.map(|EpochFont { font }| font.clone());
});
}
pub fn set_epoch_sfx(
events: Query<&ui::TargetAsset<AudioSource>, Added<ui::Active>>,
mut active_epoch: Query<(Entity, Option<&mut EpochSfx>), (With<ui::Active>, With<EpochId>)>,
mut commands: Commands,
) {
// Each time a Scene is selected in the editor
events.iter().for_each(|ui::TargetAsset { handle }| {
// Iterate over all (0 or 1) active epochs
active_epoch.iter_mut().for_each(|(entity, maybe_sfx)| {
info!("Adding sfx {:?} to epoch {:?}", maybe_sfx, entity);
if let Some(mut epoch_sfx) = maybe_sfx {
epoch_sfx.sfx.push(handle.clone());
} else {
// Set the Scene (overwrite existing Scene selections)
commands.entity(entity).insert(EpochSfx {
sfx: vec![handle.clone()],
});
}
});
});
}
pub fn load_epoch_sfx(
added: Query<Entity, (Added<ui::Active>, With<EpochId>)>,
mut removed: RemovedComponents<ui::Active>,
epoch_sfx: Query<&EpochSfx>,
mut writer: EventWriter<ControlAudio>,
) {
removed.iter().for_each(|entity| {
epoch_sfx.get(entity).iter().for_each(|EpochSfx { sfx }| {
sfx.iter().for_each(|handle| {
writer.send(ControlAudio::Stop(handle.clone()));
});
});
});
added.iter().for_each(|entity| {
epoch_sfx.get(entity).iter().for_each(|EpochSfx { sfx }| {
sfx.iter().for_each(|handle| {
writer.send(ControlAudio::Loop(handle.clone()));
});
});
});
}
pub fn set_epoch_animations(
events: Query<&ui::TargetAsset<AnimationClip>, Added<ui::Active>>,
mut active_epoch: Query<
(Entity, Option<&mut EpochAnimations>),
(With<ui::Active>, With<EpochId>),
>,
mut commands: Commands,
) {
// Each time a Scene is selected in the editor
events.iter().for_each(|ui::TargetAsset { handle }| {
// Iterate over all (0 or 1) active epochs
active_epoch
.iter_mut()
.for_each(|(entity, maybe_animations)| {
if let Some(mut epoch_animations) = maybe_animations {
epoch_animations.animations.push(handle.clone());
} else {
// Set the Scene (overwrite existing Scene selections)
commands.entity(entity).insert(EpochAnimations {
animations: vec![handle.clone()],
});
}
});
});
}
pub fn load_epoch_animations(
events: Query<Option<&EpochAnimations>, (Added<ui::Active>, With<EpochId>)>,
) {
events.iter().for_each(|epoch_animations| {
warn!("TODO: Load epoch Animations!");
})
}
Loading…
Cancel
Save