syndicate-nim/src/sam/durings.nim

44 lines
1.3 KiB
Nim

# SPDX-FileCopyrightText: ☭ Emery Hemingway
# SPDX-License-Identifier: Unlicense
import std/[hashes, tables]
import preserves
import ./[actors, patterns]
type
DuringProc* = proc (a: Value; h: Handle): FacetProc {.gcsafe.}
DuringActionKind = enum null, dead, act
DuringAction = object
case kind: DuringActionKind
of null, dead: discard
of act:
retractProc: FacetProc
DuringEntity {.final.}= ref object of Entity
publishProc: DuringProc
assertionMap: Table[Handle, DuringAction]
proc duringPublish(e: Entity; v: Value; h: Handle) {.cps: Cont.} =
var de = DuringEntity(e)
let handler = de.handler(de.facet, a.value, h)
let g = de.assertionMap.getOrDefault h
case g.kind
of null, dead:
de.assertionMap[h] = DuringAction(kind: act, action: handler)
of act:
raiseAssert("during: duplicate handle in publish: " & $h)
proc duringRetract(e: Entity; h: Handle) {.cps: Cont.} =
var de = DuringEntity(e)
let g = de.assertionMap.getOrDefault h
case g.kind
of null:
de.assertionMap[h] = DuringAction(kind: dead)
of dead:
raiseAssert("during: duplicate handle in retract: " & $h)
of act:
de.assertionMap.del h
if not g.action.isNil:
g.action(de.facet)
proc during*(cb: DuringProc): DuringEntity = DuringEntity(cb: cb)