From f424feb24d33de406b36202f146a44d55f519df4 Mon Sep 17 00:00:00 2001 From: aristocratos Date: Sat, 29 May 2021 02:32:36 +0200 Subject: [PATCH] Small changes --- btop.cpp | 195 ++++++++++++++++++++-------------------------- src/btop_config.h | 15 ++-- src/btop_draw.h | 49 ++++++++++-- src/btop_globs.h | 6 +- src/btop_input.h | 6 +- src/btop_linux.h | 5 +- src/btop_theme.h | 84 ++++++++++++-------- src/btop_tools.h | 28 +++---- 8 files changed, 208 insertions(+), 180 deletions(-) diff --git a/btop.cpp b/btop.cpp index 909b2b8..3ec509b 100644 --- a/btop.cpp +++ b/btop.cpp @@ -28,6 +28,7 @@ tab-size = 4 #include #include #include +#include namespace Global { const std::vector> Banner_src = { @@ -69,7 +70,7 @@ namespace Global { #error Platform not supported! #endif -using std::string, std::vector, std::array, std::map, std::atomic, std::endl, std::cout, std::views::iota, std::list, std::accumulate; +using std::string, std::vector, std::array, robin_hood::unordered_flat_map, std::atomic, std::endl, std::cout, std::views::iota, std::list, std::accumulate; using std::flush, std::endl, std::future, std::string_literals::operator""s, std::future_status; namespace fs = std::filesystem; using namespace Tools; @@ -79,10 +80,14 @@ namespace Global { string banner; const uint banner_width = 49; - fs::path conf_dir; - fs::path conf_file; - fs::path theme_folder; - fs::path user_theme_folder; + fs::path self_path; + + bool debuginit = false; + bool debug = false; + + uint64_t start_time; + + bool quitting = false; } @@ -94,10 +99,13 @@ void argumentParser(int argc, char **argv){ if (argument == "-v" || argument == "--version") { cout << "btop version: " << Global::Version << endl; exit(0); - } else if (argument == "-h" || argument == "--help") { + } + else if (argument == "-h" || argument == "--help") { cout << "help here" << endl; exit(0); - } else { + } + else if (argument == "--debug") Global::debug = true; + else { cout << " Unknown argument: " << argument << "\n" << " Use -h or --help for help." << endl; exit(1); @@ -134,6 +142,18 @@ string createBanner(){ return out; } +void clean_quit(int signal){ + if (Global::quitting) return; + if (Term::initialized) { + Term::restore(); + if (!Global::debuginit) cout << Term::normal_screen << Term::show_cursor << flush; + } + if (Global::debug) Logger::debug("Quitting! Runtime: " + sec_to_dhms(time_s() - Global::start_time)); + Global::quitting = true; + if (signal != -1) exit(signal); +} + +void _exit_handler() { clean_quit(-1); } //* Threading test function string my_worker(int x){ @@ -150,62 +170,83 @@ int main(int argc, char **argv){ //? Init + Global::start_time = time_s(); + cout.setf(std::ios::boolalpha); if (argc > 1) argumentParser(argc, argv); + std::atexit(_exit_handler); + #if defined(LINUX) - //? Linux init + //? Linux paths init Global::proc_path = (fs::is_directory(fs::path("/proc")) && access("/proc", R_OK) != -1) ? "/proc" : ""; if (Global::proc_path.empty()) { cout << "ERROR: Proc filesystem not found or no permission to read from it!" << endl; exit(1); } + { + std::error_code ec; + Global::self_path = fs::read_symlink("/proc/self/exe", ec).remove_filename(); + } #endif //? Setup paths for config, log and themes for (auto env : {"XDG_CONFIG_HOME", "HOME"}) { if (getenv(env) != NULL && access(getenv(env), W_OK) != -1) { - Global::conf_dir = fs::path(getenv(env)) / (((string)env == "HOME") ? ".config/btop" : "btop"); + Config::conf_dir = fs::path(getenv(env)) / (((string)env == "HOME") ? ".config/btop" : "btop"); break; } } - if (!Global::conf_dir.empty()) { - if (!fs::is_directory(Global::conf_dir) && !fs::create_directories(Global::conf_dir)) { + if (!Config::conf_dir.empty()) { + std::error_code ec; + if (!fs::is_directory(Config::conf_dir) && !fs::create_directories(Config::conf_dir, ec)) { cout << "WARNING: Could not create or access btop config directory. Logging and config saving disabled." << endl; + cout << "Make sure your $HOME environment variable is correctly set to fix this." << endl; } else { - Global::conf_file = Global::conf_dir / "btop.conf"; - Logger::logfile = Global::conf_dir / "btop.log"; - Global::user_theme_folder = Global::conf_dir / "themes"; - if (!fs::exists(Global::user_theme_folder) && !fs::create_directory(Global::user_theme_folder)) Global::user_theme_folder.clear(); + std::error_code ec; + Config::conf_file = Config::conf_dir / "btop.conf"; + Logger::logfile = Config::conf_dir / "btop.log"; + Theme::user_theme_dir = Config::conf_dir / "themes"; + if (!fs::exists(Theme::user_theme_dir) && !fs::create_directory(Theme::user_theme_dir, ec)) Theme::user_theme_dir.clear(); } } - for (auto theme_path : {"/usr/local/share/btop/themes", "/usr/share/btop/themes"}) { - if (access(theme_path, R_OK) != -1) { - Global::theme_folder = theme_path; - break; + if (!Global::self_path.empty()) { + std::error_code ec; + Theme::theme_dir = fs::canonical(Global::self_path / "../share/btop/themes", ec); + if (ec || access(Theme::theme_dir.c_str(), R_OK) == -1) Theme::theme_dir.clear(); + } + + if (Theme::theme_dir.empty()) { + for (auto theme_path : {"/usr/local/share/btop/themes", "/usr/share/btop/themes"}) { + if (fs::exists(fs::path(theme_path)) && access(theme_path, R_OK) != -1) { + Theme::theme_dir = fs::path(theme_path); + break; + } } } - string err_msg; + Global::debug = true; + if (Global::debug) { Logger::loglevel = 4; Logger::debug("Starting in debug mode");} if (!string(getenv("LANG")).ends_with("UTF-8") && !string(getenv("LANG")).ends_with("utf-8")) { - err_msg = "No UTF-8 locale was detected! Symbols might not look as intended."; + string err_msg = "No UTF-8 locale was detected! Symbols might not look as intended."; Logger::warning(err_msg); cout << "WARNING: " << err_msg << endl; } //? Initialize terminal and set options if (!Term::init()) { - err_msg = "No tty detected!"; + string err_msg = "No tty detected!"; Logger::error(err_msg + " Quitting."); cout << "ERROR: " << err_msg << endl; cout << "btop++ needs an interactive shell to run." << endl; - exit(1); + clean_quit(1); } //? Read config file if present Config::load("____"); + Config::setB("truecolor", false); auto thts = time_ms(); @@ -218,16 +259,13 @@ int main(int argc, char **argv){ //* ------------------------------------------------ TESTING ------------------------------------------------------ - int debug = 1; - int tests = 0; - bool debuginit = false; - if (debug > 0) { Logger::loglevel = 4; Logger::debug("Running in debug mode!");} + Global::debuginit = false; // cout << Theme("main_bg") << Term::clear << flush; bool thread_test = false; - if (!debuginit) cout << Term::alt_screen << Term::hide_cursor << flush; + if (!Global::debuginit) cout << Term::alt_screen << Term::hide_cursor << flush; cout << Theme::c("main_fg") << Theme::c("main_bg") << Term::clear << endl; @@ -273,8 +311,7 @@ int main(int argc, char **argv){ exit(0); } - - if (true) { + if (false) { Draw::Meter kmeter; kmeter(Term::width - 2, "cpu", false); cout << kmeter(25) << endl; @@ -285,11 +322,25 @@ int main(int argc, char **argv){ exit(0); } + if (false) { + cout << fs::absolute(fs::current_path() / "..") << endl; + cout << Global::self_path << endl; + cout << Theme::theme_dir << endl; + cout << Config::conf_dir << endl; + exit(0); + } + + if (false) { + string a = "⣿ ⣿\n⣿⣿⣿⣿ ⣿\n⣿⣿⣿⣿ ⣿\n⣿⣿⣿⣿ ⣿\n⣿⣿⣿"; + cout << a << endl; + exit(0); + } + if (thread_test){ - map> runners; - map outputs; + unordered_flat_map> runners; + unordered_flat_map outputs; for (int i : iota(0, 10)){ runners[i] = async(my_worker, i); @@ -325,7 +376,7 @@ int main(int argc, char **argv){ uint lc; string ostring; uint64_t tsl, timestamp2, rcount = 0; - list avgtimes; + list avgtimes = {0}; uint timer = 1000; bool filtering = false; bool reversing = false; @@ -369,8 +420,8 @@ int main(int argc, char **argv){ - avgtimes.push_front(timestamp); - if (avgtimes.size() > 100) avgtimes.pop_back(); + if (rcount > 0) avgtimes.push_front(timestamp); + if (avgtimes.size() > 10) avgtimes.pop_back(); cout << pbox << ostring << Fx::reset << "\n" << endl; cout << Mv::to(Term::height - 4, 1) << "Processes call took: " << rjust(to_string(timestamp), 5) << " μs. Average: " << rjust(to_string(accumulate(avgtimes.begin(), avgtimes.end(), 0) / avgtimes.size()), 5) << " μs of " << avgtimes.size() << @@ -403,79 +454,5 @@ int main(int argc, char **argv){ //*-----<<<<< - //cout << pw->pw_name << "/" << gr->gr_name << endl; - - - - - if (tests>4){ - string trim_test1 = "-*vad "; - string trim_test2 = " vad*-"; - string trim_test3 = trim_test1 + trim_test2; - - cout << "\"" << ltrim(trim_test1, "-*") << "\" \"" << rtrim(trim_test2, "*-") << "\" \"" << trim(trim_test3, "-") << "\"" << endl; - - - string testie = "Does this work as intended? Or?"; - auto t_vec = ssplit(testie); - for(auto& tp : t_vec){ - cout << "\"" << tp << "\" " << flush; - } - } - - - //if (tests>5){ - - //} - - // map dict = { - // {"Korv", "14"}, - // {"Vad", "13"} - // }; - - // cout << dict["Korv"] << ", " << dict["Vad"] << endl; - - // vector> test = { - // {{"first", 1}, {"second", 2}}, - // {{"first", 11}, {"second", 22}} - // }; - - //cout << test[0]["first"] << " " << test[1]["second"] << endl; - - // for (auto& m : test) { - // cout << endl; - // for (auto& item : m) { - // cout << item.first << " " << item.second << endl; - // } - // } - - - - if (debug == 3){ - cout << Theme::c("main_fg"); - cout << Mv::to(Term::height - 1, 0) << "Press q to exit! Timeout" << flush; - string full, key; - int wt = 90; - bool qp = false; - while (!qp && wt >= 0){ - int wtm = wt / 60; - int wts = wt - wtm * 60; - wt--; - cout << Mv::to(Term::height - 1, 26) << "(" << wtm << ":" << wts << ") " << flush; - //chr = Key(1000); - if (Input::poll(1000)) { - key = Input::get(); - cout << Mv::to(Term::height - 2, 1) << "Last key: LEN=" << key.size() << " ULEN=" << ulen(key) << " KEY=\"" << key << "\" CODE=" << (int)key.at(0) << " " << flush; - full += key; - cout << Mv::to(Term::height - 5, 1) << full << flush; - if (key == "q") qp = true; - key = ""; - wt++; - } - } - } - - Term::restore(); - if (!debuginit) cout << Term::normal_screen << Term::show_cursor << flush; return 0; } diff --git a/src/btop_config.h b/src/btop_config.h index e510a1d..e205f29 100644 --- a/src/btop_config.h +++ b/src/btop_config.h @@ -21,11 +21,13 @@ tab-size = 4 #include #include -#include +#include +#include #include -using std::string, std::vector, std::unordered_map; +using std::string, std::vector, robin_hood::unordered_flat_map; +namespace fs = std::filesystem; using namespace Tools; @@ -33,9 +35,12 @@ using namespace Tools; namespace Config { namespace { + fs::path conf_dir; + fs::path conf_file; + bool changed = false; - unordered_map strings = { + unordered_flat_map strings = { {"color_theme", "Default"}, {"shown_boxes", "cpu mem net proc"}, {"proc_sorting", "cpu lazy"}, @@ -52,7 +57,7 @@ namespace Config { {"net_iface", ""}, {"log_level", "WARNING"} }; - unordered_map bools = { + unordered_flat_map bools = { {"theme_background", true}, {"truecolor", true}, {"proc_reversed", false}, @@ -84,7 +89,7 @@ namespace Config { {"show_battery", true}, {"show_init", false} }; - unordered_map ints = { + unordered_flat_map ints = { {"update_ms", 2000}, {"proc_update_mult", 2}, {"tree_depth", 3} diff --git a/src/btop_draw.h b/src/btop_draw.h index f99cd2f..2066789 100644 --- a/src/btop_draw.h +++ b/src/btop_draw.h @@ -20,7 +20,7 @@ tab-size = 4 #include #include -#include +#include #include #include #include @@ -31,7 +31,42 @@ tab-size = 4 #ifndef _btop_draw_included_ #define _btop_draw_included_ 1 -using std::string, std::vector, std::map, std::round, std::views::iota, std::string_literals::operator""s; +using std::string, std::vector, robin_hood::unordered_flat_map, std::round, std::views::iota, std::string_literals::operator""s, std::clamp; + +namespace Symbols { + const string h_line = "─"; + const string v_line = "│"; + const string left_up = "┌"; + const string right_up = "┐"; + const string left_down = "└"; + const string right_down = "┘"; + const string title_left = "┤"; + const string title_right = "├"; + const string div_up = "┬"; + const string div_down = "┴"; + + const string meter = "■"; + + const array superscript = { "⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹" }; + + const unordered_flat_map graph_00 = { {true, Mv::r(1)}, {false, " "} }; + + unordered_flat_map graph_up = { + {0.0, " "}, {0.1, "⢀"}, {0.2, "⢠"}, {0.3, "⢰"}, {0.4, "⢸"}, + {1.0, "⡀"}, {1.1, "⣀"}, {1.2, "⣠"}, {1.3, "⣰"}, {1.4, "⣸"}, + {2.0, "⡄"}, {2.1, "⣄"}, {2.2, "⣤"}, {2.3, "⣴"}, {2.4, "⣼"}, + {3.0, "⡆"}, {3.1, "⣆"}, {3.2, "⣦"}, {3.3, "⣶"}, {3.4, "⣾"}, + {4.0, "⡇"}, {4.1, "⣇"}, {4.2, "⣧"}, {4.3, "⣷"}, {4.4, "⣿"} + }; + + unordered_flat_map graph_down = { + {0.0, " "}, {0.1, "⠈"}, {0.2, "⠘"}, {0.3, "⠸"}, {0.4, "⢸"}, + {1.0, "⠁"}, {1.1, "⠉"}, {1.2, "⠙"}, {1.3, "⠹"}, {1.4, "⢹"}, + {2.0, "⠃"}, {2.1, "⠋"}, {2.2, "⠛"}, {2.3, "⠻"}, {2.4, "⢻"}, + {3.0, "⠇"}, {3.1, "⠏"}, {3.2, "⠟"}, {3.3, "⠿"}, {3.4, "⢿"}, + {4.0, "⡇"}, {4.1, "⡏"}, {4.2, "⡟"}, {4.3, "⡿"}, {4.4, "⣿"} + }; +} namespace Draw { @@ -43,6 +78,7 @@ namespace Draw { uint num=0; }; + //* Create a box using values from a BoxConf struct and return as a string string createBox(BoxConf c){ string out; string lcolor = (c.line_color.empty()) ? Theme::c("div_line") : c.line_color; @@ -81,24 +117,27 @@ namespace Draw { return out + Fx::reset + Mv::to(c.y + 1, c.x + 2); } + //* Class holding a percentage meter class Meter { string out, color_gradient; int width = 10; bool invert = false; vector cache; public: + //* Set meter options void operator()(int width, string color_gradient, bool invert = false) { - if (width < 0) width = 1; this->width = width; this->color_gradient = color_gradient; this->invert = invert; + out.clear(); cache.clear(); cache.insert(cache.begin(), 101, ""); } + //* Return a string representation of the meter with given value string operator()(int value) { - if (value > 100) value = 100; - else if (value < 0) value = 0; + if (width < 1) return out; + value = clamp(value, 0, 100); if (!cache.at(value).empty()) return out = cache.at(value); out.clear(); int y; diff --git a/src/btop_globs.h b/src/btop_globs.h index e1d592a..ea1efd8 100644 --- a/src/btop_globs.h +++ b/src/btop_globs.h @@ -23,9 +23,9 @@ tab-size = 4 #include #include #include -#include +#include -using std::string, std::vector, std::unordered_map, std::array, std::atomic; +using std::string, std::vector, std::unordered_map, std::array, std::atomic, robin_hood::unordered_flat_map; namespace Global { @@ -33,7 +33,7 @@ namespace Global { - const unordered_map>> Menus = { + const unordered_flat_map>> Menus = { { "options", { { "normal", { "┌─┐┌─┐┌┬┐┬┌─┐┌┐┌┌─┐", diff --git a/src/btop_input.h b/src/btop_input.h index a922ae4..facaa71 100644 --- a/src/btop_input.h +++ b/src/btop_input.h @@ -20,12 +20,12 @@ tab-size = 4 #define _btop_input_included_ 1 #include -#include +#include #include #include -using std::string, std::unordered_map, std::cin; +using std::string, robin_hood::unordered_flat_map, std::cin; using namespace Tools; /* The input functions relies on the following std::cin options being set: @@ -38,7 +38,7 @@ using namespace Tools; namespace Input { namespace { //* Map for translating key codes to readable values - const unordered_map Key_escapes = { + const unordered_flat_map Key_escapes = { {"\033", "escape"}, {"\n", "enter"}, {" ", "space"}, diff --git a/src/btop_linux.h b/src/btop_linux.h index 6d9af27..8fcbdea 100644 --- a/src/btop_linux.h +++ b/src/btop_linux.h @@ -31,16 +31,17 @@ tab-size = 4 #include #include #include +#include #include #include #include #include -#include -using std::string, std::vector, std::array, std::ifstream, std::atomic, std::numeric_limits, std::streamsize, robin_hood::unordered_flat_map; + +using std::string, std::vector, std::array, std::ifstream, std::atomic, std::numeric_limits, std::streamsize; using std::cout, std::flush, std::endl; namespace fs = std::filesystem; using namespace Tools; diff --git a/src/btop_theme.h b/src/btop_theme.h index 434ba4c..92d4ffa 100644 --- a/src/btop_theme.h +++ b/src/btop_theme.h @@ -22,20 +22,24 @@ tab-size = 4 #include #include #include -#include #include +#include #include +#include #include #include #include -using std::string, std::round, std::vector, std::map, std::stoi, std::views::iota, std::array, std::unordered_map; +using std::string, std::round, std::vector, robin_hood::unordered_flat_map, std::stoi, std::views::iota, std::array, std::clamp, std::max, std::min; using namespace Tools; namespace Theme { - const unordered_map Default_theme = { + fs::path theme_dir; + fs::path user_theme_dir; + + const unordered_flat_map Default_theme = { { "main_bg", "#00" }, { "main_fg", "#cc" }, { "title", "#ee" }, @@ -83,10 +87,10 @@ namespace Theme { namespace { //* Convert 24-bit colors to 256 colors using 6x6x6 color cube int truecolor_to_256(uint r, uint g, uint b){ - if (r / 11 == g / 11 && g / 11 == b / 11) { - return 232 + r / 11; + if (round((double)r / 11) == round((double)g / 11) && round((double)g / 11) == round((double)b / 11)) { + return 232 + round((double)r / 11); } else { - return round((float)(r / 51)) * 36 + round((float)(g / 51)) * 6 + round((float)(b / 51)) + 16; + return round((double)r / 51) * 36 + round((double)g / 51) * 6 + round((double)b / 51) + 16; } } } @@ -98,7 +102,10 @@ namespace Theme { string hex_to_color(string hexa, bool t_to_256=false, string depth="fg"){ if (hexa.size() > 1){ hexa.erase(0, 1); - for (auto& c : hexa) if (!isxdigit(c)) return ""; + for (auto& c : hexa) if (!isxdigit(c)) { + Logger::error("Invalid hex value: " + hexa); + return ""; + } depth = (depth == "fg") ? "38" : "48"; string pre = Fx::e + depth + ";"; pre += (t_to_256) ? "5;" : "2;"; @@ -125,7 +132,9 @@ namespace Theme { to_string(stoi(hexa.substr(4, 2), 0, 16)) + "m"; } } + else Logger::error("Invalid size of hex value: " + hexa); } + else Logger::error("Hex value missing." + hexa); return ""; } @@ -137,9 +146,9 @@ namespace Theme { depth = (depth == "fg") ? "38" : "48"; string pre = Fx::e + depth + ";"; pre += (t_to_256) ? "5;" : "2;"; - r = (r > 255) ? 255 : r; - g = (g > 255) ? 255 : g; - b = (b > 255) ? 255 : b; + r = min(r, 255u); + g = min(g, 255u); + b = min(b, 255u); if (t_to_256) return pre + to_string(truecolor_to_256(r, g, b)) + "m"; else return pre + to_string(r) + ";" + to_string(g) + ";" + to_string(b) + "m"; } @@ -161,9 +170,9 @@ namespace Theme { namespace { - unordered_map colors; - unordered_map> rgbs; - unordered_map> gradients; + unordered_flat_map colors; + unordered_flat_map> rgbs; + unordered_flat_map> gradients; //* Convert hex color to a array of decimals array hex_to_dec(string hexa){ @@ -187,40 +196,46 @@ namespace Theme { } //* Generate colors and rgb decimal vectors for the theme - void generateColors(unordered_map& source){ + void generateColors(unordered_flat_map& source){ vector t_rgb; string depth; + bool t_to_256 = !Config::getB("truecolor"); colors.clear(); rgbs.clear(); for (auto& [name, color] : Default_theme) { depth = (name.ends_with("bg") && name != "meter_bg") ? "bg" : "fg"; if (source.contains(name)) { if (source.at(name)[0] == '#') { - colors[name] = hex_to_color(source.at(name), !Config::getB("truecolor"), depth); + colors[name] = hex_to_color(source.at(name), t_to_256, depth); rgbs[name] = hex_to_dec(source.at(name)); } else { t_rgb = ssplit(source.at(name), " "); - colors[name] = dec_to_color(stoi(t_rgb[0]), stoi(t_rgb[1]), stoi(t_rgb[2]), !Config::getB("truecolor"), depth); - rgbs[name] = array{stoi(t_rgb[0]), stoi(t_rgb[1]), stoi(t_rgb[2])}; + if (t_rgb.size() != 3) + Logger::error("Invalid RGB decimal value: \"" + source.at(name) + "\""); + else { + colors[name] = dec_to_color(stoi(t_rgb[0]), stoi(t_rgb[1]), stoi(t_rgb[2]), t_to_256, depth); + rgbs[name] = array{stoi(t_rgb[0]), stoi(t_rgb[1]), stoi(t_rgb[2])}; + } } } - else colors[name] = ""; if (colors[name].empty()) { - colors[name] = hex_to_color(color, !Config::getB("truecolor"), depth); + Logger::info("Missing color value for \"" + name + "\". Using value from default."); + colors[name] = hex_to_color(color, t_to_256, depth); rgbs[name] = array{-1, -1, -1}; } } } - //* Generate color gradients from one, two or three colors, 101 values indexed 0-100 + //* Generate color gradients from two or three colors, 101 values indexed 0-100 void generateGradients(){ gradients.clear(); array c_gradient; string wname; + bool t_to_256 = !Config::getB("truecolor"); array, 3> rgb_arr; array, 101> dec_arr; - int f, s, r, o, y; - for (auto& [name, source_arr] : rgbs){ + int arr1, arr2, rng, offset, y; + for (auto& [name, source_arr] : rgbs) { if (!name.ends_with("_start")) continue; dec_arr[0][0] = -1; wname = rtrim(name, "_start"); @@ -230,21 +245,22 @@ namespace Theme { if (rgb_arr[2][0] >= 0) { //? Split iteration in two passes of 50 + 51 instead of 101 if gradient has _start, _mid and _end values defined - r = (rgb_arr[1][0] >= 0) ? 50 : 100; - for (int i : iota(0, 3)){ - f = 0; s = (r == 50) ? 1 : 2; o = 0; - for (int c : iota(0, 101)){ - dec_arr[c][i] = rgb_arr[f][i] + (c - o) * (rgb_arr[s][i] - rgb_arr[f][i]) / r; + rng = (rgb_arr[1][0] >= 0) ? 50 : 100; + for (int rgb : iota(0, 3)){ + arr1 = 0; arr2 = (rng == 50) ? 1 : 2; offset = 0; + for (int i : iota(0, 101)) { + dec_arr[i][rgb] = rgb_arr[arr1][rgb] + (i - offset) * (rgb_arr[arr2][rgb] - rgb_arr[arr1][rgb]) / rng; //? Switch source arrays from _start/_mid to _mid/_end at 50 passes if _mid is defined - if (c == r) { ++f; ++s; o = 50;} + if (i == rng) { ++arr1; ++arr2; offset = 50;} } } } y = 0; if (dec_arr[0][0] != -1) { - for (auto& vec : dec_arr) c_gradient[y++] = dec_to_color(vec[0], vec[1], vec[2], !Config::getB("truecolor")); - } else { + for (auto& arr : dec_arr) c_gradient[y++] = dec_to_color(arr[0], arr[1], arr[2], t_to_256); + } + else { //? If only _start was defined fill array with _start color c_gradient.fill(colors[name]); } @@ -255,7 +271,7 @@ namespace Theme { //* Set current theme using map - void set(unordered_map source){ + void set(unordered_flat_map source){ generateColors(source); generateGradients(); Term::fg = colors.at("main_fg"); @@ -264,17 +280,17 @@ namespace Theme { } //* Return escape code for color - auto c(string name){ + auto& c(string name){ return colors.at(name); } //* Return array of escape codes for color gradient - auto g(string name){ + auto& g(string name){ return gradients.at(name); } //* Return array of red, green and blue in decimal for color - auto dec(string name){ + auto& dec(string name){ return rgbs.at(name); } diff --git a/src/btop_tools.h b/src/btop_tools.h index 758cf20..cc91993 100644 --- a/src/btop_tools.h +++ b/src/btop_tools.h @@ -32,6 +32,7 @@ tab-size = 4 #include #include #include +#include #include #include @@ -39,28 +40,11 @@ tab-size = 4 #include -using std::string, std::vector, std::regex, std::max, std::to_string, std::cin, std::atomic; +using std::string, std::vector, std::regex, std::max, std::to_string, std::cin, std::atomic, robin_hood::unordered_flat_map; namespace fs = std::filesystem; //? ------------------------------------------------- NAMESPACES ------------------------------------------------------ -namespace Symbols { - const string h_line = "─"; - const string v_line = "│"; - const string left_up = "┌"; - const string right_up = "┐"; - const string left_down = "└"; - const string right_down = "┘"; - const string title_left = "┤"; - const string title_right = "├"; - const string div_up = "┬"; - const string div_down = "┴"; - - const string meter = "■"; - - const array superscript = { "⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹" }; -} - //* Collection of escape codes for text style and formatting namespace Fx { //* Escape sequence start @@ -251,6 +235,11 @@ namespace Tools { [](char c) { return (static_cast(c) & 0xC0) != 0x80; } ); } + //* Return current time since epoch in seconds + inline uint64_t time_s(){ + return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + } + //* Return current time since epoch in milliseconds inline uint64_t time_ms(){ return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); @@ -459,6 +448,7 @@ namespace Tools { } +//* Simple logging implementation namespace Logger { namespace { std::atomic busy (false); @@ -466,7 +456,7 @@ namespace Logger { uint loglevel = 2; bool first = true; string tdf = "%Y/%m/%d (%T) | "; - unordered_map log_levels = { + unordered_flat_map log_levels = { { 0, "DISABLED" }, { 1, "ERROR" }, { 2, "WARNING" },