mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 00:57:44 -04:00
tests: make the offline tests aware of the current terminals row count (#2105)
This fixes the hideous output when your terminal would be too small to hold all the threads.
This commit is contained in:
parent
f699675ede
commit
2f4146d469
|
@ -65,7 +65,10 @@
|
||||||
"--iso_data_path",
|
"--iso_data_path",
|
||||||
"${workspaceRoot}/iso_data/jak2",
|
"${workspaceRoot}/iso_data/jak2",
|
||||||
"--game",
|
"--game",
|
||||||
"jak2"
|
"jak2",
|
||||||
|
"--pretty-print",
|
||||||
|
"--num_threads",
|
||||||
|
"32"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,12 +46,13 @@ add_library(common
|
||||||
util/json_util.cpp
|
util/json_util.cpp
|
||||||
util/read_iso_file.cpp
|
util/read_iso_file.cpp
|
||||||
util/SimpleThreadGroup.cpp
|
util/SimpleThreadGroup.cpp
|
||||||
util/StringUtil.cpp
|
util/string_util.cpp
|
||||||
util/Timer.cpp
|
util/Timer.cpp
|
||||||
util/os.cpp
|
util/os.cpp
|
||||||
util/print_float.cpp
|
util/print_float.cpp
|
||||||
util/FrameLimiter.cpp
|
util/FrameLimiter.cpp
|
||||||
util/unicode_util.cpp)
|
util/unicode_util.cpp
|
||||||
|
util/term_util.cpp)
|
||||||
|
|
||||||
target_link_libraries(common fmt lzokay replxx libzstd_static)
|
target_link_libraries(common fmt lzokay replxx libzstd_static)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "StringUtil.h"
|
#include "string_util.h"
|
||||||
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
49
common/util/term_util.cpp
Normal file
49
common/util/term_util.cpp
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#include "term_util.h"
|
||||||
|
|
||||||
|
#if defined _WIN32
|
||||||
|
#define NOMINMAX
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
#elif defined(__LINUX__) || defined(__gnu_linux__) || defined(__linux__) || defined(__APPLE__)
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace term_util {
|
||||||
|
void clear() {
|
||||||
|
#if defined _WIN32
|
||||||
|
system("cls");
|
||||||
|
#elif defined(__LINUX__) || defined(__gnu_linux__) || defined(__linux__) || defined(__APPLE__)
|
||||||
|
system("clear");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int row_count() {
|
||||||
|
#if defined _WIN32
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||||
|
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
|
||||||
|
return csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
|
||||||
|
#elif defined(__LINUX__) || defined(__gnu_linux__) || defined(__linux__) || defined(__APPLE__)
|
||||||
|
struct winsize w;
|
||||||
|
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||||
|
return w.ws_row;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int col_count() {
|
||||||
|
#if defined _WIN32
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||||
|
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
|
||||||
|
return csbi.srWindow.Right - csbi.srWindow.Left + 1;
|
||||||
|
#elif defined(__LINUX__) || defined(__gnu_linux__) || defined(__linux__) || defined(__APPLE__)
|
||||||
|
struct winsize w;
|
||||||
|
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||||
|
return w.ws_col;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} // namespace term_util
|
7
common/util/term_util.h
Normal file
7
common/util/term_util.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
namespace term_util {
|
||||||
|
void clear();
|
||||||
|
int row_count();
|
||||||
|
int col_count();
|
||||||
|
} // namespace term_util
|
|
@ -4,8 +4,8 @@
|
||||||
#include "common/log/log.h"
|
#include "common/log/log.h"
|
||||||
#include "common/symbols.h"
|
#include "common/symbols.h"
|
||||||
#include "common/util/FileUtil.h"
|
#include "common/util/FileUtil.h"
|
||||||
#include "common/util/StringUtil.h"
|
|
||||||
#include "common/util/Timer.h"
|
#include "common/util/Timer.h"
|
||||||
|
#include "common/util/string_util.h"
|
||||||
|
|
||||||
#include "game/graphics/gfx.h"
|
#include "game/graphics/gfx.h"
|
||||||
#include "game/kernel/common/Ptr.h"
|
#include "game/kernel/common/Ptr.h"
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
#include "common/goos/ReplUtils.h"
|
#include "common/goos/ReplUtils.h"
|
||||||
#include "common/util/DgoWriter.h"
|
#include "common/util/DgoWriter.h"
|
||||||
#include "common/util/FileUtil.h"
|
#include "common/util/FileUtil.h"
|
||||||
#include "common/util/StringUtil.h"
|
|
||||||
#include "common/util/Timer.h"
|
#include "common/util/Timer.h"
|
||||||
|
#include "common/util/string_util.h"
|
||||||
|
|
||||||
#include "goalc/compiler/Compiler.h"
|
#include "goalc/compiler/Compiler.h"
|
||||||
#include "goalc/compiler/IR.h"
|
#include "goalc/compiler/IR.h"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "execution.h"
|
#include "execution.h"
|
||||||
|
|
||||||
#include "common/util/StringUtil.h"
|
|
||||||
#include "common/util/diff.h"
|
#include "common/util/diff.h"
|
||||||
|
#include "common/util/string_util.h"
|
||||||
|
|
||||||
#include "goalc/compiler/Compiler.h"
|
#include "goalc/compiler/Compiler.h"
|
||||||
#include "test/offline/config/config.h"
|
#include "test/offline/config/config.h"
|
||||||
|
|
|
@ -5,8 +5,9 @@
|
||||||
|
|
||||||
#include "common/log/log.h"
|
#include "common/log/log.h"
|
||||||
#include "common/util/FileUtil.h"
|
#include "common/util/FileUtil.h"
|
||||||
#include "common/util/StringUtil.h"
|
|
||||||
#include "common/util/diff.h"
|
#include "common/util/diff.h"
|
||||||
|
#include "common/util/string_util.h"
|
||||||
|
#include "common/util/term_util.h"
|
||||||
|
|
||||||
#include "decompiler/ObjectFile/ObjectFileDB.h"
|
#include "decompiler/ObjectFile/ObjectFileDB.h"
|
||||||
#include "test/offline/config/config.h"
|
#include "test/offline/config/config.h"
|
||||||
|
@ -201,6 +202,14 @@ void OfflineTestThreadStatus::complete_step() {
|
||||||
g_offline_test_thread_manager.print_current_test_status(config);
|
g_offline_test_thread_manager.print_current_test_status(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OfflineTestThreadStatus::in_progress() {
|
||||||
|
return stage == OfflineTestThreadStatus::Stage::IDLE ||
|
||||||
|
stage == OfflineTestThreadStatus::Stage::COMPARING ||
|
||||||
|
stage == OfflineTestThreadStatus::Stage::COMPILING ||
|
||||||
|
stage == OfflineTestThreadStatus::Stage::DECOMPILING ||
|
||||||
|
stage == OfflineTestThreadStatus::Stage::PREPARING;
|
||||||
|
}
|
||||||
|
|
||||||
std::tuple<fmt::color, std::string> thread_stage_to_str(OfflineTestThreadStatus::Stage stage) {
|
std::tuple<fmt::color, std::string> thread_stage_to_str(OfflineTestThreadStatus::Stage stage) {
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case OfflineTestThreadStatus::Stage::IDLE:
|
case OfflineTestThreadStatus::Stage::IDLE:
|
||||||
|
@ -254,23 +263,81 @@ std::string thread_progress_bar(u32 curr_step, u32 total_steps) {
|
||||||
return progress_bar;
|
return progress_bar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int OfflineTestThreadManager::num_threads_pending() {
|
||||||
|
int count = 0;
|
||||||
|
for (const auto& status : statuses) {
|
||||||
|
if (status->in_progress()) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
int OfflineTestThreadManager::num_threads_succeeded() {
|
||||||
|
int count = 0;
|
||||||
|
for (const auto& status : statuses) {
|
||||||
|
if (status->stage == OfflineTestThreadStatus::Stage::FINISHED) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
int OfflineTestThreadManager::num_threads_failed() {
|
||||||
|
int count = 0;
|
||||||
|
for (const auto& status : statuses) {
|
||||||
|
if (status->stage == OfflineTestThreadStatus::Stage::FAILED) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
void OfflineTestThreadManager::print_current_test_status(const OfflineTestConfig& config) {
|
void OfflineTestThreadManager::print_current_test_status(const OfflineTestConfig& config) {
|
||||||
if (!config.pretty_print) {
|
if (!config.pretty_print) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> guard(print_lock);
|
||||||
|
|
||||||
|
// Handle terminal height
|
||||||
|
auto rows_available = term_util::row_count();
|
||||||
|
// Truncate any threads we can't display
|
||||||
|
// - we need to leave 1 row to say how much we are hiding
|
||||||
|
int threads_to_display = ((rows_available - 2) / 2);
|
||||||
|
int threads_hidden = statuses.size() - threads_to_display;
|
||||||
|
int lines_to_clear = (threads_to_display * 2) + (threads_hidden == 0 ? 0 : 1);
|
||||||
|
|
||||||
// [DECOMP] ▰▰▰▰▰▰▱▱▱▱ (PRI, RUI, FOR, +3 more)
|
// [DECOMP] ▰▰▰▰▰▰▱▱▱▱ (PRI, RUI, FOR, +3 more)
|
||||||
// [1/30] - target-turret-shot // MUTED TEXT
|
// [1/30] - target-turret-shot // MUTED TEXT
|
||||||
std::lock_guard<std::mutex> guard(print_lock);
|
fmt::print("\x1b[{}A", lines_to_clear); // move n lines up
|
||||||
fmt::print("\x1b[{}A", g_offline_test_thread_manager.statuses.size() * 2); // move n lines up
|
fmt::print("\e[?25l"); // hide the cursor
|
||||||
for (const auto& status : g_offline_test_thread_manager.statuses) {
|
int threads_shown = 0;
|
||||||
|
for (int i = 0; i < statuses.size() && threads_shown < threads_to_display; i++) {
|
||||||
|
const auto& status = statuses.at(i);
|
||||||
|
// Skip completed threads if there are potential in-progress ones to show
|
||||||
|
if (threads_hidden != 0 && !status->in_progress() &&
|
||||||
|
(statuses.size() - i) > threads_to_display) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// first line
|
// first line
|
||||||
const auto [color, stage_text] = thread_stage_to_str(status->stage);
|
const auto [color, stage_text] = thread_stage_to_str(status->stage);
|
||||||
fmt::print(
|
fmt::print(
|
||||||
"\33[2K\r[{:>12}] {} ({})\n", fmt::styled(stage_text, fmt::fg(color)),
|
"\33[2K\r[{:>12}] {} ({}) [{}]\n", fmt::styled(stage_text, fmt::fg(color)),
|
||||||
fmt::styled(thread_progress_bar(status->curr_step, status->total_steps), fmt::fg(color)),
|
fmt::styled(thread_progress_bar(status->curr_step, status->total_steps), fmt::fg(color)),
|
||||||
thread_dgos_to_str(status->dgos));
|
thread_dgos_to_str(status->dgos), fmt::styled(i, fmt::fg(fmt::color::gray)));
|
||||||
// second line
|
// second line
|
||||||
fmt::print(fmt::fg(fmt::color::gray), "\33[2K\r{:>14} - {}\n",
|
fmt::print(fmt::fg(fmt::color::gray), "\33[2K\r{:>14} - {}\n",
|
||||||
fmt::format("[{}/{}]", status->curr_step, status->total_steps), status->curr_file);
|
fmt::format("[{}/{}]", status->curr_step, status->total_steps), status->curr_file);
|
||||||
|
threads_shown++;
|
||||||
}
|
}
|
||||||
|
if (threads_hidden != 0) {
|
||||||
|
fmt::print(
|
||||||
|
fmt::fg(fmt::color::gray), "\33[2K\r+{} other threads. [{} | {} | {}]\n", threads_hidden,
|
||||||
|
fmt::styled(g_offline_test_thread_manager.num_threads_pending(),
|
||||||
|
fmt::fg(fmt::color::orange)),
|
||||||
|
fmt::styled(g_offline_test_thread_manager.num_threads_failed(), fmt::fg(fmt::color::red)),
|
||||||
|
fmt::styled(g_offline_test_thread_manager.num_threads_succeeded(),
|
||||||
|
fmt::fg(fmt::color::light_green)));
|
||||||
|
}
|
||||||
|
fmt::print("\e[?25h"); // show the cursor
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,7 @@ class OfflineTestThreadStatus {
|
||||||
void update_stage(Stage new_stage);
|
void update_stage(Stage new_stage);
|
||||||
void update_curr_file(const std::string& _curr_file);
|
void update_curr_file(const std::string& _curr_file);
|
||||||
void complete_step();
|
void complete_step();
|
||||||
|
bool in_progress();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OfflineTestWorkCollection {
|
struct OfflineTestWorkCollection {
|
||||||
|
@ -109,10 +110,14 @@ struct OfflineTestWorkGroup {
|
||||||
|
|
||||||
class OfflineTestThreadManager {
|
class OfflineTestThreadManager {
|
||||||
public:
|
public:
|
||||||
void print_current_test_status(const OfflineTestConfig& config);
|
|
||||||
|
|
||||||
std::vector<std::shared_ptr<OfflineTestThreadStatus>> statuses = {};
|
std::vector<std::shared_ptr<OfflineTestThreadStatus>> statuses = {};
|
||||||
|
|
||||||
|
int num_threads_pending();
|
||||||
|
int num_threads_succeeded();
|
||||||
|
int num_threads_failed();
|
||||||
|
|
||||||
|
void print_current_test_status(const OfflineTestConfig& config);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::mutex print_lock;
|
std::mutex print_lock;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "common/log/log.h"
|
#include "common/log/log.h"
|
||||||
|
#include "common/util/term_util.h"
|
||||||
#include "common/util/unicode_util.h"
|
#include "common/util/unicode_util.h"
|
||||||
|
|
||||||
#include "config/config.h"
|
#include "config/config.h"
|
||||||
|
@ -12,17 +13,6 @@
|
||||||
#include "third-party/CLI11.hpp"
|
#include "third-party/CLI11.hpp"
|
||||||
#include "third-party/fmt/format.h"
|
#include "third-party/fmt/format.h"
|
||||||
|
|
||||||
// TODO - move this into a common lib eventually
|
|
||||||
void clear_terminal() {
|
|
||||||
#if defined _WIN32
|
|
||||||
system("cls");
|
|
||||||
#elif defined(__LINUX__) || defined(__gnu_linux__) || defined(__linux__)
|
|
||||||
system("clear");
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
// system("clear");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
ArgumentGuard u8_guard(argc, argv);
|
ArgumentGuard u8_guard(argc, argv);
|
||||||
|
|
||||||
|
@ -61,7 +51,7 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
if (pretty_print) {
|
if (pretty_print) {
|
||||||
lg::set_stdout_level(lg::level::off);
|
lg::set_stdout_level(lg::level::off);
|
||||||
clear_terminal();
|
term_util::clear();
|
||||||
}
|
}
|
||||||
lg::initialize();
|
lg::initialize();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue