Skip to content

Commit a874474

Browse files
handle popup while search running
1 parent 351261b commit a874474

File tree

2 files changed

+103
-25
lines changed

2 files changed

+103
-25
lines changed

lib/features/searching/view/grid_page.dart

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,29 @@ BorderDirectional _thineVerticalBorder() => BorderDirectional(
2525
bottom: _borderSide(true),
2626
);
2727

28-
class SearchingPage extends StatelessWidget {
28+
class SearchingPage extends ConsumerWidget {
2929
const SearchingPage({super.key});
3030

3131
@override
32-
Widget build(BuildContext context) {
33-
return Scaffold(
34-
appBar: AppBar(
35-
title: const _ControlButtons(),
36-
centerTitle: true,
37-
),
38-
body: SafeArea(
39-
child: LayoutBuilder(
40-
builder: (BuildContext context, BoxConstraints constraints) {
41-
return _BuildLayout(constraints.biggest);
42-
},
32+
Widget build(BuildContext context, WidgetRef ref) {
33+
return PopScope(
34+
onPopInvokedWithResult: (didPop, result) async {
35+
if (didPop) {
36+
await ref.read(_gridNotifierProvider.notifier).cancelSearching();
37+
ref.invalidate(_gridNotifierProvider);
38+
}
39+
},
40+
child: Scaffold(
41+
appBar: AppBar(
42+
title: const _ControlButtons(),
43+
centerTitle: true,
44+
),
45+
body: SafeArea(
46+
child: LayoutBuilder(
47+
builder: (BuildContext context, BoxConstraints constraints) {
48+
return _BuildLayout(constraints.biggest);
49+
},
50+
),
4351
),
4452
),
4553
);

lib/features/searching/view_model/grid_notifier.dart

Lines changed: 83 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:collection';
22
import 'dart:math';
3+
import 'package:async/async.dart';
34
import 'package:collection/collection.dart';
45
import 'package:flutter/material.dart';
56
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -25,16 +26,22 @@ class SearchingNotifier extends StateNotifier<GridNotifierState> {
2526
final double _gridSquareSize = 25;
2627
static const Duration scaleAppearDurationForWall = Duration(milliseconds: 700);
2728
static const Duration clearDuration = Duration(microseconds: 1);
28-
static const Duration drawFindingPathDuration = Duration(milliseconds: 2);
29-
static const Duration drawSearcherDuration = Duration(milliseconds: 5);
29+
static const Duration drawSearcherDuration = Duration(milliseconds: 25);
3030
static const Duration mazeDuration = Duration(milliseconds: 10);
3131

3232
int tapDownIndex = -1;
3333
GridStatus tapDownGridStatus = GridStatus.empty;
34+
CancelableOperation<void>? _cancelableSearch;
3435

3536
/// [_isBuildingGrid] if build maze or search or even clear grid
3637
bool _isBuildingGrid = false;
3738
bool _isSearched = false;
39+
40+
Future<void> cancelSearching() async {
41+
await _cancelableSearch?.cancel();
42+
// _cancelableSearch=null;
43+
}
44+
3845
void updateGridLayout(Size size) {
3946
final screenWidth = size.width;
4047
final screenHeight = size.height;
@@ -129,6 +136,19 @@ class SearchingNotifier extends StateNotifier<GridNotifierState> {
129136
if (!clearAnyway && _isBuildingGrid) return;
130137
_isBuildingGrid = true;
131138

139+
await cancelSearching();
140+
141+
_cancelableSearch =
142+
CancelableOperation.fromFuture(_clearTheGridFun(clearAnyway: clearAnyway, keepWall: keepWall));
143+
144+
try {
145+
await _cancelableSearch?.value;
146+
} catch (e) {
147+
debugPrint("something wrong with clearTheGrid: $e");
148+
}
149+
}
150+
151+
Future<void> _clearTheGridFun({bool keepWall = false, bool clearAnyway = false}) async {
132152
await _clearTheGrid(addState: state, keepWall: keepWall);
133153

134154
state = state.copyWith(currentTappedIndex: -1);
@@ -138,20 +158,11 @@ class SearchingNotifier extends StateNotifier<GridNotifierState> {
138158
}
139159

140160
void onPointerDownOnGrid(PointerDownEvent event) {
141-
if (_isBuildingGrid) return;
142-
_isBuildingGrid = true;
143-
144161
tapDownIndex = _getIndex(addState: state, localPosition: event.localPosition);
145-
_isBuildingGrid = false;
146162
}
147163

148164
void onPointerUpOnGrid(PointerUpEvent event) {
149-
if (_isBuildingGrid) return;
150-
_isBuildingGrid = true;
151-
152165
tapDownIndex = -1;
153-
154-
_isBuildingGrid = false;
155166
}
156167

157168
void onFingerMoveOnGrid(PointerMoveEvent event) {
@@ -211,7 +222,18 @@ class SearchingNotifier extends StateNotifier<GridNotifierState> {
211222
Future<void> performBFS() async {
212223
if (_isBuildingGrid) return;
213224
_isBuildingGrid = true;
225+
await cancelSearching();
214226

227+
_cancelableSearch = CancelableOperation.fromFuture(_performBFSFun());
228+
229+
try {
230+
await _cancelableSearch?.value;
231+
} catch (e) {
232+
debugPrint("something wrong with performBFS: $e");
233+
}
234+
}
235+
236+
Future<void> _performBFSFun() async {
215237
if (_isSearched) await clearTheGrid(keepWall: true, clearAnyway: true);
216238

217239
final gridData = List<GridStatus>.from(state.gridData);
@@ -284,6 +306,18 @@ class SearchingNotifier extends StateNotifier<GridNotifierState> {
284306
Future<void> performDijkstra() async {
285307
if (_isBuildingGrid) return;
286308
_isBuildingGrid = true;
309+
await cancelSearching();
310+
311+
_cancelableSearch = CancelableOperation.fromFuture(_performDijkstraFun());
312+
313+
try {
314+
await _cancelableSearch?.value;
315+
} catch (e) {
316+
debugPrint("something wrong with performDijkstra: $e");
317+
}
318+
}
319+
320+
Future<void> _performDijkstraFun() async {
287321
if (_isSearched) await clearTheGrid(keepWall: true, clearAnyway: true);
288322

289323
final gridData = List<GridStatus>.from(state.gridData);
@@ -385,6 +419,18 @@ class SearchingNotifier extends StateNotifier<GridNotifierState> {
385419
Future<void> performAStar() async {
386420
if (_isBuildingGrid) return;
387421
_isBuildingGrid = true;
422+
await cancelSearching();
423+
424+
_cancelableSearch = CancelableOperation.fromFuture(_performAStarFun());
425+
426+
try {
427+
await _cancelableSearch?.value;
428+
} catch (e) {
429+
debugPrint("something wrong with performAStar: $e");
430+
}
431+
}
432+
433+
Future<void> _performAStarFun() async {
388434
if (_isSearched) await clearTheGrid(keepWall: true, clearAnyway: true);
389435

390436
final gridData = List<GridStatus>.from(state.gridData);
@@ -475,9 +521,21 @@ class SearchingNotifier extends StateNotifier<GridNotifierState> {
475521
return ((x1 - x2).abs() + (y1 - y2).abs()).toDouble();
476522
}
477523

478-
void generateRecursiveBacktrackerMaze() async {
524+
Future<void> generateRecursiveBacktrackerMaze() async {
479525
if (_isBuildingGrid) return;
480526
_isBuildingGrid = true;
527+
await cancelSearching();
528+
529+
_cancelableSearch = CancelableOperation.fromFuture(_generateRecursiveBacktrackerMazeFun());
530+
531+
try {
532+
await _cancelableSearch?.value;
533+
} catch (e) {
534+
debugPrint("something wrong with generateRecursiveBacktrackerMaze: $e");
535+
}
536+
}
537+
538+
Future<void> _generateRecursiveBacktrackerMazeFun() async {
481539
if (_isSearched) await clearTheGrid(clearAnyway: true);
482540

483541
final gridData = List<GridStatus>.from(state.gridData);
@@ -583,10 +641,22 @@ class SearchingNotifier extends StateNotifier<GridNotifierState> {
583641
return row > 1 && col > 1 && row < state.rowMainAxisCount - 2 && col < state.columnCrossAxisCount - 2;
584642
}
585643

586-
// Recursive Division Maze Generation
587644
Future<void> generateRecursiveDivisionMaze() async {
588645
if (_isBuildingGrid) return;
589646
_isBuildingGrid = true;
647+
await cancelSearching();
648+
649+
_cancelableSearch = CancelableOperation.fromFuture(_generateRecursiveDivisionMazeFun());
650+
651+
try {
652+
await _cancelableSearch?.value;
653+
} catch (e) {
654+
debugPrint("something wrong with generateRecursiveDivisionMaze: $e");
655+
}
656+
}
657+
658+
// Recursive Division Maze Generation
659+
Future<void> _generateRecursiveDivisionMazeFun() async {
590660
if (_isSearched) await clearTheGrid(clearAnyway: true);
591661

592662
final gridData = List<GridStatus>.from(state.gridData);

0 commit comments

Comments
 (0)