makeDataspace -> new Dataspace
This commit is contained in:
parent
4f148b19e7
commit
2846c8cbe0
92
main.ts
92
main.ts
|
@ -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 => {
|
||||||
|
|
Loading…
Reference in New Issue