Skip to content

Commit

Permalink
add dispose guard (#1323)
Browse files Browse the repository at this point in the history
* add dispose guard

* fix ci
  • Loading branch information
felix-ht authored Sep 12, 2023
1 parent ddad656 commit b2bfef6
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .github/workflows/flutter_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
- uses: actions/checkout@v1
- uses: subosito/flutter-action@v1
- name: Check Dart formatting
run: flutter format --set-exit-if-changed .
run: dart format --set-exit-if-changed .

check-swift-formatting:
name: "Check Swift formatting"
Expand Down
54 changes: 54 additions & 0 deletions lib/src/controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ class MapboxMapController extends ChangeNotifier {
onUserLocationUpdated?.call(location);
});
}
bool _disposed = false;

FillManager? fillManager;
LineManager? lineManager;
Expand Down Expand Up @@ -253,6 +254,7 @@ class MapboxMapController extends ChangeNotifier {
///
/// The returned [Future] completes after listeners have been notified.
Future<void> _updateMapOptions(Map<String, dynamic> optionsUpdate) async {
_disposeGuard();
_cameraPosition = await _mapboxGlPlatform.updateMapOptions(optionsUpdate);
notifyListeners();
}
Expand All @@ -264,14 +266,24 @@ class MapboxMapController extends ChangeNotifier {
///
/// To force resize map (without any checks) have a look at forceResizeWebMap()
void resizeWebMap() {
_disposeGuard();
_mapboxGlPlatform.resizeWebMap();
}

/// Triggers a hard map resize event on web and does not check if it is required or not.
void forceResizeWebMap() {
_disposeGuard();
_mapboxGlPlatform.forceResizeWebMap();
}

void _disposeGuard() {
if (_disposed) {
throw StateError(
'This MapboxMapController has already been disposed. This happens if flutter disposes a MapboxMap and you try to use its Controller afterwards.',
);
}
}

/// Starts an animated change of the map camera position.
///
/// [duration] is the amount of time, that the transition animation should take.
Expand All @@ -282,6 +294,7 @@ class MapboxMapController extends ChangeNotifier {
/// Note: this currently always returns immediately with a value of null on iOS
Future<bool?> animateCamera(CameraUpdate cameraUpdate,
{Duration? duration}) async {
_disposeGuard();
return _mapboxGlPlatform.animateCamera(cameraUpdate, duration: duration);
}

Expand All @@ -293,6 +306,7 @@ class MapboxMapController extends ChangeNotifier {
/// It returns true if the camera was successfully moved and false if the movement was canceled.
/// Note: this currently always returns immediately with a value of null on iOS
Future<bool?> moveCamera(CameraUpdate cameraUpdate) async {
_disposeGuard();
return _mapboxGlPlatform.moveCamera(cameraUpdate);
}

Expand All @@ -310,6 +324,7 @@ class MapboxMapController extends ChangeNotifier {
///
Future<void> addGeoJsonSource(String sourceId, Map<String, dynamic> geojson,
{String? promoteId}) async {
_disposeGuard();
await _mapboxGlPlatform.addGeoJsonSource(sourceId, geojson,
promoteId: promoteId);
}
Expand All @@ -327,6 +342,7 @@ class MapboxMapController extends ChangeNotifier {
/// platform side.
Future<void> setGeoJsonSource(
String sourceId, Map<String, dynamic> geojson) async {
_disposeGuard();
await _mapboxGlPlatform.setGeoJsonSource(sourceId, geojson);
}

Expand All @@ -343,6 +359,7 @@ class MapboxMapController extends ChangeNotifier {
/// platform side.
Future<void> setGeoJsonFeature(
String sourceId, Map<String, dynamic> geojsonFeature) async {
_disposeGuard();
await _mapboxGlPlatform.setFeatureForGeoJsonSource(
sourceId, geojsonFeature);
}
Expand Down Expand Up @@ -374,6 +391,7 @@ class MapboxMapController extends ChangeNotifier {
double? maxzoom,
dynamic filter,
bool enableInteraction = true}) async {
_disposeGuard();
await _mapboxGlPlatform.addSymbolLayer(
sourceId,
layerId,
Expand Down Expand Up @@ -414,6 +432,7 @@ class MapboxMapController extends ChangeNotifier {
double? maxzoom,
dynamic filter,
bool enableInteraction = true}) async {
_disposeGuard();
await _mapboxGlPlatform.addLineLayer(
sourceId,
layerId,
Expand Down Expand Up @@ -454,6 +473,7 @@ class MapboxMapController extends ChangeNotifier {
double? maxzoom,
dynamic filter,
bool enableInteraction = true}) async {
_disposeGuard();
await _mapboxGlPlatform.addFillLayer(
sourceId,
layerId,
Expand Down Expand Up @@ -494,6 +514,7 @@ class MapboxMapController extends ChangeNotifier {
double? maxzoom,
dynamic filter,
bool enableInteraction = true}) async {
_disposeGuard();
await _mapboxGlPlatform.addFillExtrusionLayer(
sourceId,
layerId,
Expand Down Expand Up @@ -534,6 +555,7 @@ class MapboxMapController extends ChangeNotifier {
double? maxzoom,
dynamic filter,
bool enableInteraction = true}) async {
_disposeGuard();
await _mapboxGlPlatform.addCircleLayer(
sourceId,
layerId,
Expand Down Expand Up @@ -567,6 +589,7 @@ class MapboxMapController extends ChangeNotifier {
String? sourceLayer,
double? minzoom,
double? maxzoom}) async {
_disposeGuard();
await _mapboxGlPlatform.addRasterLayer(
sourceId,
layerId,
Expand Down Expand Up @@ -598,6 +621,7 @@ class MapboxMapController extends ChangeNotifier {
String? sourceLayer,
double? minzoom,
double? maxzoom}) async {
_disposeGuard();
await _mapboxGlPlatform.addHillshadeLayer(
sourceId,
layerId,
Expand Down Expand Up @@ -629,6 +653,7 @@ class MapboxMapController extends ChangeNotifier {
String? sourceLayer,
double? minzoom,
double? maxzoom}) async {
_disposeGuard();
await _mapboxGlPlatform.addHeatmapLayer(
sourceId,
layerId,
Expand All @@ -646,6 +671,7 @@ class MapboxMapController extends ChangeNotifier {
/// platform side.
Future<void> updateMyLocationTrackingMode(
MyLocationTrackingMode myLocationTrackingMode) async {
_disposeGuard();
return _mapboxGlPlatform
.updateMyLocationTrackingMode(myLocationTrackingMode);
}
Expand All @@ -655,6 +681,7 @@ class MapboxMapController extends ChangeNotifier {
/// The returned [Future] completes after the change has been made on the
/// platform side.
Future<void> matchMapLanguageWithDeviceDefault() async {
_disposeGuard();
return _mapboxGlPlatform.matchMapLanguageWithDeviceDefault();
}

Expand All @@ -671,6 +698,7 @@ class MapboxMapController extends ChangeNotifier {
/// platform side.
Future<void> updateContentInsets(EdgeInsets insets,
[bool animated = false]) async {
_disposeGuard();
return _mapboxGlPlatform.updateContentInsets(insets, animated);
}

Expand All @@ -681,6 +709,7 @@ class MapboxMapController extends ChangeNotifier {
/// The returned [Future] completes after the change has been made on the
/// platform side.
Future<void> setMapLanguage(String language) async {
_disposeGuard();
return _mapboxGlPlatform.setMapLanguage(language);
}

Expand All @@ -689,6 +718,7 @@ class MapboxMapController extends ChangeNotifier {
/// The returned [Future] completes after the change has been made on the
/// platform side.
Future<void> setTelemetryEnabled(bool enabled) async {
_disposeGuard();
return _mapboxGlPlatform.setTelemetryEnabled(enabled);
}

Expand All @@ -697,6 +727,7 @@ class MapboxMapController extends ChangeNotifier {
/// The returned [Future] completes after the query has been made on the
/// platform side.
Future<bool> getTelemetryEnabled() async {
_disposeGuard();
return _mapboxGlPlatform.getTelemetryEnabled();
}

Expand Down Expand Up @@ -1067,29 +1098,34 @@ class MapboxMapController extends ChangeNotifier {
/// Query rendered features at a point in screen cooridnates
Future<List> queryRenderedFeatures(
Point<double> point, List<String> layerIds, List<Object>? filter) async {
_disposeGuard();
return _mapboxGlPlatform.queryRenderedFeatures(point, layerIds, filter);
}

/// Query rendered features in a Rect in screen coordinates
Future<List> queryRenderedFeaturesInRect(
Rect rect, List<String> layerIds, String? filter) async {
_disposeGuard();
return _mapboxGlPlatform.queryRenderedFeaturesInRect(
rect, layerIds, filter);
}

Future invalidateAmbientCache() async {
_disposeGuard();
return _mapboxGlPlatform.invalidateAmbientCache();
}

/// Get last my location
///
/// Return last latlng, nullable
Future<LatLng?> requestMyLocationLatLng() async {
_disposeGuard();
return _mapboxGlPlatform.requestMyLocationLatLng();
}

/// This method returns the boundaries of the region currently displayed in the map.
Future<LatLngBounds> getVisibleRegion() async {
_disposeGuard();
return _mapboxGlPlatform.getVisibleRegion();
}

Expand Down Expand Up @@ -1129,6 +1165,7 @@ class MapboxMapController extends ChangeNotifier {
/// }
/// ```
Future<void> addImage(String name, Uint8List bytes, [bool sdf = false]) {
_disposeGuard();
return _mapboxGlPlatform.addImage(name, bytes, sdf);
}

Expand All @@ -1155,37 +1192,43 @@ class MapboxMapController extends ChangeNotifier {
/// Adds an image source to the style currently displayed in the map, so that it can later be referred to by the provided id.
Future<void> addImageSource(
String imageSourceId, Uint8List bytes, LatLngQuad coordinates) {
_disposeGuard();
return _mapboxGlPlatform.addImageSource(imageSourceId, bytes, coordinates);
}

/// Update an image source to the style currently displayed in the map, so that it can later be referred to by the provided id.
Future<void> updateImageSource(
String imageSourceId, Uint8List? bytes, LatLngQuad? coordinates) {
_disposeGuard();
return _mapboxGlPlatform.updateImageSource(
imageSourceId, bytes, coordinates);
}

/// Removes previously added image source by id
@Deprecated("This method was renamed to removeSource")
Future<void> removeImageSource(String imageSourceId) {
_disposeGuard();
return _mapboxGlPlatform.removeSource(imageSourceId);
}

/// Removes previously added source by id
Future<void> removeSource(String sourceId) {
_disposeGuard();
return _mapboxGlPlatform.removeSource(sourceId);
}

/// Adds a Mapbox image layer to the map's style at render time.
Future<void> addImageLayer(String layerId, String imageSourceId,
{double? minzoom, double? maxzoom}) {
_disposeGuard();
return _mapboxGlPlatform.addLayer(layerId, imageSourceId, minzoom, maxzoom);
}

/// Adds a Mapbox image layer below the layer provided with belowLayerId to the map's style at render time.
Future<void> addImageLayerBelow(
String layerId, String sourceId, String imageSourceId,
{double? minzoom, double? maxzoom}) {
_disposeGuard();
return _mapboxGlPlatform.addLayerBelow(
layerId, sourceId, imageSourceId, minzoom, maxzoom);
}
Expand All @@ -1195,16 +1238,19 @@ class MapboxMapController extends ChangeNotifier {
Future<void> addLayerBelow(
String layerId, String sourceId, String imageSourceId,
{double? minzoom, double? maxzoom}) {
_disposeGuard();
return _mapboxGlPlatform.addLayerBelow(
layerId, sourceId, imageSourceId, minzoom, maxzoom);
}

/// Removes a Mapbox style layer
Future<void> removeLayer(String layerId) {
_disposeGuard();
return _mapboxGlPlatform.removeLayer(layerId);
}

Future<void> setFilter(String layerId, dynamic filter) {
_disposeGuard();
return _mapboxGlPlatform.setFilter(layerId, filter);
}

Expand All @@ -1222,26 +1268,31 @@ class MapboxMapController extends ChangeNotifier {
///
/// Returns null if [latLng] is not currently visible on the map.
Future<Point> toScreenLocation(LatLng latLng) async {
_disposeGuard();
return _mapboxGlPlatform.toScreenLocation(latLng);
}

Future<List<Point>> toScreenLocationBatch(Iterable<LatLng> latLngs) async {
_disposeGuard();
return _mapboxGlPlatform.toScreenLocationBatch(latLngs);
}

/// Returns the geographic location (as [LatLng]) that corresponds to a point on the screen. The screen location is specified in screen pixels (not display pixels) relative to the top left of the map (not the top left of the whole screen).
Future<LatLng> toLatLng(Point screenLocation) async {
_disposeGuard();
return _mapboxGlPlatform.toLatLng(screenLocation);
}

/// Returns the distance spanned by one pixel at the specified [latitude] and current zoom level.
/// The distance between pixels decreases as the latitude approaches the poles. This relationship parallels the relationship between longitudinal coordinates at different latitudes.
Future<double> getMetersPerPixelAtLatitude(double latitude) async {
_disposeGuard();
return _mapboxGlPlatform.getMetersPerPixelAtLatitude(latitude);
}

/// Add a new source to the map
Future<void> addSource(String sourceid, SourceProperties properties) async {
_disposeGuard();
return _mapboxGlPlatform.addSource(sourceid, properties);
}

Expand Down Expand Up @@ -1285,6 +1336,7 @@ class MapboxMapController extends ChangeNotifier {
addFillExtrusionLayer(sourceId, layerId, properties,
belowLayerId: belowLayerId,
sourceLayer: sourceLayer,
enableInteraction: enableInteraction,
minzoom: minzoom,
maxzoom: maxzoom);
} else if (properties is LineLayerProperties) {
Expand Down Expand Up @@ -1347,11 +1399,13 @@ class MapboxMapController extends ChangeNotifier {
/// Default will return snapshot uri in Android and iOS
/// If you want base64 value, you must set writeToDisk option to False
Future<String> takeSnapshot(SnapshotOptions snapshotOptions) async {
_disposeGuard();
return _mapboxGlPlatform.takeSnapshot(snapshotOptions);
}

@override
void dispose() {
_disposed = true;
super.dispose();
_mapboxGlPlatform.dispose();
}
Expand Down

0 comments on commit b2bfef6

Please sign in to comment.