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:
//
// 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) Pre-compute animation target entities
// * (hard) Harden Active Camera
@ -23,9 +29,8 @@ use monologue_trees::{debug::*, ui};
const WELCOME_MESSAGES: &'static [&'static str] = &[
"Welcome to the Monologue Trees editor!",
"Import assets by dragging and dropping files or folders into the editor!",
concat!(
"Import assets by dragging and dropping files into the editor\n",
"\n",
"Supported file types (for now):\n",
"* 3D: .gltf, .glb\n",
"* Audio: .ogg\n",
@ -56,6 +61,7 @@ fn main() {
},
))
.init_resource::<AssetRegistry>()
.insert_resource(AssetsDir::new("assets/scratch"))
.add_event::<ImportAsset>()
.add_asset::<Monologue>()
.init_asset_loader::<MonologueLoader>()
@ -87,7 +93,17 @@ fn main() {
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(
Update,
(
@ -96,7 +112,7 @@ fn main() {
directional_light_force_shadows,
),
)
.add_systems(Update, (clear_level, clear_assets))
.add_systems(Update, clear_level)
.run();
}
@ -479,10 +495,45 @@ mod audio {
use 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::*;
#[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)]
pub enum ImportAsset {
File(PathBuf),
@ -507,44 +558,82 @@ mod assets {
})
}
pub fn import_file(
mut events: EventReader<ImportAsset>,
server: Res<AssetServer>,
mut registry: ResMut<AssetRegistry>,
) {
pub fn import_file(mut events: EventReader<ImportAsset>, assets_dir: Res<AssetsDir>) {
events
.iter()
.filter_map(|event| match event {
ImportAsset::File(path) => Some(path),
ImportAsset::File(path) => Some(path.clone()),
_ => None,
})
.for_each(|path| {
registry
.0
.push(server.load_untyped(String::from(path.to_string_lossy())));
let fname = path.file_name().expect("PathBuf should have file name");
let newpath = PathBuf::from(assets_dir.root.clone()).join(fname);
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(
mut events: EventReader<ImportAsset>,
server: Res<AssetServer>,
mut registry: ResMut<AssetRegistry>,
) {
fn copy_dir(from: PathBuf, to: PathBuf) -> std::io::Result<()> {
info!("Copy dir {:?} -> {:?}", from, to);
if let Ok(entries) = read_dir(from) {
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
.iter()
.filter_map(|event| match event {
ImportAsset::Dir(path) => Some(path),
ImportAsset::Dir(path) => Some(path.clone()),
_ => None,
})
.for_each(|path| {
registry.0.extend(
server
.load_folder(String::from(path.to_string_lossy()))
.expect("Loading assets from folder"),
);
let fname = path.file_name().expect("PathBuf should have file name");
let newpath = PathBuf::from(assets_dir.root.clone()).join(fname);
info!("copying folder {:?} to {:?}", path.clone(), newpath);
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 {
if let Some(asset_path) = server.get_handle_path(handle.clone()) {
if let Some(stem) = asset_path.path().file_stem() {

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

Loading…
Cancel
Save