From 058cd57ed2d18d6e14408881c3229fab7edbadb1 Mon Sep 17 00:00:00 2001 From: yum Date: Sun, 5 Mar 2023 16:26:18 -0800 Subject: Animator generation and dumping mics no longer hang GUI Do these in a std::future. * SetAffinityMask() now returns a value on all control paths --- GUI/GUI/GUI/Frame.cpp | 210 ++++++++++++++++++++++++------------------ GUI/GUI/GUI/Frame.h | 5 +- GUI/GUI/GUI/PythonWrapper.cpp | 1 + TaSTT-Whisper | 2 +- 4 files changed, 126 insertions(+), 92 deletions(-) diff --git a/GUI/GUI/GUI/Frame.cpp b/GUI/GUI/GUI/Frame.cpp index e4b1e13..f32f658 100644 --- a/GUI/GUI/GUI/Frame.cpp +++ b/GUI/GUI/GUI/Frame.cpp @@ -339,6 +339,16 @@ Frame::Frame() py_app_ = p.get_future(); p.set_value(true); } + { + auto p = std::promise(); + unity_app_ = p.get_future(); + p.set_value(true); + } + { + auto p = std::promise(); + dump_mics_ = p.get_future(); + p.set_value(true); + } auto* main_panel = new wxPanel(this, ID_MAIN_PANEL); main_panel_ = main_panel; @@ -1498,17 +1508,27 @@ void Frame::OnSetupPython(wxCommandEvent& event) void Frame::OnDumpMics(wxCommandEvent& event) { - Log(transcribe_out_, "{}\n", PythonWrapper::DumpMics()); + auto status = dump_mics_.wait_for(std::chrono::seconds(0)); + if (status != std::future_status::ready) { + Log(transcribe_out_, "Mic dump already running\n"); + return; + } + dump_mics_ = std::move(std::async(std::launch::async, [&]() { + Log(transcribe_out_, "Getting mics...\n"); + Log(transcribe_out_, "{}\n", PythonWrapper::DumpMics()); + return true; + })); } -bool GetUserPath(const std::string& raw, std::filesystem::path& clean, +bool GetUserPath(wxTextCtrl* out, + const std::string& raw, std::filesystem::path& clean, const std::string& err_prefix = "", bool must_exist = true) { clean = raw; if (must_exist && !std::filesystem::exists(clean)) { std::ostringstream oss; oss << err_prefix << ": User-provided path does not exist at " << clean << std::endl; - wxLogError(oss.str().c_str()); + Log(out, oss.str().c_str()); return false; } return true; @@ -1516,95 +1536,109 @@ bool GetUserPath(const std::string& raw, std::filesystem::path& clean, void Frame::OnGenerateFX(wxCommandEvent& event) { - std::filesystem::path unity_assets_path; - if (!GetUserPath(unity_assets_file_picker_->GetPath().ToStdString(), - unity_assets_path, - "Cannot generate FX layer: Failed to validate assets directory")) { - return; - } - std::filesystem::path unity_animator_path; - if (!GetUserPath(unity_animator_file_picker_->GetPath().ToStdString(), - unity_animator_path, - "Cannot generate FX layer: Failed to validate animator directory")) { - return; - } - std::filesystem::path unity_parameters_path; - if (!GetUserPath(unity_parameters_file_picker_->GetPath().ToStdString(), - unity_parameters_path, - "Cannot generate FX layer: Failed to validate parameters directory")) { - return; - } - std::filesystem::path unity_menu_path; - if (!GetUserPath(unity_menu_file_picker_->GetPath().ToStdString(), - unity_menu_path, - "Cannot generate FX layer: Failed to validate menu directory")) { - return; - } + auto status = unity_app_.wait_for(std::chrono::seconds(0)); + if (status != std::future_status::ready) { + Log(unity_out_, "Unity process already running\n"); + return; + } - std::string unity_animator_generated_dir = - unity_animator_generated_dir_->GetLineText(0).ToStdString(); - std::string unity_animator_generated_name = - unity_animator_generated_name_->GetLineText(0).ToStdString(); - std::string unity_parameters_generated_name = - unity_parameters_generated_name_->GetLineText(0).ToStdString(); - std::string unity_menu_generated_name = - unity_menu_generated_name_->GetLineText(0).ToStdString(); + unity_app_ = std::move(std::async(std::launch::async, [&]() { + Log(unity_out_, "Generating animator\n"); - int chars_per_sync_idx = unity_chars_per_sync_->GetSelection(); - if (chars_per_sync_idx == wxNOT_FOUND) { - chars_per_sync_idx = kCharsDefault; - } - std::string chars_per_sync_str = - kCharsPerSync[chars_per_sync_idx].ToStdString(); - int bytes_per_char_idx = unity_bytes_per_char_->GetSelection(); - if (bytes_per_char_idx == wxNOT_FOUND) { - bytes_per_char_idx = kBytesDefault; - } - std::string bytes_per_char_str = - kBytesPerChar[bytes_per_char_idx].ToStdString(); - - std::string rows_str = unity_rows_->GetValue().ToStdString(); - std::string cols_str = unity_cols_->GetValue().ToStdString(); - int rows, cols, bytes_per_char, chars_per_sync; - try { - rows = std::stoi(rows_str); - cols = std::stoi(cols_str); - bytes_per_char = std::stoi(bytes_per_char_str); - chars_per_sync = std::stoi(chars_per_sync_str); - } - catch (const std::invalid_argument&) { - Log(unity_out_, "Could not parse rows \"{}\", cols \"{}\", bytes per " - "char \"{}\", or chars per sync \"{}\" as an integer\n", - rows_str, cols_str, bytes_per_char_str, chars_per_sync_str); - return; - } - catch (const std::out_of_range&) { - Log(unity_out_, "Rows \"{}\" or cols \"{}\" are out of range\n", - rows_str, cols_str); - return; - } + std::filesystem::path unity_assets_path; + if (!GetUserPath(unity_out_, + unity_assets_file_picker_->GetPath().ToStdString(), + unity_assets_path, + "Cannot generate FX layer: Failed to validate assets directory")) { + return false; + } + std::filesystem::path unity_animator_path; + if (!GetUserPath(unity_out_, + unity_animator_file_picker_->GetPath().ToStdString(), + unity_animator_path, + "Cannot generate FX layer: Failed to validate animator directory")) { + return false; + } + std::filesystem::path unity_parameters_path; + if (!GetUserPath(unity_out_, + unity_parameters_file_picker_->GetPath().ToStdString(), + unity_parameters_path, + "Cannot generate FX layer: Failed to validate parameters directory")) { + return false; + } + std::filesystem::path unity_menu_path; + if (!GetUserPath(unity_out_, unity_menu_file_picker_->GetPath().ToStdString(), + unity_menu_path, + "Cannot generate FX layer: Failed to validate menu directory")) { + return false; + } - app_c_->assets_path = unity_assets_path.string(); - app_c_->fx_path = unity_animator_path.string(); - app_c_->params_path = unity_parameters_path.string(); - app_c_->menu_path = unity_menu_path.string(); - app_c_->bytes_per_char = bytes_per_char; - app_c_->chars_per_sync = chars_per_sync; - app_c_->rows = rows; - app_c_->cols = cols; - app_c_->clear_osc = unity_clear_osc_->GetValue(); - app_c_->Serialize(AppConfig::kConfigPath); + std::string unity_animator_generated_dir = + unity_animator_generated_dir_->GetLineText(0).ToStdString(); + std::string unity_animator_generated_name = + unity_animator_generated_name_->GetLineText(0).ToStdString(); + std::string unity_parameters_generated_name = + unity_parameters_generated_name_->GetLineText(0).ToStdString(); + std::string unity_menu_generated_name = + unity_menu_generated_name_->GetLineText(0).ToStdString(); + + int chars_per_sync_idx = unity_chars_per_sync_->GetSelection(); + if (chars_per_sync_idx == wxNOT_FOUND) { + chars_per_sync_idx = kCharsDefault; + } + std::string chars_per_sync_str = + kCharsPerSync[chars_per_sync_idx].ToStdString(); + int bytes_per_char_idx = unity_bytes_per_char_->GetSelection(); + if (bytes_per_char_idx == wxNOT_FOUND) { + bytes_per_char_idx = kBytesDefault; + } + std::string bytes_per_char_str = + kBytesPerChar[bytes_per_char_idx].ToStdString(); + + std::string rows_str = unity_rows_->GetValue().ToStdString(); + std::string cols_str = unity_cols_->GetValue().ToStdString(); + int rows, cols, bytes_per_char, chars_per_sync; + try { + rows = std::stoi(rows_str); + cols = std::stoi(cols_str); + bytes_per_char = std::stoi(bytes_per_char_str); + chars_per_sync = std::stoi(chars_per_sync_str); + } + catch (const std::invalid_argument&) { + Log(unity_out_, "Could not parse rows \"{}\", cols \"{}\", bytes per " + "char \"{}\", or chars per sync \"{}\" as an integer\n", + rows_str, cols_str, bytes_per_char_str, chars_per_sync_str); + return false; + } + catch (const std::out_of_range&) { + Log(unity_out_, "Rows \"{}\" or cols \"{}\" are out of range\n", + rows_str, cols_str); + return false; + } - std::string out; - if (!PythonWrapper::GenerateAnimator( - *app_c_, - unity_animator_generated_dir, - unity_animator_generated_name, - unity_parameters_generated_name, - unity_menu_generated_name, - unity_out_)) { - wxLogError("Failed to generate animator:\n%s\n", out.c_str()); - } + app_c_->assets_path = unity_assets_path.string(); + app_c_->fx_path = unity_animator_path.string(); + app_c_->params_path = unity_parameters_path.string(); + app_c_->menu_path = unity_menu_path.string(); + app_c_->bytes_per_char = bytes_per_char; + app_c_->chars_per_sync = chars_per_sync; + app_c_->rows = rows; + app_c_->cols = cols; + app_c_->clear_osc = unity_clear_osc_->GetValue(); + app_c_->Serialize(AppConfig::kConfigPath); + + std::string out; + if (!PythonWrapper::GenerateAnimator( + *app_c_, + unity_animator_generated_dir, + unity_animator_generated_name, + unity_parameters_generated_name, + unity_menu_generated_name, + unity_out_)) { + Log(unity_out_, "Failed to generate animator:\n%s\n", out.c_str()); + } + return true; + })); } void Frame::OnListPip(wxCommandEvent& event) diff --git a/GUI/GUI/GUI/Frame.h b/GUI/GUI/GUI/Frame.h index 39988ef..91ec62d 100644 --- a/GUI/GUI/GUI/Frame.h +++ b/GUI/GUI/GUI/Frame.h @@ -79,13 +79,12 @@ private: std::future py_app_; bool run_py_app_; + std::future unity_app_; + std::future dump_mics_; wxProcess* env_proc_; wxTimer py_app_drain_; - wxProcess* whisper_app_; - wxTimer whisper_app_drain_; - std::unique_ptr app_c_; std::unique_ptr whisper_; diff --git a/GUI/GUI/GUI/PythonWrapper.cpp b/GUI/GUI/GUI/PythonWrapper.cpp index d5636ce..c4b2b55 100644 --- a/GUI/GUI/GUI/PythonWrapper.cpp +++ b/GUI/GUI/GUI/PythonWrapper.cpp @@ -151,6 +151,7 @@ bool SetAffinityMask( out_cb(oss.str(), ""); } } + return true; } bool PythonWrapper::InvokeCommandWithArgs(const std::string& cmd, diff --git a/TaSTT-Whisper b/TaSTT-Whisper index 8050fba..a74ee78 160000 --- a/TaSTT-Whisper +++ b/TaSTT-Whisper @@ -1 +1 @@ -Subproject commit 8050fba80e08dc2d107944fb20da7028dc73d059 +Subproject commit a74ee78dbb79c551851dc182090e7d4292b1e80c -- cgit v1.2.3