Merge remote-tracking branch 'Leptopoda/linting'

This commit is contained in:
Calcitem 2021-10-11 02:08:16 +08:00
commit e7f7b6cf6f
No known key found for this signature in database
GPG Key ID: F2F7C29E054CFB80
5 changed files with 251 additions and 263 deletions

View File

@ -32,6 +32,7 @@ class Game {
final String tag = "[game]";
void init() {
// TODO: _position is allready initialized with Position(). seems like duplicate code
_position = Position();
focusIndex = blurIndex = invalidIndex;
}
@ -71,7 +72,7 @@ class Game {
PieceColor.black: false
};
bool aiIsSearching() {
bool get aiIsSearching {
debugPrint(
"$tag White is searching? ${isSearching[PieceColor.white]}\n"
"$tag Black is searching? ${isSearching[PieceColor.black]}\n",
@ -115,14 +116,14 @@ class Game {
blurIndex = invalidIndex;
}
bool doMove(String move) {
Future<bool> doMove(String move) async {
if (position.phase == Phase.ready) {
start();
}
debugPrint("$tag AI do move: $move");
if (!position.doMove(move)) {
if (await position.doMove(move) == false) {
return false;
}

View File

@ -25,6 +25,7 @@ import 'package:sanmill/mill/types.dart';
import 'package:sanmill/mill/zobrist.dart';
import 'package:sanmill/services/audios.dart';
import 'package:sanmill/services/engine/engine.dart';
import 'package:sanmill/shared/common/config.dart';
List<int> posKeyHistory = [];
@ -62,7 +63,7 @@ class Position {
String us = PieceColor.white;
String them = PieceColor.black;
String winner = PieceColor.nobody;
String _winner = PieceColor.nobody;
GameOverReason gameOverReason = GameOverReason.noReason;
@ -114,7 +115,7 @@ class Position {
st.pliesFromNull = other.st.pliesFromNull;
them = other.them;
winner = other.winner;
_winner = other._winner;
gameOverReason = other.gameOverReason;
phase = other.phase;
@ -135,7 +136,7 @@ class Position {
String movedPiece(int move) => pieceOn(fromSq(move));
bool movePiece(int from, int to) {
Future<bool> movePiece(int from, int to) async {
if (selectPiece(from) == 0) {
return putPiece(to);
}
@ -261,7 +262,7 @@ class Position {
return true;
}
bool doMove(String move) {
Future<bool> doMove(String move) async {
if (move.length > "Player".length &&
move.substring(0, "Player".length - 1) == "Player") {
if (move["Player".length] == '1') {
@ -278,7 +279,7 @@ class Position {
if (move == "draw") {
phase = Phase.gameOver;
winner = PieceColor.draw;
_winner = PieceColor.draw;
if (score[PieceColor.draw] != null) {
score[PieceColor.draw] = score[PieceColor.draw]! + 1;
}
@ -287,7 +288,7 @@ class Position {
if (rule.nMoveRule > 0 && posKeyHistory.length >= rule.nMoveRule - 1) {
gameOverReason = GameOverReason.drawReasonRule50;
} else if (rule.endgameNMoveRule < rule.nMoveRule &&
isThreeEndgame() &&
isThreeEndgame &&
posKeyHistory.length >= rule.endgameNMoveRule - 1) {
gameOverReason = GameOverReason.drawReasonEndgameRule50;
} else if (rule.threefoldRepetitionRule) {
@ -308,20 +309,20 @@ class Position {
switch (m.type) {
case MoveType.remove:
ret = removePiece(m.to) == 0;
ret = await removePiece(m.to) == 0;
if (ret) {
// Reset rule 50 counter
st.rule50 = 0;
}
break;
case MoveType.move:
ret = movePiece(m.from, m.to);
ret = await movePiece(m.from, m.to);
if (ret) {
++st.rule50;
}
break;
case MoveType.place:
ret = putPiece(m.to);
ret = await putPiece(m.to);
if (ret) {
// Reset rule 50 counter
st.rule50 = 0;
@ -414,7 +415,7 @@ class Position {
setSideToMove(PieceColor.white);
action = Act.place;
winner = PieceColor.nobody;
_winner = PieceColor.nobody;
gameOverReason = GameOverReason.noReason;
clearBoard();
@ -457,7 +458,7 @@ class Position {
}
}
bool putPiece(int s) {
Future<bool> putPiece(int s) async {
var piece = Piece.noPiece;
final us = _sideToMove;
@ -472,6 +473,7 @@ class Position {
start();
}
// TODO: use switch case
if (phase == Phase.placing) {
piece = sideToMove;
if (pieceInHandCount[us] != null) {
@ -501,7 +503,7 @@ class Position {
if (pieceInHandCount[PieceColor.white] == 0 &&
pieceInHandCount[PieceColor.black] == 0) {
if (checkIfGameIsOver()) {
if (isGameOver()) {
return true;
}
@ -516,14 +518,14 @@ class Position {
changeSideToMove();
}
if (checkIfGameIsOver()) {
if (isGameOver()) {
return true;
}
} else {
changeSideToMove();
}
gameInstance.focusIndex = squareToIndex[s] ?? invalidIndex;
Audios.playTone(Audios.placeSoundId);
await Audios.playTone(Sound.place);
} else {
pieceToRemoveCount = rule.mayRemoveMultiple ? n : 1;
updateKeyMisc();
@ -539,7 +541,7 @@ class Position {
if (pieceInHandCount[PieceColor.white] == 0 &&
pieceInHandCount[PieceColor.black] == 0) {
if (checkIfGameIsOver()) {
if (isGameOver()) {
return true;
}
@ -550,7 +552,7 @@ class Position {
changeSideToMove();
}
if (checkIfGameIsOver()) {
if (isGameOver()) {
return true;
}
}
@ -559,10 +561,10 @@ class Position {
}
gameInstance.focusIndex = squareToIndex[s] ?? invalidIndex;
Audios.playTone(Audios.millSoundId);
await Audios.playTone(Sound.mill);
}
} else if (phase == Phase.moving) {
if (checkIfGameIsOver()) {
if (isGameOver()) {
return true;
}
@ -603,18 +605,18 @@ class Position {
action = Act.select;
changeSideToMove();
if (checkIfGameIsOver()) {
if (isGameOver()) {
return true;
} else {
gameInstance.focusIndex = squareToIndex[s] ?? invalidIndex;
Audios.playTone(Audios.placeSoundId);
await Audios.playTone(Sound.place);
}
} else {
pieceToRemoveCount = rule.mayRemoveMultiple ? n : 1;
updateKeyMisc();
action = Act.remove;
gameInstance.focusIndex = squareToIndex[s] ?? invalidIndex;
Audios.playTone(Audios.millSoundId);
await Audios.playTone(Sound.mill);
}
} else {
assert(false);
@ -623,7 +625,7 @@ class Position {
return true;
}
int removePiece(int s) {
Future<int> removePiece(int s) async {
if (phase == Phase.ready || phase == Phase.gameOver) return -1;
if (action != Act.remove) return -1;
@ -641,7 +643,7 @@ class Position {
revertKey(s);
Audios.playTone(Audios.removeSoundId);
await Audios.playTone(Sound.remove);
if (rule.hasBannedLocations && phase == Phase.placing) {
// Remove and put ban
@ -685,7 +687,7 @@ class Position {
}
if (rule.isDefenderMoveFirst) {
checkIfGameIsOver();
isGameOver();
return 0;
}
} else {
@ -696,7 +698,7 @@ class Position {
}
changeSideToMove();
checkIfGameIsOver();
isGameOver();
return 0;
}
@ -733,14 +735,12 @@ class Position {
return true;
}
String getWinner() {
return winner;
}
String get winner => _winner;
void setGameOver(String w, GameOverReason reason) {
phase = Phase.gameOver;
gameOverReason = reason;
winner = w;
_winner = w;
debugPrint("[position] Game over, $w win, because of $reason");
updateScore();
@ -748,7 +748,7 @@ class Position {
void updateScore() {
if (phase == Phase.gameOver) {
if (winner == PieceColor.draw) {
if (_winner == PieceColor.draw) {
if (score[PieceColor.draw] != null) {
score[PieceColor.draw] = score[PieceColor.draw]! + 1;
}
@ -756,13 +756,13 @@ class Position {
return;
}
if (score[winner] != null) {
score[winner] = score[winner]! + 1;
if (score[_winner] != null) {
score[_winner] = score[_winner]! + 1;
}
}
}
bool isThreeEndgame() {
bool get isThreeEndgame {
if (phase == Phase.placing) {
return false;
}
@ -771,7 +771,7 @@ class Position {
pieceOnBoardCount[PieceColor.black] == 3;
}
bool checkIfGameIsOver() {
bool isGameOver() {
if (phase == Phase.ready || phase == Phase.gameOver) {
return true;
}
@ -782,7 +782,7 @@ class Position {
}
if (rule.endgameNMoveRule < rule.nMoveRule &&
isThreeEndgame() &&
isThreeEndgame &&
posKeyHistory.length >= rule.endgameNMoveRule) {
setGameOver(PieceColor.draw, GameOverReason.drawReasonEndgameRule50);
return true;
@ -1047,7 +1047,7 @@ class Position {
nPiecesInHand;
pieceToRemoveCount = 0;
winner = PieceColor.nobody;
_winner = PieceColor.nobody;
Mills.adjacentSquaresInit();
Mills.millTableInit();
currentSquare = 0;
@ -1086,25 +1086,29 @@ class Position {
}
///////////////////////////////////////////////////////////////////////////////
Future<String> _gotoHistory(int moveIndex) async {
String errString = "";
Future<String> gotoHistory(HistoryMove move, [int? index]) async {
final int moveIndex = _gotoHistoryIndex(move, index);
if (recorder == null) {
debugPrint("[goto] recorder is null.");
return "null";
}
if (recorder!.cur == moveIndex) {
debugPrint("[goto] cur is equal to moveIndex.");
return "equal";
}
final history = recorder!.history;
if (moveIndex < -1 || history.length <= moveIndex) {
debugPrint("[goto] moveIndex is out of range.");
return "out-of-range";
}
if (recorder!.cur == moveIndex) {
debugPrint("[goto] cur is equal to moveIndex.");
return "equal";
}
String errString = "";
Audios.isTemporaryMute = true;
// Backup context
final engineTypeBackup = gameInstance.engineType;
@ -1121,13 +1125,10 @@ class Position {
}
for (var i = 0; i <= moveIndex; i++) {
if (gameInstance.doMove(history[i].move!) == false) {
if (await gameInstance.doMove(history[i].move!) == false) {
errString = history[i].move!;
break;
}
//await Future.delayed(Duration(seconds: 1));
//setState(() {});
}
// Restore context
@ -1136,31 +1137,46 @@ class Position {
recorder!.history = historyBack;
recorder!.cur = moveIndex;
Audios.isTemporaryMute = false;
await _gotoHistoryPlaySound(move);
return errString;
}
Future<String> takeBackN(int n) async {
int index = recorder!.cur - n;
if (index < -1) {
index = -1;
int _gotoHistoryIndex(HistoryMove move, [int? index]) {
switch (move) {
case HistoryMove.forwardAll:
return recorder!.history.length - 1;
case HistoryMove.backAll:
return -1;
case HistoryMove.farward:
return recorder!.cur + 1;
case HistoryMove.backN:
assert(index != null);
int _index = recorder!.cur - index!;
if (_index < -1) {
_index = -1;
}
return _index;
case HistoryMove.backOne:
return recorder!.cur - 1;
}
return _gotoHistory(index);
}
Future<String> takeBack() async {
return _gotoHistory(recorder!.cur - 1);
}
Future<void> _gotoHistoryPlaySound(HistoryMove move) async {
if (!Config.keepMuteWhenTakingBack) {
switch (move) {
case HistoryMove.forwardAll:
case HistoryMove.farward:
await Audios.playTone(Sound.place);
break;
case HistoryMove.backAll:
case HistoryMove.backN:
Future<String> stepForward() async {
return _gotoHistory(recorder!.cur + 1);
}
Future<String> takeBackAll() async {
return _gotoHistory(-1);
}
Future<String> stepForwardAll() async {
return _gotoHistory(recorder!.history.length - 1);
case HistoryMove.backOne:
await Audios.playTone(Sound.remove);
}
}
}
String movesSinceLastRemove() {
@ -1205,3 +1221,5 @@ class Position {
String? get lastPositionWithRemove => recorder!.lastPositionWithRemove;
}
enum HistoryMove { forwardAll, backAll, farward, backN, backOne }

View File

@ -172,7 +172,7 @@ class _GamePageState extends State<GamePage>
}
}
dynamic onBoardTap(int index) {
Future<dynamic> onBoardTap(int index) async {
if (!isReady) {
debugPrint("[tap] Not ready, ignore tapping.");
return false;
@ -208,18 +208,18 @@ class _GamePageState extends State<GamePage>
gameInstance.newGame();
if (gameInstance.isAiToMove) {
if (gameInstance.aiIsSearching()) {
if (gameInstance.aiIsSearching) {
debugPrint("$tag AI is thinking, skip tapping.");
return false;
} else {
debugPrint("[tap] AI is not thinking. AI is to move.");
engineToGo(false);
await engineToGo(false);
return false;
}
}
}
if (gameInstance.isAiToMove || gameInstance.aiIsSearching()) {
if (gameInstance.isAiToMove || gameInstance.aiIsSearching) {
debugPrint("[tap] AI's turn, skip tapping.");
return false;
}
@ -231,12 +231,12 @@ class _GamePageState extends State<GamePage>
// Human to go
bool ret = false;
Chain.capture(() {
await Chain.capture(() async {
switch (position.action) {
case Act.place:
if (position.putPiece(sq)) {
if (await position.putPiece(sq)) {
if (position.action == Act.remove) {
//Audios.playTone(Audios.millSoundId);
//Audios.playTone(Audios.mill);
if (mounted) {
showTip(S.of(context).tipMill);
if (Config.screenReaderSupport) {
@ -244,7 +244,7 @@ class _GamePageState extends State<GamePage>
}
}
} else {
//Audios.playTone(Audios.placeSoundId);
//Audios.playTone(Audios.place);
if (gameInstance.engineType == EngineType.humanVsAi && mounted) {
if (rule.mayOnlyRemoveUnplacedPieceInPlacingPhase) {
showTip(S.of(context).continueToMakeMove);
@ -296,7 +296,7 @@ class _GamePageState extends State<GamePage>
final int selectRet = position.selectPiece(sq);
switch (selectRet) {
case 0:
Audios.playTone(Audios.selectSoundId);
await Audios.playTone(Sound.select);
gameInstance.select(index);
ret = true;
debugPrint("[tap] selectPiece: [$sq]");
@ -325,7 +325,7 @@ class _GamePageState extends State<GamePage>
break;
case -2:
Audios.playTone(Audios.illegalSoundId);
await Audios.playTone(Sound.illegal);
debugPrint("[tap] selectPiece: skip [$sq]");
if (mounted && position.phase != Phase.gameOver) {
showTip(S.of(context).tipCannotMove);
@ -336,7 +336,7 @@ class _GamePageState extends State<GamePage>
}
break;
case -3:
Audios.playTone(Audios.illegalSoundId);
await Audios.playTone(Sound.illegal);
debugPrint("[tap] selectPiece: skip [$sq]");
if (mounted) {
showTip(S.of(context).tipCanMoveOnePoint);
@ -347,7 +347,7 @@ class _GamePageState extends State<GamePage>
}
break;
case -4:
Audios.playTone(Audios.illegalSoundId);
await Audios.playTone(Sound.illegal);
debugPrint("[tap] selectPiece: skip [$sq]");
if (mounted) {
showTip(S.of(context).tipSelectPieceToMove);
@ -357,7 +357,7 @@ class _GamePageState extends State<GamePage>
}
break;
default:
Audios.playTone(Audios.illegalSoundId);
await Audios.playTone(Sound.illegal);
debugPrint("[tap] selectPiece: skip [$sq]");
if (mounted) {
showTip(S.of(context).tipSelectWrong);
@ -372,11 +372,11 @@ class _GamePageState extends State<GamePage>
break;
case Act.remove:
final int removeRet = position.removePiece(sq);
final int removeRet = await position.removePiece(sq);
switch (removeRet) {
case 0:
//Audios.playTone(Audios.removeSoundId);
//Audios.playTone(Audios.remove);
ret = true;
debugPrint("[tap] removePiece: [$sq]");
if (gameInstance.position.pieceToRemoveCount >= 1) {
@ -404,7 +404,7 @@ class _GamePageState extends State<GamePage>
}
break;
case -2:
Audios.playTone(Audios.illegalSoundId);
await Audios.playTone(Sound.illegal);
debugPrint(
"[tap] removePiece: Cannot Remove our pieces, skip [$sq]",
);
@ -416,7 +416,7 @@ class _GamePageState extends State<GamePage>
}
break;
case -3:
Audios.playTone(Audios.illegalSoundId);
await Audios.playTone(Sound.illegal);
debugPrint(
"[tap] removePiece: Cannot remove piece from Mill, skip [$sq]",
);
@ -432,7 +432,7 @@ class _GamePageState extends State<GamePage>
}
break;
default:
Audios.playTone(Audios.illegalSoundId);
await Audios.playTone(Sound.illegal);
debugPrint("[tap] removePiece: skip [$sq]");
if (mounted && position.phase != Phase.gameOver) {
showTip(S.of(context).tipBanRemove);
@ -587,7 +587,7 @@ class _GamePageState extends State<GamePage>
);
}
gameInstance.doMove(move.move!);
await gameInstance.doMove(move.move!);
showTips();
if (Config.screenReaderSupport && move.notation != null) {
showSnackBar(context, "${S.of(context).ai}: ${move.notation!}");
@ -657,7 +657,7 @@ class _GamePageState extends State<GamePage>
debugPrint("Clipboard text:");
debugPrint(text);
await onTakeBackAllButtonPressed(pop: false);
await onTakeBackAllButtonPressed(false);
gameInstance.position.recorder!.clear();
final importFailedStr = gameInstance.position.recorder!.import(text);
@ -670,7 +670,7 @@ class _GamePageState extends State<GamePage>
return;
}
await onStepForwardAllButtonPressed(pop: false);
await onStepForwardAllButtonPressed(false);
showTip(S.of(context).gameImported);
if (Config.screenReaderSupport) {
@ -774,8 +774,8 @@ class _GamePageState extends State<GamePage>
Future<void> onAutoReplayButtonPressed() async {
Navigator.pop(context);
await onTakeBackAllButtonPressed(pop: false);
await onStepForwardAllButtonPressed(pop: false);
await onTakeBackAllButtonPressed(false);
await onStepForwardAllButtonPressed(false);
}
void onGameButtonPressed() {
@ -969,8 +969,9 @@ class _GamePageState extends State<GamePage>
}
Future<void> onGotoHistoryButtonsPressed(
Future<String> func, {
HistoryMove move, {
bool pop = true,
int? number,
}) async {
if (pop == true) {
Navigator.pop(context);
@ -989,9 +990,7 @@ class _GamePageState extends State<GamePage>
isGoingToHistory = true;
Audios.isTemporaryMute = Config.keepMuteWhenTakingBack;
final errMove = await func;
final errMove = await gameInstance.position.gotoHistory(move, number);
switch (errMove) {
case "":
@ -1008,14 +1007,10 @@ class _GamePageState extends State<GamePage>
break;
}
Audios.isTemporaryMute = false;
isGoingToHistory = false;
if (mounted) {
String text = "";
final pos = gameInstance.position;
/*
String us = "";
String them = "";
@ -1028,6 +1023,7 @@ class _GamePageState extends State<GamePage>
}
*/
late final String text;
final lastEffectiveMove = pos.recorder!.lastEffectiveMove;
if (lastEffectiveMove != null && lastEffectiveMove.notation != null) {
text = "${S.of(context).lastMove}: ${lastEffectiveMove.notation}";
@ -1044,28 +1040,37 @@ class _GamePageState extends State<GamePage>
}
}
Future<void> onTakeBackButtonPressed({bool pop = true}) async {
onGotoHistoryButtonsPressed(gameInstance.position.takeBack(), pop: pop);
}
Future<void> onTakeBackButtonPressed([bool pop = true]) async =>
onGotoHistoryButtonsPressed(
HistoryMove.backOne,
pop: pop,
);
Future<void> onStepForwardButtonPressed({bool pop = true}) async {
onGotoHistoryButtonsPressed(gameInstance.position.stepForward(), pop: pop);
}
Future<void> onStepForwardButtonPressed([bool pop = true]) async =>
onGotoHistoryButtonsPressed(
HistoryMove.farward,
pop: pop,
);
Future<void> onTakeBackAllButtonPressed({bool pop = true}) async {
onGotoHistoryButtonsPressed(gameInstance.position.takeBackAll(), pop: pop);
}
Future<void> onTakeBackAllButtonPressed([bool pop = true]) async =>
onGotoHistoryButtonsPressed(
HistoryMove.backAll,
pop: pop,
);
Future<void> onStepForwardAllButtonPressed({bool pop = true}) async {
Future<void> onStepForwardAllButtonPressed([bool pop = true]) async {
onGotoHistoryButtonsPressed(
gameInstance.position.stepForwardAll(),
HistoryMove.forwardAll,
pop: pop,
);
}
Future<void> onTakeBackNButtonPressed(int n, {bool pop = true}) async {
onGotoHistoryButtonsPressed(gameInstance.position.takeBackN(n), pop: pop);
}
Future<void> onTakeBackNButtonPressed(int n, [bool pop = true]) async =>
onGotoHistoryButtonsPressed(
HistoryMove.backN,
number: n,
pop: pop,
);
void onMoveListButtonPressed() {
final moveHistoryText = gameInstance.position.moveHistoryText;
@ -1177,7 +1182,7 @@ class _GamePageState extends State<GamePage>
debugPrint("[config] isPrivacyPolicyAccepted: $value");
Config.save();
await Config.save();
}
Future<void> onShowPrivacyDialog() async {
@ -1259,10 +1264,10 @@ class _GamePageState extends State<GamePage>
switch (result) {
case GameResult.win:
//Audios.playTone(Audios.winSoundId);
//Audios.playTone(Audios.win);
break;
case GameResult.lose:
//Audios.playTone(Audios.loseSoundId);
//Audios.playTone(Audios.lose);
break;
case GameResult.draw:
break;
@ -1694,7 +1699,7 @@ class _GamePageState extends State<GamePage>
color: Color(Config.navigationToolbarIconColor),
),
),
onPressed: () => onTakeBackAllButtonPressed(pop: false),
onPressed: () => onTakeBackAllButtonPressed(false),
);
final takeBackButton = TextButton(
@ -1707,7 +1712,7 @@ class _GamePageState extends State<GamePage>
color: Color(Config.navigationToolbarIconColor),
),
),
onPressed: () => onTakeBackButtonPressed(pop: false),
onPressed: () async => onTakeBackButtonPressed(false),
);
final stepForwardButton = TextButton(
@ -1720,7 +1725,7 @@ class _GamePageState extends State<GamePage>
color: Color(Config.navigationToolbarIconColor),
),
),
onPressed: () => onStepForwardButtonPressed(pop: false),
onPressed: () async => onStepForwardButtonPressed(false),
);
final stepForwardAllButton = TextButton(
@ -1733,7 +1738,7 @@ class _GamePageState extends State<GamePage>
color: Color(Config.navigationToolbarIconColor),
),
),
onPressed: () => onStepForwardAllButtonPressed(pop: false),
onPressed: () async => onStepForwardAllButtonPressed(false),
);
return GamePageToolBar(

View File

@ -24,22 +24,35 @@ import 'package:sanmill/shared/common/config.dart';
import 'package:soundpool/soundpool.dart';
import 'package:stack_trace/stack_trace.dart';
enum Sound {
draw,
fly,
go,
illegal,
lose,
mill,
place,
remove,
select,
win,
}
class Audios {
const Audios._();
//static AudioPlayer? _player;
static Soundpool? _soundpool;
// TODO: use enum for the sounds
static int? _alarmSoundStreamId;
static int? drawSoundId;
static int? flySoundId;
static int? goSoundId;
static int? illegalSoundId;
static int? loseSoundId;
static int? millSoundId;
static int? placeSoundId;
static int? removeSoundId;
static int? selectSoundId;
static int? winSoundId;
static final Soundpool _soundpool = Soundpool.fromOptions();
static bool _initialized = false;
static int _alarmSoundStreamId = 0;
static late final int _drawSoundId;
static late final int _flySoundId;
static late final int _goSoundId;
static late final int _illegalSoundId;
static late final int _loseSoundId;
static late final int _millSoundId;
static late final int _placeSoundId;
static late final int _removeSoundId;
static late final int _selectSoundId;
static late final int _winSoundId;
static bool isTemporaryMute = false;
static Future<void> loadSounds() async {
@ -48,156 +61,110 @@ class Audios {
return;
}
_soundpool ??= Soundpool.fromOptions();
_drawSoundId = await _soundpool.load(
await rootBundle.load("assets/audios/draw.mp3"),
);
if (_soundpool == null) {
if (Config.developerMode) {
assert(false);
}
debugPrint("[audio] Error: _soundpool is null.");
return;
}
_flySoundId = await _soundpool.load(
await rootBundle.load("assets/audios/fly.mp3"),
);
drawSoundId ??=
await _soundpool!.load(await rootBundle.load("assets/audios/draw.mp3"));
if (drawSoundId == null) {
if (Config.developerMode) {
assert(false);
}
debugPrint("[audio] Error: drawSoundId is null.");
return;
}
_goSoundId = await _soundpool.load(
await rootBundle.load("assets/audios/go.mp3"),
);
flySoundId ??=
await _soundpool!.load(await rootBundle.load("assets/audios/fly.mp3"));
if (flySoundId == null) {
if (Config.developerMode) {
assert(false);
}
debugPrint("[audio] Error: flySoundId is null.");
return;
}
_illegalSoundId = await _soundpool.load(
await rootBundle.load("assets/audios/illegal.mp3"),
);
goSoundId ??=
await _soundpool!.load(await rootBundle.load("assets/audios/go.mp3"));
if (goSoundId == null) {
if (Config.developerMode) {
assert(false);
}
debugPrint("[audio] Error: goSoundId is null.");
return;
}
_loseSoundId = await _soundpool.load(
await rootBundle.load("assets/audios/lose.mp3"),
);
illegalSoundId = await _soundpool!
.load(await rootBundle.load("assets/audios/illegal.mp3"));
if (illegalSoundId == null) {
if (Config.developerMode) {
assert(false);
}
debugPrint("[audio] Error: illegalSoundId is null.");
return;
}
_millSoundId = await _soundpool.load(
await rootBundle.load("assets/audios/mill.mp3"),
);
loseSoundId ??=
await _soundpool!.load(await rootBundle.load("assets/audios/lose.mp3"));
if (loseSoundId == null) {
if (Config.developerMode) {
assert(false);
}
debugPrint("[audio] Error: loseSoundId is null.");
return;
}
_placeSoundId = await _soundpool.load(
await rootBundle.load("assets/audios/place.mp3"),
);
millSoundId ??=
await _soundpool!.load(await rootBundle.load("assets/audios/mill.mp3"));
if (millSoundId == null) {
if (Config.developerMode) {
assert(false);
}
debugPrint("[audio] Error: millSoundId is null.");
return;
}
_removeSoundId = await _soundpool.load(
await rootBundle.load("assets/audios/remove.mp3"),
);
placeSoundId ??= await _soundpool!
.load(await rootBundle.load("assets/audios/place.mp3"));
if (placeSoundId == null) {
if (Config.developerMode) {
assert(false);
}
debugPrint("[audio] Error: placeSoundId is null.");
return;
}
_selectSoundId = await _soundpool.load(
await rootBundle.load("assets/audios/select.mp3"),
);
removeSoundId ??= await _soundpool!
.load(await rootBundle.load("assets/audios/remove.mp3"));
if (removeSoundId == null) {
if (Config.developerMode) {
assert(false);
}
debugPrint("[audio] Error: removeSoundId is null.");
return;
}
_winSoundId = await _soundpool.load(
await rootBundle.load("assets/audios/win.mp3"),
);
selectSoundId ??= await _soundpool!
.load(await rootBundle.load("assets/audios/select.mp3"));
if (selectSoundId == null) {
if (Config.developerMode) {
assert(false);
}
debugPrint("[audio] Error: selectSoundId is null.");
return;
}
winSoundId ??=
await _soundpool!.load(await rootBundle.load("assets/audios/win.mp3"));
if (winSoundId == null) {
if (Config.developerMode) {
assert(false);
}
debugPrint("[audio] Error: winSoundId is null.");
return;
}
_initialized = true;
}
static Future<void> _playSound(int? soundId) async {
if (Platform.isWindows) {
return;
static Future<void> _playSound(Sound sound) async {
assert(!Platform.isWindows);
late final int soundId;
switch (sound) {
case Sound.draw:
soundId = _drawSoundId;
break;
case Sound.fly:
soundId = _flySoundId;
break;
case Sound.go:
soundId = _goSoundId;
break;
case Sound.illegal:
soundId = _illegalSoundId;
break;
case Sound.lose:
soundId = _loseSoundId;
break;
case Sound.mill:
soundId = _millSoundId;
break;
case Sound.place:
soundId = _placeSoundId;
break;
case Sound.remove:
soundId = _removeSoundId;
break;
case Sound.select:
soundId = _selectSoundId;
break;
case Sound.win:
soundId = _winSoundId;
break;
}
if (soundId == null) {
if (Config.developerMode) {
assert(false);
}
debugPrint("[audio] Error: soundId is null.");
return;
}
_alarmSoundStreamId = await _soundpool!.play(soundId);
_alarmSoundStreamId = await _soundpool.play(soundId);
}
static Future<void> _stopSound() async {
if (Platform.isWindows) {
return;
}
assert(!Platform.isWindows);
if (_alarmSoundStreamId != null && _alarmSoundStreamId! > 0) {
await _soundpool!.stop(_alarmSoundStreamId!);
if (_alarmSoundStreamId > 0) {
await _soundpool.stop(_alarmSoundStreamId);
}
}
static Future<void> disposePool() async {
if (Platform.isWindows) {
return;
}
static void disposePool() {
assert(!Platform.isWindows);
_soundpool!.dispose();
_soundpool.dispose();
}
static Future<void> playTone(int? soundId) async {
Chain.capture(() async {
static Future<void> playTone(Sound sound) async {
await Chain.capture(() async {
if (!Config.toneEnabled ||
isTemporaryMute ||
Config.screenReaderSupport) {
Config.screenReaderSupport ||
!_initialized) {
return;
}
@ -206,14 +173,11 @@ class Audios {
return;
}
// TODO: isn't debug chain meant to catch errors? so why catching them in here and not in onError??
try {
if (_soundpool == null) {
await loadSounds();
}
await _stopSound();
_playSound(soundId);
await _playSound(sound);
} catch (e) {
// Fallback for all errors
debugPrint(e.toString());

View File

@ -111,7 +111,7 @@ class _DrawerControllerState extends State<DrawerController>
super.initState();
}
Future<bool> getInitState() async {
bool getInitState() {
scrollController.jumpTo(
widget.drawerWidth,
);