From 6718a3b0409ea06c1750a3d9149ba0215e7f28d8 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Thu, 6 Jun 2024 10:46:27 +0300 Subject: [PATCH] esc-printer-driver: async device file --- src/esc_printer_driver.nim | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/esc_printer_driver.nim b/src/esc_printer_driver.nim index a9c38dc..c7aaf03 100644 --- a/src/esc_printer_driver.nim +++ b/src/esc_printer_driver.nim @@ -4,12 +4,15 @@ ## ESC/P printer control actor. import - std/[cmdline, oserrors, posix, sets], + std/[cmdline, oserrors, posix, sequtils, sets], + pkg/sys/[files, ioqueue], preserves, preserves/sugar, syndicate, syndicate/relays, syndicate/protocols/[gatekeeper, sturdy], ./private/esc_p +from pkg/sys/handles import FD + proc echo(args: varargs[string, `$`]) {.used.} = stderr.writeLine(args) @@ -17,12 +20,26 @@ type HandleSet = HashSet[Handle] Printer = ref object of Entity - device: cint + device: AsyncFile boldHandles, italicHandles, superscriptHandles, subscriptHandles: HandleSet + buffer: seq[byte] + isBusy: bool + +proc flush(printer: Printer) {.asyncio.} = + printer.isBusy = true + while printer.buffer.len > 0: + let n = printer.device.write(printer.buffer) + if n > 0: + printer.buffer.delete(0, n) + elif n < 0: + osLastError().osErrorMsg().quit() + printer.isBusy = false proc write(printer: Printer; s: string) {.inline.} = - if posix.write(printer.device, s[0].addr, s.len) < 0: - osLastError().osErrorMsg().quit() + printer.buffer.add cast[seq[byte]](s) + if not printer.isBusy: + discard trampoline: + whelp printer.flush() proc writeLine(printer: Printer; s: string) {.inline.} = printer.write(s) @@ -73,7 +90,9 @@ let devicePath = paramStr(1) proc openPrinter(turn: Turn): Printer = new result result.facet = turn.facet - result.device = posix.open(devicePath, O_WRONLY, 0) + let fd = posix.open(devicePath, O_WRONLY or O_NONBLOCK, 0) + if fd < 0: osLastError().osErrorMsg().quit() + result.device = newAsyncFile(FD fd) result.write(InitializePrinter) runActor(devicePath) do (turn: Turn):