Skip to content

Commit

Permalink
Add more granular asset loading for the editor (#52)
Browse files Browse the repository at this point in the history
  • Loading branch information
mbrea-c authored Jul 4, 2024
1 parent 296f0d2 commit 7fadb3f
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 32 deletions.
2 changes: 1 addition & 1 deletion crates/bevy_animation_graph_editor/src/asset_saving.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{ui::UiState, PersistedAssetHandles};
use crate::{scanner::PersistedAssetHandles, ui::UiState};
use bevy::{
asset::io::{file::FileAssetReader, AssetReader, AssetSourceId},
prelude::*,
Expand Down
36 changes: 6 additions & 30 deletions crates/bevy_animation_graph_editor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,18 @@ mod egui_nodes;
mod fsm_show;
mod graph_show;
mod graph_update;
mod scanner;
mod tree;
mod ui;

use asset_saving::AssetSavingPlugin;
use bevy::{asset::LoadedFolder, prelude::*, utils::HashSet};
use bevy_animation_graph::core::{
animation_graph::AnimationGraph, plugin::AnimationGraphPlugin,
state_machine::high_level::StateMachine,
};
use bevy::prelude::*;
use bevy_animation_graph::core::plugin::AnimationGraphPlugin;
use bevy_egui::EguiPlugin;
use bevy_inspector_egui::{bevy_egui, DefaultInspectorConfigPlugin};
use clap::Parser;
use egui_inspector_impls::BetterInspectorPlugin;
use scanner::ScannerPlugin;
use std::path::PathBuf;
use ui::{graph_debug_draw_bone_system, UiState};

Expand All @@ -27,15 +26,6 @@ struct Cli {
asset_source: PathBuf,
}

/// Keeps a handle to the folder so that it does not get unloaded
#[derive(Resource)]
struct PersistedAssetHandles {
#[allow(dead_code)]
folder: Handle<LoadedFolder>,
unsaved_graphs: HashSet<Handle<AnimationGraph>>,
unsaved_fsms: HashSet<Handle<StateMachine>>,
}

fn main() {
let cli = Cli::parse();

Expand All @@ -56,9 +46,10 @@ fn main() {
.add_plugins(DefaultInspectorConfigPlugin)
.add_plugins(BetterInspectorPlugin)
.add_plugins(AssetSavingPlugin)
.add_plugins(ScannerPlugin)
.insert_resource(UiState::new())
.insert_resource(cli)
.add_systems(Startup, (core_setup, ui::setup_system))
.add_systems(Startup, ui::setup_system)
.add_systems(
Update,
(
Expand All @@ -72,18 +63,3 @@ fn main() {

app.run();
}

fn core_setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut gizmo_config: ResMut<GizmoConfigStore>,
) {
commands.insert_resource(PersistedAssetHandles {
folder: asset_server.load_folder(""),
unsaved_graphs: HashSet::default(),
unsaved_fsms: HashSet::default(),
});

let config = gizmo_config.config_mut::<DefaultGizmoConfigGroup>().0;
config.depth_bias = -1.;
}
84 changes: 84 additions & 0 deletions crates/bevy_animation_graph_editor/src/scanner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use crate::Cli;
use bevy::{asset::LoadedUntypedAsset, prelude::*, utils::HashSet};
use bevy_animation_graph::{
core::state_machine::high_level::StateMachine, prelude::AnimationGraph,
};
use std::{
fs, io,
path::{Path, PathBuf},
};

pub struct ScannerPlugin;
impl Plugin for ScannerPlugin {
fn build(&self, app: &mut bevy::prelude::App) {
app.insert_resource(PersistedAssetHandles {
unsaved_graphs: HashSet::default(),
unsaved_fsms: HashSet::default(),
loaded_paths: HashSet::default(),
})
.add_event::<RescanAssets>()
.add_systems(Startup, core_setup)
.add_systems(Update, asset_reload);
}
}

/// Keeps a handle to the folder so that it does not get unloaded
#[derive(Resource)]
pub struct PersistedAssetHandles {
#[allow(dead_code)]
pub loaded_paths: HashSet<Handle<LoadedUntypedAsset>>,
pub unsaved_graphs: HashSet<Handle<AnimationGraph>>,
pub unsaved_fsms: HashSet<Handle<StateMachine>>,
}

#[derive(Event)]
pub struct RescanAssets;

pub fn core_setup(
mut evw_rescan_events: EventWriter<RescanAssets>,
mut gizmo_config: ResMut<GizmoConfigStore>,
) {
evw_rescan_events.send(RescanAssets);

let config = gizmo_config.config_mut::<DefaultGizmoConfigGroup>().0;
config.depth_bias = -1.;
}

pub fn asset_reload(
mut reload_events: EventReader<RescanAssets>,
asset_server: Res<AssetServer>,
mut persisted_asset_handles: ResMut<PersistedAssetHandles>,
cli: Res<Cli>,
) {
if reload_events.read().next().is_some() {
visit_dirs(&cli.asset_source, &mut |path| {
let relative_path = path.strip_prefix(&cli.asset_source).unwrap().to_owned();
let loaded = asset_server.load_untyped(relative_path);
persisted_asset_handles.loaded_paths.insert(loaded);
})
.unwrap_or_else(|err| {
panic!(
"Failed to load asset path {:?}: {:?}",
cli.asset_source, err
)
});
}
}

// one possible implementation of walking a directory only visiting files
// taken from https://doc.rust-lang.org/nightly/std/fs/fn.read_dir.html#examples
fn visit_dirs(dir: &Path, cb: &mut dyn FnMut(PathBuf)) -> io::Result<()> {
if dir.is_dir() {
for entry in fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
visit_dirs(&path, cb)?;
} else {
info!("Loading {path:?}");
cb(path);
}
}
}
Ok(())
}
2 changes: 1 addition & 1 deletion crates/bevy_animation_graph_editor/src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use crate::graph_update::{
apply_global_changes, convert_fsm_change, convert_graph_change, update_graph, Change,
FsmChange, FsmPropertiesChange, GlobalChange, GraphChange,
};
use crate::scanner::PersistedAssetHandles;
use crate::tree::{Tree, TreeInternal, TreeResult};
use crate::PersistedAssetHandles;
use bevy::asset::UntypedAssetId;
use bevy::ecs::system::CommandQueue;
use bevy::prelude::*;
Expand Down

0 comments on commit 7fadb3f

Please sign in to comment.