2020-09-15 10:06:11 +02:00
|
|
|
import {UserInterface} from "./UserInterface";
|
|
|
|
import {PointInterface} from "_Model/Websocket/PointInterface";
|
|
|
|
import {PositionInterface} from "_Model/PositionInterface";
|
|
|
|
|
2020-09-15 16:21:41 +02:00
|
|
|
export type UserEntersCallback = (user: UserInterface, listener: UserInterface) => void;
|
|
|
|
export type UserMovesCallback = (user: UserInterface, position: PointInterface, listener: UserInterface) => void;
|
|
|
|
export type UserLeavesCallback = (user: UserInterface, listener: UserInterface) => void;
|
2020-09-15 10:06:11 +02:00
|
|
|
|
|
|
|
export class Zone {
|
|
|
|
private players: Set<UserInterface> = new Set<UserInterface>();
|
|
|
|
private listeners: Set<UserInterface> = new Set<UserInterface>();
|
|
|
|
|
|
|
|
constructor(private onUserEnters: UserEntersCallback, private onUserMoves: UserMovesCallback, private onUserLeaves: UserLeavesCallback) {
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A user leaves the zone
|
|
|
|
*/
|
|
|
|
public leave(user: UserInterface, newZone: Zone|null) {
|
|
|
|
this.players.delete(user);
|
|
|
|
this.notifyUserLeft(user, newZone);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Notify listeners of this zone that this user left
|
|
|
|
*/
|
|
|
|
private notifyUserLeft(user: UserInterface, newZone: Zone|null) {
|
|
|
|
for (const listener of this.listeners) {
|
|
|
|
if (listener !== user && (newZone === null || !listener.listenedZones.has(newZone))) {
|
2020-09-15 16:21:41 +02:00
|
|
|
this.onUserLeaves(user, listener);
|
2020-09-15 10:06:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public enter(user: UserInterface, oldZone: Zone|null, position: PointInterface) {
|
|
|
|
this.players.add(user);
|
|
|
|
this.notifyUserEnter(user, oldZone, position);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Notify listeners of this zone that this user entered
|
|
|
|
*/
|
|
|
|
private notifyUserEnter(user: UserInterface, oldZone: Zone|null, position: PointInterface) {
|
|
|
|
for (const listener of this.listeners) {
|
|
|
|
if (listener === user) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (oldZone === null || !listener.listenedZones.has(oldZone)) {
|
2020-09-15 16:21:41 +02:00
|
|
|
this.onUserEnters(user, listener);
|
2020-09-15 10:06:11 +02:00
|
|
|
} else {
|
2020-09-15 16:21:41 +02:00
|
|
|
this.onUserMoves(user, position, listener);
|
2020-09-15 10:06:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public move(user: UserInterface, position: PointInterface) {
|
2020-09-15 16:21:41 +02:00
|
|
|
if (!this.players.has(user)) {
|
|
|
|
this.players.add(user);
|
|
|
|
const foo = this.players;
|
|
|
|
this.notifyUserEnter(user, null, position);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-09-15 10:06:11 +02:00
|
|
|
for (const listener of this.listeners) {
|
|
|
|
if (listener !== user) {
|
2020-09-15 16:21:41 +02:00
|
|
|
this.onUserMoves(user,position, listener);
|
2020-09-15 10:06:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-15 16:21:41 +02:00
|
|
|
public startListening(listener: UserInterface): void {
|
2020-09-15 10:06:11 +02:00
|
|
|
for (const player of this.players) {
|
2020-09-15 16:21:41 +02:00
|
|
|
if (player !== listener) {
|
|
|
|
this.onUserEnters(player, listener);
|
2020-09-15 10:06:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-15 16:21:41 +02:00
|
|
|
this.listeners.add(listener);
|
|
|
|
listener.listenedZones.add(this);
|
2020-09-15 10:06:11 +02:00
|
|
|
}
|
|
|
|
|
2020-09-15 16:21:41 +02:00
|
|
|
public stopListening(listener: UserInterface): void {
|
2020-09-15 10:06:11 +02:00
|
|
|
for (const player of this.players) {
|
2020-09-15 16:21:41 +02:00
|
|
|
if (player !== listener) {
|
|
|
|
this.onUserLeaves(player, listener);
|
2020-09-15 10:06:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-15 16:21:41 +02:00
|
|
|
this.listeners.delete(listener);
|
|
|
|
listener.listenedZones.delete(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
public getPlayers(): Set<UserInterface> {
|
|
|
|
return this.players;
|
2020-09-15 10:06:11 +02:00
|
|
|
}
|
|
|
|
}
|