58 lines
1.7 KiB
Nim
58 lines
1.7 KiB
Nim
|
# SPDX-FileCopyrightText: ☭ 2021 Emery Hemingway
|
||
|
# SPDX-License-Identifier: Unlicense
|
||
|
|
||
|
import std/[hashes, macros, tables]
|
||
|
import preserves
|
||
|
import ./actors, ./patterns, ./protocols/dataspace
|
||
|
|
||
|
from ./protocols/protocol import Handle
|
||
|
|
||
|
type
|
||
|
Observe = dataspace.Observe[Ref]
|
||
|
Turn = actors.Turn
|
||
|
|
||
|
type
|
||
|
DuringProc* = proc (turn: var Turn; a: Assertion): TurnAction {.gcsafe.}
|
||
|
DuringActionKind = enum null, dead, act
|
||
|
DuringAction = object
|
||
|
case kind: DuringActionKind
|
||
|
of null, dead: discard
|
||
|
of act:
|
||
|
action: TurnAction
|
||
|
DuringEntity {.final.}= ref object of Entity
|
||
|
cb: DuringProc
|
||
|
assertionMap: Table[Handle, DuringAction]
|
||
|
|
||
|
proc duringPublish(e: Entity; turn: var Turn; a: Assertion; h: Handle) =
|
||
|
var de = DuringEntity(e)
|
||
|
let action = de.cb(turn, a)
|
||
|
# assert(not action.isNil "should have put in a no-op action")
|
||
|
let g = de.assertionMap.getOrDefault h
|
||
|
case g.kind
|
||
|
of null:
|
||
|
de.assertionMap[h] = DuringAction(kind: act, action: action)
|
||
|
of dead:
|
||
|
de.assertionMap.del h
|
||
|
freshen(turn, action)
|
||
|
of act:
|
||
|
raiseAssert("during: duplicate handle in publish: " & $h)
|
||
|
|
||
|
proc duringRetract(e: Entity; turn: var Turn; h: Handle) =
|
||
|
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
|
||
|
g.action(turn)
|
||
|
|
||
|
proc during*(cb: DuringProc): DuringEntity =
|
||
|
result = DuringEntity(cb: cb)
|
||
|
result.setProcs(publish = duringPublish, retract = duringRetract)
|
||
|
|
||
|
proc observe*(turn: var Turn; ds: Ref; pat: Pattern; e: Entity): Handle =
|
||
|
publish(turn, ds, Observe(pattern: pat, observer: embed newRef(turn, e)))
|