aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAakarsh Kashyap <[email protected]>2026-06-29 22:27:45 +0530
committerAakarsh Kashyap <[email protected]>2026-06-29 22:27:45 +0530
commit36db9ebac493aa07a08c8a92a1380d253e05718e (patch)
tree70b528aa4ca444f2251d01787307225c551f8d91
parent53a8f41171179663cebdb9afbee5de88f8b6bbd4 (diff)
input handling using SCSP ring buffer
-rw-r--r--.clang-format4
-rw-r--r--include/reader.h60
-rwxr-xr-xrunbin56048 -> 79656 bytes
-rw-r--r--src/main.cpp33
-rw-r--r--src/reader.cpp46
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);
diff --git a/run b/run
index 7dc69b5..a9f5274 100755
--- a/run
+++ b/run
Binary files differ
diff --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;
+ }
+ }
+}