2020-09-16 16:06:43 +02:00
|
|
|
import {User} from "./User";
|
2020-09-15 10:06:11 +02:00
|
|
|
import {PositionInterface} from "_Model/PositionInterface";
|
2020-09-16 16:06:43 +02:00
|
|
|
import {Movable} from "_Model/Movable";
|
2020-09-15 10:06:11 +02:00
|
|
|
|
2020-09-16 16:06:43 +02:00
|
|
|
export type EntersCallback = (thing: Movable, listener: User) => void;
|
|
|
|
export type MovesCallback = (thing: Movable, position: PositionInterface, listener: User) => void;
|
|
|
|
export type LeavesCallback = (thing: Movable, listener: User) => void;
|
2020-09-15 10:06:11 +02:00
|
|
|
|
|
|
|
export class Zone {
|
2020-09-16 16:06:43 +02:00
|
|
|
private things: Set<Movable> = new Set<Movable>();
|
|
|
|
private listeners: Set<User> = new Set<User>();
|
2020-09-15 10:06:11 +02:00
|
|
|
|
2020-09-16 16:06:43 +02:00
|
|
|
constructor(private onEnters: EntersCallback, private onMoves: MovesCallback, private onLeaves: LeavesCallback) {
|
2020-09-15 10:06:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-09-16 16:06:43 +02:00
|
|
|
* A user/thing leaves the zone
|
2020-09-15 10:06:11 +02:00
|
|
|
*/
|
2020-09-16 16:06:43 +02:00
|
|
|
public leave(thing: Movable, newZone: Zone|null) {
|
|
|
|
this.things.delete(thing);
|
|
|
|
this.notifyLeft(thing, newZone);
|
2020-09-15 10:06:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-09-16 16:06:43 +02:00
|
|
|
* Notify listeners of this zone that this user/thing left
|
2020-09-15 10:06:11 +02:00
|
|
|
*/
|
2020-09-16 16:06:43 +02:00
|
|
|
private notifyLeft(thing: Movable, newZone: Zone|null) {
|
2020-09-15 10:06:11 +02:00
|
|
|
for (const listener of this.listeners) {
|
2020-09-16 16:06:43 +02:00
|
|
|
if (listener !== thing && (newZone === null || !listener.listenedZones.has(newZone))) {
|
|
|
|
this.onLeaves(thing, listener);
|
2020-09-15 10:06:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-16 16:06:43 +02:00
|
|
|
public enter(thing: Movable, oldZone: Zone|null, position: PositionInterface) {
|
|
|
|
this.things.add(thing);
|
|
|
|
this.notifyUserEnter(thing, oldZone, position);
|
2020-09-15 10:06:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Notify listeners of this zone that this user entered
|
|
|
|
*/
|
2020-09-16 16:06:43 +02:00
|
|
|
private notifyUserEnter(thing: Movable, oldZone: Zone|null, position: PositionInterface) {
|
2020-09-15 10:06:11 +02:00
|
|
|
for (const listener of this.listeners) {
|
2020-09-16 16:06:43 +02:00
|
|
|
if (listener === thing) {
|
2020-09-15 10:06:11 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (oldZone === null || !listener.listenedZones.has(oldZone)) {
|
2020-09-16 16:06:43 +02:00
|
|
|
this.onEnters(thing, listener);
|
2020-09-15 10:06:11 +02:00
|
|
|
} else {
|
2020-09-16 16:06:43 +02:00
|
|
|
this.onMoves(thing, position, listener);
|
2020-09-15 10:06:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-16 16:06:43 +02:00
|
|
|
public move(thing: Movable, position: PositionInterface) {
|
|
|
|
if (!this.things.has(thing)) {
|
|
|
|
this.things.add(thing);
|
|
|
|
const foo = this.things;
|
|
|
|
this.notifyUserEnter(thing, null, position);
|
2020-09-15 16:21:41 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-09-15 10:06:11 +02:00
|
|
|
for (const listener of this.listeners) {
|
2020-09-16 16:06:43 +02:00
|
|
|
if (listener !== thing) {
|
|
|
|
this.onMoves(thing,position, listener);
|
2020-09-15 10:06:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-16 16:06:43 +02:00
|
|
|
public startListening(listener: User): void {
|
|
|
|
for (const thing of this.things) {
|
|
|
|
if (thing !== listener) {
|
|
|
|
this.onEnters(thing, 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-16 16:06:43 +02:00
|
|
|
public stopListening(listener: User): void {
|
|
|
|
for (const thing of this.things) {
|
|
|
|
if (thing !== listener) {
|
|
|
|
this.onLeaves(thing, 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);
|
|
|
|
}
|
|
|
|
|
2020-09-16 16:06:43 +02:00
|
|
|
public getThings(): Set<Movable> {
|
|
|
|
return this.things;
|
2020-09-15 10:06:11 +02:00
|
|
|
}
|
|
|
|
}
|