2020-05-03 16:08:04 +02:00
|
|
|
import { World, ConnectCallback, DisconnectCallback } from "./World";
|
2020-09-16 16:06:43 +02:00
|
|
|
import { User } from "./User";
|
2020-04-29 22:41:48 +02:00
|
|
|
import {PositionInterface} from "_Model/PositionInterface";
|
2020-05-01 21:15:00 +02:00
|
|
|
import {uuid} from "uuidv4";
|
2020-09-16 16:06:43 +02:00
|
|
|
import {Movable} from "_Model/Movable";
|
2020-04-09 23:26:19 +02:00
|
|
|
|
2020-09-16 16:06:43 +02:00
|
|
|
export class Group implements Movable {
|
2020-04-07 10:08:04 +02:00
|
|
|
static readonly MAX_PER_GROUP = 4;
|
2020-04-28 22:40:54 +02:00
|
|
|
|
2020-05-01 21:15:00 +02:00
|
|
|
private id: string;
|
2020-09-16 16:06:43 +02:00
|
|
|
private users: Set<User>;
|
2020-05-03 16:08:04 +02:00
|
|
|
private connectCallback: ConnectCallback;
|
|
|
|
private disconnectCallback: DisconnectCallback;
|
2020-04-09 23:26:19 +02:00
|
|
|
|
2020-04-07 10:08:04 +02:00
|
|
|
|
2020-09-16 16:06:43 +02:00
|
|
|
constructor(users: User[], connectCallback: ConnectCallback, disconnectCallback: DisconnectCallback) {
|
|
|
|
this.users = new Set<User>();
|
2020-04-09 23:26:19 +02:00
|
|
|
this.connectCallback = connectCallback;
|
|
|
|
this.disconnectCallback = disconnectCallback;
|
2020-05-01 21:15:00 +02:00
|
|
|
this.id = uuid();
|
2020-04-28 22:40:54 +02:00
|
|
|
|
2020-09-16 16:06:43 +02:00
|
|
|
users.forEach((user: User) => {
|
2020-04-09 23:26:19 +02:00
|
|
|
this.join(user);
|
|
|
|
});
|
2020-04-07 10:08:04 +02:00
|
|
|
}
|
|
|
|
|
2020-09-16 16:06:43 +02:00
|
|
|
getUsers(): User[] {
|
2020-06-29 22:10:23 +02:00
|
|
|
return Array.from(this.users.values());
|
2020-04-07 10:08:04 +02:00
|
|
|
}
|
|
|
|
|
2020-05-01 21:15:00 +02:00
|
|
|
getId() : string{
|
|
|
|
return this.id;
|
|
|
|
}
|
|
|
|
|
2020-04-29 22:41:48 +02:00
|
|
|
/**
|
|
|
|
* Returns the barycenter of all users (i.e. the center of the group)
|
|
|
|
*/
|
|
|
|
getPosition(): PositionInterface {
|
|
|
|
let x = 0;
|
|
|
|
let y = 0;
|
|
|
|
// Let's compute the barycenter of all users.
|
2020-09-16 16:06:43 +02:00
|
|
|
this.users.forEach((user: User) => {
|
2020-04-29 22:41:48 +02:00
|
|
|
x += user.position.x;
|
|
|
|
y += user.position.y;
|
|
|
|
});
|
2020-06-29 22:10:23 +02:00
|
|
|
x /= this.users.size;
|
|
|
|
y /= this.users.size;
|
2020-04-29 22:41:48 +02:00
|
|
|
return {
|
|
|
|
x,
|
|
|
|
y
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-04-07 10:08:04 +02:00
|
|
|
isFull(): boolean {
|
2020-06-29 22:10:23 +02:00
|
|
|
return this.users.size >= Group.MAX_PER_GROUP;
|
2020-04-07 10:08:04 +02:00
|
|
|
}
|
2020-04-08 20:40:44 +02:00
|
|
|
|
2020-04-29 23:12:55 +02:00
|
|
|
isEmpty(): boolean {
|
2020-06-29 22:10:23 +02:00
|
|
|
return this.users.size <= 1;
|
2020-04-29 23:12:55 +02:00
|
|
|
}
|
|
|
|
|
2020-09-16 16:06:43 +02:00
|
|
|
join(user: User): void
|
2020-04-09 23:26:19 +02:00
|
|
|
{
|
|
|
|
// Broadcast on the right event
|
2020-05-03 16:08:04 +02:00
|
|
|
this.connectCallback(user.id, this);
|
2020-06-29 22:10:23 +02:00
|
|
|
this.users.add(user);
|
2020-04-09 23:26:19 +02:00
|
|
|
user.group = this;
|
|
|
|
}
|
|
|
|
|
2020-09-16 16:06:43 +02:00
|
|
|
leave(user: User): void
|
2020-04-29 23:12:55 +02:00
|
|
|
{
|
2020-06-29 22:13:07 +02:00
|
|
|
const success = this.users.delete(user);
|
2020-06-29 22:10:23 +02:00
|
|
|
if (success === false) {
|
|
|
|
throw new Error("Could not find user "+user.id+" in the group "+this.id);
|
2020-04-29 23:12:55 +02:00
|
|
|
}
|
|
|
|
user.group = undefined;
|
|
|
|
|
|
|
|
// Broadcast on the right event
|
2020-05-03 16:08:04 +02:00
|
|
|
this.disconnectCallback(user.id, this);
|
2020-04-29 23:12:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Let's kick everybody out.
|
|
|
|
* Usually used when there is only one user left.
|
|
|
|
*/
|
|
|
|
destroy(): void
|
|
|
|
{
|
2020-06-29 22:13:07 +02:00
|
|
|
for (const user of this.users) {
|
2020-04-29 23:12:55 +02:00
|
|
|
this.leave(user);
|
2020-06-29 22:10:23 +02:00
|
|
|
}
|
2020-04-08 20:40:44 +02:00
|
|
|
}
|
2020-04-28 22:40:54 +02:00
|
|
|
}
|