tirbofish/dropbear · diff
worked on async and channels, with the dependency checking working perfectly :)
Signature present but could not be verified.
Unverified
@@ -58,6 +58,7 @@ flate2 = "1.1" reqwest = { version = "0.11", features = ["stream"] } tar = "0.4" async-trait = "0.1" +futures-util = "0.3" gltf = "1" thiserror = "2.0" @@ -68,7 +68,7 @@ pub struct LazyAdoptedEntity { impl LazyAdoptedEntity { /// Create a LazyAdoptedEntity from a file path (can be run on background thread) pub async fn from_file(path: &PathBuf, label: Option<&str>) -> anyhow::Result<Self> { - let buffer = std::fs::read(path)?; + let buffer = tokio::fs::read(path).await?; Self::from_memory(buffer, label).await } @@ -407,14 +407,14 @@ impl App { /// - setup: A closure that can initialise the first scenes, such as a menu or the game itself. /// It takes an input of a scene manager and an input manager, and expects you to return back the changed /// managers. - pub fn run<F>(config: WindowConfiguration, app_name: &str, setup: F) -> anyhow::Result<()> + pub async fn run<F>(config: WindowConfiguration, app_name: &str, setup: F) -> anyhow::Result<()> where F: FnOnce(scene::Manager, input::Manager) -> (scene::Manager, input::Manager), { let log_dir = app_dirs2::app_root(AppDataType::UserData, &config.app_info) .expect("Failed to get app data directory") .join("logs"); - std::fs::create_dir_all(&log_dir).expect("Failed to create log dir"); + tokio::fs::create_dir_all(&log_dir).await.expect("Failed to create log dir"); let datetime_str = Local::now().format("%Y-%m-%d_%H-%M-%S"); let log_filename = format!("{}.{}.log", app_name, datetime_str); @@ -299,7 +299,6 @@ impl Model { buffer: impl AsRef<[u8]>, label: Option<&str> ) -> anyhow::Result<Model> { - println!("========== Benchmarking speed of loading {:?} ==========", label); let start = Instant::now(); let cache_key = label.unwrap_or("default").to_string(); @@ -307,7 +306,8 @@ impl Model { log::debug!("Model loaded from memory cache: {:?}", cache_key); return Ok(cached_model.clone()); } - + + println!("========== Benchmarking speed of loading {:?} ==========", label); log::debug!("Loading from memory"); let res_ref = ResourceReference::from_bytes(buffer.as_ref()); @@ -481,7 +481,7 @@ impl Model { return Ok(cached_model.clone()); } - let buffer = std::fs::read(path)?; + let buffer = tokio::fs::read(path).await?; let model = Self::load_from_memory(graphics, buffer, label).await?; MODEL_CACHE.lock().insert(path_str, model.clone()); @@ -32,6 +32,7 @@ flate2.workspace = true tar.workspace = true zip.workspace = true tokio.workspace = true +futures-util.workspace = true [dev-dependencies] pollster = "*" @@ -3,6 +3,8 @@ use std::process::Command; use app_dirs2::{AppInfo, AppDataType, app_dir}; use tokio::fs; use tokio::io::AsyncWriteExt; +use tokio::sync::mpsc::UnboundedSender; +use futures_util::StreamExt; const GLEAM_VERSION: &'static str = "1.12.0"; const BUN_VERSION: &'static str = "1.2.22"; @@ -13,6 +15,17 @@ pub const APP_INFO: AppInfo = AppInfo { author: "4tkbytes", }; +pub enum InstallStatus { + NotStarted, + InProgress { + tool: String, + step: String, + progress: f32, + }, + Success, + Failed(String), +} + /// Compiles a gleam project into WASM through a pipeline. pub struct GleamScriptCompiler { #[allow(dead_code)] @@ -26,29 +39,31 @@ impl GleamScriptCompiler { } } - pub async fn build(self) -> anyhow::Result<()> { - Self::ensure_dependencies().await?; + pub async fn build(self, sender: Option<UnboundedSender<InstallStatus>>) -> anyhow::Result<()> { + Self::ensure_dependencies(sender).await?; Ok(()) } - pub async fn ensure_dependencies() -> anyhow::Result<()> { + pub async fn ensure_dependencies(sender: Option<UnboundedSender<InstallStatus>>) -> anyhow::Result<()> { println!("Checking dependencies..."); - let gleam_available = Self::check_tool_in_path("gleam").await; - if gleam_available { - println!("Gleam already exists in path"); + if let Some(ref s) = sender { + let _ = s.send(InstallStatus::InProgress { + tool: "None".to_string(), + step: "Checking existing tools...".to_string(), + progress: 0.05, + }); } + + let gleam_available = Self::check_tool_in_path("gleam").await; let bun_available = Self::check_tool_in_path("bun").await; - if bun_available { - println!("Bun already exists in path"); - } let javy_available = Self::check_tool_in_path("javy").await; - if javy_available { - println!("Javy already exists in path"); - } if gleam_available && bun_available && javy_available { println!("All dependencies found in PATH"); + if let Some(ref s) = sender { + let _ = s.send(InstallStatus::Success); + } return Ok(()); } @@ -59,18 +74,82 @@ impl GleamScriptCompiler { let app_dir = app_dir(AppDataType::UserData, &APP_INFO, "") .map_err(|e| anyhow::anyhow!("Failed to get app directory: {}", e))?; + let tools_to_install: Vec<(&str, bool)> = vec![ + ("Gleam", gleam_available), + ("Bun", bun_available), + ("Javy", javy_available), + ]; + let total_to_install = tools_to_install.iter().filter(|(_, avail)| !avail).count(); + let mut installed_count = 0; + if !gleam_available { - Self::download_gleam(&app_dir).await?; + if let Some(ref s) = sender.clone() { + let _ = s.send(InstallStatus::InProgress { + tool: "Gleam".to_string(), + step: "Downloading Gleam...".to_string(), + progress: 0.2 + (installed_count as f32 / total_to_install as f32) * 0.6, + }); + } + Self::download_gleam(&app_dir, sender.clone()).await?; + installed_count += 1; + } else { + if let Some(ref s) = sender.clone() { + let _ = s.send(InstallStatus::InProgress { + tool: "Gleam".to_string(), + step: "Done!".to_string(), + progress: 1.0, + }); + } + installed_count += 1; } if !bun_available { - Self::download_bun(&app_dir).await?; + if let Some(ref s) = sender.clone() { + let _ = s.send(InstallStatus::InProgress { + tool: "Bun".to_string(), + step: "Downloading Bun...".to_string(), + progress: 0.2 + (installed_count as f32 / total_to_install as f32) * 0.6, + }); + } + Self::download_bun(&app_dir, sender.clone()).await?; + installed_count += 1; + } else { + if let Some(ref s) = sender.clone() { + let _ = s.send(InstallStatus::InProgress { + tool: "Bun".to_string(), + step: "Done!".to_string(), + progress: 1.0, + }); + } + installed_count += 1; } if !javy_available { - Self::download_javy(&app_dir).await?; + if let Some(ref s) = sender.clone() { + let _ = s.send(InstallStatus::InProgress { + tool: "Javy".to_string(), + step: "Downloading Javy...".to_string(), + progress: 0.2 + (installed_count as f32 / total_to_install as f32) * 0.6, + }); + } + Self::download_javy(&app_dir, sender.clone()).await?; + installed_count += 1; + } else { + if let Some(ref s) = sender.clone() { + let _ = s.send(InstallStatus::InProgress { + tool: "Javy".to_string(), + step: "Done!".to_string(), + progress: 1.0, + }); + } + installed_count += 1; } + if let Some(ref s) = sender.clone() { + let _ = s.send(InstallStatus::Success); + } + + println!("All {} dependencies installed successfully", installed_count); Ok(()) } @@ -87,7 +166,7 @@ impl GleamScriptCompiler { } } - pub async fn download_gleam(app_dir: &PathBuf) -> anyhow::Result<()> { + pub async fn download_gleam(app_dir: &PathBuf, sender: Option<UnboundedSender<InstallStatus>>) -> anyhow::Result<()> { let gleam_dir = app_dir.join("dependencies").join("gleam").join(GLEAM_VERSION); if gleam_dir.exists() { @@ -98,13 +177,13 @@ impl GleamScriptCompiler { println!("Downloading Gleam v{}...", GLEAM_VERSION); let gleam_link = Self::get_gleam_download_url()?; - Self::download_and_extract(&gleam_link, &gleam_dir, "gleam").await?; + Self::download_and_extract(&gleam_link, &gleam_dir, "gleam", sender).await?; println!("Gleam v{} downloaded successfully", GLEAM_VERSION); Ok(()) } - pub async fn download_bun(app_dir: &PathBuf) -> anyhow::Result<()> { + pub async fn download_bun(app_dir: &PathBuf, sender: Option<UnboundedSender<InstallStatus>>) -> anyhow::Result<()> { let bun_dir = app_dir.join("dependencies").join("bun").join(BUN_VERSION); if bun_dir.exists() { @@ -115,13 +194,13 @@ impl GleamScriptCompiler { println!("Downloading Bun v{}...", BUN_VERSION); let bun_link = Self::get_bun_download_url()?; - Self::download_and_extract(&bun_link, &bun_dir, "bun").await?; + Self::download_and_extract(&bun_link, &bun_dir, "bun", sender).await?; println!("Bun v{} downloaded successfully", BUN_VERSION); Ok(()) } - pub async fn download_javy(app_dir: &PathBuf) -> anyhow::Result<()> { + pub async fn download_javy(app_dir: &PathBuf, sender: Option<UnboundedSender<InstallStatus>>) -> anyhow::Result<()> { let javy_dir = app_dir.join("dependencies").join("javy").join(JAVY_VERSION); if javy_dir.exists() { @@ -132,24 +211,70 @@ impl GleamScriptCompiler { println!("Downloading Javy v{}...", JAVY_VERSION); let javy_link = Self::get_javy_download_url()?; - Self::download_and_extract(&javy_link, &javy_dir, "javy").await?; + Self::download_and_extract(&javy_link, &javy_dir, "javy", sender).await?; println!("Javy v{} downloaded successfully", JAVY_VERSION); Ok(()) } - async fn download_and_extract(url: &str, target_dir: &PathBuf, tool_name: &str) -> anyhow::Result<()> { + async fn download_and_extract( + url: &str, + target_dir: &PathBuf, + tool_name: &str, + sender: Option<UnboundedSender<InstallStatus>> + ) -> anyhow::Result<()> { + if let Some(ref s) = sender { + let _ = s.send(InstallStatus::InProgress { + step: format!("Creating directories for {}...", tool_name), + progress: 0.0, + tool: tool_name.to_string(), + }); + } + fs::create_dir_all(target_dir).await?; - + + if let Some(ref s) = sender { + let _ = s.send(InstallStatus::InProgress { + step: format!("Downloading {}...", tool_name), + progress: 0.3, + tool: tool_name.to_string(), + }); + } + let response = reqwest::get(url).await?; - let bytes = response.bytes().await?; - + let total_size = response.content_length().unwrap_or(0); + let mut downloaded = 0; + let mut stream = response.bytes_stream(); + let temp_file = target_dir.join(format!("{}_download", tool_name)); let mut file = fs::File::create(&temp_file).await?; - file.write_all(&bytes).await?; + + while let Some(item) = stream.next().await { + let bytes = item?; + file.write_all(&bytes).await?; + downloaded += bytes.len() as u64; + + if let Some(ref s) = sender { + let progress = 0.3 + (downloaded as f32 / total_size as f32) * 0.4; + let _ = s.send(InstallStatus::InProgress { + step: format!("Downloading {}...", tool_name), + progress, + tool: tool_name.to_string(), + }); + } + } + file.sync_all().await?; drop(file); + if let Some(ref s) = sender { + let _ = s.send(InstallStatus::InProgress { + step: format!("Extracting {}...", tool_name), + progress: 0.7, + tool: tool_name.to_string(), + }); + } + if url.ends_with(".zip") { Self::extract_zip(&temp_file, target_dir).await?; } else if url.ends_with(".tar.gz") { @@ -159,6 +284,15 @@ impl GleamScriptCompiler { } fs::remove_file(&temp_file).await?; + + if let Some(ref s) = sender { + let _ = s.send(InstallStatus::InProgress { + step: format!("{} installation complete", tool_name), + progress: 0.9, + tool: tool_name.to_string(), + }); + } + Ok(()) } @@ -402,5 +536,5 @@ impl GleamScriptCompiler { #[tokio::test] async fn check_if_dependencies_install() { - GleamScriptCompiler::ensure_dependencies().await.unwrap(); + GleamScriptCompiler::ensure_dependencies(None).await.unwrap(); } @@ -1,249 +1,180 @@ //! Used to aid with debugging any issues with the editor. use crate::editor::Signal; -use egui::{Ui, Window, ProgressBar}; -use eucalyptus_core::scripting::build::GleamScriptCompiler; +use egui::Ui; +use egui::ProgressBar; +use egui::Window; +use eucalyptus_core::scripting::build::{GleamScriptCompiler, InstallStatus}; use tokio::sync::mpsc; -#[derive(Debug, Clone)] -pub enum DependencyProgress { - Starting, - CheckingPath(String), - Downloading(String), - Extracting(String), - Completed(String), - Error(String), - Finished, -} - pub struct DependencyInstaller { - pub progress_receiver: Option<mpsc::UnboundedReceiver<DependencyProgress>>, - pub current_progress: Vec<String>, + pub progress_receiver: Option<mpsc::UnboundedReceiver<InstallStatus>>, pub is_installing: bool, - pub progress_value: f32, + + pub gleam_progress: f32, + pub bun_progress: f32, + pub javy_progress: f32, + + pub gleam_status: String, + pub bun_status: String, + pub javy_status: String, } impl Default for DependencyInstaller { fn default() -> Self { Self { progress_receiver: None, - current_progress: Vec::new(), is_installing: false, - progress_value: 0.0, + gleam_progress: 0.0, + bun_progress: 0.0, + javy_progress: 0.0, + gleam_status: "Not started".to_string(), + bun_status: "Not started".to_string(), + javy_status: "Not started".to_string(), } } } -/// Show a menu bar for debug. A new "Debug" menu button will show up on the editors menu bar. -pub(crate) fn show_menu_bar(ui: &mut Ui, signal: &mut Signal, dependency_installer: &mut DependencyInstaller) { - ui.menu_button("Debug", |ui_debug| { - if ui_debug.button("Panic").clicked() { - log::warn!("Panic caused on purpose from Menu Button Click"); - panic!("Testing out panicking with new panic module, this is a test") - } - - if ui_debug.button("Show Entities Loaded").clicked() { - log::info!("Show Entities Loaded under Debug Menu is clicked"); - *signal = Signal::LogEntities; - } - - ui_debug.add_enabled_ui(!dependency_installer.is_installing, |ui| { - if ui.button("Ensure dependencies").clicked() { - log::info!("Clicked ensure dependencies from debug menu"); - start_dependency_installation(dependency_installer); - } - }); - - if ui_debug.button("Evaluate script").clicked() { - log::info!("Evaluating script"); - } - }); -} - -pub(crate) fn show_dependency_progress_window( - ctx: &egui::Context, - dependency_installer: &mut DependencyInstaller, -) { - if let Some(receiver) = &mut dependency_installer.progress_receiver { - while let Ok(progress) = receiver.try_recv() { - match &progress { - DependencyProgress::Starting => { - dependency_installer.current_progress.clear(); - dependency_installer.current_progress.push("Starting dependency check...".to_string()); - dependency_installer.progress_value = 0.0; - } - DependencyProgress::CheckingPath(tool) => { - dependency_installer.current_progress.push(format!("Checking if {} is in PATH...", tool)); - dependency_installer.progress_value = 0.1; - } - DependencyProgress::Downloading(tool) => { - dependency_installer.current_progress.push(format!("Downloading {}...", tool)); - dependency_installer.progress_value += 0.25; - } - DependencyProgress::Extracting(tool) => { - dependency_installer.current_progress.push(format!("Extracting {}...", tool)); - dependency_installer.progress_value += 0.1; - } - DependencyProgress::Completed(tool) => { - dependency_installer.current_progress.push(format!("✓ {} ready", tool)); - dependency_installer.progress_value += 0.1; - } - DependencyProgress::Error(error) => { - dependency_installer.current_progress.push(format!("❌ Error: {}", error)); - } - DependencyProgress::Finished => { - dependency_installer.current_progress.push("✓ All dependencies ready!".to_string()); - dependency_installer.progress_value = 1.0; - dependency_installer.is_installing = false; - // dependency_installer.progress_receiver = None; +impl DependencyInstaller { + pub fn update_progress(&mut self) { + let mut local_prog_rec = false; + let mut update_tool_status: (bool, String, f32, String) = Default::default(); + if let Some(receiver) = &mut self.progress_receiver { + while let Ok(status) = receiver.try_recv() { + match status { + InstallStatus::NotStarted => { + self.is_installing = false; + } + InstallStatus::InProgress { tool, step, progress } => { + self.is_installing = true; + update_tool_status = (true, String::from(&tool), progress, String::from(&step)); + } + InstallStatus::Success => { + self.is_installing = false; + local_prog_rec = true; + self.gleam_status = "Complete".to_string(); + self.gleam_progress = 1.0; + self.bun_status = "Complete".to_string(); + self.bun_progress = 1.0; + self.javy_status = "Complete".to_string(); + self.javy_progress = 1.0; + } + InstallStatus::Failed(msg) => { + self.is_installing = false; + log::error!("Installation error: {}", msg); + self.gleam_status = format!("Error: {}", msg); + self.bun_status = format!("Error: {}", msg); + self.javy_status = format!("Error: {}", msg); + } } } } - } - - if dependency_installer.is_installing || !dependency_installer.current_progress.is_empty() { - Window::new("Dependency Installation") - .collapsible(false) - .resizable(false) - .show(ctx, |ui| { - ui.vertical(|ui| { - ui.add( - ProgressBar::new(dependency_installer.progress_value) - .show_percentage() - .animate(dependency_installer.is_installing) - ); - - ui.separator(); - - egui::ScrollArea::vertical() - .max_height(200.0) - .show(ui, |ui| { - for message in &dependency_installer.current_progress { - ui.label(message); - } - }); - - if !dependency_installer.is_installing && ui.button("Close").clicked() { - dependency_installer.current_progress.clear(); - } - }); - }); - } -} - -fn start_dependency_installation(dependency_installer: &mut DependencyInstaller) { - let (sender, receiver) = mpsc::unbounded_channel(); - dependency_installer.progress_receiver = Some(receiver); - dependency_installer.is_installing = true; - dependency_installer.progress_value = 0.0; - - tokio::spawn(async move { - let _ = sender.send(DependencyProgress::Starting); - - match ensure_dependencies_with_progress(sender.clone()).await { - Ok(_) => { - let _ = sender.send(DependencyProgress::Finished); - } - Err(e) => { - let _ = sender.send(DependencyProgress::Error(e.to_string())); - let _ = sender.send(DependencyProgress::Finished); - } + if local_prog_rec { + self.progress_receiver = None; } - }); -} - -async fn ensure_dependencies_with_progress( - progress_sender: mpsc::UnboundedSender<DependencyProgress>, -) -> anyhow::Result<()> { - let tools = vec![ - ("gleam", "Gleam"), - ("bun", "Bun"), - ("javy", "Javy"), - ]; - - let mut tools_to_download = Vec::new(); - - for (tool_cmd, tool_name) in &tools { - let _ = progress_sender.send(DependencyProgress::CheckingPath(tool_name.to_string())); - - let available = check_tool_in_path(tool_cmd).await; - if !available { - tools_to_download.push((*tool_cmd, *tool_name)); - } else { - let _ = progress_sender.send(DependencyProgress::Completed(format!("{} (found in PATH)", tool_name))); + if update_tool_status.0 { + self.update_tool_status(update_tool_status.1.as_str(), update_tool_status.2, update_tool_status.3.as_str()); } } - - if tools_to_download.is_empty() { - return Ok(()); - } - - let app_dir = app_dirs2::app_dir(app_dirs2::AppDataType::UserData, &eucalyptus_core::scripting::build::APP_INFO, "") - .map_err(|e| anyhow::anyhow!("Failed to get app directory: {}", e))?; - - for (tool_cmd, tool_name) in tools_to_download { - let _ = progress_sender.send(DependencyProgress::Downloading(tool_name.to_string())); - - match tool_cmd { + + fn update_tool_status(&mut self, tool: &str, progress: f32, status: &str) { + match tool.to_lowercase().as_str() { "gleam" => { - if let Err(e) = download_gleam_with_progress(&app_dir, progress_sender.clone()).await { - let _ = progress_sender.send(DependencyProgress::Error(format!("Failed to download Gleam: {}", e))); - return Err(e); - } + self.gleam_progress = progress; + self.gleam_status = status.to_string(); } "bun" => { - if let Err(e) = download_bun_with_progress(&app_dir, progress_sender.clone()).await { - let _ = progress_sender.send(DependencyProgress::Error(format!("Failed to download Bun: {}", e))); - return Err(e); - } + self.bun_progress = progress; + self.bun_status = status.to_string(); } "javy" => { - if let Err(e) = download_javy_with_progress(&app_dir, progress_sender.clone()).await { - let _ = progress_sender.send(DependencyProgress::Error(format!("Failed to download Javy: {}", e))); - return Err(e); - } + self.javy_progress = progress; + self.javy_status = status.to_string(); } _ => {} } - - let _ = progress_sender.send(DependencyProgress::Completed(tool_name.to_string())); } - - Ok(()) -} -async fn check_tool_in_path(tool: &str) -> bool { - let cmd = if cfg!(target_os = "windows") { - std::process::Command::new("where").arg(tool).output() - } else { - std::process::Command::new("which").arg(tool).output() - }; + pub fn show_installation_window(&mut self, ctx: &egui::Context) { + Window::new("Installing Dependencies") + .resizable(true) + .collapsible(false) + .default_width(400.0) + .show(ctx, |ui| { + ui.heading("Installing Dependencies"); + + ui.separator(); + + ui.label("Gleam:"); + ui.label(&self.gleam_status); + ui.add(ProgressBar::new(self.gleam_progress).show_percentage()); + ui.separator(); + + ui.label("Bun:"); + ui.label(&self.bun_status); + ui.add(ProgressBar::new(self.bun_progress).show_percentage()); + ui.separator(); + + ui.label("Javy:"); + ui.label(&self.javy_status); + ui.add(ProgressBar::new(self.javy_progress).show_percentage()); + ui.separator(); - match cmd { - Ok(output) => output.status.success(), - Err(_) => false, + let overall_progress = (self.gleam_progress + self.bun_progress + self.javy_progress) / 3.0; + ui.label("Overall Progress:"); + ui.add(ProgressBar::new(overall_progress).show_percentage()); + + ui.separator(); + + if ui.button("Cancel").clicked() { + self.is_installing = false; + self.progress_receiver = None; + } + }); } } -async fn download_gleam_with_progress( - app_dir: &std::path::PathBuf, - progress_sender: mpsc::UnboundedSender<DependencyProgress>, -) -> anyhow::Result<()> { - let _ = progress_sender.send(DependencyProgress::Extracting("Gleam".to_string())); - GleamScriptCompiler::download_gleam(app_dir).await -} +pub(crate) fn show_menu_bar(ui: &mut Ui, signal: &mut Signal, dependency_installer: &mut DependencyInstaller) { + ui.menu_button("Debug", |ui_debug| { + if ui_debug.button("Panic").clicked() { + log::warn!("Panic caused on purpose from Menu Button Click"); + panic!("Testing out panicking with new panic module, this is a test") + } -async fn download_bun_with_progress( - app_dir: &std::path::PathBuf, - progress_sender: mpsc::UnboundedSender<DependencyProgress>, -) -> anyhow::Result<()> { - let _ = progress_sender.send(DependencyProgress::Extracting("Bun".to_string())); - GleamScriptCompiler::download_bun(app_dir).await -} + if ui_debug.button("Show Entities Loaded").clicked() { + log::info!("Show Entities Loaded under Debug Menu is clicked"); + *signal = Signal::LogEntities; + } -async fn download_javy_with_progress( - app_dir: &std::path::PathBuf, - progress_sender: mpsc::UnboundedSender<DependencyProgress>, -) -> anyhow::Result<()> { - let _ = progress_sender.send(DependencyProgress::Extracting("Javy".to_string())); - GleamScriptCompiler::download_javy(app_dir).await + ui_debug.add_enabled_ui(!dependency_installer.is_installing, |ui| { + if ui.button("Ensure dependencies").clicked() { + log::info!("Clicked ensure dependencies from debug menu"); + + let (sender, receiver) = mpsc::unbounded_channel(); + dependency_installer.progress_receiver = Some(receiver); + dependency_installer.is_installing = true; + + dependency_installer.gleam_progress = 0.0; + dependency_installer.bun_progress = 0.0; + dependency_installer.javy_progress = 0.0; + dependency_installer.gleam_status = "Starting...".to_string(); + dependency_installer.bun_status = "Starting...".to_string(); + dependency_installer.javy_status = "Starting...".to_string(); + + tokio::task::spawn(async move { + match GleamScriptCompiler::ensure_dependencies(Some(sender.clone())).await { + Ok(_) => { + let _ = sender.send(InstallStatus::Success); + } + Err(e) => { + let _ = sender.send(InstallStatus::Failed(e.to_string())); + } + } + }); + } + }); + + if ui_debug.button("Evaluate script").clicked() { + log::info!("Evaluating script"); + } + }); } @@ -18,7 +18,7 @@ use log; use parking_lot::Mutex; use transform_gizmo_egui::{ EnumSet, Gizmo, GizmoConfig, GizmoExt, GizmoMode, - math::{DMat4, DVec3}, + math::DVec3, }; pub struct EditorTabViewer<'a> { @@ -360,30 +360,8 @@ impl<'a> TabViewer for EditorTabViewer<'a> { { if let Some((camera, _, _)) = q.get() { self.gizmo.update_config(GizmoConfig { - view_matrix: DMat4::look_at_lh( - DVec3::new( - camera.eye.x as f64, - camera.eye.y as f64, - camera.eye.z as f64, - ), - DVec3::new( - camera.target.x as f64, - camera.target.y as f64, - camera.target.z as f64, - ), - DVec3::new( - camera.up.x as f64, - camera.up.y as f64, - camera.up.z as f64, - ), - ) - .into(), - projection_matrix: DMat4::perspective_infinite_reverse_lh( - camera.fov_y as f64, - display_width as f64 / display_height as f64, - camera.znear as f64, - ) - .into(), + view_matrix: camera.view_mat.into(), + projection_matrix: camera.proj_mat.into(), viewport: image_rect, modes: *self.gizmo_mode, orientation: transform_gizmo_egui::GizmoOrientation::Global, @@ -326,7 +326,7 @@ impl Editor { Ok(()) } - pub fn show_ui(&mut self, ctx: &Context) { + pub async fn show_ui(&mut self, ctx: &Context) { egui::TopBottomPanel::top("menu_bar").show(ctx, |ui| { egui::MenuBar::new().ui(ui, |ui| { ui.menu_button("File", |ui| { @@ -547,7 +547,7 @@ impl Scene for Editor { script.path.display() ); - let bytes = match std::fs::read(&script.path) { + let bytes = match tokio::fs::read(&script.path).await { Ok(val) => val, Err(e) => { fatal!("Unable to read script {} to bytes because {}", &script.path.display(), e); @@ -937,7 +937,8 @@ impl Scene for Editor { } } Signal::LogEntities => { - log::info!("===================="); + log::debug!("===================="); + let mut counter = 0; for entity in Arc::get_mut(&mut self.world).unwrap().iter() { if let Some(entity) = entity.get::<&AdoptedEntity>() { log::info!("Model: {:?}", entity.label()); @@ -946,8 +947,10 @@ impl Scene for Editor { if let Some(entity) = entity.get::<&Light>() { log::info!("Light: {:?}", entity.label()); } + counter += 1; } - log::info!("===================="); + log::debug!("===================="); + info!("Total entity count: {}", counter); self.signal = Signal::None; }, Signal::Spawn(entity_type) => { @@ -1062,7 +1065,10 @@ impl Scene for Editor { self.light_manager.update(graphics.shared.clone(), &Arc::get_mut(&mut self.world).unwrap()); - crate::debug::show_dependency_progress_window(&graphics.shared.get_egui_context(), &mut self.dep_installer); + if self.dep_installer.is_installing { + self.dep_installer.show_installation_window(&mut graphics.shared.get_egui_context()); + } + self.dep_installer.update_progress(); } async fn render<'a>(&mut self, graphics: &mut RenderContext<'a>) { @@ -1077,7 +1083,7 @@ impl Scene for Editor { self.color = color.clone(); self.size = graphics.shared.viewport_texture.size.clone(); self.texture_id = Some(*graphics.shared.texture_id.clone()); - self.show_ui(&graphics.shared.get_egui_context()); + self.show_ui(&graphics.shared.get_egui_context()).await; self.window = Some(graphics.shared.window.clone()); logging::render(&graphics.shared.get_egui_context()); @@ -136,6 +136,7 @@ async fn main() -> anyhow::Result<()> { (scene_manager, input_manager) }) + .await .unwrap(); } _ => unreachable!(),