diff --git a/src/btop.cpp b/src/btop.cpp index 1a35181..4722d17 100644 --- a/src/btop.cpp +++ b/src/btop.cpp @@ -141,16 +141,16 @@ void argumentParser(int argc, char **argv){ } } -//* Handler for SIGWINCH and general resizing events -void _resize(bool force=false){ - if (Term::refresh(false) or force) { +//* Handler for SIGWINCH and general resizing events, does nothing if terminal hasn't been resized unless force=true +void term_resize(bool force=false){ + if (auto refreshed = Term::refresh() or force) { + if (force and refreshed) force = false; Global::resized = true; Runner::stop(); - Term::refresh(); } else return; - while (true) { + while (not force) { sleep_ms(100); if (not Term::refresh()) break; } @@ -188,7 +188,7 @@ void _sleep(){ void _resume(){ Term::init(); if (not Global::debuginit) cout << Term::alt_screen << Term::hide_cursor << flush; - _resize(true); + term_resize(true); } void _exit_handler() { @@ -207,7 +207,7 @@ void _signal_handler(int sig) { _resume(); break; case SIGWINCH: - _resize(); + term_resize(); break; } } @@ -267,37 +267,34 @@ namespace Runner { string out; out.reserve(output.size()); - try { - for (auto& box : boxes) { - if (stopping) break; - try { - if (box == "cpu") { - out += Cpu::draw(Cpu::collect(no_update), force_redraw); - } - else if (box == "mem") { - out += Mem::draw(Mem::collect(no_update), force_redraw); - } - else if (box == "net") { - out += Net::draw(Net::collect(no_update), force_redraw); - } - else if (box == "proc") { - out += Proc::draw(Proc::collect(no_update), force_redraw); - } + for (auto& box : boxes) { + if (stopping) break; + try { + if (box == "cpu") { + out += Cpu::draw(Cpu::collect(no_update), force_redraw); } - catch (const std::exception& e) { - string fname = box; - fname[0] = toupper(fname[0]); - throw std::runtime_error(fname + "::draw(" + fname + "::collect(no_update=" + (no_update ? "true" : "false") - + "), force_redraw=" + (force_redraw ? "true" : "false") + ") : " + (string)e.what()); + else if (box == "mem") { + out += Mem::draw(Mem::collect(no_update), force_redraw); + } + else if (box == "net") { + out += Net::draw(Net::collect(no_update), force_redraw); + } + else if (box == "proc") { + out += Proc::draw(Proc::collect(no_update), force_redraw); } } - } - catch (std::exception& e) { - Global::exit_error_msg = "Exception in runner thread -> " + (string)e.what(); - Logger::error(Global::exit_error_msg); - Global::thread_exception = true; - Input::interrupt = true; - stopping = true; + catch (const std::exception& e) { + string fname = box; + fname[0] = toupper(fname[0]); + Global::exit_error_msg = "Exception in runner thread -> " + + fname + "::draw(" + fname + "::collect(no_update=" + (no_update ? "true" : "false") + + "), force_redraw=" + (force_redraw ? "true" : "false") + ") : " + (string)e.what(); + Logger::error(Global::exit_error_msg); + Global::thread_exception = true; + Input::interrupt = true; + stopping = true; + break; + } } if (stopping) { @@ -325,7 +322,7 @@ namespace Runner { active = true; Config::lock(); vector boxes; - if (box.empty()) boxes = Config::current_boxes; + if (box == "all") boxes = Config::current_boxes; else boxes.push_back(box); std::thread run_thread(_runner, boxes, no_update, force_redraw, input_interrupt); run_thread.detach(); @@ -475,7 +472,7 @@ int main(int argc, char **argv){ if (not Global::debuginit) cout << Term::alt_screen << Term::hide_cursor << Term::clear << endl; - cout << Cpu::box << Mem::box << Net::box << Proc::box << flush; + cout << Term::sync_start << Cpu::box << Mem::box << Net::box << Proc::box << Term::sync_end << flush; //* Test theme @@ -562,7 +559,7 @@ int main(int argc, char **argv){ << Mv::d(1) << "Init took " << time_micros() - kts << " μs. " << endl; list ktavg; - while (true) { + for (;;) { mydata.back() = std::rand() % 101; kts = time_micros(); cout << Term::sync_start << Mv::restore << kgraph(mydata) @@ -592,36 +589,50 @@ int main(int argc, char **argv){ list avgtimes; try { - while (true) { + while (not true not_eq not false) { if (Global::thread_exception) clean_quit(1); + uint64_t update_ms = Config::getI("update_ms"); + //? Make sure terminal size hasn't changed (in case of SIGWINCH not working properly) + term_resize(); + + //? Print out boxes outlines and trigger secondary thread to redraw if terminal has been resized + if (Global::resized) { + cout << Term::sync_start << Cpu::box << Mem::box << Net::box << Proc::box << Term::sync_end << flush; + Global::resized = false; + if (time_ms() < future_time) + Runner::run("all", true, true); + } + + //? Print out any available output from secondary thread if (Runner::has_output) { cout << Term::sync_start << Runner::get_output() << Term::sync_end << flush; - //! DEBUG stats + //! DEBUG stats --> avgtimes.push_front(Runner::time_spent); if (avgtimes.size() > 30) avgtimes.pop_back(); cout << Fx::reset << Mv::to(2, 2) << "Runner took: " << rjust(to_string(avgtimes.front()), 5) << " μs. Average: " << rjust(to_string(accumulate(avgtimes.begin(), avgtimes.end(), 0) / avgtimes.size()), 5) << " μs of " << avgtimes.size() << " samples. Run count: " << ++rcount << ". " << flush; + //! <-- } + //? Start collect & draw thread at the interval set by config value if (time_ms() >= future_time) { - Runner::run(); - future_time = time_ms() + Config::getI("update_ms"); + Runner::run("all"); + future_time = time_ms() + update_ms; } - while (time_ms() < future_time and not Global::resized) { - if (Input::poll(future_time - time_ms())) + //? Loop over input polling and input action processing and check for external clock changes + for (auto current_time = time_ms(); current_time < future_time and not Global::resized; current_time = time_ms()) { + if (future_time - current_time > update_ms) + future_time = current_time; + else if (Input::poll(future_time - current_time)) Input::process(Input::get()); else break; } - if (Global::resized) { - // cout << Cpu::box << Mem::box << Net::box << Proc::box << flush; - Global::resized = false; - future_time = time_ms(); - } + } } catch (std::exception& e) { @@ -630,8 +641,4 @@ int main(int argc, char **argv){ clean_quit(1); } - -//*-----<<<<< - - return 0; } diff --git a/src/btop_draw.cpp b/src/btop_draw.cpp index 49745ff..2f7e76b 100644 --- a/src/btop_draw.cpp +++ b/src/btop_draw.cpp @@ -351,20 +351,20 @@ namespace Proc { else selected++; } else if (cmd_key == "page_up") { - if (start == 0) selected = 0; + if (selected > 0 and start == 0) selected = 0; else start = max(0, start - (height - 3)); } else if (cmd_key == "page_down") { - if (start >= numpids - select_max) selected = select_max; + if (selected > 0 and start >= numpids - select_max) selected = select_max; else start = clamp(start + select_max, 0, max(0, numpids - select_max)); } else if (cmd_key == "home") { start = 0; - selected = (selected > 0) ? 1 : 0; + if (selected > 0) selected = 1; } else if (cmd_key == "end") { start = max(0, numpids - select_max); - selected = select_max; + if (selected > 0) selected = select_max; } Config::set("proc_start", start); @@ -510,7 +510,6 @@ namespace Proc { namespace Draw { void calcSizes(){ - Config::unlock(); auto& boxes = Config::getS("shown_boxes"); Cpu::box.clear(); diff --git a/src/btop_linux.cpp b/src/btop_linux.cpp index e35e5aa..aba3264 100644 --- a/src/btop_linux.cpp +++ b/src/btop_linux.cpp @@ -498,9 +498,8 @@ namespace Proc { } } - catch (std::invalid_argument const&) { continue; } - catch (std::out_of_range const&) { continue; } - catch (std::ios_base::failure const&) {} + catch (const std::invalid_argument&) { continue; } + catch (const std::out_of_range&) { continue; } stat_loop_done: pread.close(); diff --git a/src/btop_shared.hpp b/src/btop_shared.hpp index 61627b0..34d3c60 100644 --- a/src/btop_shared.hpp +++ b/src/btop_shared.hpp @@ -36,6 +36,7 @@ namespace Global { extern atomic thread_exception; extern int coreCount; extern string banner; + extern atomic resized; } namespace Runner { diff --git a/src/btop_tools.cpp b/src/btop_tools.cpp index cce168c..5e1d8bc 100644 --- a/src/btop_tools.cpp +++ b/src/btop_tools.cpp @@ -120,14 +120,12 @@ namespace Term { } } - bool refresh(bool update){ + bool refresh(){ struct winsize w; ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); if (width != w.ws_col or height != w.ws_row) { - if (update) { - width = w.ws_col; - height = w.ws_row; - } + width = w.ws_col; + height = w.ws_row; return true; } return false; @@ -144,6 +142,7 @@ namespace Term { echo(false); linebuffered(false); refresh(); + Global::resized = false; } } return initialized; diff --git a/src/btop_tools.hpp b/src/btop_tools.hpp index bd93681..016560d 100644 --- a/src/btop_tools.hpp +++ b/src/btop_tools.hpp @@ -137,8 +137,8 @@ namespace Term { //* Escape sequence for end of synchronized output extern const string sync_end; - //* Returns true if terminal has been resized, updates width and height if update=true - bool refresh(bool update=true); + //* Returns true if terminal has been resized and updates width and height + bool refresh(); //* Check for a valid tty, save terminal options and set new options bool init();