1
0
Fork 0
spacetac/src/ui/battle/MultiBattle.ts

101 lines
3 KiB
TypeScript
Raw Normal View History

2017-09-24 22:23:22 +00:00
module TK.SpaceTac.UI {
/**
* 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
// Network exchange of messages
2018-01-31 18:19:50 +00:00
exchange!: Multi.Exchange
// True if this peer is the primary one (the one that invited the other)
2018-01-31 18:19:50 +00:00
primary!: boolean
// Battle being played
2018-01-31 18:19:50 +00:00
battle!: Battle
// Count of battle log events that were processed
2018-01-31 18:19:50 +00:00
processed!: number
// Serializer to use for actions
2018-01-31 18:19:50 +00:00
serializer!: Serializer
// Timer for scheduling
2018-01-31 18:19:50 +00:00
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);
this.processed = this.battle.log.count();
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
if (this.exchange.writing) {
await this.sendDiffs();
} else {
await this.receiveDiff();
}
}
}
/**
* Send one new diff from the battle log
*/
async sendDiffs() {
if (this.processed >= this.battle.log.count()) {
await this.timer.sleep(500);
} else {
2017-11-14 00:31:13 +00:00
let diff = this.battle.log.get(this.processed);
this.processed++;
2017-11-14 00:31:13 +00:00
if (this.debug) {
console.debug("Send diff to exchange", diff);
}
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);
}
}
/**
* Read and apply one diff from the peer
*/
async receiveDiff() {
let message = await this.exchange.readMessage();
let received = this.serializer.unserialize(message);
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]);
} else {
console.error("Exchange received something that is not a battle diff", received);
}
this.processed = this.battle.log.count();
}
}
}