Kopie van https://gitlab.com/studieverenigingvia/ict/centurion met een paar aanpassingen
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
centurion/backend/src/Room.ts

203 lines
4.7 KiB

import {Socket} from "socket.io";
import User from "./User";
import {getIndex, getNextShot, getTimeline, getTimelineNames, indexForTime} from "./timeline";
import {getCurrentTime} from "./util";
export interface RoomOptions {
seekTime: number
timelineName: string
}
export default class Room {
id: number = 0;
users: User[] = [];
leader: User | null = null;
running = false;
startTime = 0;
currentSeconds = 0;
timelineIndex: number = 0;
seekTime: number = 0;
timelineName: string = 'Centurion';
// For debugging purposes
speedFactor = 1;
constructor(name: number) {
this.id = name;
}
serialize(user: User) {
return {
'id': this.id,
'userCount': this.users.length,
'isLeader': this.leader == user,
'running': this.running,
'startTime': this.startTime,
'timelineName': this.timelineName,
'seekTime': this.seekTime,
'readyToParticipate': user.readyToParticipate || this.leader == user,
'speedFactor': this.speedFactor
}
}
serializeTimeline(user: User) {
return getTimeline(this.timelineName);
}
sync() {
this.users.forEach(u => u.sync());
}
join(user: User) {
this.users.push(user);
user.setRoom(this);
if (!this.hasLeader()) {
this.setLeader(user);
}
this.sync();
}
leave(user: User) {
this.users.splice(this.users.indexOf(user), 1);
user.setRoom(null);
if (this.leader == user) {
this.setRandomLeader();
}
this.sync();
}
onBeforeDelete() {
}
setOptions(options: any) {
this.seekTime = Math.max(0, Math.min(options.seekTime, 250 * 60 * 1000))
if (getTimelineNames().indexOf(options.timelineName) >= 0) {
this.timelineName = options.timelineName;
}
this.sync()
}
start() {
this.running = true;
this.startTime = getCurrentTime() - this.seekTime
this.sync();
}
run(io: Socket) {
this.running = true;
this.startTime = Date.now();
// io.to(this.id.toString()).emit('timeline', {
// 'timeline': {
// }
// });
const doTick = () => {
if (this.users.length === 0) {
// this room is over.
return;
}
const timestamp = getIndex(this.timelineIndex);
const nextShot = getNextShot(this.timelineIndex);
if (!timestamp) {
// We are done.
io.to(this.id.toString()).emit('tick_event', {
tick: {
current: this.currentSeconds
}
});
console.log("Done");
this.running = false;
return;
}
console.log("ticking", this.currentSeconds);
io.to(this.id.toString()).emit('tick_event', {
tick: {
current: this.currentSeconds,
next: timestamp,
nextShot: nextShot
}
});
if (this.currentSeconds >= timestamp.timestamp) {
this.timelineIndex += 1;
}
this.currentSeconds += 1;
// We spend some time processing, wait a bit less than 1000ms
const nextTickTime = this.startTime + (1000 * this.currentSeconds / this.speedFactor);
const waitTime = nextTickTime - Date.now();
console.log("waiting", waitTime);
setTimeout(doTick, Math.floor(waitTime / this.speedFactor));
};
doTick();
}
/**
*
* @param io
* @param {number} time
*/
seek(io: Socket, time: number) {
this.currentSeconds = time;
this.startTime = Date.now() - time * 1000;
this.timelineIndex = indexForTime(this.currentSeconds);
io.to(this.id.toString()).emit('seek', time);
}
/**
*
* @returns {boolean}
*/
hasUsers() {
return this.users.length !== 0;
}
setRandomLeader() {
if (this.hasUsers()) {
this.leader = this.users[0];
}
}
/**
*
* @param id
* @returns {User|undefined}
*/
getUser(id: string) {
return this.users.find(u => u.id === id);
}
/**
*
* @param {string} id
*/
removeUser(id: string) {
this.users = this.users.filter(u => u.id !== id);
}
hasLeader(): boolean {
return this.leader != null;
}
setLeader(user: User) {
this.leader = user;
}
getLeader(): User | null {
return this.leader;
}
};