2021-02-19 16:23:11 +01:00
|
|
|
/*
|
|
|
|
* This file is part of BlueMap, licensed under the MIT License (MIT).
|
|
|
|
*
|
|
|
|
* Copyright (c) Blue (Lukas Rieger) <https://bluecolored.de>
|
|
|
|
* Copyright (c) contributors
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
|
|
* in the Software without restriction, including without limitation the rights
|
|
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
|
|
* furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
* THE SOFTWARE.
|
|
|
|
*/
|
2021-01-28 19:57:54 +01:00
|
|
|
import {FileLoader, Scene} from "three";
|
|
|
|
import {MarkerSet} from "./MarkerSet";
|
2021-03-18 21:05:12 +01:00
|
|
|
import {alert, generateCacheHash} from "../util/Utils";
|
2022-07-31 12:38:50 +02:00
|
|
|
import {PlayerMarkerSet} from "./PlayerMarkerSet";
|
|
|
|
|
|
|
|
export const MarkerFileType = {
|
|
|
|
NORMAL: 1,
|
|
|
|
PLAYER: 2,
|
|
|
|
}
|
|
|
|
|
|
|
|
export const PLAYER_MARKER_SET_ID = "bm-players";
|
2021-01-28 19:57:54 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* A manager for loading and updating markers from a file
|
|
|
|
*/
|
|
|
|
export class MarkerManager {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @constructor
|
2022-07-31 12:38:50 +02:00
|
|
|
* @param root {MarkerSet} - The scene to which all markers will be added
|
2021-01-28 19:57:54 +01:00
|
|
|
* @param fileUrl {string} - The marker file from which this manager updates its markers
|
2022-07-31 12:38:50 +02:00
|
|
|
* @param fileType {number} - The type of the marker-file, see MarkerManager.NORMAL and MarkerManager.PLAYER
|
2021-01-28 19:57:54 +01:00
|
|
|
* @param events {EventTarget}
|
|
|
|
*/
|
2022-07-31 12:38:50 +02:00
|
|
|
constructor(root, fileUrl, fileType, events = null) {
|
2021-01-28 19:57:54 +01:00
|
|
|
Object.defineProperty(this, 'isMarkerManager', {value: true});
|
|
|
|
|
2022-07-31 12:38:50 +02:00
|
|
|
this.root = root;
|
2021-01-28 19:57:54 +01:00
|
|
|
this.fileUrl = fileUrl;
|
2022-07-31 12:38:50 +02:00
|
|
|
this.fileType = fileType;
|
2021-01-28 19:57:54 +01:00
|
|
|
this.events = events;
|
|
|
|
|
|
|
|
/** @type {NodeJS.Timeout} */
|
|
|
|
this._updateInterval = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the automatic-update frequency, setting this to 0 or negative disables automatic updates (default).
|
|
|
|
* This is better than using setInterval() on update() because this will wait for the update to finish before requesting the next update.
|
|
|
|
* @param ms - interval in milliseconds
|
|
|
|
*/
|
|
|
|
setAutoUpdateInterval(ms) {
|
2021-03-09 12:57:35 +01:00
|
|
|
if (this._updateInterval) clearTimeout(this._updateInterval);
|
2021-01-28 19:57:54 +01:00
|
|
|
if (ms > 0) {
|
|
|
|
let autoUpdate = () => {
|
2021-03-09 12:57:35 +01:00
|
|
|
this.update()
|
2021-03-28 13:22:45 +02:00
|
|
|
.then(success => {
|
|
|
|
if (success) {
|
|
|
|
this._updateInterval = setTimeout(autoUpdate, ms);
|
|
|
|
} else {
|
|
|
|
this._updateInterval = setTimeout(autoUpdate, Math.max(ms, 1000 * 15));
|
|
|
|
}
|
2021-03-09 12:57:35 +01:00
|
|
|
})
|
|
|
|
.catch(e => {
|
|
|
|
alert(this.events, e, "warning");
|
|
|
|
this._updateInterval = setTimeout(autoUpdate, Math.max(ms, 1000 * 15));
|
|
|
|
});
|
2021-01-28 19:57:54 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
this._updateInterval = setTimeout(autoUpdate, ms);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Loads the marker-file and updates all managed markers.
|
|
|
|
* @returns {Promise<object>} - A promise completing when the markers finished updating
|
|
|
|
*/
|
|
|
|
update() {
|
|
|
|
return this.loadMarkerFile()
|
2021-03-09 12:57:35 +01:00
|
|
|
.then(markerFileData => this.updateFromData(markerFileData));
|
2021-01-28 19:57:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-07-31 12:38:50 +02:00
|
|
|
* @private
|
|
|
|
* @param markerData
|
2021-01-28 19:57:54 +01:00
|
|
|
*/
|
2022-07-31 12:38:50 +02:00
|
|
|
updateFromData(markerData) {
|
|
|
|
switch (this.fileType) {
|
|
|
|
case MarkerFileType.NORMAL: return this.updateFromDataNormal(markerData);
|
|
|
|
case MarkerFileType.PLAYER: return this.updateFromDataPlayer(markerData);
|
|
|
|
}
|
2021-01-28 19:57:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-07-31 12:38:50 +02:00
|
|
|
* @private
|
|
|
|
* @param markerData
|
|
|
|
* @returns {boolean}
|
2021-01-28 19:57:54 +01:00
|
|
|
*/
|
2022-07-31 12:38:50 +02:00
|
|
|
updateFromDataNormal(markerData) {
|
|
|
|
this.root.updateMarkerSetsFromData(markerData, [PLAYER_MARKER_SET_ID, "bm-popup-set"]);
|
|
|
|
return true;
|
2021-01-28 19:57:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-07-31 12:38:50 +02:00
|
|
|
* @private
|
|
|
|
* @param markerFileData
|
|
|
|
* @returns {boolean}
|
2021-01-28 19:57:54 +01:00
|
|
|
*/
|
2022-07-31 12:38:50 +02:00
|
|
|
updateFromDataPlayer(markerFileData) {
|
|
|
|
let playerMarkerSet = this.getPlayerMarkerSet();
|
|
|
|
return playerMarkerSet.updateFromPlayerData(markerFileData);
|
2021-01-28 19:57:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-07-31 12:38:50 +02:00
|
|
|
* @private
|
|
|
|
* @returns {PlayerMarkerSet}
|
2021-01-28 19:57:54 +01:00
|
|
|
*/
|
2022-07-31 12:38:50 +02:00
|
|
|
getPlayerMarkerSet() {
|
|
|
|
/** @type {PlayerMarkerSet} */
|
|
|
|
let playerMarkerSet = /** @type {PlayerMarkerSet} */ this.root.markerSets.get(PLAYER_MARKER_SET_ID);
|
2021-01-28 19:57:54 +01:00
|
|
|
|
2022-07-31 12:38:50 +02:00
|
|
|
if (!playerMarkerSet) {
|
|
|
|
playerMarkerSet = new PlayerMarkerSet(PLAYER_MARKER_SET_ID);
|
|
|
|
this.root.add(playerMarkerSet);
|
2021-01-28 19:57:54 +01:00
|
|
|
}
|
2022-07-31 12:38:50 +02:00
|
|
|
|
|
|
|
return playerMarkerSet;
|
2021-01-28 19:57:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-07-31 12:38:50 +02:00
|
|
|
* @param playerUuid {string}
|
|
|
|
* @returns {PlayerMarker | undefined}
|
2021-01-28 19:57:54 +01:00
|
|
|
*/
|
2022-07-31 12:38:50 +02:00
|
|
|
getPlayerMarker(playerUuid) {
|
|
|
|
return this.getPlayerMarkerSet().getPlayerMarker(playerUuid)
|
2021-01-28 19:57:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-07-31 12:38:50 +02:00
|
|
|
* Stops automatic-updates and disposes all markersets and markers managed by this manager
|
2021-01-28 19:57:54 +01:00
|
|
|
*/
|
2022-07-31 12:38:50 +02:00
|
|
|
dispose() {
|
|
|
|
this.setAutoUpdateInterval(0);
|
|
|
|
this.clear();
|
2021-01-28 19:57:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-07-31 12:38:50 +02:00
|
|
|
* Removes all markers managed by this marker-manager
|
2021-01-28 19:57:54 +01:00
|
|
|
*/
|
2022-07-31 12:38:50 +02:00
|
|
|
clear() {
|
|
|
|
this.root.clear();
|
2021-03-28 13:22:45 +02:00
|
|
|
}
|
2021-01-28 19:57:54 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
* Loads the marker file
|
|
|
|
* @returns {Promise<Object>} - A promise completing with the parsed json object from the loaded file
|
|
|
|
*/
|
|
|
|
loadMarkerFile() {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
let loader = new FileLoader();
|
|
|
|
loader.setResponseType("json");
|
2021-03-18 21:05:12 +01:00
|
|
|
loader.load(this.fileUrl + "?" + generateCacheHash(),
|
2021-01-28 19:57:54 +01:00
|
|
|
markerFileData => {
|
|
|
|
if (!markerFileData) reject(`Failed to parse '${this.fileUrl}'!`);
|
|
|
|
else resolve(markerFileData);
|
|
|
|
},
|
|
|
|
() => {},
|
|
|
|
() => reject(`Failed to load '${this.fileUrl}'!`)
|
|
|
|
)
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|