Further simplify syncing
This commit is contained in:
parent
252e82a887
commit
38584c40bd
42
actor.ts
42
actor.ts
|
@ -9,8 +9,6 @@ export type ExitReason = null | { ok: true } | { ok: false, err: Error };
|
||||||
export const assert = Symbol('assert');
|
export const assert = Symbol('assert');
|
||||||
export const retract = Symbol('retract');
|
export const retract = Symbol('retract');
|
||||||
export const message = Symbol('message');
|
export const message = Symbol('message');
|
||||||
export const sync = Symbol('sync');
|
|
||||||
export const synced = Symbol('synced');
|
|
||||||
|
|
||||||
export interface Entity {
|
export interface Entity {
|
||||||
[assert](turn: Turn, assertion: Assertion, handle: Handle): void;
|
[assert](turn: Turn, assertion: Assertion, handle: Handle): void;
|
||||||
|
@ -18,26 +16,23 @@ export interface Entity {
|
||||||
[message](turn: Turn, message: Assertion): void;
|
[message](turn: Turn, message: Assertion): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SyncTarget {
|
export class Ref<T> {
|
||||||
[sync](turn: Turn, source: Ref<SyncSource>): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SyncSource {
|
|
||||||
[synced](turn: Turn): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Ref<T = Entity> {
|
|
||||||
readonly actor: Actor;
|
readonly actor: Actor;
|
||||||
readonly target: T;
|
readonly target: T;
|
||||||
|
|
||||||
constructor(actor: Actor, target: T) {
|
constructor(actor: Actor, target: T) {
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sync(turn: Turn, syncable: Ref<LocalAction>) {
|
||||||
|
turn.enqueue(syncable.actor, t => syncable.target(t));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type OutboundMap = Map<Handle, [Ref, Assertion]>;
|
export type OutboundMap = Map<Handle, [Ref<Entity>, Assertion]>;
|
||||||
|
|
||||||
export class Actor implements SyncTarget {
|
export class Actor {
|
||||||
readonly outbound: OutboundMap;
|
readonly outbound: OutboundMap;
|
||||||
exitReason: ExitReason = null;
|
exitReason: ExitReason = null;
|
||||||
|
|
||||||
|
@ -76,10 +71,6 @@ export class Actor implements SyncTarget {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[sync](t: Turn, source: Ref<SyncSource>): void {
|
|
||||||
t.synced(source);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let nextHandle = 0;
|
let nextHandle = 0;
|
||||||
|
@ -131,7 +122,7 @@ export class Turn {
|
||||||
this.localActions.push(t => actor.stop(t));
|
this.localActions.push(t => actor.stop(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(location: Ref, assertion: Assertion): Handle {
|
assert(location: Ref<Entity>, assertion: Assertion): Handle {
|
||||||
this._ensureActor("assert");
|
this._ensureActor("assert");
|
||||||
const h = nextHandle++;
|
const h = nextHandle++;
|
||||||
this.enqueue(location.actor, t => {
|
this.enqueue(location.actor, t => {
|
||||||
|
@ -145,31 +136,26 @@ export class Turn {
|
||||||
this._retract(this._ensureActor("retract").outbound.get(h)![0], h);
|
this._retract(this._ensureActor("retract").outbound.get(h)![0], h);
|
||||||
}
|
}
|
||||||
|
|
||||||
replace(location: Ref, h: Handle | undefined, assertion: Assertion): Handle {
|
replace(location: Ref<Entity>, h: Handle | undefined, assertion: Assertion): Handle {
|
||||||
const newHandle = this.assert(location, assertion);
|
const newHandle = this.assert(location, assertion);
|
||||||
if (h !== void 0) this.retract(h);
|
if (h !== void 0) this.retract(h);
|
||||||
return newHandle;
|
return newHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
_retract(location: Ref, handle: Handle): void {
|
_retract(location: Ref<Entity>, handle: Handle): void {
|
||||||
this.enqueue(location.actor, t => {
|
this.enqueue(location.actor, t => {
|
||||||
this.actor!.outbound.delete(handle);
|
this.actor!.outbound.delete(handle);
|
||||||
location.target[retract](t, handle);
|
location.target[retract](t, handle);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sync(location: Ref<SyncTarget>): Promise<Turn> {
|
sync(location: Ref<any>): Promise<Turn> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const k = this.ref({ [synced]: resolve }, "sync");
|
this.enqueue(location.actor, t => location.sync(t, this.ref(resolve, "sync")));
|
||||||
this.enqueue(location.actor, t => location.target[sync](t, k));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
synced(syncable: Ref<SyncSource>): void {
|
message(location: Ref<Entity>, assertion: Assertion): void {
|
||||||
this.enqueue(syncable.actor, t => syncable.target[synced](t));
|
|
||||||
}
|
|
||||||
|
|
||||||
message(location: Ref, assertion: Assertion): void {
|
|
||||||
this.enqueue(location.actor, t => location.target[message](t, assertion));
|
this.enqueue(location.actor, t => location.target[message](t, assertion));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue