2023-05-17 09:40:41 +00:00
|
|
|
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
|
|
|
# SPDX-License-Identifier: Unlicense
|
|
|
|
|
2024-03-14 13:14:51 +00:00
|
|
|
import std/[oserrors, parseopt, posix, strutils]
|
|
|
|
import pkg/sys/[files, handles, ioqueue]
|
2023-10-21 16:38:28 +00:00
|
|
|
import preserves, syndicate, syndicate/relays
|
2023-05-17 09:40:41 +00:00
|
|
|
|
|
|
|
type
|
|
|
|
Present {.preservesRecord: "Present".} = object
|
|
|
|
username: string
|
|
|
|
Says {.preservesRecord: "Says".} = object
|
|
|
|
who, what: string
|
|
|
|
|
2024-03-14 13:14:51 +00:00
|
|
|
proc syncAndStop(facet: Facet; cap: Cap) =
|
|
|
|
## Stop the actor responsible for `facet` after
|
|
|
|
## synchronizing with `cap`.
|
|
|
|
run(facet) do (turn: var Turn):
|
|
|
|
sync(turn, cap, stopActor)
|
|
|
|
|
|
|
|
proc readStdin(facet: Facet; ds: Cap; username: string) {.asyncio.} =
|
|
|
|
let
|
|
|
|
fd = stdin.getOsFileHandle()
|
|
|
|
flags = fcntl(fd.cint, F_GETFL, 0)
|
|
|
|
if flags < 0:
|
|
|
|
raiseOSError(osLastError())
|
|
|
|
if fcntl(fd.cint, F_SETFL, flags or O_NONBLOCK) < 0:
|
|
|
|
raiseOSError(osLastError())
|
|
|
|
let
|
|
|
|
file = newAsyncFile(FD fd)
|
|
|
|
buf = new string
|
|
|
|
buf[].setLen(0x1000)
|
|
|
|
while true:
|
|
|
|
let n = read(file, buf)
|
|
|
|
if n < 1:
|
|
|
|
stderr.writeLine "test_chat calls stopsActor ", facet.actor
|
|
|
|
syncAndStop(facet, ds)
|
|
|
|
return
|
|
|
|
else:
|
|
|
|
var msg = buf[][0..<n].strip
|
|
|
|
proc send(turn: var Turn) =
|
|
|
|
message(turn, ds, Says(who: username, what: msg))
|
|
|
|
run(facet, send)
|
2023-05-17 09:40:41 +00:00
|
|
|
|
2023-07-24 15:13:36 +00:00
|
|
|
proc chat(turn: var Turn; ds: Cap; username: string) =
|
2024-03-15 10:21:24 +00:00
|
|
|
during(turn, ds, ?:Present) do (who: string):
|
|
|
|
echo who, " joined"
|
|
|
|
do:
|
|
|
|
echo who, " left"
|
2023-05-18 10:20:44 +00:00
|
|
|
|
2024-03-15 10:21:24 +00:00
|
|
|
onMessage(turn, ds, ?:Says) do (who: string, what: string):
|
|
|
|
echo who, ": ", what
|
2023-05-18 10:20:44 +00:00
|
|
|
|
2024-03-15 10:21:24 +00:00
|
|
|
discard publish(turn, ds, Present(username: username))
|
|
|
|
|
|
|
|
discard trampoline:
|
|
|
|
whelp readStdin(turn.facet, ds, username)
|
2023-05-18 10:20:44 +00:00
|
|
|
|
2023-05-17 09:40:41 +00:00
|
|
|
proc main =
|
2023-10-21 16:38:28 +00:00
|
|
|
var username = ""
|
|
|
|
|
2023-05-17 09:40:41 +00:00
|
|
|
for kind, key, val in getopt():
|
|
|
|
if kind == cmdLongOption:
|
|
|
|
case key
|
|
|
|
of "user", "username":
|
|
|
|
username = val
|
|
|
|
|
2023-11-02 13:53:59 +00:00
|
|
|
if username == "":
|
|
|
|
stderr.writeLine "--user: unspecified"
|
|
|
|
else:
|
2024-03-14 13:14:51 +00:00
|
|
|
runActor("chat") do (turn: var Turn):
|
|
|
|
resolveEnvironment(turn) do (turn: var Turn; ds: Cap):
|
2023-10-21 16:38:28 +00:00
|
|
|
chat(turn, ds, username)
|
2023-05-17 09:40:41 +00:00
|
|
|
|
|
|
|
main()
|