Open inv2004 opened 5 months ago
getKeys
example:
while true:
for key in getKeys():
case key
of Key.None: discard
of Key.Escape, Key.Q: exitProc()
else:
tb.write(8, 4, ' '.repeat(31))
tb.write(2, 4, resetStyle, "Key pressed: ", fgGreen, $key)
tb.display()
sleep(20)
getKey
with buffer example:
Not sure if display should be in the inner while loop or not
while true:
var key = getKey()
while key != Key.None:
case key
of Key.None: discard
of Key.Escape, Key.Q: exitProc()
else:
tb.write(8, 4, ' '.repeat(31))
tb.write(2, 4, resetStyle, "Key pressed: ", fgGreen, $key)
key = getKey()
tb.display()
sleep(20)
getKey
with buffer example:
Yeah, so this is how I want the API to look like, getKeys
is an unnecessary complication.
Don't you think the double while loop looks not obvious and even ugly? Also, it is just iterator over while simulation.
Don't you think the double while loop looks not obvious and even ugly? Also, it is just iterator over while simulation.
I want to have a minimal API surface. If you really want getKeys()
, you can trivially implement it in your code.
Also, you don't need a double while loop if you don't particularly care about 20ms delay between processing keypresses now and then. Or you can do 5 or 10ms sleep. Again, up to the client code how to deal with this, the minimum we need is getKey
.
The only good, in my opinion, solution to avoid the cpu usage and to avoid sleep without any delays is:
while true:
let key = getKeyWithTimeout(1000)
case key
of Key.None:
buf.add '.'
of Key.Escape, Key.Q: exitProc()
else:
buf.add $key
if buf.len > 20:
buf = buf[^20..^1]
tb.write(8, 4, ' '.repeat(31))
tb.write(2, 4, resetStyle, "Key pressed: ", fgGreen, buf)
tb.display()
Thanks for the examples @inv2004, but I've said all I wanted on the matter. getKeyWithTimeout
is against my vision how an immediate mode UI API should operate.
I only want getKey
, and getKeys
needs to become private. If you feel like making the change, a PR is welcome, otherwise I will do it in the coming days.
Thank you.
Actually @inv2004, thought about it a bit more and getKeyWithTimeout(20)
or something could work, yeah. Your 1000 ms wait time just threw me off ;) If you want to work on this, I'm happy for you to introduce getKeyWithTimeout
in addition to getKey
. Then people can decide which one to use.
I am working on getKeyWithTimeout
When it is ready - getKeys can be rolled back
The main challenge is to avoid any addition buffers and to make parser for long sequences works directly on stdin next char
@inv2004 Please make sure that your async solution works not only in Linux terminals but also on Windows in CMD.EXE
and on macOS. All illwill features need to be cross-platform. I don't have much time and interest to figure this out, so getKey
+ sleep is always the fallback option if you can't do Windows & macOS 😏
Done here https://github.com/johnnovak/illwill/pull/47
BTW: win api looks 10 times better than the stdin escapes
-- added -- Please check macos by yourself
Here is an iterator for someone who wants pretty monotonic ticks without sleep:
iterator keyEachSec(): Key =
var timeout = 1000
while true:
let a = getMonoTime().ticks
let k = getKeyWithTimeout(timeout)
if k == Key.None:
timeout = 1000
else:
let b = int((getMonoTime().ticks - a) div 1000000)
timeout = timeout - (b mod 1000)
yield k
Initial example in readme: