syndicate-nim/src/sam/dataspaces.nim

53 lines
1.5 KiB
Nim

# SPDX-FileCopyrightText: ☭ Emery Hemingway
# SPDX-License-Identifier: Unlicense
import std/[hashes, options, tables]
import pkg/cps
import preserves
import ./[actors, patterns, skeletons]
from ./protocols/protocol import Handle
from ./protocols/dataspace import Observe
type
Dataspace {.final.} = ref object of Entity
index: Index
handleMap: Table[Handle, Value]
proc dsPublish(e: Entity; v: Value; h: Handle) {.cps: Cont.} =
var ds = Dataspace(e)
if ds.index.add(v):
var obs = v.preservesTo(Observe)
if obs.isSome and obs.get.observer of Cap:
ds.index.add(obs.get.pattern, Cap(obs.get.observer))
ds.handleMap[h] = v
proc dsRetract(e: Entity; h: Handle) {.cps: Cont.} =
var ds = Dataspace(e)
var v = ds.handleMap[h]
if ds.index.remove(v):
ds.handleMap.del h
var obs = v.preservesTo(Observe)
if obs.isSome and obs.get.observer of Cap:
ds.index.remove(obs.get.pattern, Cap(obs.get.observer))
proc dsMessage(e: Entity; v: Value) {.cps: Cont.} =
var ds = Dataspace(e)
ds.index.deliverMessage(v)
proc newDataspace*(f: Facet): Cap =
var ds = Dataspace(
index: initIndex(),
).setActions(
publish = whelp dsPublish,
retract = whelp dsRetract,
message = whelp dsMessage,
)
newCap(f, ds)
proc observe*(cap: Cap; pat: Pattern; peer: Cap): Handle =
publish(cap, Observe(pattern: pat, observer: peer))
proc observe*(cap: Cap; pat: Pattern; e: Entity): Handle =
observe(cap, pat, newCap(cap.relay, e))