syndicate-nim/src/sam/durings.nim

50 lines
1.4 KiB
Nim
Raw Normal View History

2024-02-16 12:58:17 +00:00
# SPDX-FileCopyrightText: ☭ Emery Hemingway
2022-03-10 23:30:07 +00:00
# SPDX-License-Identifier: Unlicense
import std/[hashes, tables]
2022-03-10 23:30:07 +00:00
import preserves
2024-02-24 16:51:41 +00:00
import pkg/cps
2024-02-19 22:40:40 +00:00
import ./[actors, patterns]
2022-03-10 23:30:07 +00:00
type
2024-02-24 19:27:08 +00:00
DuringProc* = proc (f: Facet; a: Value; h: Handle): FacetProc {.gcsafe.}
2022-03-10 23:30:07 +00:00
DuringActionKind = enum null, dead, act
DuringAction = object
case kind: DuringActionKind
of null, dead: discard
of act:
2024-02-19 22:40:40 +00:00
retractProc: FacetProc
2024-02-15 10:52:12 +00:00
DuringEntity {.final.}= ref object of Entity
2024-02-19 22:40:40 +00:00
publishProc: DuringProc
2022-03-10 23:30:07 +00:00
assertionMap: Table[Handle, DuringAction]
2024-02-19 22:40:40 +00:00
proc duringPublish(e: Entity; v: Value; h: Handle) {.cps: Cont.} =
var de = DuringEntity(e)
2022-03-10 23:30:07 +00:00
let g = de.assertionMap.getOrDefault h
case g.kind
2024-02-19 22:40:40 +00:00
of null, dead:
2024-02-24 16:51:41 +00:00
var cb = de.publishProc(e.facet, v, h)
de.assertionMap[h] = DuringAction(kind: act, retractProc: cb)
2022-03-10 23:30:07 +00:00
of act:
raiseAssert("during: duplicate handle in publish: " & $h)
2024-02-19 22:40:40 +00:00
proc duringRetract(e: Entity; h: Handle) {.cps: Cont.} =
var de = DuringEntity(e)
2022-03-10 23:30:07 +00:00
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
2024-02-24 16:51:41 +00:00
if not g.retractProc.isNil:
g.retractProc(de.facet)
2022-03-10 23:30:07 +00:00
2024-02-24 16:51:41 +00:00
proc during*(cb: DuringProc): Entity =
## TODO: this doesn't follow Nim idom well.
DuringEntity(publishProc: cb).setActions(
publish = whelp duringPublish,
retract = whelp duringRetract,
)