2017-09-24 22:23:22 +00:00
|
|
|
module TK.SpaceTac.UI {
|
2017-07-24 22:02:43 +00:00
|
|
|
/**
|
|
|
|
* Tool to synchronize two players sharing a battle over network
|
|
|
|
*/
|
|
|
|
export class MultiBattle {
|
2017-11-14 00:31:13 +00:00
|
|
|
// Debug mode
|
|
|
|
debug = false
|
|
|
|
|
2017-07-24 22:02:43 +00:00
|
|
|
// Network exchange of messages
|
|
|
|
exchange: Multi.Exchange
|
|
|
|
|
|
|
|
// True if this peer is the primary one (the one that invited the other)
|
|
|
|
primary: boolean
|
|
|
|
|
|
|
|
// Battle being played
|
|
|
|
battle: Battle
|
|
|
|
|
|
|
|
// Count of battle log events that were processed
|
|
|
|
processed: number
|
|
|
|
|
|
|
|
// Serializer to use for actions
|
|
|
|
serializer: Serializer
|
|
|
|
|
|
|
|
// Timer for scheduling
|
|
|
|
timer: Timer
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Setup the session other a token
|
|
|
|
*/
|
|
|
|
async setup(view: BaseView, battle: Battle, token: string, primary: boolean) {
|
|
|
|
if (this.exchange) {
|
|
|
|
// TODO close it
|
|
|
|
}
|
|
|
|
|
|
|
|
this.battle = battle;
|
|
|
|
this.primary = primary;
|
|
|
|
|
|
|
|
this.exchange = new Multi.Exchange(view.getConnection(), token, primary);
|
|
|
|
await this.exchange.start();
|
|
|
|
|
2017-09-24 22:23:22 +00:00
|
|
|
this.serializer = new Serializer(TK.SpaceTac);
|
2017-11-14 00:07:06 +00:00
|
|
|
this.processed = this.battle.log.count();
|
2017-07-24 22:02:43 +00:00
|
|
|
this.timer = view.timer;
|
|
|
|
|
|
|
|
// This is voluntarily not waited on, as it is a background task
|
|
|
|
this.backgroundSync();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Background work to maintain the battle state in sync between the two peers
|
|
|
|
*/
|
|
|
|
async backgroundSync() {
|
2017-11-14 00:31:13 +00:00
|
|
|
while (true) { // TODO Close the task on exchange close
|
2017-07-24 22:02:43 +00:00
|
|
|
if (this.exchange.writing) {
|
2017-11-14 00:07:06 +00:00
|
|
|
await this.sendDiffs();
|
2017-07-24 22:02:43 +00:00
|
|
|
} else {
|
2017-11-14 00:07:06 +00:00
|
|
|
await this.receiveDiff();
|
2017-07-24 22:02:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-11-14 00:07:06 +00:00
|
|
|
* Send one new diff from the battle log
|
2017-07-24 22:02:43 +00:00
|
|
|
*/
|
2017-11-14 00:07:06 +00:00
|
|
|
async sendDiffs() {
|
|
|
|
if (this.processed >= this.battle.log.count()) {
|
2017-07-24 22:02:43 +00:00
|
|
|
await this.timer.sleep(500);
|
|
|
|
} else {
|
2017-11-14 00:31:13 +00:00
|
|
|
let diff = this.battle.log.get(this.processed);
|
2017-11-14 00:07:06 +00:00
|
|
|
this.processed++;
|
2017-07-24 22:02:43 +00:00
|
|
|
|
2017-11-14 00:31:13 +00:00
|
|
|
if (this.debug) {
|
|
|
|
console.debug("Send diff to exchange", diff);
|
2017-07-24 22:02:43 +00:00
|
|
|
}
|
2017-11-14 00:31:13 +00:00
|
|
|
|
|
|
|
let data = this.serializer.serialize(diff);
|
|
|
|
// TODO "over" should be true if the current ship should be played by remote player
|
|
|
|
await this.exchange.writeMessage(data, false);
|
2017-07-24 22:02:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-11-14 00:07:06 +00:00
|
|
|
* Read and apply one diff from the peer
|
2017-07-24 22:02:43 +00:00
|
|
|
*/
|
2017-11-14 00:07:06 +00:00
|
|
|
async receiveDiff() {
|
2017-07-24 22:02:43 +00:00
|
|
|
let message = await this.exchange.readMessage();
|
|
|
|
let received = this.serializer.unserialize(message);
|
2017-11-14 00:07:06 +00:00
|
|
|
if (received instanceof BaseBattleDiff) {
|
2017-11-14 00:31:13 +00:00
|
|
|
if (this.debug) {
|
|
|
|
console.log("Received diff from exchange", received);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.battle.applyDiffs([received]);
|
2017-07-24 22:02:43 +00:00
|
|
|
} else {
|
2017-11-14 00:07:06 +00:00
|
|
|
console.error("Exchange received something that is not a battle diff", received);
|
2017-07-24 22:02:43 +00:00
|
|
|
}
|
2017-11-14 00:07:06 +00:00
|
|
|
this.processed = this.battle.log.count();
|
2017-07-24 22:02:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|