partey_workadventure/back/src/Model/Zone.ts

110 lines
3.4 KiB
TypeScript
Raw Normal View History

2020-09-16 16:06:43 +02:00
import {User} from "./User";
import {PositionInterface} from "_Model/PositionInterface";
import {Movable} from "./Movable";
import {Group} from "./Group";
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;
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>();
/**
* @param x For debugging purpose only
* @param y For debugging purpose only
*/
constructor(private onEnters: EntersCallback, private onMoves: MovesCallback, private onLeaves: LeavesCallback, private x: number, private y: number) {
}
/**
2020-09-16 16:06:43 +02:00
* A user/thing leaves the zone
*/
2020-09-16 16:06:43 +02:00
public leave(thing: Movable, newZone: Zone|null) {
const result = this.things.delete(thing);
if (!result) {
if (thing instanceof User) {
console.error('Could not find user in zone '+thing.id);
}
if (thing instanceof Group) {
console.error('Could not find group '+thing.getId()+' in zone ('+this.x+','+this.y+'). Position of group: ('+thing.getPosition().x+','+thing.getPosition().y+')');
}
}
2020-09-16 16:06:43 +02:00
this.notifyLeft(thing, newZone);
}
/**
2020-09-16 16:06:43 +02:00
* Notify listeners of this zone that this user/thing left
*/
2020-09-16 16:06:43 +02:00
private notifyLeft(thing: Movable, newZone: Zone|null) {
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-16 16:06:43 +02:00
public enter(thing: Movable, oldZone: Zone|null, position: PositionInterface) {
this.things.add(thing);
this.notifyEnter(thing, oldZone, position);
}
/**
* Notify listeners of this zone that this user entered
*/
private notifyEnter(thing: Movable, oldZone: Zone|null, position: PositionInterface) {
for (const listener of this.listeners) {
2020-09-16 16:06:43 +02:00
if (listener === thing) {
continue;
}
if (oldZone === null || !listener.listenedZones.has(oldZone)) {
2020-09-16 16:06:43 +02:00
this.onEnters(thing, listener);
} else {
2020-09-16 16:06:43 +02:00
this.onMoves(thing, position, listener);
}
}
}
2020-09-16 16:06:43 +02:00
public move(thing: Movable, position: PositionInterface) {
if (!this.things.has(thing)) {
this.things.add(thing);
this.notifyEnter(thing, null, position);
return;
}
for (const listener of this.listeners) {
2020-09-16 16:06:43 +02:00
if (listener !== thing) {
this.onMoves(thing,position, listener);
}
}
}
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);
}
}
this.listeners.add(listener);
listener.listenedZones.add(this);
}
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);
}
}
this.listeners.delete(listener);
listener.listenedZones.delete(this);
}
2020-09-16 16:06:43 +02:00
public getThings(): Set<Movable> {
return this.things;
}
}