Skip to content

Commit

Permalink
added automatic re-initialization on CONTEXT_LOST_WEBGL
Browse files Browse the repository at this point in the history
  • Loading branch information
razorness committed May 15, 2023
1 parent a0aa4d6 commit 32bd4c8
Show file tree
Hide file tree
Showing 11 changed files with 61 additions and 47 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vue-maplibre-gl",
"version": "2.0.4",
"version": "2.0.5",
"description": "Vue 3 plugin for maplibre-gl",
"keywords": [
"vue",
Expand Down
9 changes: 5 additions & 4 deletions src/lib/components/controls/attribution.control.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defineComponent, inject, onBeforeUnmount, PropType, toRef } from 'vue';
import { AttributionControl } from 'maplibre-gl';
import { Position, PositionProp, PositionValues } from '@/lib/components/controls/position.enum';
import { mapSymbol } from '@/lib/types';
import { isInitializedSymbol, mapSymbol } from '@/lib/types';
import { usePositionWatcher } from '@/lib/composable/usePositionWatcher';


Expand All @@ -19,11 +19,12 @@ export default /*#__PURE__*/ defineComponent({
},
setup(props) {

const map = inject(mapSymbol)!,
control = new AttributionControl({ compact: props.compact, customAttribution: props.customAttribution });
const map = inject(mapSymbol)!,
isInitialized = inject(isInitializedSymbol)!,
control = new AttributionControl({ compact: props.compact, customAttribution: props.customAttribution });

usePositionWatcher(toRef(props, 'position'), map, control);
onBeforeUnmount(() => map.value!.removeControl(control));
onBeforeUnmount(() => isInitialized.value && map.value!.removeControl(control));

},
render() {
Expand Down
13 changes: 6 additions & 7 deletions src/lib/components/controls/custom.control.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createCommentVNode, defineComponent, h, inject, nextTick, onBeforeUnmount, PropType, ref, Ref, Teleport, toRef, watch } from 'vue';
import { Position, PositionProp, PositionValues } from '@/lib/components/controls/position.enum';
import { ControlPosition, IControl } from 'maplibre-gl';
import { mapSymbol } from '@/lib/types';
import { isInitializedSymbol, mapSymbol } from '@/lib/types';
import { usePositionWatcher } from '@/lib/composable/usePositionWatcher';


Expand Down Expand Up @@ -59,15 +59,14 @@ export default /*#__PURE__*/ defineComponent({
},
setup(props) {

const map = inject(mapSymbol)!,
isAdded = ref(false),
control = new CustomControl(isAdded, props.noClasses!);
const map = inject(mapSymbol)!,
isInitialized = inject(isInitializedSymbol)!,
isAdded = ref(false),
control = new CustomControl(isAdded, props.noClasses!);

usePositionWatcher(toRef(props, 'position'), map, control);
watch(toRef(props, 'noClasses'), v => control.setClasses(v!));
onBeforeUnmount(() => {
map.value?.removeControl(control);
});
onBeforeUnmount(() => isInitialized.value && map.value?.removeControl(control));

return { isAdded, container: control.container };

Expand Down
9 changes: 5 additions & 4 deletions src/lib/components/controls/frameRate.control.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defineComponent, inject, onBeforeUnmount, PropType, toRef } from 'vue';
import { IControl, Map as MMap } from 'maplibre-gl';
import { Position, PositionProp, PositionValues } from '@/lib/components/controls/position.enum';
import { mapSymbol } from '@/lib/types';
import { isInitializedSymbol, mapSymbol } from '@/lib/types';
import { usePositionWatcher } from '@/lib/composable/usePositionWatcher';

export class FrameRateControl implements IControl {
Expand Down Expand Up @@ -195,8 +195,9 @@ export default /*#__PURE__*/ defineComponent({
},
setup(props) {

const map = inject(mapSymbol)!,
control = new FrameRateControl(
const map = inject(mapSymbol)!,
isInitialized = inject(isInitializedSymbol)!,
control = new FrameRateControl(
props.background,
props.barWidth,
props.color,
Expand All @@ -209,7 +210,7 @@ export default /*#__PURE__*/ defineComponent({
);

usePositionWatcher(toRef(props, 'position'), map, control);
onBeforeUnmount(() => map.value?.removeControl(control));
onBeforeUnmount(() => isInitialized.value && map.value?.removeControl(control));

},
render() {
Expand Down
9 changes: 5 additions & 4 deletions src/lib/components/controls/fullscreen.control.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineComponent, inject, onBeforeUnmount, PropType, toRef } from 'vue';
import { Position, PositionProp, PositionValues } from '@/lib/components/controls/position.enum';
import { mapSymbol } from '@/lib/types';
import { isInitializedSymbol, mapSymbol } from '@/lib/types';
import { FullscreenControl } from 'maplibre-gl';
import { usePositionWatcher } from '@/lib/composable/usePositionWatcher';

Expand All @@ -21,11 +21,12 @@ export default /*#__PURE__*/ defineComponent({
},
setup(props) {

const map = inject(mapSymbol)!,
control = new FullscreenControl({ container: props.container || undefined });
const map = inject(mapSymbol)!,
isInitialized = inject(isInitializedSymbol)!,
control = new FullscreenControl({ container: props.container || undefined });

usePositionWatcher(toRef(props, 'position'), map, control);
onBeforeUnmount(() => map.value?.removeControl(control));
onBeforeUnmount(() => isInitialized.value && map.value?.removeControl(control));

},
render() {
Expand Down
9 changes: 5 additions & 4 deletions src/lib/components/controls/geolocation.control.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineComponent, inject, onBeforeUnmount, PropType, toRef } from 'vue';
import { Position, PositionProp, PositionValues } from '@/lib/components/controls/position.enum';
import { mapSymbol } from '@/lib/types';
import { isInitializedSymbol, mapSymbol } from '@/lib/types';
import { FitBoundsOptions, GeolocateControl } from 'maplibre-gl';
import { usePositionWatcher } from '@/lib/composable/usePositionWatcher';

Expand Down Expand Up @@ -37,8 +37,9 @@ export default /*#__PURE__*/ defineComponent({
},
setup(props) {

const map = inject(mapSymbol)!,
control = new GeolocateControl({
const map = inject(mapSymbol)!,
isInitialized = inject(isInitializedSymbol)!,
control = new GeolocateControl({
positionOptions : props.positionOptions,
fitBoundsOptions : props.fitBoundsOptions,
trackUserLocation : props.trackUserLocation,
Expand All @@ -47,7 +48,7 @@ export default /*#__PURE__*/ defineComponent({
});

usePositionWatcher(toRef(props, 'position'), map, control);
onBeforeUnmount(() => map.value?.removeControl(control));
onBeforeUnmount(() => isInitialized.value && map.value?.removeControl(control));

},
render() {
Expand Down
9 changes: 5 additions & 4 deletions src/lib/components/controls/navigation.control.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineComponent, inject, onBeforeUnmount, PropType, toRef } from 'vue';
import { Position, PositionProp, PositionValues } from '@/lib/components/controls/position.enum';
import { mapSymbol } from '@/lib/types';
import { isInitializedSymbol, mapSymbol } from '@/lib/types';
import { NavigationControl } from 'maplibre-gl';
import { usePositionWatcher } from '@/lib/composable/usePositionWatcher';

Expand All @@ -20,11 +20,12 @@ export default /*#__PURE__*/ defineComponent({
},
setup(props) {

const map = inject(mapSymbol)!,
control = new NavigationControl({ showCompass: props.showCompass, showZoom: props.showZoom, visualizePitch: props.visualizePitch });
const map = inject(mapSymbol)!,
isInitialized = inject(isInitializedSymbol)!,
control = new NavigationControl({ showCompass: props.showCompass, showZoom: props.showZoom, visualizePitch: props.visualizePitch });

usePositionWatcher(toRef(props, 'position'), map, control);
onBeforeUnmount(() => map.value?.removeControl(control));
onBeforeUnmount(() => isInitialized.value && map.value?.removeControl(control));

},
render() {
Expand Down
9 changes: 5 additions & 4 deletions src/lib/components/controls/scale.control.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineComponent, inject, onBeforeUnmount, PropType, toRef } from 'vue';
import { Position, PositionProp, PositionValues } from '@/lib/components/controls/position.enum';
import { mapSymbol } from '@/lib/types';
import { isInitializedSymbol, mapSymbol } from '@/lib/types';
import { ScaleControl } from 'maplibre-gl';
import { usePositionWatcher } from '@/lib/composable/usePositionWatcher';

Expand Down Expand Up @@ -34,11 +34,12 @@ export default /*#__PURE__*/ defineComponent({
},
setup(props) {

const map = inject(mapSymbol)!,
control = new ScaleControl({ maxWidth: props.maxWidth, unit: props.unit });
const map = inject(mapSymbol)!,
isInitialized = inject(isInitializedSymbol)!,
control = new ScaleControl({ maxWidth: props.maxWidth, unit: props.unit });

usePositionWatcher(toRef(props, 'position'), map, control);
onBeforeUnmount(() => map.value?.removeControl(control));
onBeforeUnmount(() => isInitialized.value && map.value?.removeControl(control));

},
render() {
Expand Down
25 changes: 14 additions & 11 deletions src/lib/components/controls/styleSwitch.control.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createCommentVNode, createTextVNode, defineComponent, h, inject, onBeforeUnmount, PropType, ref, shallowRef, Teleport, toRef, watch } from 'vue';
import { Position, PositionProp, PositionValues } from '@/lib/components/controls/position.enum';
import { emitterSymbol, isLoadedSymbol, mapSymbol, StyleSwitchItem } from '@/lib/types';
import { emitterSymbol, isInitializedSymbol, isLoadedSymbol, mapSymbol, StyleSwitchItem } from '@/lib/types';
import { CustomControl } from '@/lib/components/controls/custom.control';
import { usePositionWatcher } from '@/lib/composable/usePositionWatcher';
import { MglButton } from '@/lib/components';
Expand Down Expand Up @@ -35,14 +35,15 @@ export default /*#__PURE__*/ defineComponent({
emits: [ 'update:modelValue', 'update:isOpen' ],
setup(props, { emit }) {

const map = inject(mapSymbol)!,
isMapLoaded = inject(isLoadedSymbol)!,
emitter = inject(emitterSymbol)!,
isAdded = ref(false),
isOpen = ref(props.isOpen === undefined ? false : props.isOpen),
modelValue = shallowRef(props.modelValue === undefined ? (props.mapStyles.length ? props.mapStyles[ 0 ] : null) : props.modelValue),
control = new CustomControl(isAdded, false),
closer = toggleOpen.bind(null, false);
const map = inject(mapSymbol)!,
isInitialized = inject(isInitializedSymbol)!,
isMapLoaded = inject(isLoadedSymbol)!,
emitter = inject(emitterSymbol)!,
isAdded = ref(false),
isOpen = ref(props.isOpen === undefined ? false : props.isOpen),
modelValue = shallowRef(props.modelValue === undefined ? (props.mapStyles.length ? props.mapStyles[ 0 ] : null) : props.modelValue),
control = new CustomControl(isAdded, false),
closer = toggleOpen.bind(null, false);

function setStyleByMap() {
const name = map.value!.getStyle().name;
Expand Down Expand Up @@ -75,8 +76,10 @@ export default /*#__PURE__*/ defineComponent({
}

onBeforeUnmount(() => {
map.value!.removeControl(control);
map.value!.off('style.load', setStyleByMap);
if (isInitialized.value) {
map.value!.removeControl(control);
map.value!.off('style.load', setStyleByMap);
}
document.removeEventListener('click', closer);
});

Expand Down
13 changes: 9 additions & 4 deletions src/lib/components/map.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
RequestTransformFunction,
StyleSpecification
} from 'maplibre-gl';
import { componentIdSymbol, emitterSymbol, isLoadedSymbol, mapSymbol, MglEvents, sourceIdSymbol } from '@/lib/types';
import { componentIdSymbol, emitterSymbol, isInitializedSymbol, isLoadedSymbol, mapSymbol, MglEvents, sourceIdSymbol } from '@/lib/types';
import { defaults } from '@/lib/defaults';
import { MapLib } from '@/lib/lib/map.lib';
import { Position } from '@/lib/components/controls/position.enum';
Expand Down Expand Up @@ -111,6 +111,7 @@ export default /*#__PURE__*/ defineComponent({

provide(mapSymbol, map);
provide(isLoadedSymbol, isLoaded);
provide(isInitializedSymbol, isInitialized);
provide(componentIdSymbol, component.uid);
provide(sourceIdSymbol, '');
provide(emitterSymbol, emitter);
Expand Down Expand Up @@ -224,19 +225,23 @@ export default /*#__PURE__*/ defineComponent({

}

function dispose() {
async function dispose() {

registryItem.isMounted = false;
registryItem.isLoaded = false;
isLoaded.value = false;
isLoaded.value = false;

// unbind events
if (map.value) {
// unbind events
map.value.getCanvas().removeEventListener('webglcontextlost', restart);
map.value._controls.forEach((control) => {
map.value!.removeControl(control);
});
isInitialized.value = false;
boundMapEvents.forEach((func, en) => {
map.value!.off(en.startsWith('__') ? en.substring(2) : en, func as any);
});
// destroy map
map.value.remove();
}

Expand Down
1 change: 1 addition & 0 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { SourceLayerRegistry } from '@/lib/lib/sourceLayer.registry';

export const mapSymbol = Symbol('map') as InjectionKey<ShallowRef<Map | null>>,
isLoadedSymbol = Symbol('isLoaded') as InjectionKey<Ref<boolean>>,
isInitializedSymbol = Symbol('isInitialized') as InjectionKey<Ref<boolean>>,
componentIdSymbol = Symbol('componentId') as InjectionKey<number>,
sourceIdSymbol = Symbol('sourceId') as InjectionKey<string>,
sourceLayerRegistry = Symbol('sourceLayerRegistry') as InjectionKey<SourceLayerRegistry>,
Expand Down

0 comments on commit 32bd4c8

Please sign in to comment.