mirror of
https://github.com/xcat2/confluent.git
synced 2024-11-22 09:32:21 +00:00
beab6a3c02
C implementation to improve memory and cpu utilization. Forked off to further move the work off the main process. Still needs attribute rendition and packaging before merging to main branch.
144 lines
3.8 KiB
C
144 lines
3.8 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <locale.h>
|
|
#include <unistd.h>
|
|
#include "tmt.h"
|
|
#define HASHSIZE 2053
|
|
#define MAXNAMELEN 256
|
|
#define MAXDATALEN 8192
|
|
struct terment {
|
|
struct terment *next;
|
|
char *name;
|
|
TMT *vt;
|
|
};
|
|
|
|
#define SETNODE 1
|
|
#define WRITE 2
|
|
#define READBUFF 0
|
|
static struct terment *buffers[HASHSIZE];
|
|
|
|
unsigned long hash(char *str)
|
|
/* djb2a */
|
|
{
|
|
unsigned long idx = 5381;
|
|
int c;
|
|
|
|
while ((c = *str++))
|
|
idx = ((idx << 5) + idx) + c;
|
|
return idx % HASHSIZE;
|
|
}
|
|
|
|
TMT *get_termentbyname(char *name) {
|
|
struct terment *ret;
|
|
for (ret = buffers[hash(name)]; ret != NULL; ret = ret->next)
|
|
if (strcmp(name, ret->name) == 0)
|
|
return ret->vt;
|
|
return NULL;
|
|
}
|
|
|
|
TMT *set_termentbyname(char *name) {
|
|
struct terment *ret;
|
|
int idx;
|
|
|
|
idx = hash(name);
|
|
for (ret = buffers[idx]; ret != NULL; ret = ret->next)
|
|
if (strcmp(name, ret->name) == 0)
|
|
return ret->vt;
|
|
ret = (struct terment *)malloc(sizeof(*ret));
|
|
ret->next = buffers[idx];
|
|
ret->name = strdup(name);
|
|
ret->vt = tmt_open(31, 100, NULL, NULL, L"→←↑↓■◆▒°±▒┘┐┌└┼⎺───⎽├┤┴┬│≤≥π≠£•");
|
|
buffers[idx] = ret;
|
|
return ret->vt;
|
|
}
|
|
|
|
void dump_vt(TMT* outvt) {
|
|
const TMTSCREEN *out = tmt_screen(outvt);
|
|
const TMTPOINT *curs = tmt_cursor(outvt);
|
|
int line, idx, deferredlines, deferredspaces;
|
|
bool printedline, skipnl;
|
|
wprintf(L"\033[H\033[J");
|
|
deferredlines = 0;
|
|
skipnl = true;
|
|
for (line = 0; line < out->nline; line++) {
|
|
deferredspaces = 0;
|
|
printedline = false;
|
|
for (idx = 0; idx < out->ncol; idx++) {
|
|
if (out->lines[line]->chars[idx].c == L' ') {
|
|
deferredspaces += 1;
|
|
} else {
|
|
if (!printedline) {
|
|
printedline = true;
|
|
if (skipnl)
|
|
skipnl = false;
|
|
else
|
|
wprintf(L"\r\n");
|
|
}
|
|
while (deferredlines) {
|
|
wprintf(L"\r\n");
|
|
deferredlines -= 1;
|
|
}
|
|
while (deferredspaces > 0) {
|
|
wprintf(L" ");
|
|
deferredspaces -= 1;
|
|
}
|
|
wprintf(L"%lc", out->lines[line]->chars[idx].c);
|
|
}
|
|
}
|
|
if (!printedline)
|
|
deferredlines += 1;
|
|
}
|
|
fflush(stdout);
|
|
wprintf(L"\x1b[%ld;%ldH", curs->r + 1, curs->c + 1);
|
|
fflush(stdout);
|
|
idx = write(1, "\x00", 1);
|
|
if (idx < 0) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
int main(int argc, char* argv[]) {
|
|
int cmd, length;
|
|
setlocale(LC_ALL, "");
|
|
char cmdbuf[MAXDATALEN];
|
|
char currnode[MAXNAMELEN];
|
|
TMT *currvt = NULL;
|
|
TMT *outvt = NULL;
|
|
stdin = freopen(NULL, "rb", stdin);
|
|
if (stdin == NULL) {
|
|
exit(1);
|
|
}
|
|
while (1) {
|
|
length = fread(&cmd, 4, 1, stdin);
|
|
if (length < 0)
|
|
continue;
|
|
length = cmd & 536870911;
|
|
cmd = cmd >> 29;
|
|
if (cmd == SETNODE) {
|
|
currnode[length] = 0;
|
|
cmd = fread(currnode, 1, length, stdin);
|
|
if (cmd < 0)
|
|
continue;
|
|
currvt = set_termentbyname(currnode);
|
|
} else if (cmd == WRITE) {
|
|
if (currvt == NULL)
|
|
currvt = set_termentbyname("");
|
|
cmdbuf[length] = 0;
|
|
cmd = fread(cmdbuf, 1, length, stdin);
|
|
if (cmd < 0)
|
|
continue;
|
|
tmt_write(currvt, cmdbuf, length);
|
|
} else if (cmd == READBUFF) {
|
|
cmdbuf[length] = 0;
|
|
cmd = fread(cmdbuf, 1, length, stdin);
|
|
if (cmd < 0)
|
|
continue;
|
|
outvt = get_termentbyname(cmdbuf);
|
|
if (outvt != NULL) {
|
|
dump_vt(outvt);
|
|
}
|
|
}
|
|
}
|
|
}
|