# 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))