Compare commits
3 Commits
55fcbb0754
...
515ef22805
Author | SHA1 | Date |
---|---|---|
Emery Hemingway | 515ef22805 | |
Emery Hemingway | dc420c1a22 | |
Emery Hemingway | 21bdaeb26b |
|
@ -3,7 +3,7 @@
|
|||
|
||||
import std/macros
|
||||
import preserves
|
||||
import syndicate/[actors, patterns]
|
||||
import syndicate/[actors, dataspaces, patterns]
|
||||
export patterns
|
||||
|
||||
proc wrapPublishHandler(handler: NimNode): NimNode =
|
||||
|
@ -30,15 +30,20 @@ proc wrapPublishHandler(handler: NimNode): NimNode =
|
|||
var
|
||||
varSectionOuter = newNimNode(nnkVarSection, handler).add(
|
||||
newIdentDefs(valuesSym, valuesTuple))
|
||||
body = newStmtList(varSectionInner, handler[6])
|
||||
publishBody = newStmtList(varSectionInner, handler[6])
|
||||
turnSym = ident"turn"
|
||||
handleSym = ident"handle"
|
||||
handlerSym = genSym(nskProc, "publish")
|
||||
onRetractIdent = ident"onRetract"
|
||||
quote do:
|
||||
proc `handlerSym`(_: Entity; `turnSym`: var Turn; bindings: Assertion; `handleSym`: Handle) =
|
||||
proc `handlerSym`(entity: Entity; `turnSym`: var Turn; bindings: Assertion; `handleSym`: Handle) =
|
||||
`varSectionOuter`
|
||||
if fromPreserve(`valuesSym`, bindings):
|
||||
`body`
|
||||
template `onRetractIdent`(retractBody: untyped): untyped =
|
||||
proc callback(e: Entity; turn: var Turn; h: Handle) =
|
||||
retractBody
|
||||
entity.retractImpl = callback # TODO: fine to clobber previous callback?
|
||||
`publishBody`
|
||||
|
||||
proc wrapMessageHandler(handler: NimNode): NimNode =
|
||||
handler.expectKind nnkDo
|
||||
|
|
|
@ -3,13 +3,11 @@
|
|||
|
||||
import std/[hashes, macros, tables]
|
||||
import preserves
|
||||
import ../syndicate/protocols/[dataspace, dataspacePatterns]
|
||||
import ./actors, ./bags
|
||||
import ./actors, ./bags, ./patterns, ./protocols/dataspace
|
||||
|
||||
from ../syndicate/protocols/protocol import Handle
|
||||
from ./protocols/protocol import Handle
|
||||
|
||||
type
|
||||
Pattern* = dataspacePatterns.Pattern[Ref]
|
||||
Observe = dataspace.Observe[Ref]
|
||||
Turn = actors.Turn
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import std/[macros, tables]
|
||||
|
||||
import preserves
|
||||
import ../syndicate/protocols/dataspacePatterns
|
||||
import ./protocols/dataspacePatterns
|
||||
from ./actors import Ref
|
||||
|
||||
export dataspacePatterns.`$`
|
||||
|
@ -17,9 +17,6 @@ type
|
|||
DCompound* = dataspacePatterns.DCompound[Ref]
|
||||
Pattern* = dataspacePatterns.Pattern[Ref]
|
||||
|
||||
proc `?`*(): Pattern =
|
||||
Pattern(orKind: PatternKind.DDiscard)
|
||||
|
||||
proc `?`*(d: DBind): Pattern =
|
||||
Pattern(orKind: PatternKind.DBind, dbind: d)
|
||||
|
||||
|
@ -29,20 +26,33 @@ proc `?`*(d: DLit): Pattern =
|
|||
proc `?`*(d: DCompound): Pattern =
|
||||
Pattern(orKind: PatternKind.DCompound, dcompound: d)
|
||||
|
||||
proc `?`*(s: string): Pattern =
|
||||
?DLit(value: toPreserve(s, Ref))
|
||||
|
||||
proc arity(T: typedesc): int =
|
||||
var t: ptr T # a hack to iterate the fields of a non-existent instance
|
||||
for _ in fields(t[]): inc result
|
||||
var t: T # a hack to iterate the fields of a non-existent instance
|
||||
for _ in fields(t): inc result
|
||||
|
||||
proc `?_`*(): Pattern = Pattern(orKind: PatternKind.DDiscard)
|
||||
|
||||
proc `?*`*(): Pattern = ?DBind(pattern: `?_`())
|
||||
|
||||
proc `?`*(T: typedesc; bindings: openArray[(int, Pattern)]): Pattern =
|
||||
## Pattern constructor operator.
|
||||
when T.hasCustomPragma(preservesRecord):
|
||||
var
|
||||
label = tosymbol(T.getCustomPragmaVal(preservesRecord), Ref)
|
||||
members: Table[BiggestInt, Pattern]
|
||||
for (i, p) in bindings:
|
||||
members[BiggestInt i] = ?DBind(pattern: p)
|
||||
var label = tosymbol(T.getCustomPragmaVal(preservesRecord), Ref)
|
||||
result = ?DCompound(
|
||||
orKind: DCompoundKind.rec,
|
||||
rec: DCompoundRec(
|
||||
ctor: CRec(label: label, arity: T.arity),
|
||||
members: members))
|
||||
members: toTable bindings))
|
||||
else:
|
||||
{.error: "no custom pragma on " & $T.}
|
||||
|
||||
proc observe*(pat: Pattern): Pattern =
|
||||
# TODO: why doesn't Observe from ./protocols/dataspace.nim work?
|
||||
?DCompound(
|
||||
orKind: DCompoundKind.rec,
|
||||
rec: DCompoundRec(
|
||||
ctor: CRec(label: toSymbol("Observe", Ref), arity: 2),
|
||||
members: toTable {0 : pat}))
|
||||
|
|
|
@ -5,7 +5,7 @@ import
|
|||
type
|
||||
CRec*[E] {.preservesRecord: "rec".} = ref object
|
||||
`label`*: Preserve[E]
|
||||
`arity`*: BiggestInt
|
||||
`arity`*: int
|
||||
|
||||
DLit*[E] {.preservesRecord: "lit".} = ref object
|
||||
`value`*: Preserve[E]
|
||||
|
@ -14,19 +14,19 @@ type
|
|||
`pattern`*: Pattern[E]
|
||||
|
||||
DDiscard* {.preservesRecord: "_".} = object
|
||||
|
||||
|
||||
CArr* {.preservesRecord: "arr".} = object
|
||||
`arity`*: BiggestInt
|
||||
`arity`*: int
|
||||
|
||||
DCompoundKind* {.pure.} = enum
|
||||
`rec`, `arr`, `dict`
|
||||
DCompoundRec*[E] {.preservesRecord: "compound".} = ref object
|
||||
`ctor`*: CRec[E]
|
||||
`members`*: Table[BiggestInt, Pattern[E]]
|
||||
`members`*: Table[int, Pattern[E]]
|
||||
|
||||
DCompoundArr*[E] {.preservesRecord: "compound".} = ref object
|
||||
`ctor`*: CArr
|
||||
`members`*: Table[BiggestInt, Pattern[E]]
|
||||
`members`*: Table[int, Pattern[E]]
|
||||
|
||||
DCompoundDict*[E] {.preservesRecord: "compound".} = ref object
|
||||
`ctor`*: CDict
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
|
||||
import std/[asyncdispatch, options, tables]
|
||||
import preserves, preserves/parse
|
||||
import ../syndicate/protocols/[protocol, sturdy]
|
||||
import ./actors, ./dataspaces
|
||||
import ./actors, ./dataspaces, ./protocols/[protocol, sturdy]
|
||||
|
||||
type Oid = sturdy.Oid
|
||||
|
||||
|
@ -280,13 +279,13 @@ proc dispatch(relay: Relay; v: Preserve[WireRef]) =
|
|||
close relay
|
||||
|
||||
|
||||
proc recv(relay: Relay; buf: seq[byte]) =
|
||||
proc recv(relay: Relay; buf: string) =
|
||||
# var pkt = decodePreserves(buf, WireRef)
|
||||
echo "S: ", buf
|
||||
var pkt = cast[Preserve[WireRef]](
|
||||
parsePreserves(cast[string](buf), sturdy.WireRef[void]))
|
||||
parsePreserves(buf, sturdy.WireRef[void]))
|
||||
# the compiler cannot convert `Preserve[void]` to `Preserve[WireRef[Ref]]`
|
||||
# so convert to `Preserve[WireRef[void]]` and cast.
|
||||
echo "S: ", pkt
|
||||
dispatch(relay, pkt)
|
||||
|
||||
type
|
||||
|
@ -361,13 +360,16 @@ proc connectUnix*(turn: var Turn; path: string; cap: SturdyRef; bootProc: During
|
|||
proc setup(turn: var Turn; relay: Relay) =
|
||||
let facet = turn.activeFacet
|
||||
proc recvCb(pktFut: Future[string]) {.gcsafe.} =
|
||||
let buf = cast[seq[byte]](pktFut.read)
|
||||
if buf.len == 0:
|
||||
if pktFut.failed:
|
||||
run(facet) do (turn: var Turn): stopActor(turn)
|
||||
else:
|
||||
relay.recv(buf )
|
||||
socket.recv(recvSize).addCallback(recvCb)
|
||||
# TODO: should this need be callSoon?
|
||||
let buf = pktFut.read
|
||||
if buf.len == 0:
|
||||
run(facet) do (turn: var Turn): stopActor(turn)
|
||||
else:
|
||||
relay.recv(buf)
|
||||
socket.recv(recvSize).addCallback(recvCb)
|
||||
# TODO: should this need be callSoon?
|
||||
socket.recv(recvSize).addCallback(recvCb)
|
||||
turn.activeFacet.actor.atExit do (turn: var Turn): close(socket)
|
||||
discard publish(turn, connectionClosedRef, true)
|
||||
|
|
|
@ -3,24 +3,16 @@
|
|||
|
||||
import std/[asyncdispatch, strutils]
|
||||
import preserves, preserves/parse
|
||||
import syndicate, syndicate/protocols/[simpleChatProtocol]
|
||||
import syndicate/[actors, capabilities, dataspaces, patterns, relay]
|
||||
|
||||
import syndicate,
|
||||
syndicate/[actors, capabilities, dataspaces, patterns, relay],
|
||||
syndicate/protocols/[simpleChatProtocol]
|
||||
from syndicate/protocols/protocol import Handle
|
||||
|
||||
from os import getCurrentProcessId
|
||||
|
||||
when defined(linux):
|
||||
proc getentropy(buf: pointer; bufLen: csize_t): cint {.
|
||||
importc, header: "sys/random.h".}
|
||||
|
||||
proc mint(): SturdyRef =
|
||||
|
||||
#var key: array[32, byte]
|
||||
#doAssert getEntropy(addr key[0], csize_t key.len) == 0
|
||||
#mint(key, "syndicate")
|
||||
let pr = parsePreserves("""<ref "syndicate" [] #x"a6480df5306611ddd0d3882b546e1977">""", Ref)
|
||||
doAssert fromPreserve(result, pr)
|
||||
var key: array[16, byte]
|
||||
mint(key, "syndicate")
|
||||
|
||||
waitFor runActor("chat") do (turn: var Turn):
|
||||
|
||||
|
@ -40,12 +32,12 @@ waitFor runActor("chat") do (turn: var Turn):
|
|||
|
||||
updateUsername(turn, "user" & $getCurrentProcessId())
|
||||
|
||||
onPublish(turn, ds, Present ? {0: `?`()}) do (username: string):
|
||||
onPublish(turn, ds, Present ? {0: `?*`()}) do (username: string):
|
||||
echo username, " arrived"
|
||||
#onRetract:
|
||||
# echo username, " left"
|
||||
onRetract:
|
||||
echo username, " left"
|
||||
|
||||
onMessage(turn, ds, Says ? {0: `?`(), 1: `?`()}) do (who: string; what: string):
|
||||
onMessage(turn, ds, Says ? {0: `?*`(), 1: `?*`()}) do (who: string; what: string):
|
||||
echo who, ": ", what
|
||||
|
||||
message(turn, ds, Says(who: username, what: "hello"))
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
#!/usr/bin/env spry
|
||||
|
||||
title = "Simple Chat Demo"
|
||||
|
||||
# Initialize libui
|
||||
uiInit
|
||||
|
||||
username = "user"
|
||||
|
||||
menu = newMenu "Menu"
|
||||
|
||||
# menu addItem: "Username" onClicked: [
|
||||
# dialog = newWindow: "Username" width: 200 height: 40 hasBar: false
|
||||
# entry = newEntryText: username onChanged: []
|
||||
# quitit = newButton: "Quit" onClicked: [
|
||||
# destroy dialog
|
||||
# true
|
||||
# ]
|
||||
# layout = newHorizontalBox
|
||||
# #layout add: entry stretch: true
|
||||
# layout.add: quitit stretch: false
|
||||
# group = newGroup "Username"
|
||||
# group setChild: layout
|
||||
# dialog setChild: quitit
|
||||
# dialog show
|
||||
# ]
|
||||
|
||||
menu menuAppendAboutItem
|
||||
|
||||
menu addQuitItemShouldClose: [
|
||||
win destroy
|
||||
uiQuit
|
||||
true
|
||||
]
|
||||
|
||||
# Create a new Window
|
||||
win = newWindow: title width: 640 height: 400 hasBar: true
|
||||
win margined: true
|
||||
|
||||
# create text boxes
|
||||
scrollback = newMultilineEntryText
|
||||
scrollback readonly: true
|
||||
|
||||
sendEntry = newMultilineEntryText
|
||||
|
||||
# create layouts
|
||||
layout = newVerticalBox
|
||||
sendBox = newHorizontalBox
|
||||
|
||||
# Some buttons and their handlers
|
||||
sendButton = newButton: "Send" onClicked: [
|
||||
msg = (sendEntry text)
|
||||
msg != "" then: [
|
||||
scrollback addText: (msg, "\x0a")
|
||||
sendEntry text: ""
|
||||
]
|
||||
]
|
||||
|
||||
# Group
|
||||
group = newGroup "Workspace"
|
||||
group margined: false
|
||||
group setChild: layout
|
||||
|
||||
sendBox add: sendEntry stretch: true
|
||||
sendBox add: sendButton stretch: false
|
||||
|
||||
# Put things in the boxes
|
||||
layout padded: true
|
||||
layout add: scrollback stretch: true
|
||||
layout add: sendBox stretch: false
|
||||
|
||||
# Add box to window
|
||||
win setChild: group
|
||||
|
||||
# Set initial text
|
||||
sendEntry text: "compose a message here"
|
||||
|
||||
# Close handler
|
||||
closeHandler = [
|
||||
win destroy
|
||||
uiQuit
|
||||
true
|
||||
]
|
||||
|
||||
# Set a handler on closing window
|
||||
win onClosingShouldClose: [ true ]
|
||||
|
||||
# Show the window
|
||||
win show
|
||||
|
||||
# Enter libui's event loop
|
||||
uiMain
|
Loading…
Reference in New Issue