diff --git a/src/api.ts b/src/api.ts index 8db7998..85f4094 100644 --- a/src/api.ts +++ b/src/api.ts @@ -11,7 +11,7 @@ import { DynmapMarkerSetUpdates, DynmapMessageConfig, DynmapPlayer, - DynmapServerConfig, DynmapUpdate, + DynmapServerConfig, DynmapTileUpdate, DynmapUpdate, DynmapUpdateResponse, DynmapUpdates, DynmapWorld } from "@/dynmap"; @@ -68,9 +68,9 @@ function buildWorlds(response: AxiosResponse): Array { background: '#121212', //map.background || '#000000', backgroundDay: map.backgroundday || '#000000', backgroundNight: map.backgroundnight || '#000000', - compassView: map.compassView || 'S', + compassView: map.compassview || 'S', icon: map.icon || undefined, - imageFormat: map.imageFormat || 'png', + imageFormat: map['image-format'] || 'png', name: map.name || '(Unnamed map)', nightAndDay: map.nightandday || false, prefix: map.prefix || '', @@ -303,7 +303,7 @@ function buildCircle(circle: any): DynmapCircle { function buildUpdates(data: Array): DynmapUpdates { const updates = { markerSets: new Map(), - tiles: new Map(), + tiles: [] as DynmapTileUpdate[], chat: [], } @@ -370,7 +370,10 @@ function buildUpdates(data: Array): DynmapUpdates { break; } - updates.tiles.set(entry.name, entry.timestamp); + updates.tiles.push({ + name: entry.name, + timestamp: entry.timestamp, + }); break; default: diff --git a/src/components/map/layer/MapLayer.vue b/src/components/map/layer/MapLayer.vue index bbdd439..cc3a449 100644 --- a/src/components/map/layer/MapLayer.vue +++ b/src/components/map/layer/MapLayer.vue @@ -5,6 +5,7 @@ import {Map} from 'leaflet'; import {useStore} from "@/store"; import {HDMapType} from "@/leaflet/mapType/HDMapType"; import {MutationTypes} from "@/store/mutation-types"; +import {ActionTypes} from "@/store/action-types"; export default defineComponent({ props: { @@ -23,11 +24,15 @@ export default defineComponent({ }, setup(props) { + let updateFrame = 0, + stopUpdateWatch: Function; + const store = useStore(), layer = new HDMapType({ errorTileUrl: 'images/blank.png', mapSettings: Object.freeze(JSON.parse(JSON.stringify(props.map))), }), + pendingUpdates = computed(() => !!store.state.pendingTileUpdates.length), active = computed(() => props.map === store.state.currentMap), enableLayer = () => { @@ -37,9 +42,38 @@ export default defineComponent({ noMoveStart: true, animate: false, }); + + stopUpdateWatch = watch(pendingUpdates, (newValue, oldValue) => { + if(newValue && !oldValue && !updateFrame) { + handlePendingUpdates(); + } + }); }, - disableLayer = () => layer.remove(); + disableLayer = () => { + layer.remove(); + + if(stopUpdateWatch) { + stopUpdateWatch(); + } + }, + + handlePendingUpdates = () => { + useStore().dispatch(ActionTypes.POP_TILE_UPDATES, 10).then(updates => { + for(const update of updates) { + console.log('Updating tile ' + update.name); + layer.updateNamedTile(update.name, update.timestamp); + } + + if(pendingUpdates.value) { + console.log('More updates left, scheduling frame'); + // eslint-disable-next-line no-unused-vars + updateFrame = requestAnimationFrame(() => handlePendingUpdates()); + } else { + updateFrame = 0; + } + }); + }; watch(active, (newValue) => newValue ? enableLayer() : disableLayer()); @@ -49,7 +83,13 @@ export default defineComponent({ } }); - onUnmounted(() => disableLayer()); + onUnmounted(() => { + disableLayer(); + + if(updateFrame) { + cancelAnimationFrame(updateFrame); + } + }); }, render() { diff --git a/src/dynmap.d.ts b/src/dynmap.d.ts index ce663f8..770ac33 100644 --- a/src/dynmap.d.ts +++ b/src/dynmap.d.ts @@ -1,4 +1,4 @@ -import {CircleMarkerOptions, PathOptions, PointTuple, PolylineOptions} from "leaflet"; +import {PathOptions, PointTuple, PolylineOptions} from "leaflet"; import {CoordinatesControlOptions} from "@/leaflet/control/CoordinatesControl"; import {LogoControlOptions} from "@/leaflet/control/LogoControl"; import {ClockControlOptions} from "@/leaflet/control/ClockControl"; @@ -214,7 +214,7 @@ interface DynmapCircle { interface DynmapUpdates { markerSets: Map, - tiles: Map, + tiles: Array, chat: Array //TODO } @@ -245,4 +245,9 @@ interface DynmapCircleUpdate extends DynmapUpdate { interface DynmapLineUpdate extends DynmapUpdate { payload?: DynmapLine +} + +interface DynmapTileUpdate { + name: string + timestamp: number } \ No newline at end of file diff --git a/src/leaflet/tileLayer/DynmapTileLayer.ts b/src/leaflet/tileLayer/DynmapTileLayer.ts index 4a8f5a7..1cc9d02 100644 --- a/src/leaflet/tileLayer/DynmapTileLayer.ts +++ b/src/leaflet/tileLayer/DynmapTileLayer.ts @@ -83,24 +83,34 @@ export class DynmapTileLayer extends L.TileLayer { } getTileUrl(coords: Coordinate) { - const tileName = this.getTileName(coords); - let url = this._cachedTileUrls.get(tileName); + return this.getTileUrlFromName(this.getTileName(coords)); + } + + getTileUrlFromName(name: string, timestamp?: number) { + let url = this._cachedTileUrls.get(name); if (!url) { - const path = escape(`${this._mapSettings.world.name}/${tileName}`); + const path = escape(`${this._mapSettings.world.name}/${name}`); url = `${window.config.url.tiles}${path}`; - this._cachedTileUrls.set(tileName, url); + + if(typeof timestamp !== 'undefined') { + url += `×tamp=${timestamp}`; + } + + this._cachedTileUrls.set(name, url); } return url; } - updateNamedTile(name: string) { + updateNamedTile(name: string, timestamp: number) { const tile = this._namedTiles.get(name); this._cachedTileUrls.delete(name); if (tile) { - //tile.src = this._cachedTileUrls[name] = this.getTileUrl(name); + tile.dataset.src = this.getTileUrlFromName(name, timestamp); + this._loadQueue.push(tile); + this._tickLoadQueue(); } } diff --git a/src/store/action-types.ts b/src/store/action-types.ts index 97b951f..deb8d93 100644 --- a/src/store/action-types.ts +++ b/src/store/action-types.ts @@ -7,4 +7,5 @@ export enum ActionTypes { POP_AREA_UPDATES = "popAreaUpdates", POP_CIRCLE_UPDATES = "popCircleUpdates", POP_LINE_UPDATES = "popLineUpdates", + POP_TILE_UPDATES = "popTileUpdates", } \ No newline at end of file diff --git a/src/store/actions.ts b/src/store/actions.ts index 7c7beed..9408885 100644 --- a/src/store/actions.ts +++ b/src/store/actions.ts @@ -9,7 +9,7 @@ import { DynmapConfigurationResponse, DynmapLineUpdate, DynmapMarkerSet, DynmapMarkerUpdate, - DynmapPlayer, + DynmapPlayer, DynmapTileUpdate, DynmapUpdateResponse } from "@/dynmap"; @@ -50,6 +50,10 @@ export interface Actions { {commit}: AugmentedActionContext, payload: {markerSet: string, amount: number} ): Promise + [ActionTypes.POP_TILE_UPDATES]( + {commit}: AugmentedActionContext, + payload: number + ): Promise } export const actions: ActionTree & Actions = { @@ -80,6 +84,7 @@ export const actions: ActionTree & Actions = { commit(MutationTypes.SET_UPDATE_TIMESTAMP, new Date(update.timestamp)); commit(MutationTypes.INCREMENT_REQUEST_ID, undefined); commit(MutationTypes.ADD_MARKER_SET_UPDATES, update.updates.markerSets); + commit(MutationTypes.ADD_TILE_UPDATES, update.updates.tiles); return dispatch(ActionTypes.SET_PLAYERS, update.players).then(() => { return update; @@ -175,4 +180,11 @@ export const actions: ActionTree & Actions = { return Promise.resolve(updates); }, + [ActionTypes.POP_TILE_UPDATES]({commit, state}, amount: number): Promise> { + const updates = state.pendingTileUpdates.slice(0, amount); + + commit(MutationTypes.POP_TILE_UPDATES, amount); + + return Promise.resolve(updates); + }, } \ No newline at end of file diff --git a/src/store/mutation-types.ts b/src/store/mutation-types.ts index 12f361f..ed7eac4 100644 --- a/src/store/mutation-types.ts +++ b/src/store/mutation-types.ts @@ -8,10 +8,12 @@ export enum MutationTypes { SET_WORLD_STATE = 'setWorldState', SET_UPDATE_TIMESTAMP = 'setUpdateTimestamp', ADD_MARKER_SET_UPDATES = 'addMarkerSetUpdates', + ADD_TILE_UPDATES = 'addTileUpdates', POP_MARKER_UPDATES = 'popMarkerUpdates', POP_AREA_UPDATES = 'popAreaUpdates', POP_CIRCLE_UPDATES = 'popCircleUpdates', POP_LINE_UPDATES = 'popLineUpdates', + POP_TILE_UPDATES = 'popTileUpdates', INCREMENT_REQUEST_ID = 'incrementRequestId', SET_PLAYERS = 'setPlayers', SET_PLAYERS_ASYNC = 'setPlayersAsync', diff --git a/src/store/mutations.ts b/src/store/mutations.ts index 09a8a93..01b83ce 100644 --- a/src/store/mutations.ts +++ b/src/store/mutations.ts @@ -15,7 +15,7 @@ import { DynmapMarkerUpdate, DynmapMessageConfig, DynmapPlayer, - DynmapServerConfig, + DynmapServerConfig, DynmapTileUpdate, DynmapWorld, DynmapWorldState } from "@/dynmap"; @@ -36,11 +36,13 @@ export type Mutations = { [MutationTypes.SET_WORLD_STATE](state: S, worldState: DynmapWorldState): void [MutationTypes.SET_UPDATE_TIMESTAMP](state: S, time: Date): void [MutationTypes.ADD_MARKER_SET_UPDATES](state: S, updates: Map): void + [MutationTypes.ADD_TILE_UPDATES](state: S, updates: Array): void [MutationTypes.POP_MARKER_UPDATES](state: S, payload: {markerSet: string, amount: number}): Array [MutationTypes.POP_AREA_UPDATES](state: S, payload: {markerSet: string, amount: number}): Array [MutationTypes.POP_CIRCLE_UPDATES](state: S, payload: {markerSet: string, amount: number}): Array [MutationTypes.POP_LINE_UPDATES](state: S, payload: {markerSet: string, amount: number}): Array + [MutationTypes.POP_TILE_UPDATES](state: S, amount: number): Array [MutationTypes.INCREMENT_REQUEST_ID](state: S): void [MutationTypes.SET_PLAYERS_ASYNC](state: S, players: Set): Set @@ -167,6 +169,10 @@ export const mutations: MutationTree & Mutations = { } }, + [MutationTypes.ADD_TILE_UPDATES](state: State, updates: Array) { + state.pendingTileUpdates = state.pendingTileUpdates.concat(updates); + }, + [MutationTypes.POP_MARKER_UPDATES](state: State, {markerSet, amount}): Array { if(!state.markerSets.has(markerSet)) { console.log(`Marker set ${markerSet} doesn't exist`); @@ -203,6 +209,10 @@ export const mutations: MutationTree & Mutations = { return state.pendingSetUpdates.get(markerSet)!.lineUpdates.splice(0, amount); }, + [MutationTypes.POP_TILE_UPDATES](state: State, amount: number): Array { + return state.pendingTileUpdates.splice(0, amount); + }, + //Increments the request id for the next update fetch [MutationTypes.INCREMENT_REQUEST_ID](state: State) { state.updateRequestId++; diff --git a/src/store/state.ts b/src/store/state.ts index 7df637f..c67f54c 100644 --- a/src/store/state.ts +++ b/src/store/state.ts @@ -3,7 +3,7 @@ import { DynmapMap, DynmapMarkerSet, DynmapMarkerSetUpdates, DynmapMessageConfig, DynmapPlayer, - DynmapServerConfig, + DynmapServerConfig, DynmapTileUpdate, DynmapWorld, DynmapWorldState } from "@/dynmap"; import {DynmapProjection} from "@/leaflet/projection/DynmapProjection"; @@ -19,7 +19,7 @@ export type State = { markerSets: Map; pendingSetUpdates: Map; - pendingTileUpdates: Array; + pendingTileUpdates: Array; following?: DynmapPlayer;