action buttons work again I guess

main
Elijah Voigt 2 years ago
parent 0e643965f4
commit 50ee319921

BIN
assets/models/FlightHelmet.bin (Stored with Git LFS)

Binary file not shown.

BIN
assets/models/FlightHelmet.gltf (Stored with Git LFS)

Binary file not shown.

BIN
assets/models/materials.blend (Stored with Git LFS)

Binary file not shown.

BIN
assets/models/materials.blend1 (Stored with Git LFS)

Binary file not shown.

@ -1,7 +1,7 @@
(
resources: {},
entities: {
4: (
19: (
components: {
"bevy_transform::components::transform::Transform": (
translation: (
@ -42,20 +42,20 @@
)),
"bevy_render::view::visibility::Visibility": Inherited,
"bevy_hierarchy::components::children::Children": ([
5,
6,
20,
21,
]),
},
),
5: (
20: (
components: {
"bevy_hierarchy::components::parent::Parent": (4),
"bevy_hierarchy::components::parent::Parent": (19),
"bevy_asset::handle::Handle<bevy_audio::audio_source::AudioSource>": (
id: AssetPathId(((5718828327369153735), (8823233378563626002))),
),
},
),
6: (
21: (
components: {
"bevy_transform::components::transform::Transform": (
translation: (
@ -95,9 +95,9 @@
),
)),
"bevy_render::view::visibility::Visibility": Inherited,
"bevy_hierarchy::components::parent::Parent": (4),
"bevy_hierarchy::components::parent::Parent": (19),
"bevy_hierarchy::components::children::Children": ([
16,
22,
]),
"bevy_asset::handle::Handle<bevy_scene::scene::Scene>": (
id: AssetPathId(((8329447081204006281), (13531267934229906755))),

@ -56,6 +56,7 @@ fn main() {
},
))
.init_resource::<AssetRegistry>()
.add_event::<ImportAsset>()
.add_asset::<Monologue>()
.init_asset_loader::<MonologueLoader>()
.add_systems(Startup, (initialize_ui, init_texts_ui, welcome_message))
@ -78,7 +79,6 @@ fn main() {
.add_systems(
Update,
(
import_files,
gltf_ui,
fonts_ui,
texts_ui,
@ -87,6 +87,7 @@ fn main() {
sync_monologue_font,
),
)
.add_systems(Update, (import_assets, import_file, import_folder))
.add_systems(
Update,
(
@ -386,27 +387,6 @@ fn spawn_tab_container<T: Default + Component>(
)
}
fn import_files(
mut events: EventReader<FileDragAndDrop>,
server: Res<AssetServer>,
mut registry: ResMut<AssetRegistry>,
) {
events.iter().for_each(|event| match event {
FileDragAndDrop::DroppedFile { path_buf, .. } => {
registry.0.push(
server.load_untyped(
path_buf
.clone()
.into_os_string()
.into_string()
.expect("Path converts to string"),
),
);
}
_ => (),
})
}
use audio::*;
mod audio {
@ -499,8 +479,72 @@ mod audio {
use assets::*;
mod assets {
use std::path::PathBuf;
use super::*;
#[derive(Debug, Event)]
pub enum ImportAsset {
File(PathBuf),
Dir(PathBuf),
}
pub fn import_assets(
mut events: EventReader<FileDragAndDrop>,
mut writer: EventWriter<ImportAsset>,
) {
events.iter().for_each(|event| match event {
FileDragAndDrop::DroppedFile { path_buf, .. } => {
if path_buf.is_file() {
writer.send(ImportAsset::File(path_buf.clone()));
} else if path_buf.is_dir() {
writer.send(ImportAsset::Dir(path_buf.clone()));
} else {
warn!("Could not identify filetype for {:?}", path_buf)
}
}
_ => (),
})
}
pub fn import_file(
mut events: EventReader<ImportAsset>,
server: Res<AssetServer>,
mut registry: ResMut<AssetRegistry>,
) {
events
.iter()
.filter_map(|event| match event {
ImportAsset::File(path) => Some(path),
_ => None,
})
.for_each(|path| {
registry
.0
.push(server.load_untyped(String::from(path.to_string_lossy())));
});
}
pub fn import_folder(
mut events: EventReader<ImportAsset>,
server: Res<AssetServer>,
mut registry: ResMut<AssetRegistry>,
) {
events
.iter()
.filter_map(|event| match event {
ImportAsset::Dir(path) => Some(path),
_ => None,
})
.for_each(|path| {
registry.0.extend(
server
.load_folder(String::from(path.to_string_lossy()))
.expect("Loading assets from folder"),
);
});
}
pub fn get_asset_name<T: Asset>(server: &AssetServer, handle: Handle<T>) -> String {
if let Some(asset_path) = server.get_handle_path(handle.clone()) {
if let Some(stem) = asset_path.path().file_stem() {
@ -1336,7 +1380,9 @@ mod reset {
mut registry: ResMut<AssetRegistry>,
mut commands: Commands,
) {
events.iter().for_each(|entity| {
events.iter().for_each(|_| {
info!("Clearing assets");
// Clear buttons holding asset references
asset_holders
.iter()

@ -1,33 +1,67 @@
use std::{fs::File, io::Write};
use bevy::{audio::PlaybackMode, prelude::*, tasks::IoTaskPool};
// TODO:
// * Determine where local assets folder needs to be created
// * Create local assets folder
// * Recusrively laod that folder and watch for changes
// * Copy assets into local folder in leue of importing them
// * Check portability by moving binary + folder to new location
use std::{
fs::{DirBuilder, File},
io::Write,
time::Duration,
};
use bevy::{
asset::{Asset, ChangeWatcher},
audio::PlaybackMode,
gltf::Gltf,
prelude::*,
tasks::IoTaskPool,
};
use monologue_trees::{debug::*, ui};
fn main() {
App::new()
.init_resource::<AssetRegistry>()
.add_plugins((
DefaultPlugins.set(WindowPlugin {
DefaultPlugins
.set(WindowPlugin {
primary_window: Some(Window {
title: "Serialization WTF".into(),
resolution: (640., 480.).into(),
..default()
}),
..default()
})
.set(AssetPlugin {
asset_folder: "assets".into(),
// Tell the asset server to watch for asset changes on disk:
watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(0)),
..default()
}),
DebugInfoPlugin,
ui::GameUiPlugin { ..default() },
))
.add_systems(Startup, init)
.add_systems(Startup, (init, init_assets_dir))
.add_systems(
Update,
(
export.run_if(interaction_condition::<ExportAction>),
clear.run_if(interaction_condition::<ClearAction>),
import.run_if(interaction_condition::<ImportAction>),
inspect.run_if(interaction_condition::<InspectAction>),
load.run_if(interaction_condition::<LoadAssetsAction>),
unload.run_if(interaction_condition::<UnloadAssetsAction>),
spawn_level.run_if(interaction_condition::<SpawnLevelAction>),
asset_inspector::<AudioSource>,
asset_inspector::<Scene>,
),
)
.add_systems(
PostUpdate,
(
rehydrate::<Visibility, ComputedVisibility>,
rehydrate::<Handle<AudioSource>, PlaybackSettings>,
inspect.run_if(interaction_condition::<InspectAction>),
fallback_camera.run_if(fallback_camera_condition),
),
)
@ -50,38 +84,37 @@ struct ImportAction;
#[derive(Debug, Component)]
struct InspectAction;
#[derive(Debug, Component)]
struct LoadAssetsAction;
#[derive(Debug, Component)]
struct UnloadAssetsAction;
#[derive(Debug, Component)]
struct SpawnLevelAction;
#[derive(Debug, Resource, Default)]
struct AssetRegistry {
handles: Vec<HandleUntyped>,
}
fn init(server: Res<AssetServer>, mut commands: Commands, mut registry: ResMut<AssetRegistry>) {
fn init_assets_dir() {
IoTaskPool::get()
.spawn(async move {
match DirBuilder::new().create("assets") {
Ok(_) => info!("Created assets directory"),
Err(e) => warn!("Error creating assets directory", e),
}
})
.detach();
}
fn init(mut commands: Commands) {
commands.spawn((
Camera2dBundle { ..default() },
UiCameraConfig { show_ui: true },
));
let audio_handle: Handle<AudioSource> = server.load("audio/Ambient/Lake Sound 1.ogg");
let scene_handle: Handle<Scene> = server.load("models/materials.glb#Scene0");
commands
.spawn((SpatialBundle { ..default() }, LevelRoot))
.with_children(|parent| {
parent.spawn(AudioSourceBundle {
source: audio_handle.clone(),
settings: PlaybackSettings {
mode: PlaybackMode::Loop,
paused: false,
..default()
},
});
parent.spawn((SceneBundle {
scene: scene_handle.clone(),
..default()
},));
});
registry.handles.push(audio_handle.clone_untyped());
registry.handles.push(scene_handle.clone_untyped());
commands
.spawn((
NodeBundle {
@ -101,6 +134,57 @@ fn init(server: Res<AssetServer>, mut commands: Commands, mut registry: ResMut<A
ui::Select::Action,
))
.with_children(|parent| {
parent.spawn((
ButtonBundle {
style: Style {
margin: UiRect::all(Val::Px(5.0)),
padding: UiRect::all(Val::Px(5.0)),
border: UiRect::all(Val::Px(1.0)),
..default()
},
border_color: Color::BLACK.into(),
..default()
},
ui::Title {
text: "Load Assets".into(),
..default()
},
LoadAssetsAction,
));
parent.spawn((
ButtonBundle {
style: Style {
margin: UiRect::all(Val::Px(5.0)),
padding: UiRect::all(Val::Px(5.0)),
border: UiRect::all(Val::Px(1.0)),
..default()
},
border_color: Color::BLACK.into(),
..default()
},
ui::Title {
text: "Dump Assets".into(),
..default()
},
UnloadAssetsAction,
));
parent.spawn((
ButtonBundle {
style: Style {
margin: UiRect::all(Val::Px(5.0)),
padding: UiRect::all(Val::Px(5.0)),
border: UiRect::all(Val::Px(1.0)),
..default()
},
border_color: Color::BLACK.into(),
..default()
},
ui::Title {
text: "Spawn Level".into(),
..default()
},
SpawnLevelAction,
));
parent.spawn((
ButtonBundle {
style: Style {
@ -269,6 +353,8 @@ fn clear(root: Query<Entity, With<LevelRoot>>, mut commands: Commands) {
});
}
// TODO: Figure out how to import the same asset from a differnt source
// How do the plugins do it??
fn import(mut commands: Commands, server: Res<AssetServer>) {
info!("Importing level");
@ -295,3 +381,47 @@ fn fallback_camera(
) {
ui_camera.single_mut().is_active = cameras.iter().len() <= 0;
}
fn asset_inspector<T: Asset>(mut events: EventReader<AssetEvent<T>>) {
events.iter().for_each(|event| match event {
AssetEvent::Created { handle } => info!("Asset Created {:?}", handle),
AssetEvent::Modified { handle } => info!("Asset Modified {:?}", handle),
AssetEvent::Removed { handle } => info!("Asset Removed {:?}", handle),
});
}
// OK seems like `load_folder` does not automatically pick up added files
fn load(mut registry: ResMut<AssetRegistry>, server: Res<AssetServer>) {
info!("Loading assets");
registry.handles = server.load_folder("./dynamic").unwrap();
info!("Current files: {:?}", registry.handles);
}
fn unload(mut registry: ResMut<AssetRegistry>, mut gltfs: ResMut<Assets<Gltf>>) {
info!("Unloading asstes");
registry.handles.clear();
// This is required to clear scenes from asset cache
gltfs.clear();
}
fn spawn_level(mut commands: Commands, server: Res<AssetServer>) {
commands
.spawn((SpatialBundle { ..default() }, LevelRoot))
.with_children(|parent| {
parent.spawn(AudioSourceBundle {
source: server.load::<AudioSource, &str>("dynamic/Lake Sound 1.ogg"),
settings: PlaybackSettings {
mode: PlaybackMode::Loop,
paused: false,
..default()
},
});
parent.spawn((SceneBundle {
scene: server.load("dynamic/materials.glb#Scene0"),
..default()
},));
});
}

@ -439,12 +439,12 @@ mod buttons {
) {
events
.iter()
.filter(|(_, _, _, &interaction)| interaction == Interaction::Pressed)
.for_each(|(entity, parent, active, _)| {
.for_each(|(entity, parent, active, interaction)| {
selects
.get(parent.get())
.iter()
.for_each(|(select, children)| {
.for_each(|(select, children)| match interaction {
Interaction::Pressed => {
match active {
Some(_) => {
commands.entity(entity).remove::<Active>();
@ -454,10 +454,7 @@ mod buttons {
}
}
match select {
Select::Action => {
commands.entity(entity).remove::<Active>();
}
Select::Multi => (),
Select::Multi | Select::Action => (),
Select::Single => {
children.iter().filter(|&child| *child != entity).for_each(
|&child| {
@ -466,6 +463,15 @@ mod buttons {
);
}
}
}
// A silly hack to get actions to maintain the active tag for 1+ frames
Interaction::None => match select {
Select::Action => {
commands.entity(entity).remove::<Active>();
}
_ => (),
},
_ => (),
});
});
}

Loading…
Cancel
Save