Move night/update handling into DynmapTileLayer
This commit is contained in:
parent
355c0c71cf
commit
5fb0a3e2f4
@ -18,8 +18,6 @@
|
|||||||
import {defineComponent, onUnmounted, computed, watch} from "@vue/runtime-core";
|
import {defineComponent, onUnmounted, computed, watch} from "@vue/runtime-core";
|
||||||
import {Map} from 'leaflet';
|
import {Map} from 'leaflet';
|
||||||
import {useStore} from "@/store";
|
import {useStore} from "@/store";
|
||||||
import {ActionTypes} from "@/store/action-types";
|
|
||||||
import {getMinecraftTime} from "@/util";
|
|
||||||
import {DynmapTileLayer} from "@/leaflet/tileLayer/DynmapTileLayer";
|
import {DynmapTileLayer} from "@/leaflet/tileLayer/DynmapTileLayer";
|
||||||
import LiveAtlasMapDefinition from "@/model/LiveAtlasMapDefinition";
|
import LiveAtlasMapDefinition from "@/model/LiveAtlasMapDefinition";
|
||||||
|
|
||||||
@ -40,58 +38,22 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setup(props) {
|
setup(props) {
|
||||||
let updateFrame = 0,
|
|
||||||
stopUpdateWatch: Function;
|
|
||||||
|
|
||||||
const store = useStore(),
|
const store = useStore(),
|
||||||
night = computed(() => getMinecraftTime(store.state.currentWorldState.timeOfDay).night),
|
|
||||||
layer = new DynmapTileLayer({
|
layer = new DynmapTileLayer({
|
||||||
errorTileUrl: 'images/blank.png',
|
errorTileUrl: 'images/blank.png',
|
||||||
mapSettings: Object.freeze(JSON.parse(JSON.stringify(props.map))),
|
mapSettings: Object.freeze(JSON.parse(JSON.stringify(props.map))),
|
||||||
night: night.value,
|
|
||||||
}),
|
}),
|
||||||
pendingUpdates = computed(() => !!store.state.pendingTileUpdates.length),
|
active = computed(() => props.map === store.state.currentMap);
|
||||||
active = computed(() => props.map === store.state.currentMap),
|
|
||||||
|
|
||||||
enableLayer = () => {
|
const enableLayer = () => {
|
||||||
props.leaflet.addLayer(layer);
|
props.leaflet.addLayer(layer);
|
||||||
|
|
||||||
stopUpdateWatch = watch(pendingUpdates, (newValue, oldValue) => {
|
|
||||||
if(newValue && !oldValue && !updateFrame) {
|
|
||||||
handlePendingUpdates();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
disableLayer = () => {
|
disableLayer = () => {
|
||||||
layer.remove();
|
layer.remove();
|
||||||
|
|
||||||
if(stopUpdateWatch) {
|
|
||||||
stopUpdateWatch();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
handlePendingUpdates = async () => {
|
|
||||||
const updates = await useStore().dispatch(ActionTypes.POP_TILE_UPDATES, 10);
|
|
||||||
|
|
||||||
for(const update of updates) {
|
|
||||||
layer.updateNamedTile(update.name, update.timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pendingUpdates.value) {
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
updateFrame = requestAnimationFrame(() => handlePendingUpdates());
|
|
||||||
} else {
|
|
||||||
updateFrame = 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(active, (newValue) => newValue ? enableLayer() : disableLayer());
|
watch(active, (newValue) => newValue ? enableLayer() : disableLayer());
|
||||||
watch(night, (newValue) => {
|
|
||||||
if(props.map.nightAndDay) {
|
|
||||||
layer.setNight(newValue);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if(active.value) {
|
if(active.value) {
|
||||||
enableLayer();
|
enableLayer();
|
||||||
@ -99,10 +61,6 @@ export default defineComponent({
|
|||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
disableLayer();
|
disableLayer();
|
||||||
|
|
||||||
if(updateFrame) {
|
|
||||||
cancelAnimationFrame(updateFrame);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -17,10 +17,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {TileLayer, Coords, DoneCallback, TileLayerOptions, DomUtil, Util} from 'leaflet';
|
import {Coords, DoneCallback, DomUtil, TileLayerOptions, TileLayer, Util} from 'leaflet';
|
||||||
import {store} from "@/store";
|
import {useStore} from "@/store";
|
||||||
import {Coordinate} from "@/index";
|
import {Coordinate} from "@/index";
|
||||||
import LiveAtlasMapDefinition from "@/model/LiveAtlasMapDefinition";
|
import LiveAtlasMapDefinition from "@/model/LiveAtlasMapDefinition";
|
||||||
|
import {computed, watch} from "@vue/runtime-core";
|
||||||
|
import {ComputedRef} from "@vue/reactivity";
|
||||||
|
import {WatchStopHandle} from "vue";
|
||||||
|
import {ActionTypes} from "@/store/action-types";
|
||||||
|
|
||||||
export interface DynmapTileLayerOptions extends TileLayerOptions {
|
export interface DynmapTileLayerOptions extends TileLayerOptions {
|
||||||
mapSettings: LiveAtlasMapDefinition;
|
mapSettings: LiveAtlasMapDefinition;
|
||||||
@ -54,6 +58,8 @@ export interface TileInfo {
|
|||||||
fmt: string;
|
fmt: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const store = useStore();
|
||||||
|
|
||||||
// noinspection JSUnusedGlobalSymbols
|
// noinspection JSUnusedGlobalSymbols
|
||||||
export class DynmapTileLayer extends TileLayer {
|
export class DynmapTileLayer extends TileLayer {
|
||||||
private readonly _mapSettings: LiveAtlasMapDefinition;
|
private readonly _mapSettings: LiveAtlasMapDefinition;
|
||||||
@ -63,7 +69,15 @@ export class DynmapTileLayer extends TileLayer {
|
|||||||
private readonly _loadingTiles: Set<DynmapTileElement> = Object.seal(new Set());
|
private readonly _loadingTiles: Set<DynmapTileElement> = Object.seal(new Set());
|
||||||
private readonly _tileTemplate: DynmapTileElement;
|
private readonly _tileTemplate: DynmapTileElement;
|
||||||
private readonly _baseUrl: string;
|
private readonly _baseUrl: string;
|
||||||
declare readonly options: DynmapTileLayerOptions;
|
|
||||||
|
private readonly _night: ComputedRef<boolean>;
|
||||||
|
private readonly _pendingUpdates: ComputedRef<boolean>;
|
||||||
|
private readonly _nightUnwatch: WatchStopHandle;
|
||||||
|
private readonly _updateUnwatch: WatchStopHandle;
|
||||||
|
private _updateFrame: number = 0;
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
declare options: DynmapTileLayerOptions;
|
||||||
|
|
||||||
constructor(options: DynmapTileLayerOptions) {
|
constructor(options: DynmapTileLayerOptions) {
|
||||||
super('', options);
|
super('', options);
|
||||||
@ -93,9 +107,23 @@ export class DynmapTileLayer extends TileLayer {
|
|||||||
if(this.options.crossOrigin || this.options.crossOrigin === '') {
|
if(this.options.crossOrigin || this.options.crossOrigin === '') {
|
||||||
this._tileTemplate.crossOrigin = this.options.crossOrigin === true ? '' : this.options.crossOrigin;
|
this._tileTemplate.crossOrigin = this.options.crossOrigin === true ? '' : this.options.crossOrigin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._pendingUpdates = computed(() => !!store.state.pendingTileUpdates.length);
|
||||||
|
this._updateUnwatch = watch(this._pendingUpdates, (newValue, oldValue) => {
|
||||||
|
if(newValue && !oldValue && !this._updateFrame) {
|
||||||
|
this.handlePendingUpdates();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this._night = computed(() => store.getters.night);
|
||||||
|
this._nightUnwatch = watch(this._night, () => {
|
||||||
|
if(this._mapSettings.nightAndDay) {
|
||||||
|
this.redraw();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getTileName(coords: Coordinate) {
|
private getTileName(coords: Coordinate) {
|
||||||
const info = this.getTileInfo(coords);
|
const info = this.getTileInfo(coords);
|
||||||
// Y is inverted for HD-map.
|
// Y is inverted for HD-map.
|
||||||
info.y = -info.y;
|
info.y = -info.y;
|
||||||
@ -107,7 +135,7 @@ export class DynmapTileLayer extends TileLayer {
|
|||||||
return this.getTileUrlFromName(this.getTileName(coords));
|
return this.getTileUrlFromName(this.getTileName(coords));
|
||||||
}
|
}
|
||||||
|
|
||||||
getTileUrlFromName(name: string, timestamp?: number) {
|
private getTileUrlFromName(name: string, timestamp?: number) {
|
||||||
let url = this._cachedTileUrls.get(name);
|
let url = this._cachedTileUrls.get(name);
|
||||||
|
|
||||||
if (!url) {
|
if (!url) {
|
||||||
@ -124,7 +152,7 @@ export class DynmapTileLayer extends TileLayer {
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateNamedTile(name: string, timestamp: number) {
|
private updateNamedTile(name: string, timestamp: number) {
|
||||||
const tile = this._namedTiles.get(name);
|
const tile = this._namedTiles.get(name);
|
||||||
this._cachedTileUrls.delete(name);
|
this._cachedTileUrls.delete(name);
|
||||||
|
|
||||||
@ -231,14 +259,14 @@ export class DynmapTileLayer extends TileLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Some helper functions.
|
// Some helper functions.
|
||||||
zoomprefix(amount: number) {
|
private zoomprefix(amount: number) {
|
||||||
// amount == 0 -> ''
|
// amount == 0 -> ''
|
||||||
// amount == 1 -> 'z_'
|
// amount == 1 -> 'z_'
|
||||||
// amount == 2 -> 'zz_'
|
// amount == 2 -> 'zz_'
|
||||||
return 'z'.repeat(amount) + (amount === 0 ? '' : '_');
|
return 'z'.repeat(amount) + (amount === 0 ? '' : '_');
|
||||||
}
|
}
|
||||||
|
|
||||||
getTileInfo(coords: Coordinate): TileInfo {
|
private getTileInfo(coords: Coordinate): TileInfo {
|
||||||
// zoom: max zoomed in = this.options.maxZoom, max zoomed out = 0
|
// zoom: max zoomed in = this.options.maxZoom, max zoomed out = 0
|
||||||
// izoom: max zoomed in = 0, max zoomed out = this.options.maxZoom
|
// izoom: max zoomed in = 0, max zoomed out = this.options.maxZoom
|
||||||
// zoomoutlevel: izoom < mapzoomin -> 0, else -> izoom - mapzoomin (which ranges from 0 till mapzoomout)
|
// zoomoutlevel: izoom < mapzoomin -> 0, else -> izoom - mapzoomin (which ranges from 0 till mapzoomout)
|
||||||
@ -250,7 +278,7 @@ export class DynmapTileLayer extends TileLayer {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
prefix: this._mapSettings.prefix,
|
prefix: this._mapSettings.prefix,
|
||||||
nightday: (this._mapSettings.nightAndDay && !this.options.night) ? '_day' : '',
|
nightday: (this._mapSettings.nightAndDay && !this._night.value) ? '_day' : '',
|
||||||
scaledx: x >> 5,
|
scaledx: x >> 5,
|
||||||
scaledy: y >> 5,
|
scaledy: y >> 5,
|
||||||
zoom: this.zoomprefix(zoomoutlevel),
|
zoom: this.zoomprefix(zoomoutlevel),
|
||||||
@ -261,10 +289,34 @@ export class DynmapTileLayer extends TileLayer {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
setNight(night: boolean) {
|
private async handlePendingUpdates() {
|
||||||
if(this.options.night !== night) {
|
const updates = await store.dispatch(ActionTypes.POP_TILE_UPDATES, 10);
|
||||||
this.options.night = night;
|
|
||||||
this.redraw();
|
for(const update of updates) {
|
||||||
|
this.updateNamedTile(update.name, update.timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this._pendingUpdates.value) {
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
this._updateFrame = requestAnimationFrame(() => this.handlePendingUpdates());
|
||||||
|
} else {
|
||||||
|
this._updateFrame = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remove() {
|
||||||
|
super.remove();
|
||||||
|
|
||||||
|
this._nightUnwatch();
|
||||||
|
|
||||||
|
if(this._updateFrame) {
|
||||||
|
cancelAnimationFrame(this._updateFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this._updateUnwatch) {
|
||||||
|
this._updateUnwatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user