diff --git a/CMakeLists.txt b/CMakeLists.txt index fd9e14152..ed5b155b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,12 +74,15 @@ target_link_libraries(notcurses Threads::Threads "${TERMINFO_LIBRARIES}" "${LIBRT}" + PUBLIC + Threads::Threads ) target_link_libraries(notcurses-static PRIVATE - Threads::Threads "${TERMINFO_STATIC_LIBRARIES}" "${LIBRT}" + PUBLIC + Threads::Threads ) target_link_directories(notcurses PRIVATE @@ -315,7 +318,6 @@ target_include_directories(notcurses-demo target_link_libraries(notcurses-demo PRIVATE notcurses - Threads::Threads ) target_compile_options(notcurses-demo PRIVATE @@ -461,7 +463,6 @@ target_include_directories(notcurses-tetris ) target_link_libraries(notcurses-tetris PRIVATE - Threads::Threads notcurses++ ) target_compile_options(notcurses-tetris diff --git a/src/input/input.cpp b/src/input/input.cpp index c5169deb2..0f13d4855 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -1,18 +1,35 @@ #include #include +#include +#include +#include +#include #include #include #include #include #include - -#include #include #include +#define NANOSECS_IN_SEC 1000000000 + +static inline uint64_t +timenow_to_ns(){ + struct timespec t; + if(clock_gettime(CLOCK_MONOTONIC, &t)){ + throw std::runtime_error("error retrieving time"); + } + return t.tv_sec * NANOSECS_IN_SEC + t.tv_nsec; +} + using namespace ncpp; +std::mutex mtx; +uint64_t start; static int dimy, dimx; +std::atomic done; +static struct ncplot* plot; // return the string version of a special composed key const char* nckeystr(char32_t spkey){ @@ -134,7 +151,7 @@ char32_t printutf8(char32_t kp){ // Dim all text on the plane by the same amount. This will stack for // older text, and thus clearly indicate the current output. static bool -dim_rows(std::unique_ptr& n){ +dim_rows(const Plane* n){ int y, x; Cell c; for(y = 2 ; y < dimy ; ++y){ @@ -168,16 +185,46 @@ dim_rows(std::unique_ptr& n){ return true; } +void Tick(ncpp::NotCurses* nc, uint64_t sec) { + const std::lock_guard lock(mtx); + if(ncplot_add_sample(plot, sec, 0)){ + throw std::runtime_error("couldn't register timetick"); + } + if(!nc->render()){ + throw std::runtime_error("error rendering"); + } + mtx.unlock(); +} + +void Ticker(ncpp::NotCurses* nc) { + do{ + std::this_thread::sleep_for(std::chrono::seconds{1}); + const uint64_t sec = (timenow_to_ns() - start) / NANOSECS_IN_SEC; + Tick(nc, sec); + }while(!done); +} + int main(void){ + constexpr auto PLOTHEIGHT = 6; if(setlocale(LC_ALL, "") == nullptr){ return EXIT_FAILURE; } NotCurses nc; - if(!nc.mouse_enable ()){ + if(!nc.mouse_enable()){ + return EXIT_FAILURE; + } + auto n = nc.get_stdplane(&dimy, &dimx); + ncpp::Plane pplane{PLOTHEIGHT, dimx, dimy - PLOTHEIGHT, 0, nullptr}; + struct ncplot_options popts{}; + popts.labelaxisd = true; + popts.minchannel = popts.maxchannel = 0; + channels_set_fg_rgb(&popts.maxchannel, 0xa0, 0x50, 0xb0); + channels_set_fg_rgb(&popts.minchannel, 0xa0, 0xff, 0xb0); + popts.gridtype = static_cast(NCPLOT_8x1); + plot = ncplot_create(pplane, &popts); + if(!plot){ return EXIT_FAILURE; } - std::unique_ptr n(nc.get_stdplane ()); - nc.get_term_dim(&dimy, &dimx); n->set_fg(0); n->set_bg(0xbb64bb); n->styles_on(CellStyle::Underline); @@ -190,6 +237,9 @@ int main(void){ int y = 2; std::deque cells; char32_t r; + done = false; + start = timenow_to_ns(); + std::thread tid(Ticker, &nc); ncinput ni; while(errno = 0, (r = nc.getc(true, &ni)) != (char32_t)-1){ if(r == 0){ // interrupted by signal @@ -232,11 +282,19 @@ int main(void){ if(!dim_rows(n)){ break; } - if(!nc.render()){ + const uint64_t sec = (timenow_to_ns() - start) / NANOSECS_IN_SEC; + mtx.lock(); + if(ncplot_add_sample(plot, sec, 1)){ + mtx.unlock(); break; } - if(++y >= dimy - 2){ // leave a blank line at the bottom - y = 2; // and at the top + if(!nc.render()){ + mtx.unlock(); + break; + } + mtx.unlock(); + if(++y >= dimy - PLOTHEIGHT){ // leave six lines free on the bottom... + y = 2; // ...and one free on the top. } while(cells.size() >= dimy - 3u){ cells.pop_back(); diff --git a/src/input/keyplot.cpp b/src/input/keyplot.cpp deleted file mode 100644 index d74fe9cf5..000000000 --- a/src/input/keyplot.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#define NANOSECS_IN_SEC 1000000000 - -static inline uint64_t -timenow_to_ns(){ - struct timespec t; - if(clock_gettime(CLOCK_MONOTONIC, &t)){ - throw std::runtime_error("error retrieving time"); - } - return t.tv_sec * NANOSECS_IN_SEC + t.tv_nsec; -} - -std::mutex mtx; -uint64_t start; -std::atomic done; -std::array plots; - -void Tick(ncpp::NotCurses* nc, uint64_t sec) { - const std::lock_guard lock(mtx); - for(auto i = 0u ; i < plots.size() ; ++i){ - if(ncplot_add_sample(plots[i], sec, 0)){ - throw std::runtime_error("couldn't register timetick"); - } - } - if(!nc->render()){ - throw std::runtime_error("error rendering"); - } - mtx.unlock(); -} - -void Ticker(ncpp::NotCurses* nc) { - do{ - std::this_thread::sleep_for(std::chrono::seconds{1}); - const uint64_t sec = (timenow_to_ns() - start) / NANOSECS_IN_SEC; - Tick(nc, sec); - }while(!done); -} - -int main(void){ - if(setlocale(LC_ALL, "") == nullptr){ - return EXIT_FAILURE; - } - srand(time(NULL)); - ncpp::NotCurses nc; - if(!nc.mouse_enable()){ - return EXIT_FAILURE; - } - std::unique_ptr n(nc.get_stdplane()); - ncpp::Cell tl, tr, bl, br, hl, vl; - if(!n->load_double_box(0, 0, tl, tr, bl, br, hl, vl)){ - return EXIT_FAILURE; - } - if(!n->perimeter(tl, tr, bl, br, hl, vl, 0)){ - return EXIT_FAILURE; - } - std::vector planes; - const int plotlen = n->get_dim_x() - 2; - planes.emplace_back(6, plotlen, 1, 1, nullptr); - planes.emplace_back(6, plotlen, 8, 1, nullptr); - planes.emplace_back(6, plotlen, 15, 1, nullptr); - planes.emplace_back(6, plotlen, 23, 1, nullptr); - planes.emplace_back(6, plotlen, 31, 1, nullptr); - struct ncplot_options popts{}; - for(auto i = 0u ; i < plots.size() ; ++i){ - popts.labelaxisd = (i % 2 == 0); - popts.minchannel = popts.maxchannel = 0; - channels_set_fg_rgb(&popts.maxchannel, random() % 256, random() % 256, random() % 256); - channels_set_fg_rgb(&popts.minchannel, random() % 256, random() % 256, random() % 256); - popts.gridtype = static_cast(i); - plots[i] = ncplot_create(planes[i], &popts); - if(!plots[i]){ - return EXIT_FAILURE; - } - } - char32_t r; - ncinput ni; - if(!nc.render()){ - return EXIT_FAILURE; - } - done = false; - start = timenow_to_ns(); - std::thread tid(Ticker, &nc); - while(errno = 0, (r = nc.getc(true, &ni)) != (char32_t)-1){ - if(r == 0){ // interrupted by signal - continue; - } - const uint64_t sec = (timenow_to_ns() - start) / NANOSECS_IN_SEC; - mtx.lock(); - for(auto i = 0u ; i < plots.size() ; ++i){ - if(ncplot_add_sample(plots[i], sec, 1)){ - return EXIT_FAILURE; - } - } - if(!nc.render()){ - return EXIT_FAILURE; - } - mtx.unlock(); - } - return EXIT_SUCCESS; -}