Quick and dirty copy folder works

main
Elijah Voigt 2 years ago
parent 50ee319921
commit 5294f64946

BIN
assets/foo/bar/baz/inspect.glb (Stored with Git LFS)

Binary file not shown.

BIN
assets/scratch/foo/bar/baz/inspect.glb (Stored with Git LFS)

Binary file not shown.

BIN
assets/scratch/materials.glb (Stored with Git LFS)

Binary file not shown.

@ -5,6 +5,12 @@
// BUGS: // BUGS:
// //
// TODO: // TODO:
// * re-load assets dir when new asset is copied
// * copy-and-reload drag-and-drop dirs
// * font resource for monologues
// * edit textbox with actions
// * run_if logic for actions where possible
// * make min/max/close buttons into actions not selects
// * (medium) Select Font -> "Default Font" Resource // * (medium) Select Font -> "Default Font" Resource
// * (medium) Pre-compute animation target entities // * (medium) Pre-compute animation target entities
// * (hard) Harden Active Camera // * (hard) Harden Active Camera
@ -23,9 +29,8 @@ use monologue_trees::{debug::*, ui};
const WELCOME_MESSAGES: &'static [&'static str] = &[ const WELCOME_MESSAGES: &'static [&'static str] = &[
"Welcome to the Monologue Trees editor!", "Welcome to the Monologue Trees editor!",
"Import assets by dragging and dropping files or folders into the editor!",
concat!( concat!(
"Import assets by dragging and dropping files into the editor\n",
"\n",
"Supported file types (for now):\n", "Supported file types (for now):\n",
"* 3D: .gltf, .glb\n", "* 3D: .gltf, .glb\n",
"* Audio: .ogg\n", "* Audio: .ogg\n",
@ -56,6 +61,7 @@ fn main() {
}, },
)) ))
.init_resource::<AssetRegistry>() .init_resource::<AssetRegistry>()
.insert_resource(AssetsDir::new("assets/scratch"))
.add_event::<ImportAsset>() .add_event::<ImportAsset>()
.add_asset::<Monologue>() .add_asset::<Monologue>()
.init_asset_loader::<MonologueLoader>() .init_asset_loader::<MonologueLoader>()
@ -87,7 +93,17 @@ fn main() {
sync_monologue_font, sync_monologue_font,
), ),
) )
.add_systems(Update, (import_assets, import_file, import_folder)) .add_systems(
Update,
(
init_assets_dir,
import_assets,
import_file,
import_folder,
reload_assets,
clear_assets,
),
)
.add_systems( .add_systems(
Update, Update,
( (
@ -96,7 +112,7 @@ fn main() {
directional_light_force_shadows, directional_light_force_shadows,
), ),
) )
.add_systems(Update, (clear_level, clear_assets)) .add_systems(Update, clear_level)
.run(); .run();
} }
@ -479,10 +495,45 @@ mod audio {
use assets::*; use assets::*;
mod assets { mod assets {
use std::path::PathBuf; use std::{
fs::DirBuilder,
fs::{copy, create_dir_all, read_dir},
path::PathBuf,
};
use bevy::tasks::IoTaskPool;
use super::*; use super::*;
#[derive(Debug, Resource)]
pub struct AssetsDir {
pub root: PathBuf,
}
impl AssetsDir {
pub fn new(root: &str) -> Self {
AssetsDir {
root: PathBuf::from(root)
.canonicalize()
.expect("Setting assets dir"),
}
}
}
pub fn init_assets_dir(assets_dir: Res<AssetsDir>) {
if assets_dir.is_added() || assets_dir.is_changed() {
let d = assets_dir.root.clone();
IoTaskPool::get()
.spawn(async move {
match DirBuilder::new().create(d) {
Ok(_) => info!("Created assets directory"),
Err(e) => warn!("Error creating assets directory {:?}", e),
}
})
.detach();
}
}
#[derive(Debug, Event)] #[derive(Debug, Event)]
pub enum ImportAsset { pub enum ImportAsset {
File(PathBuf), File(PathBuf),
@ -507,44 +558,82 @@ mod assets {
}) })
} }
pub fn import_file( pub fn import_file(mut events: EventReader<ImportAsset>, assets_dir: Res<AssetsDir>) {
mut events: EventReader<ImportAsset>,
server: Res<AssetServer>,
mut registry: ResMut<AssetRegistry>,
) {
events events
.iter() .iter()
.filter_map(|event| match event { .filter_map(|event| match event {
ImportAsset::File(path) => Some(path), ImportAsset::File(path) => Some(path.clone()),
_ => None, _ => None,
}) })
.for_each(|path| { .for_each(|path| {
registry let fname = path.file_name().expect("PathBuf should have file name");
.0 let newpath = PathBuf::from(assets_dir.root.clone()).join(fname);
.push(server.load_untyped(String::from(path.to_string_lossy()))); IoTaskPool::get()
.spawn(async move {
match copy(path, newpath) {
Ok(_) => info!("Created assets directory"),
Err(e) => warn!("Error creating assets directory {:?}", e),
}
})
.detach();
}); });
} }
pub fn import_folder( fn copy_dir(from: PathBuf, to: PathBuf) -> std::io::Result<()> {
mut events: EventReader<ImportAsset>, info!("Copy dir {:?} -> {:?}", from, to);
server: Res<AssetServer>, if let Ok(entries) = read_dir(from) {
mut registry: ResMut<AssetRegistry>, for entry in entries.filter_map(|e| e.ok()) {
) { if entry.path().is_file() {
let from_file = entry.path();
let to_file = to.join(entry.file_name());
copy(from_file, to_file).map(|_| ())?;
} else if entry.path().is_dir() {
info!("Recursive");
let target = to.join(entry.file_name());
create_dir_all(target.clone())?;
copy_dir(entry.path(), target.clone())?;
}
}
}
Ok(())
}
pub fn import_folder(mut events: EventReader<ImportAsset>, assets_dir: Res<AssetsDir>) {
events events
.iter() .iter()
.filter_map(|event| match event { .filter_map(|event| match event {
ImportAsset::Dir(path) => Some(path), ImportAsset::Dir(path) => Some(path.clone()),
_ => None, _ => None,
}) })
.for_each(|path| { .for_each(|path| {
registry.0.extend( let fname = path.file_name().expect("PathBuf should have file name");
server let newpath = PathBuf::from(assets_dir.root.clone()).join(fname);
.load_folder(String::from(path.to_string_lossy())) info!("copying folder {:?} to {:?}", path.clone(), newpath);
.expect("Loading assets from folder"), IoTaskPool::get()
); .spawn(async move {
match copy_dir(path.clone(), newpath) {
Ok(_) => info!("Created assets directory"),
Err(e) => warn!("Error creating assets directory {:?}", e),
}
})
.detach();
}); });
} }
pub fn reload_assets(
mut events: EventReader<ImportAsset>,
server: Res<AssetServer>,
mut registry: ResMut<AssetRegistry>,
assets_dir: Res<AssetsDir>,
) {
// Reduce all import events in a frame to one "load_folder" action
if events.iter().len() > 0 {
registry.0 = server
.load_folder(assets_dir.root.clone())
.expect("Reload assets folder");
}
}
pub fn get_asset_name<T: Asset>(server: &AssetServer, handle: Handle<T>) -> String { 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(asset_path) = server.get_handle_path(handle.clone()) {
if let Some(stem) = asset_path.path().file_stem() { if let Some(stem) = asset_path.path().file_stem() {

@ -507,7 +507,7 @@ mod scroll {
self_hover || child_hover || parent_hover self_hover || child_hover || parent_hover
}) })
.for_each(|(_, _, _, mut style)| { .for_each(|(_, _, _, mut style)| {
let factor = 2.0; let factor = 8.0;
let val = match unit { let val = match unit {
MouseScrollUnit::Line => match style.top { MouseScrollUnit::Line => match style.top {
Val::Px(v) => v + (y * factor), Val::Px(v) => v + (y * factor),

Loading…
Cancel
Save