From d077934800231a5f0d36fca638c7fea905cb3136 Mon Sep 17 00:00:00 2001 From: Tarek Tolba Date: Tue, 28 Oct 2025 15:05:23 +0300 Subject: [PATCH 1/5] Fix race condition --- lib/src/manager/route_map_icon_manager.dart | 21 +- .../route_map_icon.freezed.dart | 270 ++++++++---------- .../route_map_route.freezed.dart | 144 +++++----- ...e_map_user_location_indicator.freezed.dart | 104 ++++--- lib/src/route_map_base.dart | 68 +++-- 5 files changed, 279 insertions(+), 328 deletions(-) diff --git a/lib/src/manager/route_map_icon_manager.dart b/lib/src/manager/route_map_icon_manager.dart index 5855e11..a15aea7 100644 --- a/lib/src/manager/route_map_icon_manager.dart +++ b/lib/src/manager/route_map_icon_manager.dart @@ -74,10 +74,9 @@ class RouteMapIconManager { } Future removeIcon({required String identifier}) async { - final searchedSymbolId = - _symbolMap.entries - .firstWhereOrNull((entry) => entry.value.identifier == identifier) - ?.key; + final searchedSymbolId = _symbolMap.entries + .firstWhereOrNull((entry) => entry.value.identifier == identifier) + ?.key; if (searchedSymbolId == null) { return; @@ -182,14 +181,12 @@ class RouteMapIconManager { final pictureInfo = await vg.loadPicture(loader, null); // Draw the SVG icon - final iconWidth = - drawCircleAroundIcon - ? circleRadius * 1.3 - : sizeBeforeStroke.width - padding * 2; - final iconHeight = - drawCircleAroundIcon - ? circleRadius * 1.3 - : sizeBeforeStroke.height - padding * 2; + final iconWidth = drawCircleAroundIcon + ? circleRadius * 1.3 + : sizeBeforeStroke.width - padding * 2; + final iconHeight = drawCircleAroundIcon + ? circleRadius * 1.3 + : sizeBeforeStroke.height - padding * 2; // Compute scaling factors final iconScaleX = iconWidth / pictureInfo.size.width; final iconScaleY = iconHeight / pictureInfo.size.height; diff --git a/lib/src/model/route_map_icon/route_map_icon.freezed.dart b/lib/src/model/route_map_icon/route_map_icon.freezed.dart index a0b4ee6..3558b75 100644 --- a/lib/src/model/route_map_icon/route_map_icon.freezed.dart +++ b/lib/src/model/route_map_icon/route_map_icon.freezed.dart @@ -87,56 +87,46 @@ class _$RouteMapIconCopyWithImpl<$Res, $Val extends RouteMapIcon> }) { return _then( _value.copyWith( - markerPath: - null == markerPath - ? _value.markerPath - : markerPath // ignore: cast_nullable_to_non_nullable - as Path, - latLng: - null == latLng - ? _value.latLng - : latLng // ignore: cast_nullable_to_non_nullable - as LatLng, - identifier: - null == identifier - ? _value.identifier - : identifier // ignore: cast_nullable_to_non_nullable - as String, - theme: - null == theme - ? _value.theme - : theme // ignore: cast_nullable_to_non_nullable - as RouteMapIconTheme, - darkTheme: - freezed == darkTheme - ? _value.darkTheme - : darkTheme // ignore: cast_nullable_to_non_nullable - as RouteMapIconTheme?, - svgIconPath: - freezed == svgIconPath - ? _value.svgIconPath - : svgIconPath // ignore: cast_nullable_to_non_nullable - as String?, - text: - freezed == text - ? _value.text - : text // ignore: cast_nullable_to_non_nullable - as String?, - label: - freezed == label - ? _value.label - : label // ignore: cast_nullable_to_non_nullable - as String?, - draggable: - null == draggable - ? _value.draggable - : draggable // ignore: cast_nullable_to_non_nullable - as bool, - anchor: - null == anchor - ? _value.anchor - : anchor // ignore: cast_nullable_to_non_nullable - as RouteMapIconAnchor, + markerPath: null == markerPath + ? _value.markerPath + : markerPath // ignore: cast_nullable_to_non_nullable + as Path, + latLng: null == latLng + ? _value.latLng + : latLng // ignore: cast_nullable_to_non_nullable + as LatLng, + identifier: null == identifier + ? _value.identifier + : identifier // ignore: cast_nullable_to_non_nullable + as String, + theme: null == theme + ? _value.theme + : theme // ignore: cast_nullable_to_non_nullable + as RouteMapIconTheme, + darkTheme: freezed == darkTheme + ? _value.darkTheme + : darkTheme // ignore: cast_nullable_to_non_nullable + as RouteMapIconTheme?, + svgIconPath: freezed == svgIconPath + ? _value.svgIconPath + : svgIconPath // ignore: cast_nullable_to_non_nullable + as String?, + text: freezed == text + ? _value.text + : text // ignore: cast_nullable_to_non_nullable + as String?, + label: freezed == label + ? _value.label + : label // ignore: cast_nullable_to_non_nullable + as String?, + draggable: null == draggable + ? _value.draggable + : draggable // ignore: cast_nullable_to_non_nullable + as bool, + anchor: null == anchor + ? _value.anchor + : anchor // ignore: cast_nullable_to_non_nullable + as RouteMapIconAnchor, ) as $Val, ); @@ -222,56 +212,46 @@ class __$$RouteMapIconImplCopyWithImpl<$Res> }) { return _then( _$RouteMapIconImpl( - markerPath: - null == markerPath - ? _value.markerPath - : markerPath // ignore: cast_nullable_to_non_nullable - as Path, - latLng: - null == latLng - ? _value.latLng - : latLng // ignore: cast_nullable_to_non_nullable - as LatLng, - identifier: - null == identifier - ? _value.identifier - : identifier // ignore: cast_nullable_to_non_nullable - as String, - theme: - null == theme - ? _value.theme - : theme // ignore: cast_nullable_to_non_nullable - as RouteMapIconTheme, - darkTheme: - freezed == darkTheme - ? _value.darkTheme - : darkTheme // ignore: cast_nullable_to_non_nullable - as RouteMapIconTheme?, - svgIconPath: - freezed == svgIconPath - ? _value.svgIconPath - : svgIconPath // ignore: cast_nullable_to_non_nullable - as String?, - text: - freezed == text - ? _value.text - : text // ignore: cast_nullable_to_non_nullable - as String?, - label: - freezed == label - ? _value.label - : label // ignore: cast_nullable_to_non_nullable - as String?, - draggable: - null == draggable - ? _value.draggable - : draggable // ignore: cast_nullable_to_non_nullable - as bool, - anchor: - null == anchor - ? _value.anchor - : anchor // ignore: cast_nullable_to_non_nullable - as RouteMapIconAnchor, + markerPath: null == markerPath + ? _value.markerPath + : markerPath // ignore: cast_nullable_to_non_nullable + as Path, + latLng: null == latLng + ? _value.latLng + : latLng // ignore: cast_nullable_to_non_nullable + as LatLng, + identifier: null == identifier + ? _value.identifier + : identifier // ignore: cast_nullable_to_non_nullable + as String, + theme: null == theme + ? _value.theme + : theme // ignore: cast_nullable_to_non_nullable + as RouteMapIconTheme, + darkTheme: freezed == darkTheme + ? _value.darkTheme + : darkTheme // ignore: cast_nullable_to_non_nullable + as RouteMapIconTheme?, + svgIconPath: freezed == svgIconPath + ? _value.svgIconPath + : svgIconPath // ignore: cast_nullable_to_non_nullable + as String?, + text: freezed == text + ? _value.text + : text // ignore: cast_nullable_to_non_nullable + as String?, + label: freezed == label + ? _value.label + : label // ignore: cast_nullable_to_non_nullable + as String?, + draggable: null == draggable + ? _value.draggable + : draggable // ignore: cast_nullable_to_non_nullable + as bool, + anchor: null == anchor + ? _value.anchor + : anchor // ignore: cast_nullable_to_non_nullable + as RouteMapIconAnchor, ), ); } @@ -467,31 +447,26 @@ class _$RouteMapIconThemeCopyWithImpl<$Res, $Val extends RouteMapIconTheme> }) { return _then( _value.copyWith( - background: - null == background - ? _value.background - : background // ignore: cast_nullable_to_non_nullable - as Color, - foreground: - null == foreground - ? _value.foreground - : foreground // ignore: cast_nullable_to_non_nullable - as Color, - drawCircleAroundIcon: - null == drawCircleAroundIcon - ? _value.drawCircleAroundIcon - : drawCircleAroundIcon // ignore: cast_nullable_to_non_nullable - as bool, - strokeWidth: - null == strokeWidth - ? _value.strokeWidth - : strokeWidth // ignore: cast_nullable_to_non_nullable - as double, - padding: - null == padding - ? _value.padding - : padding // ignore: cast_nullable_to_non_nullable - as double, + background: null == background + ? _value.background + : background // ignore: cast_nullable_to_non_nullable + as Color, + foreground: null == foreground + ? _value.foreground + : foreground // ignore: cast_nullable_to_non_nullable + as Color, + drawCircleAroundIcon: null == drawCircleAroundIcon + ? _value.drawCircleAroundIcon + : drawCircleAroundIcon // ignore: cast_nullable_to_non_nullable + as bool, + strokeWidth: null == strokeWidth + ? _value.strokeWidth + : strokeWidth // ignore: cast_nullable_to_non_nullable + as double, + padding: null == padding + ? _value.padding + : padding // ignore: cast_nullable_to_non_nullable + as double, ) as $Val, ); @@ -538,31 +513,26 @@ class __$$RouteMapIconThemeImplCopyWithImpl<$Res> }) { return _then( _$RouteMapIconThemeImpl( - background: - null == background - ? _value.background - : background // ignore: cast_nullable_to_non_nullable - as Color, - foreground: - null == foreground - ? _value.foreground - : foreground // ignore: cast_nullable_to_non_nullable - as Color, - drawCircleAroundIcon: - null == drawCircleAroundIcon - ? _value.drawCircleAroundIcon - : drawCircleAroundIcon // ignore: cast_nullable_to_non_nullable - as bool, - strokeWidth: - null == strokeWidth - ? _value.strokeWidth - : strokeWidth // ignore: cast_nullable_to_non_nullable - as double, - padding: - null == padding - ? _value.padding - : padding // ignore: cast_nullable_to_non_nullable - as double, + background: null == background + ? _value.background + : background // ignore: cast_nullable_to_non_nullable + as Color, + foreground: null == foreground + ? _value.foreground + : foreground // ignore: cast_nullable_to_non_nullable + as Color, + drawCircleAroundIcon: null == drawCircleAroundIcon + ? _value.drawCircleAroundIcon + : drawCircleAroundIcon // ignore: cast_nullable_to_non_nullable + as bool, + strokeWidth: null == strokeWidth + ? _value.strokeWidth + : strokeWidth // ignore: cast_nullable_to_non_nullable + as double, + padding: null == padding + ? _value.padding + : padding // ignore: cast_nullable_to_non_nullable + as double, ), ); } diff --git a/lib/src/model/route_map_route/route_map_route.freezed.dart b/lib/src/model/route_map_route/route_map_route.freezed.dart index d06869d..d3d82de 100644 --- a/lib/src/model/route_map_route/route_map_route.freezed.dart +++ b/lib/src/model/route_map_route/route_map_route.freezed.dart @@ -69,26 +69,22 @@ class _$RouteMapRouteCopyWithImpl<$Res, $Val extends RouteMapRoute> }) { return _then( _value.copyWith( - identifier: - null == identifier - ? _value.identifier - : identifier // ignore: cast_nullable_to_non_nullable - as String, - points: - null == points - ? _value.points - : points // ignore: cast_nullable_to_non_nullable - as List, - theme: - null == theme - ? _value.theme - : theme // ignore: cast_nullable_to_non_nullable - as RouteMapRouteTheme, - darkTheme: - freezed == darkTheme - ? _value.darkTheme - : darkTheme // ignore: cast_nullable_to_non_nullable - as RouteMapRouteTheme?, + identifier: null == identifier + ? _value.identifier + : identifier // ignore: cast_nullable_to_non_nullable + as String, + points: null == points + ? _value.points + : points // ignore: cast_nullable_to_non_nullable + as List, + theme: null == theme + ? _value.theme + : theme // ignore: cast_nullable_to_non_nullable + as RouteMapRouteTheme, + darkTheme: freezed == darkTheme + ? _value.darkTheme + : darkTheme // ignore: cast_nullable_to_non_nullable + as RouteMapRouteTheme?, ) as $Val, ); @@ -162,26 +158,22 @@ class __$$RouteMapRouteImplCopyWithImpl<$Res> }) { return _then( _$RouteMapRouteImpl( - identifier: - null == identifier - ? _value.identifier - : identifier // ignore: cast_nullable_to_non_nullable - as String, - points: - null == points - ? _value._points - : points // ignore: cast_nullable_to_non_nullable - as List, - theme: - null == theme - ? _value.theme - : theme // ignore: cast_nullable_to_non_nullable - as RouteMapRouteTheme, - darkTheme: - freezed == darkTheme - ? _value.darkTheme - : darkTheme // ignore: cast_nullable_to_non_nullable - as RouteMapRouteTheme?, + identifier: null == identifier + ? _value.identifier + : identifier // ignore: cast_nullable_to_non_nullable + as String, + points: null == points + ? _value._points + : points // ignore: cast_nullable_to_non_nullable + as List, + theme: null == theme + ? _value.theme + : theme // ignore: cast_nullable_to_non_nullable + as RouteMapRouteTheme, + darkTheme: freezed == darkTheme + ? _value.darkTheme + : darkTheme // ignore: cast_nullable_to_non_nullable + as RouteMapRouteTheme?, ), ); } @@ -324,26 +316,22 @@ class _$RouteMapRouteThemeCopyWithImpl<$Res, $Val extends RouteMapRouteTheme> }) { return _then( _value.copyWith( - lineWidth: - null == lineWidth - ? _value.lineWidth - : lineWidth // ignore: cast_nullable_to_non_nullable - as double, - color: - null == color - ? _value.color - : color // ignore: cast_nullable_to_non_nullable - as Color, - backLineWidth: - freezed == backLineWidth - ? _value.backLineWidth - : backLineWidth // ignore: cast_nullable_to_non_nullable - as double?, - backLineColor: - freezed == backLineColor - ? _value.backLineColor - : backLineColor // ignore: cast_nullable_to_non_nullable - as Color?, + lineWidth: null == lineWidth + ? _value.lineWidth + : lineWidth // ignore: cast_nullable_to_non_nullable + as double, + color: null == color + ? _value.color + : color // ignore: cast_nullable_to_non_nullable + as Color, + backLineWidth: freezed == backLineWidth + ? _value.backLineWidth + : backLineWidth // ignore: cast_nullable_to_non_nullable + as double?, + backLineColor: freezed == backLineColor + ? _value.backLineColor + : backLineColor // ignore: cast_nullable_to_non_nullable + as Color?, ) as $Val, ); @@ -388,26 +376,22 @@ class __$$RouteMapRouteThemeImplCopyWithImpl<$Res> }) { return _then( _$RouteMapRouteThemeImpl( - lineWidth: - null == lineWidth - ? _value.lineWidth - : lineWidth // ignore: cast_nullable_to_non_nullable - as double, - color: - null == color - ? _value.color - : color // ignore: cast_nullable_to_non_nullable - as Color, - backLineWidth: - freezed == backLineWidth - ? _value.backLineWidth - : backLineWidth // ignore: cast_nullable_to_non_nullable - as double?, - backLineColor: - freezed == backLineColor - ? _value.backLineColor - : backLineColor // ignore: cast_nullable_to_non_nullable - as Color?, + lineWidth: null == lineWidth + ? _value.lineWidth + : lineWidth // ignore: cast_nullable_to_non_nullable + as double, + color: null == color + ? _value.color + : color // ignore: cast_nullable_to_non_nullable + as Color, + backLineWidth: freezed == backLineWidth + ? _value.backLineWidth + : backLineWidth // ignore: cast_nullable_to_non_nullable + as double?, + backLineColor: freezed == backLineColor + ? _value.backLineColor + : backLineColor // ignore: cast_nullable_to_non_nullable + as Color?, ), ); } diff --git a/lib/src/model/route_map_user_location_indicator/route_map_user_location_indicator.freezed.dart b/lib/src/model/route_map_user_location_indicator/route_map_user_location_indicator.freezed.dart index b1b5ed7..9bd6e7e 100644 --- a/lib/src/model/route_map_user_location_indicator/route_map_user_location_indicator.freezed.dart +++ b/lib/src/model/route_map_user_location_indicator/route_map_user_location_indicator.freezed.dart @@ -78,26 +78,22 @@ class _$RouteMapUserLocationIndicatorCopyWithImpl< }) { return _then( _value.copyWith( - location: - null == location - ? _value.location - : location // ignore: cast_nullable_to_non_nullable - as LatLng, - accuracyWidth: - null == accuracyWidth - ? _value.accuracyWidth - : accuracyWidth // ignore: cast_nullable_to_non_nullable - as double, - theme: - null == theme - ? _value.theme - : theme // ignore: cast_nullable_to_non_nullable - as RouteMapUserLocationIndicatorTheme, - darkTheme: - freezed == darkTheme - ? _value.darkTheme - : darkTheme // ignore: cast_nullable_to_non_nullable - as RouteMapUserLocationIndicatorTheme?, + location: null == location + ? _value.location + : location // ignore: cast_nullable_to_non_nullable + as LatLng, + accuracyWidth: null == accuracyWidth + ? _value.accuracyWidth + : accuracyWidth // ignore: cast_nullable_to_non_nullable + as double, + theme: null == theme + ? _value.theme + : theme // ignore: cast_nullable_to_non_nullable + as RouteMapUserLocationIndicatorTheme, + darkTheme: freezed == darkTheme + ? _value.darkTheme + : darkTheme // ignore: cast_nullable_to_non_nullable + as RouteMapUserLocationIndicatorTheme?, ) as $Val, ); @@ -180,26 +176,22 @@ class __$$RouteMapUserLocationIndicatorImplCopyWithImpl<$Res> }) { return _then( _$RouteMapUserLocationIndicatorImpl( - location: - null == location - ? _value.location - : location // ignore: cast_nullable_to_non_nullable - as LatLng, - accuracyWidth: - null == accuracyWidth - ? _value.accuracyWidth - : accuracyWidth // ignore: cast_nullable_to_non_nullable - as double, - theme: - null == theme - ? _value.theme - : theme // ignore: cast_nullable_to_non_nullable - as RouteMapUserLocationIndicatorTheme, - darkTheme: - freezed == darkTheme - ? _value.darkTheme - : darkTheme // ignore: cast_nullable_to_non_nullable - as RouteMapUserLocationIndicatorTheme?, + location: null == location + ? _value.location + : location // ignore: cast_nullable_to_non_nullable + as LatLng, + accuracyWidth: null == accuracyWidth + ? _value.accuracyWidth + : accuracyWidth // ignore: cast_nullable_to_non_nullable + as double, + theme: null == theme + ? _value.theme + : theme // ignore: cast_nullable_to_non_nullable + as RouteMapUserLocationIndicatorTheme, + darkTheme: freezed == darkTheme + ? _value.darkTheme + : darkTheme // ignore: cast_nullable_to_non_nullable + as RouteMapUserLocationIndicatorTheme?, ), ); } @@ -256,9 +248,10 @@ class _$RouteMapUserLocationIndicatorImpl _$$RouteMapUserLocationIndicatorImplCopyWith< _$RouteMapUserLocationIndicatorImpl > - get copyWith => __$$RouteMapUserLocationIndicatorImplCopyWithImpl< - _$RouteMapUserLocationIndicatorImpl - >(this, _$identity); + get copyWith => + __$$RouteMapUserLocationIndicatorImplCopyWithImpl< + _$RouteMapUserLocationIndicatorImpl + >(this, _$identity); } abstract class _RouteMapUserLocationIndicator @@ -336,11 +329,10 @@ class _$RouteMapUserLocationIndicatorThemeCopyWithImpl< $Res call({Object? color = null}) { return _then( _value.copyWith( - color: - null == color - ? _value.color - : color // ignore: cast_nullable_to_non_nullable - as Color, + color: null == color + ? _value.color + : color // ignore: cast_nullable_to_non_nullable + as Color, ) as $Val, ); @@ -379,11 +371,10 @@ class __$$RouteMapUserLocationIndicatorThemeImplCopyWithImpl<$Res> $Res call({Object? color = null}) { return _then( _$RouteMapUserLocationIndicatorThemeImpl( - color: - null == color - ? _value.color - : color // ignore: cast_nullable_to_non_nullable - as Color, + color: null == color + ? _value.color + : color // ignore: cast_nullable_to_non_nullable + as Color, ), ); } @@ -422,9 +413,10 @@ class _$RouteMapUserLocationIndicatorThemeImpl _$$RouteMapUserLocationIndicatorThemeImplCopyWith< _$RouteMapUserLocationIndicatorThemeImpl > - get copyWith => __$$RouteMapUserLocationIndicatorThemeImplCopyWithImpl< - _$RouteMapUserLocationIndicatorThemeImpl - >(this, _$identity); + get copyWith => + __$$RouteMapUserLocationIndicatorThemeImplCopyWithImpl< + _$RouteMapUserLocationIndicatorThemeImpl + >(this, _$identity); } abstract class _RouteMapUserLocationIndicatorTheme diff --git a/lib/src/route_map_base.dart b/lib/src/route_map_base.dart index 7e2e776..4ab8417 100644 --- a/lib/src/route_map_base.dart +++ b/lib/src/route_map_base.dart @@ -64,20 +64,32 @@ class RouteMap extends StatefulWidget { } class _RouteMapState extends State { + final _fullyLoadedCompleter = Completer(); final _controllerCompleter = Completer(); - final _mapCreatedCompleter = Completer(); - final _iconManagerCompleter = Completer(); - final _lineManagerCompleter = Completer(); - final _circleManagerCompleter = Completer(); - Future get _controller => _mapCreatedCompleter.future; + late final RouteMapIconManager _iconManagerInstance; - Future get _iconManager => _iconManagerCompleter.future; + late final RouteMapLineManager _lineManagerInstance; - Future get _lineManager => _lineManagerCompleter.future; + late final RouteMapCircleManager _circleManagerInstance; - Future get _circleManager => - _circleManagerCompleter.future; + Future get _controller => _controllerCompleter.future; + + Future get _iconManager async { + // wait for style and restore to complete + await _fullyLoadedCompleter.future; + return _iconManagerInstance; + } + + Future get _lineManager async { + await _fullyLoadedCompleter.future; + return _lineManagerInstance; + } + + Future get _circleManager async { + await _fullyLoadedCompleter.future; + return _circleManagerInstance; + } @override void initState() { @@ -100,8 +112,8 @@ class _RouteMapState extends State { } Future _removeListeners() async { - if (!_mapCreatedCompleter.isCompleted) return; - final controller = await _mapCreatedCompleter.future; + if (!_controllerCompleter.isCompleted) return; + final controller = await _controllerCompleter.future; controller.onFeatureDrag.remove(_onFeatureDrag); if (kIsWeb) { controller.onFeatureHover.remove(_onFeatureHover); @@ -166,17 +178,19 @@ class _RouteMapState extends State { tiltGesturesEnabled: false, onMapClick: widget.onMapClicked, onMapCreated: (controller) { - _mapCreatedCompleter.complete(controller); + _iconManagerInstance = RouteMapIconManager(controller: controller); + _lineManagerInstance = RouteMapLineManager(controller: controller); + _circleManagerInstance = RouteMapCircleManager( + controller: controller, + ); + _controllerCompleter.complete(controller); + controller.onFeatureDrag.add(_onFeatureDrag); if (kIsWeb) { controller.onFeatureHover.add(_onFeatureHover); } }, onStyleLoadedCallback: () async { - if (!_controllerCompleter.isCompleted) { - await _completeInit(); - } - await _addNoServiceAreaLayer(); await _setMapLanguage(); @@ -184,6 +198,10 @@ class _RouteMapState extends State { unawaited(_setOverlap()); await _scheduleGeometryRedraw(); + + if (!_fullyLoadedCompleter.isCompleted) { + _fullyLoadedCompleter.complete(); + } }, annotationOrder: const [ AnnotationType.fill, @@ -195,17 +213,6 @@ class _RouteMapState extends State { ); } - Future _completeInit() async { - final controller = await _mapCreatedCompleter.future; - final iconManager = RouteMapIconManager(controller: controller); - final lineManager = RouteMapLineManager(controller: controller); - final circleManager = RouteMapCircleManager(controller: controller); - _controllerCompleter.complete(controller); - _iconManagerCompleter.complete(iconManager); - _lineManagerCompleter.complete(lineManager); - _circleManagerCompleter.complete(circleManager); - } - Future _setMapLanguage() async { final controller = await _controller; if (!mounted) return; @@ -213,9 +220,10 @@ class _RouteMapState extends State { } Future _scheduleGeometryRedraw() async { - final lineManager = await _lineManager; - final symbolManager = await _iconManager; - final circleManger = await _circleManager; + // Use instance directly because _fullyLoadedCompleter is not completed yet + final lineManager = _lineManagerInstance; + final symbolManager = _iconManagerInstance; + final circleManger = _circleManagerInstance; if (!mounted) return; final brightness = MediaQuery.platformBrightnessOf(context); From 023591cd9f620cfde44b99c61e493ce02f114f86 Mon Sep 17 00:00:00 2001 From: Tarek Tolba Date: Tue, 28 Oct 2025 15:07:20 +0300 Subject: [PATCH 2/5] Fix race condition --- lib/src/route_map_base.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/route_map_base.dart b/lib/src/route_map_base.dart index 4ab8417..af37867 100644 --- a/lib/src/route_map_base.dart +++ b/lib/src/route_map_base.dart @@ -220,7 +220,8 @@ class _RouteMapState extends State { } Future _scheduleGeometryRedraw() async { - // Use instance directly because _fullyLoadedCompleter is not completed yet + // Use [_lineManagerInstance] directly instead of [_lineManager] + // because _fullyLoadedCompleter is not completed yet final lineManager = _lineManagerInstance; final symbolManager = _iconManagerInstance; final circleManger = _circleManagerInstance; From 689d167221c705666692e053f3a9213107d9a5c7 Mon Sep 17 00:00:00 2001 From: Tarek Tolba Date: Tue, 28 Oct 2025 18:56:06 +0300 Subject: [PATCH 3/5] Add check workflow + clean code --- .github/workflows/check.yml | 29 +++++++++++++++++++++++++++++ lib/src/route_map_base.dart | 3 +-- 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/check.yml diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..87e5d65 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,29 @@ +name: check + +on: + pull_request: + push: + branches: + - develop + - master + +# Cancel previous builds by only allowing one concurrent build per ref. +concurrency: + group: bieter_tool_app_check-${{ github.ref }} + cancel-in-progress: true + +jobs: + check: + timeout-minutes: 10 + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v5 + - uses: subosito/flutter-action@v2 + with: + channel: stable + - name: Get dependencies + run: flutter pub get + - name: Analyze + run: flutter analyze + - name: Run format check + run: dart format -o none --set-exit-if-changed $(find . -name '*.dart' ! -name '*.g.dart' ! -name '*.freezed.dart' ! -path '*/generated/*' ! -path '*/gen/*') diff --git a/lib/src/route_map_base.dart b/lib/src/route_map_base.dart index af37867..b712e2b 100644 --- a/lib/src/route_map_base.dart +++ b/lib/src/route_map_base.dart @@ -64,7 +64,7 @@ class RouteMap extends StatefulWidget { } class _RouteMapState extends State { - final _fullyLoadedCompleter = Completer(); + final _fullyLoadedCompleter = Completer(); final _controllerCompleter = Completer(); late final RouteMapIconManager _iconManagerInstance; @@ -226,7 +226,6 @@ class _RouteMapState extends State { final symbolManager = _iconManagerInstance; final circleManger = _circleManagerInstance; - if (!mounted) return; final brightness = MediaQuery.platformBrightnessOf(context); await Future.wait([ lineManager.restore(brightness), From aefb9d2ae5e9aaa0d2ee4965f039f45da67690b2 Mon Sep 17 00:00:00 2001 From: Tarek Tolba Date: Tue, 28 Oct 2025 18:56:32 +0300 Subject: [PATCH 4/5] Update workflow branch name --- .github/workflows/check.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 87e5d65..b9ffdfe 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -4,8 +4,7 @@ on: pull_request: push: branches: - - develop - - master + - main # Cancel previous builds by only allowing one concurrent build per ref. concurrency: From 3ff1d301adbdc8b83a0b6c6402827a9ea0df7178 Mon Sep 17 00:00:00 2001 From: Julian Bissekkou <36447137+JulianBissekkou@users.noreply.github.com> Date: Tue, 28 Oct 2025 17:04:47 +0100 Subject: [PATCH 5/5] Update .github/workflows/check.yml --- .github/workflows/check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index b9ffdfe..ae1d9eb 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -8,7 +8,7 @@ on: # Cancel previous builds by only allowing one concurrent build per ref. concurrency: - group: bieter_tool_app_check-${{ github.ref }} + group: route_map_check-${{ github.ref }} cancel-in-progress: true jobs: