I have the following loop:
while true:
var
timeout = false
readKeys = false
block:
var
keyFuture: Future[string]
timeoutFuture: Future[void]
sequence: string
keyFuture = this.terminal.key()
if keyTranslator.activeSequence.len > 0:
debugEcho "active sequence: ", keyTranslator.activeSequence, ", timeout"
timeoutFuture = sleepAsync(300) # TODO: make constant
timeout = true
timeoutFuture.callback =
proc () =
if not keyFuture.finished:
keyFuture.complete("")
debugEcho "wait…"
yield keyFuture
debugEcho "…done"
sequence = keyFuture.read
asyncCheck keyFuture
if timeout:
timeoutFuture.clearCallbacks
debugEcho "read sequence: ", sequence.escape
readKeys = keyTranslator.keySequence(sequence)
debugEcho "end block"
debugEcho "readKeys=", readKeys
if readKeys:
for k in keyTranslator.read:
debugEcho "read key: ", k.toUTF8.escape, " (", k.int.toHex, ")"
if k == F1.Rune: # XXX for testing only
debugEcho "F1!"
this.isRunning = false
return
if this.screen.focus != -1:
this.send KeyEvent(this.time, this.screen.focus, k)
debugEcho "end loop"
This gets the following error on the yield statement after once the timeoutFuture was active and completed the keyFuture and then the keyFuture is used without the timeout:
Error: unhandled exception: An attempt was made to complete a Future more than once. Details:
Future ID: 510
Created in proc: asyncfile.read
Stack trace to moment of creation:
/home/j/Personal/Projects/nim/term/src/test2.nim(55) test2
/home/j/Personal/Projects/nim/term/src/test2.nim(52) main
/home/j/Personal/Projects/nim/term/src/term/engine.nim(211) run
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncdispatch.nim(1576) poll
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncdispatch.nim(1340) runOnce
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncdispatch.nim(210) processPendingCallbacks
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncmacro.nim(34) keyboardInputNimAsyncContinue
/home/j/Personal/Projects/nim/term/src/term/engine.nim(173) keyboardInputIter
/home/j/Personal/Projects/nim/term/src/term/term.nim(63) key
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncfile.nim(209) read
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncfutures.nim(110) newFuture
Contents (string):
Stack trace to moment of secondary completion:
Traceback (most recent call last)
/home/j/Personal/Projects/nim/term/src/test2.nim(55) test2
/home/j/Personal/Projects/nim/term/src/test2.nim(52) main
/home/j/Personal/Projects/nim/term/src/term/engine.nim(211) run
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncdispatch.nim(1576) poll
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncdispatch.nim(1306) runOnce
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncdispatch.nim(1214) processBasicCallbacks
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncfile.nim(290) cb
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncfutures.nim(211) complete
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncfutures.nim(154) checkFinished [FutureError]
I don't understand why the async system wants to complete the keyFuture when it was already completed. I put the keyFuture into a block that should remove the future all together. Could this be a bug in asyncdispatch/asyncfutures?