Implement update handling for map tiles

This commit is contained in:
James Lyne 2020-12-11 18:51:23 +00:00
parent b0e53b5fc9
commit 52bb6f5778
9 changed files with 102 additions and 19 deletions

View File

@ -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<DynmapWorld> {
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<any>): DynmapUpdates {
const updates = {
markerSets: new Map<string, DynmapMarkerSetUpdates>(),
tiles: new Map(),
tiles: [] as DynmapTileUpdate[],
chat: [],
}
@ -370,7 +370,10 @@ function buildUpdates(data: Array<any>): DynmapUpdates {
break;
}
updates.tiles.set(entry.name, entry.timestamp);
updates.tiles.push({
name: entry.name,
timestamp: entry.timestamp,
});
break;
default:

View File

@ -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() {

9
src/dynmap.d.ts vendored
View File

@ -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<string, DynmapMarkerSetUpdates>,
tiles: Map<string, number>,
tiles: Array<DynmapTileUpdate>,
chat: Array<any> //TODO
}
@ -246,3 +246,8 @@ interface DynmapCircleUpdate extends DynmapUpdate {
interface DynmapLineUpdate extends DynmapUpdate {
payload?: DynmapLine
}
interface DynmapTileUpdate {
name: string
timestamp: number
}

View File

@ -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 += `&timestamp=${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();
}
}

View File

@ -7,4 +7,5 @@ export enum ActionTypes {
POP_AREA_UPDATES = "popAreaUpdates",
POP_CIRCLE_UPDATES = "popCircleUpdates",
POP_LINE_UPDATES = "popLineUpdates",
POP_TILE_UPDATES = "popTileUpdates",
}

View File

@ -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<DynmapLineUpdate[]>
[ActionTypes.POP_TILE_UPDATES](
{commit}: AugmentedActionContext,
payload: number
): Promise<DynmapTileUpdate[]>
}
export const actions: ActionTree<State, State> & Actions = {
@ -80,6 +84,7 @@ export const actions: ActionTree<State, State> & 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<State, State> & Actions = {
return Promise.resolve(updates);
},
[ActionTypes.POP_TILE_UPDATES]({commit, state}, amount: number): Promise<Array<DynmapTileUpdate>> {
const updates = state.pendingTileUpdates.slice(0, amount);
commit(MutationTypes.POP_TILE_UPDATES, amount);
return Promise.resolve(updates);
},
}

View File

@ -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',

View File

@ -15,7 +15,7 @@ import {
DynmapMarkerUpdate,
DynmapMessageConfig,
DynmapPlayer,
DynmapServerConfig,
DynmapServerConfig, DynmapTileUpdate,
DynmapWorld,
DynmapWorldState
} from "@/dynmap";
@ -36,11 +36,13 @@ export type Mutations<S = State> = {
[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<string, DynmapMarkerSetUpdates>): void
[MutationTypes.ADD_TILE_UPDATES](state: S, updates: Array<DynmapTileUpdate>): void
[MutationTypes.POP_MARKER_UPDATES](state: S, payload: {markerSet: string, amount: number}): Array<DynmapMarkerUpdate>
[MutationTypes.POP_AREA_UPDATES](state: S, payload: {markerSet: string, amount: number}): Array<DynmapAreaUpdate>
[MutationTypes.POP_CIRCLE_UPDATES](state: S, payload: {markerSet: string, amount: number}): Array<DynmapCircleUpdate>
[MutationTypes.POP_LINE_UPDATES](state: S, payload: {markerSet: string, amount: number}): Array<DynmapLineUpdate>
[MutationTypes.POP_TILE_UPDATES](state: S, amount: number): Array<DynmapTileUpdate>
[MutationTypes.INCREMENT_REQUEST_ID](state: S): void
[MutationTypes.SET_PLAYERS_ASYNC](state: S, players: Set<DynmapPlayer>): Set<DynmapPlayer>
@ -167,6 +169,10 @@ export const mutations: MutationTree<State> & Mutations = {
}
},
[MutationTypes.ADD_TILE_UPDATES](state: State, updates: Array<DynmapTileUpdate>) {
state.pendingTileUpdates = state.pendingTileUpdates.concat(updates);
},
[MutationTypes.POP_MARKER_UPDATES](state: State, {markerSet, amount}): Array<DynmapMarkerUpdate> {
if(!state.markerSets.has(markerSet)) {
console.log(`Marker set ${markerSet} doesn't exist`);
@ -203,6 +209,10 @@ export const mutations: MutationTree<State> & Mutations = {
return state.pendingSetUpdates.get(markerSet)!.lineUpdates.splice(0, amount);
},
[MutationTypes.POP_TILE_UPDATES](state: State, amount: number): Array<DynmapTileUpdate> {
return state.pendingTileUpdates.splice(0, amount);
},
//Increments the request id for the next update fetch
[MutationTypes.INCREMENT_REQUEST_ID](state: State) {
state.updateRequestId++;

View File

@ -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<string, DynmapMarkerSet>;
pendingSetUpdates: Map<string, DynmapMarkerSetUpdates>;
pendingTileUpdates: Array<string>;
pendingTileUpdates: Array<DynmapTileUpdate>;
following?: DynmapPlayer;