# SPDX-FileCopyrightText: ☭ 2022 Emery Hemingway # SPDX-License-Identifier: Unlicense import std/[hashes, tables] from ./actors import Cap, hash from ./protocols/sturdy import Oid proc hash(r: Cap): Hash = !$(r.relay.hash !& r.target.unsafeAddr.hash) type Membrane* = object ## Bidirectional mapping between `Oid` and `Cap` values. ## https://synit.org/book/protocol.html#membranes byOid: Table[Oid, WireSymbol] byCap: Table[Cap, WireSymbol] WireSymbol* = ref object oid: Oid cap: Cap count: int proc oid*(sym: WireSymbol): Oid = sym.oid proc cap*(sym: WireSymbol): Cap = sym.cap proc grab*(mem: Membrane; key: Oid): WireSymbol = ## Grab a `WireSymbol` from a `Membrane`. mem.byOid.getOrDefault(key) proc grab*(mem: Membrane; key: Cap): WireSymbol = ## Grab a `WireSymbol` from a `Membrane`. mem.byCap.getOrDefault(key) proc drop*(mem: var Membrane; sym: WireSymbol) = ## Drop a `WireSymbol` from a `Membrane`. dec sym.count if sym.count < 1: mem.byOid.del sym.oid mem.byCap.del sym.cap proc newWireSymbol*(mem: var Membrane; o: Oid; r: Cap): WireSymbol = ## Allocate a `WireSymbol` at a `Membrane`. result = WireSymbol(oid: o, cap: r, count: 1) mem.byOid[result.oid] = result mem.byCap[result.cap] = result