workadventure/back/src/Model/Zone.ts
2020-09-16 16:06:43 +02:00

97 lines
2.9 KiB
TypeScript

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