makeDataspace -> new Dataspace

This commit is contained in:
Tony Garnock-Jones 2021-02-23 08:52:54 +01:00
parent 4f148b19e7
commit 2846c8cbe0
1 changed files with 45 additions and 47 deletions

92
main.ts
View File

@ -4,54 +4,52 @@ import { Bag, ChangeDescription } from './bag';
const Observe = Record.makeConstructor<Ref<Entity>>('Observe', ['label', 'observer']); const Observe = Record.makeConstructor<Ref<Entity>>('Observe', ['label', 'observer']);
function makeDataspace(): Entity { class Dataspace implements Entity {
const handleMap: IdentityMap<Handle, Record<Ref<Entity>>> = new IdentityMap(); readonly handleMap: IdentityMap<Handle, Record<Ref<Entity>>> = new IdentityMap();
const assertions = new Bag<Ref<Entity>>(); readonly assertions = new Bag<Ref<Entity>>();
const subscriptions: Dictionary<Map<Ref<Entity>, Dictionary<Handle>>> = new Dictionary(); readonly subscriptions: Dictionary<Map<Ref<Entity>, Dictionary<Handle>>> = new Dictionary();
return { [assert](turn: Turn, rec: Assertion, handle: Handle): void {
[assert](turn: Turn, rec: Assertion, handle: Handle): void { if (!Record.isRecord<Ref<Entity>>(rec)) return;
if (!Record.isRecord<Ref<Entity>>(rec)) return; this.handleMap.set(handle, rec);
handleMap.set(handle, rec); if (this.assertions.change(rec, +1) !== ChangeDescription.ABSENT_TO_PRESENT) return;
if (assertions.change(rec, +1) !== ChangeDescription.ABSENT_TO_PRESENT) return; if (Observe.isClassOf(rec)) {
if (Observe.isClassOf(rec)) { const label = Observe._.label(rec)!;
const label = Observe._.label(rec)!; const observer = Observe._.observer(rec) as Ref<Entity>;
const observer = Observe._.observer(rec) as Ref<Entity>; const seen = new Dictionary<Handle>();
const seen = new Dictionary<Handle>(); if (!this.subscriptions.has(label)) this.subscriptions.set(label, new Map());
if (!subscriptions.has(label)) subscriptions.set(label, new Map()); this.subscriptions.get(label)!.set(observer, seen);
subscriptions.get(label)!.set(observer, seen); this.assertions.forEach((_count, prev) =>
assertions.forEach((_count, prev) => is((prev as Record<Ref<Entity>>).label, label)
is((prev as Record<Ref<Entity>>).label, label) && seen.set(prev, turn.assert(observer, prev)));
&& seen.set(prev, turn.assert(observer, prev)));
}
subscriptions.get(rec.label)?.forEach((seen, peer) =>
seen.has(rec) || seen.set(rec, turn.assert(peer, rec)));
},
[retract](turn: Turn, upstreamHandle: Handle): void {
const rec = handleMap.get(upstreamHandle);
if (rec === void 0) return;
handleMap.delete(upstreamHandle);
if (assertions.change(rec, -1) !== ChangeDescription.PRESENT_TO_ABSENT) return;
subscriptions.get(rec.label)?.forEach((seen, _peer) => {
const downstreamHandle = seen.get(rec);
if (downstreamHandle !== void 0) {
turn.retract(downstreamHandle);
seen.delete(rec);
}
});
if (Observe.isClassOf(rec)) {
let peerMap = subscriptions.get(Observe._.label(rec)!)!;
peerMap.delete(Observe._.observer(rec) as Ref<Entity>);
if (peerMap.size === 0) subscriptions.delete(Observe._.label(rec)!);
}
},
[message](turn: Turn, rec: Assertion): void {
if (!Record.isRecord<Ref<Entity>>(rec)) return;
subscriptions.get(rec.label)?.forEach((_seen, peer) => turn.message(peer, rec));
} }
}; this.subscriptions.get(rec.label)?.forEach((seen, peer) =>
seen.has(rec) || seen.set(rec, turn.assert(peer, rec)));
}
[retract](turn: Turn, upstreamHandle: Handle): void {
const rec = this.handleMap.get(upstreamHandle);
if (rec === void 0) return;
this.handleMap.delete(upstreamHandle);
if (this.assertions.change(rec, -1) !== ChangeDescription.PRESENT_TO_ABSENT) return;
this.subscriptions.get(rec.label)?.forEach((seen, _peer) => {
const downstreamHandle = seen.get(rec);
if (downstreamHandle !== void 0) {
turn.retract(downstreamHandle);
seen.delete(rec);
}
});
if (Observe.isClassOf(rec)) {
let peerMap = this.subscriptions.get(Observe._.label(rec)!)!;
peerMap.delete(Observe._.observer(rec) as Ref<Entity>);
if (peerMap.size === 0) this.subscriptions.delete(Observe._.label(rec)!);
}
}
[message](turn: Turn, rec: Assertion): void {
if (!Record.isRecord<Ref<Entity>>(rec)) return;
this.subscriptions.get(rec.label)?.forEach((_seen, peer) => turn.message(peer, rec));
}
} }
const BoxState = Record.makeConstructor<Ref<Entity>>('BoxState', ['value']); const BoxState = Record.makeConstructor<Ref<Entity>>('BoxState', ['value']);
@ -60,7 +58,7 @@ const SetBox = Record.makeConstructor<Ref<Entity>>('SetBox', ['newValue']);
let startTime = Date.now(); let startTime = Date.now();
let prevValue = 0; let prevValue = 0;
Turn.for(null, async (t: Turn) => { Turn.for(null, async (t: Turn) => {
const ds = new Ref(new Actor(), makeDataspace()); const ds = new Ref(new Actor(), new Dataspace());
// Box // Box
t.spawn(t => { t.spawn(t => {