Skip to content

Commit 1c39fc0

Browse files
committed
fix progress bar bug
1 parent d3689d9 commit 1c39fc0

2 files changed

Lines changed: 55 additions & 5 deletions

File tree

src/hydrochrono_runner/run_hydrochrono_from_yaml.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <sstream>
2424
#include <chrono>
2525
#include <iomanip>
26+
#include <cmath>
2627

2728
#ifdef _WIN32
2829
#include <windows.h>
@@ -697,6 +698,14 @@ int RunHydroChronoFromYAML(int argc, char* argv[]) {
697698

698699
if (nogui) {
699700
const double end_time_bound = (yaml_end_time > 0.0) ? yaml_end_time : 40.0;
701+
// Estimate total steps for progress bar; ensure at least 1
702+
const double remaining_time = std::max(0.0, end_time_bound - initial_time);
703+
const size_t total_steps_est = static_cast<size_t>(std::max(1.0, std::ceil(remaining_time / std::max(1e-12, loop_dt))));
704+
size_t last_progress_step = 0;
705+
706+
// Initial progress line
707+
hydroc::cli::ShowProgress(0, total_steps_est, std::string("t=") + hydroc::FormatNumber(initial_time, 2) + " / " + hydroc::FormatNumber(end_time_bound, 2) + " s");
708+
700709
while (system->GetChTime() < end_time_bound) {
701710
double current_time = system->GetChTime();
702711
try {
@@ -709,18 +718,33 @@ int RunHydroChronoFromYAML(int argc, char* argv[]) {
709718
exporter->RecordStep(system.get());
710719
if (profile_mode) { prof_export_seconds += std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::steady_clock::now() - t).count(); }
711720
}
721+
// Update progress periodically to reduce console churn
722+
if (step_count == 1 || step_count - static_cast<int>(last_progress_step) >= 25) {
723+
const size_t current_steps = static_cast<size_t>(std::min<double>(total_steps_est, std::ceil((system->GetChTime() - initial_time) / std::max(1e-12, loop_dt))));
724+
std::string msg = std::string("t=") + hydroc::FormatNumber(system->GetChTime(), 2) + " / " + hydroc::FormatNumber(end_time_bound, 2) + " s";
725+
hydroc::cli::ShowProgress(current_steps, total_steps_est, msg);
726+
last_progress_step = static_cast<size_t>(step_count);
727+
}
712728
previous_time = current_time;
713729
} catch (const std::exception& e) {
730+
hydroc::cli::StopProgress();
714731
hydroc::cli::LogError(std::string("🔥 Exception during DoStepDynamics at step ") + std::to_string(step_count) + ": " + e.what());
715732
hydroc::cli::LogError(std::string("Simulation time: ") + hydroc::FormatNumber(current_time, 6) + " s");
716733
hydroc::cli::LogError(std::string("Step size: ") + hydroc::FormatNumber(loop_dt, 6) + " s");
717734
break;
718735
} catch (...) {
736+
hydroc::cli::StopProgress();
719737
hydroc::cli::LogError(std::string("🔥 Unknown exception during DoStepDynamics at step ") + std::to_string(step_count));
720738
hydroc::cli::LogError(std::string("Simulation time: ") + hydroc::FormatNumber(current_time, 6) + " s");
721739
break;
722740
}
723741
}
742+
// Finalize progress line
743+
if (system->GetChTime() >= end_time_bound - 1e-9) {
744+
hydroc::cli::ShowProgress(total_steps_est, total_steps_est, "Completed");
745+
} else {
746+
hydroc::cli::StopProgress();
747+
}
724748
} else {
725749
// GUI-driven loop: respects pause via ui.simulationStarted and closes when window stops
726750
while (ui.IsRunning(loop_dt)) {

src/utils/logging.cpp

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,6 @@ class CLILogger {
168168
*/
169169
void StopProgress() noexcept {
170170
if (showing_progress_) {
171-
LoggingWriteGuard guard;
172171
if (!progress_completed_) {
173172
// Clear the in-place progress line only if not completed
174173
std::cerr << "\r";
@@ -255,8 +254,7 @@ class CLILogger {
255254
const int percentage = static_cast<int>(progress * 100);
256255
std::string progress_text = bar + std::string(" ") + std::to_string(percentage) + "%";
257256
if (!message.empty()) progress_text += std::string(" - ") + message;
258-
// Write in-place on the same console line using stderr, guarded to bypass interception
259-
LoggingWriteGuard guard;
257+
// Write in-place on the same console line using stderr; let interceptor handle quiet mode
260258
std::cerr << "\r" << progress_text;
261259
// Clear any remnants from a longer previous line
262260
int pad = std::max(0, progress_last_width_ - static_cast<int>(progress_text.size()));
@@ -460,6 +458,11 @@ namespace {
460458
// a newline (commonly used for in-place progress updates coming from
461459
// external libraries). We bypass the logger to preserve terminal state.
462460
if (buffer_.find('\r') != std::string::npos) {
461+
// Respect quiet mode: suppress CLI output entirely when disabled
462+
if (!g_initialized || !g_backend || !g_backend->GetConfig().enable_cli_output) {
463+
buffer_.clear();
464+
return;
465+
}
463466
if (original_) {
464467
original_->sputn(buffer_.data(), static_cast<std::streamsize>(buffer_.size()));
465468
}
@@ -469,16 +472,34 @@ namespace {
469472

470473
// If line looks like our own logger output (e.g., starts with '[' or begins with ANSI then '['), pass through
471474
if (!buffer_.empty() && (buffer_[0] == '[' || (buffer_[0] == '\033' && buffer_.find("[") != std::string::npos))) {
475+
// Respect quiet mode: suppress CLI output when disabled
476+
if (!g_initialized || !g_backend || !g_backend->GetConfig().enable_cli_output) {
477+
buffer_.clear();
478+
return;
479+
}
480+
// Heuristic: if it looks like a progress bar (e.g., contains '%'), render in-place without newline
481+
bool looks_like_progress = (buffer_.find('%') != std::string::npos);
472482
if (original_) {
473-
original_->sputn(buffer_.data(), static_cast<std::streamsize>(buffer_.size()));
474-
original_->sputc('\n');
483+
if (looks_like_progress) {
484+
original_->sputc('\r');
485+
original_->sputn(buffer_.data(), static_cast<std::streamsize>(buffer_.size()));
486+
// Do not append newline; UpdateProgressDisplay will manage padding and final newline
487+
} else {
488+
original_->sputn(buffer_.data(), static_cast<std::streamsize>(buffer_.size()));
489+
original_->sputc('\n');
490+
}
475491
}
476492
buffer_.clear();
477493
return;
478494
}
479495

480496
// Route or suppress external prints
481497
if (kind_ == StreamKind::StdOut) {
498+
// Respect quiet mode: suppress CLI output entirely when disabled
499+
if (!g_initialized || !g_backend || !g_backend->GetConfig().enable_cli_output) {
500+
buffer_.clear();
501+
return;
502+
}
482503
if (StartsWith(buffer_, "File: ")) {
483504
// Treat noisy OBJ path echoes as debug-only
484505
hydroc::debug::LogDebug(buffer_);
@@ -492,6 +513,11 @@ namespace {
492513
hydroc::cli::LogInfo(buffer_);
493514
}
494515
} else { // StdErr
516+
// Respect quiet mode: suppress CLI output entirely when disabled
517+
if (!g_initialized || !g_backend || !g_backend->GetConfig().enable_cli_output) {
518+
buffer_.clear();
519+
return;
520+
}
495521
if (buffer_.find("Cannot open colormap data file") != std::string::npos) {
496522
// Collect for Warnings section only; avoid inline duplication
497523
hydroc::cli::CollectWarning(buffer_);

0 commit comments

Comments
 (0)