@terrencecrowley/ot-js
Version:
Javascript OT library
99 lines (84 loc) • 2.5 kB
text/typescript
import * as LogAbstract from "@terrencecrowley/logabstract";
import * as Context from "@terrencecrowley/context";
interface TestEnv { context: Context.IContext, log: LogAbstract.ILog };
import * as OT from "../lib/ottypes";
import * as OTC from "../lib/otcomposite";
import * as OTS from "../lib/otsession";
import * as OTEngine from "../lib/otserverengine";
import * as OTTestClient from "./ottestclient";
export class OTTestServer
{
private env: TestEnv;
private engine: OTEngine.OTServerEngine;
private clients: OTTestClient.OTTestClient[];
private editQueue: OTC.OTCompositeResource[];
// construct
constructor(env: TestEnv)
{
this.env = env;
this.engine = new OTEngine.OTServerEngine(env.log, "1");
this.clients = [];
this.editQueue = [];
}
addClient(client: OTTestClient.OTTestClient): void
{
this.clients.push(client);
client.setServer(this);
}
receive(edit: OTC.OTCompositeResource): void
{
this.editQueue.push(edit.copy());
}
private findClient(uid: string): OTTestClient.OTTestClient
{
for (let i: number = 0; i < this.clients.length; i++)
if (this.clients[i].clientID === uid)
return this.clients[i];
return null;
}
tick(): void
{
// Drain the queue of received client events
while (this.editQueue.length > 0)
{
let edit: OTC.OTCompositeResource = this.editQueue.shift();
let nResult: number = this.engine.addServer(edit);
if (nResult === OTS.ESuccess)
{
edit = this.engine.logServer[this.engine.logServer.length-1];
for (let i: number = 0; i < this.clients.length; i++)
this.clients[i].receiveRemoteAction(edit.copy());
}
else
{
// Clock Unavailable
if (nResult === OTS.EClockFailure)
console.log("Clock failure for client " + edit.clientID);
else if (nResult === OTS.EClockSeen)
console.log("Sequence failure for client " + edit.clientID);
edit.clock = nResult;
let c: OTTestClient.OTTestClient = this.findClient(edit.clientID);
if (c)
c.receiveRemoteAction(edit.copy());
}
}
}
drain(): void
{
let bCont: boolean = true;
while (bCont)
{
// Dispatch any events from queue
this.tick();
// And then give clients chance to respond.
for (let i: number = 0; i < this.clients.length; i++)
this.clients[i].checkForSend();
// And continue if they responded.
bCont = this.editQueue.length > 0;
}
}
toValue(): any
{
return this.engine.toValue();
}
};