diff options
| -rw-r--r-- | .clang-format | 4 | ||||
| -rw-r--r-- | include/reader.h | 60 | ||||
| -rwxr-xr-x | run | bin | 56048 -> 79656 bytes | |||
| -rw-r--r-- | src/main.cpp | 33 | ||||
| -rw-r--r-- | src/reader.cpp | 46 |
5 files changed, 127 insertions, 16 deletions
diff --git a/.clang-format b/.clang-format deleted file mode 100644 index 9fa6cda..0000000 --- a/.clang-format +++ /dev/null @@ -1,4 +0,0 @@ -BasedOnStyle: LLVM -IndentWidth: 8 -TabWidth: 8 -UseTab: Never diff --git a/include/reader.h b/include/reader.h index cad8bf3..8ff6d72 100644 --- a/include/reader.h +++ b/include/reader.h @@ -11,6 +11,7 @@ #include <termios.h> #include <unistd.h> +#include <atomic> #include <string> #include <vector> @@ -19,6 +20,7 @@ typedef struct EditorCfg { int screenrows; int screencols; + int speed; struct termios termios_inst; } EditorCfg; @@ -47,3 +49,61 @@ int is_number(char *strnum); size_t split(const std::string &txt, std::vector<std::string> &strings, const std::string &delims); + + + +template <typename T> +class +SCPCQueue +{ +private: + std::vector<T> buff; + const size_t capacity; + + alignas(64) std::atomic<size_t> head; + alignas(64) std::atomic<size_t> tail; + +public: + SCPCQueue(size_t size) + : buff(size + 1), capacity(size + 1), head(0), tail(0) {} + + SCPCQueue(const SCPCQueue&) = delete; + SCPCQueue& operator=(const SCPCQueue&) = delete; + + bool + push(const T& data) + { + const size_t cur_tail = tail.load(std::memory_order_relaxed); + const size_t next_tail = (cur_tail + 1) % capacity; + + if (next_tail == head.load(std::memory_order_acquire)) { + /* Queue is full */ + return false; + } + + buff[cur_tail] = data; + + tail.store(next_tail, std::memory_order_release); + + return true; + } + bool pop(T &result) + { + const size_t cur_head = head.load(std::memory_order_relaxed); + + if (cur_head == tail.load(std::memory_order_acquire)) { + return false; + } + result = buff[cur_head]; + + const size_t next_head = (cur_head + 1) % capacity; + + head.store(next_head, std::memory_order_release); + + return true; + } +}; + +void producer(SCPCQueue<char> &queue); + +void consumer(SCPCQueue<char> &queue, EditorCfg *cfg); Binary files differdiff --git a/src/main.cpp b/src/main.cpp index 7565371..4959eef 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,6 @@ /* main.cpp - reader: RSVP-style terminal word reader */ +#include <thread> #define _POSIX_C_SOURCE 200809L #include <stdio.h> @@ -15,18 +16,18 @@ int main(int argc, char *argv[]) { - EditorCfg *cfg; - FILE *fp; - long size; - int speed; - std::string content; - std::vector<std::string> data; - size_t i; - std::string *k; + EditorCfg *cfg; + FILE *fp; + long size; + std::string content; + std::vector<std::string> data; + size_t i; + std::string *k; + SCPCQueue<char> queue(1024); cfg = (EditorCfg *)malloc(sizeof(EditorCfg)); - speed = 250000; - + cfg->speed = 250000; + int& speed = cfg->speed; if (!cfg) die("[err]: malloc failed\n"); @@ -58,6 +59,8 @@ main(int argc, char *argv[]) split(content, data, " \t\r\n,;:!?"); + std::thread input_thread(producer, std::ref(queue)); + for (;;) { for (i = 0; i < data.size(); i++) { k = &data[i]; @@ -65,16 +68,26 @@ main(int argc, char *argv[]) continue; window_size_callback(cfg); editor_refresh_scrn(cfg); + consumer(queue, cfg); { int mid = (int)k->size() / 2; int remaining = (int)k->size() - mid - 1; const char *cstr = k->c_str(); + const char message[] = "Current delay: "; + char buf[32]; + int len{}; + write(STDOUT_FILENO, cstr, mid); write(STDOUT_FILENO, "\x1b[31m", 5); write(STDOUT_FILENO, cstr + mid, 1); write(STDOUT_FILENO, "\x1b[m", 3); write(STDOUT_FILENO, cstr + mid + 1, remaining); + + write(STDOUT_FILENO, "\x1b[H", 3); + write(STDOUT_FILENO, message, sizeof(message)-1); + len = snprintf(buf, sizeof(buf), "%d", cfg->speed); + write(STDOUT_FILENO, buf, len); } usleep(speed); } diff --git a/src/reader.cpp b/src/reader.cpp index 4bc88a6..eec7478 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -144,7 +144,7 @@ window_size_callback(EditorCfg *cfg) if (get_window_size(&rows, &cols) < 0) { fprintf(stderr, - "[err]: window_size_callback: get_window_size\n"); + "[err]: window_size_callback: get_window_size\n"); return; } if (cfg->screenrows != rows || cfg->screencols != cols) { @@ -188,7 +188,7 @@ editor_refresh_scrn(EditorCfg *cfg) ab_append(&ab, "\x1b[2J", 4); memset(buff, 0, sizeof(buff)); snprintf(buff, sizeof(buff), "\x1b[%d;%dH", - cfg->screenrows / 2, cfg->screencols / 2); + cfg->screenrows / 2, cfg->screencols / 2); ab_append(&ab, buff, strlen(buff)); ab_write(&ab); ab_free(&ab); @@ -227,3 +227,45 @@ split(const std::string &txt, } return strings.size(); } + +static void +editor_process_key_process(char c, EditorCfg *cfg) +{ + + switch (c) + { + case CTRL_KEY('q'): + write(STDOUT_FILENO, "\x1b[2J", 4); + write(STDOUT_FILENO, "\x1b[H", 3); + exit(0); + break; + case CTRL_KEY('j'): + cfg->speed += 10000; + break; + case CTRL_KEY('k'): + cfg->speed -= 10000; + break; + } +} + +void +producer(SCPCQueue<char> &queue) +{ + for (;;) { + char value = editor_readkey(); + queue.push(value); + } +} + +void +consumer(SCPCQueue<char> &queue, EditorCfg *cfg) +{ + for (;;) { + char value{}; + if (queue.pop(value)) { + editor_process_key_process(value, cfg); + } else { + break; + } + } +} |
