satoshinm / NetCraft

Web-based fork of fogleman/Craft ⛺
https://satoshinm.github.io/NetCraft/
MIT License
57 stars 13 forks source link

Add scrollable chat console (up/down keys). Closes GH-83 #129

Closed satoshinm closed 7 years ago

satoshinm commented 7 years ago

https://github.com/satoshinm/NetCraft/issues Scrolling up to view chat history

satoshinm commented 7 years ago

So far, increased the ring buffer messages[], while constraining its visibility to the same number of lines as before. It can be helpful to simulate this algorithm to visualize how it works and get the state machine working properly, for this purpose, whipped up a simple Python script, simulating the lines scrolling off while showing 4 lines would be visible of the 20-line buffer:

MAX_MESSAGES = 20
MAX_VISIBLE_MESSAGES = 4
console=[""] * MAX_MESSAGES
message_index = 0
message_view_index = 0

def show():
    print "--- message_index=",message_index," message_view_index=",message_view_index
    for i in range(0, MAX_MESSAGES):
        mark = ""
        if i == message_index: mark += "idx"
        if i == message_view_index: mark += "(v)"
        print mark,"\t",i,console[i]

    for i in range(0, MAX_VISIBLE_MESSAGES):
        index = (message_view_index + i) % MAX_MESSAGES
        print "%2d %s" % (i,console[index])
    print "---"

def add(line):
    global message_index, message_view_index
    console[message_index] = line
    message_index = (message_index + 1) % MAX_MESSAGES

    message_view_index = message_index - MAX_VISIBLE_MESSAGES
    if message_view_index < 0: message_view_index += MAX_MESSAGES

def clear():
    import os
    os.system("clear")

add("A")
add("B")
add("C")
add("D")
show()

add("E")
show()

add("F")
show()

for i in range(0, 15):
    add(chr(ord("G") + i))
    show()

def sim():
    import sys, time
    j = 0
    while True:
        #sys.stdout.write("> ")
        #line = raw_input().strip()
        j += 1
        line = "#%s" % (j,)
        add(line)
        clear()
        show()
        time.sleep(0.1)

if __name__ == "__main__":
    sim()
satoshinm commented 7 years ago
import sys, time
MAX_MESSAGES = 20
MAX_VISIBLE_MESSAGES = 4
console=[""] * MAX_MESSAGES
message_index = 0
message_view_index = 0
message_view_offset = 0

def show():
    print "--- message_index=",message_index," message_view_index=",message_view_index," message_view_offset=",message_view_offset
    for i in range(0, MAX_MESSAGES):
        mark = ""
        if i == message_index: mark += "idx"
        if i == message_view_index: mark += "(v)"
        print mark,"\t",i,console[i]

    for i in range(0, MAX_VISIBLE_MESSAGES):
        index = (message_view_index + i + message_view_offset) % MAX_MESSAGES
        print "%2d %s" % (i,console[index])
    print "---"

def add(line):
    global message_index, message_view_index
    console[message_index] = line
    message_index = (message_index + 1) % MAX_MESSAGES

    message_view_index = message_index - MAX_VISIBLE_MESSAGES
    if message_view_index < 0: message_view_index += MAX_MESSAGES

def clear():
    import os
    os.system("clear")

add("A")
add("B")
add("C")
add("D")
show()

add("E")
show()

add("F")
show()

for i in range(0, 15):
    add(chr(ord("G") + i))
    show()

def sim():
    j = 0
    for i in range(0,50):
        #sys.stdout.write("> ")
        #line = raw_input().strip()
        j += 1
        line = "#%s" % (j,)
        add(line)
        clear()
        show()
        #time.sleep(0.1)

def sim2():
    global message_view_index, message_view_offset
    while True:
        sys.stdout.write("> ")
        cmd = raw_input().strip()
        if cmd == 'u':
            #message_view_offset -= 1
            message_view_index = (message_view_index - 1) % MAX_MESSAGES
        elif cmd == 'd':
            #message_view_offset += 1
            message_view_index = (message_view_index + 1) % MAX_MESSAGES
        else:
            add(cmd)
        clear()
        show()

if __name__ == "__main__":
    sim()
    sim2()

Added arrow keys to scroll, but doesn't handle boundaries well in the ring-buffer. Testing with simulation script above.

satoshinm commented 7 years ago

Simulated console for debugging:

@@ -1911,24 +1911,6 @@ void add_message(const char *text) {

      g->message_view_index = g->message_index - MAX_VISIBLE_MESSAGES;
      if (g->message_view_index < 0) g->message_view_index += MAX_MESSAGES;
 -
 -    printf("---\n");
 -    for (int i = 0; i < MAX_MESSAGES; ++i) {
 -        if (g->messages[i] && *g->messages[i]) {
 -            printf("%s%s %d. %s\n",
 -                    (i == g->message_index ? "i" : " "),
 -                    (i == g->message_view_index ? "v" : " "),
 -                    i, g->messages[i]);
 -        }
 -    }
 -    printf("---\n");
 -    // SHOW_CHAT_TEXT
 -    printf("Simulated console: (g->message_index=%d)\n", g->message_index);
 -    for (int i = 0; i < MAX_VISIBLE_MESSAGES; i++) {
 -        int index = (g->message_view_index + i) % MAX_MESSAGES;
 -        //index = (index + g->message_view_index) % MAX_MESSAGES;
 -        printf("LINE(i=%d, index=%d): %s\n", i, index, g->messages[index]);
 -    }
  }