have you ever tried making a cps function that takes a closure as an argument?

This commit is contained in:
Emery Hemingway 2024-02-16 13:21:28 +00:00
parent da93f9eb1f
commit fe268dea8d
2 changed files with 21 additions and 18 deletions

View File

@ -196,29 +196,21 @@ macro during*(ds: Cap; pattern: Pattern; publishBody: untyped) =
discard observe(activeTurn(), `ds`, `pattern`, during(`callbackSym`))
]#
type BootProc = proc (ds: Cap)
#[
proc runActor*(name: string; bootProc: BootProc) =
## Run an `Actor` to completion.
let actor = newActor(name)
let actor = bootDataspace(name, bootProc)
while actor.running:
ioqueue.run()
proc runActor*(name: string; bootProc: DeprecatedBootProc) {.deprecated.} =
## Run an `Actor` to completion.
runActor(name) do (turn: Turn, ds: Cap):
bootProc(ds, turn)
]#
proc wrapHandler(body: NimNode; ident: string): NimNode =
var sym = genSym(nskProc, ident)
quote do:
proc `sym`(cont: Cont): Cont {.cpsMagic.} =
proc `sym`() =
`body`
nil
macro onStop*(body: untyped) =
let
handlerDef = wrapHandler(body, "onStop")
handlerSym = handlerDef[0]
result = quote do:
`handlerDef`
addOnStopHandler(`handlerSym`)
#[
macro onStop*(body: untyped) =
quote do:
block:
@ -227,3 +219,4 @@ macro onStop*(body: untyped) =
if facet.stopped():
`body`
return
]#

View File

@ -28,12 +28,15 @@ type
FacetState = enum fFresh, fRunning, fEnded
Callback* = proc () {.nimcall.}
Facet* = ref object
## https://synit.org/book/glossary.html#facet
actor: Actor
parent: Facet
children: seq[Facet]
stopHandlers: HandlerDeque
stopCallbacks: seq[Callback]
state: FacetState
when traceSyndicate:
id: FacetId
@ -221,6 +224,9 @@ proc stop(turn; facet; reason: FacetStopReason) =
var c = whelp runNextFacetStop()
c.facet = facet
complete(turn, c)
while facet.stopCallbacks.len > 0:
var cb = facet.stopCallbacks.pop()
cb()
while facet.children.len > 0:
stop(turn, facet.children.pop(), FacetStopReason.parentStopping)
when traceSyndicate:
@ -335,3 +341,7 @@ proc sync*(cap: Cap) {.syndicate.} =
proc installStopHook*(c: Cont, facet: Facet): Cont {.cpsMagic.} =
facet.stopHandlers.add(c.fn)
return c
proc addOnStopHandler*(c: Cont; cb: Callback): Cont {.cpsMagic.} =
c.facet.stopCallbacks.add(cb)
result = c