From 2ddc280eda764d8a567af72921212f0feaaa86ff Mon Sep 17 00:00:00 2001 From: Nathaniel Wesley Filardo Date: Sat, 27 Oct 2018 16:24:13 +0100 Subject: [PATCH] Switch to enum for rationales Stop using strings from lib/; fetch them from the string table like we're supposed to. --- .../ctfwstimer/lib/CtFwSGameStateManager.java | 26 +++++--- .../ctfwstimer/CtFwSDisplayLocal.java | 60 ++++++++++++++----- .../ctfwstimer/MainServiceNotification.java | 40 +++++++++---- mobile/src/main/res/values/strings.xml | 13 ++-- 4 files changed, 100 insertions(+), 39 deletions(-) diff --git a/lib/src/main/java/com/acmetensortoys/ctfwstimer/lib/CtFwSGameStateManager.java b/lib/src/main/java/com/acmetensortoys/ctfwstimer/lib/CtFwSGameStateManager.java index 0935cf8..b765b53 100644 --- a/lib/src/main/java/com/acmetensortoys/ctfwstimer/lib/CtFwSGameStateManager.java +++ b/lib/src/main/java/com/acmetensortoys/ctfwstimer/lib/CtFwSGameStateManager.java @@ -90,8 +90,16 @@ public class CtFwSGameStateManager { } } + public enum NowRationale { + NR_GAME_IN_PROGRESS, + NR_NOT_CONFIG, + NR_EXPLICIT_END, + NR_START_FUTURE, + NR_TIME_UP, + } + public class Now { - public String rationale = null; // null if game is in play, otherwise other fields invalid + public NowRationale rationale = NowRationale.NR_NOT_CONFIG; public boolean stop = false; public boolean past = false; public int round = 0; // 0 for setup @@ -107,21 +115,22 @@ public class CtFwSGameStateManager { synchronized (this) { if (!curstate.configured) { - res.rationale = "Game not configured!"; + res.rationale = NowRationale.NR_NOT_CONFIG; res.stop = true; + return res; } else if (curstate.endT >= curstate.startT) { - res.rationale = "Game declared over!"; + res.rationale = NowRationale.NR_EXPLICIT_END; res.stop = true; res.past = true; + return res; } else if (now < curstate.startT) { - res.rationale = "Start time in the future!"; + res.rationale = NowRationale.NR_START_FUTURE; res.roundStart = res.roundEnd = curstate.startT; - } - if (res.rationale != null) { return res; } long elapsed = now - curstate.startT; if (elapsed < curstate.setupD) { + res.rationale = NowRationale.NR_GAME_IN_PROGRESS; res.round = 0; res.roundStart = curstate.startT; res.roundEnd = curstate.startT + curstate.setupD; @@ -130,11 +139,12 @@ public class CtFwSGameStateManager { elapsed -= curstate.setupD; res.round = (int) (elapsed / curstate.roundD); if (res.round >= curstate.rounds) { - res.rationale = "Game time up!"; + res.rationale = NowRationale.NR_TIME_UP; res.stop = true; res.past = true; return res; } + res.rationale = NowRationale.NR_GAME_IN_PROGRESS; res.roundStart = curstate.startT + curstate.setupD + (res.round * curstate.roundD); res.roundEnd = res.roundStart + curstate.roundD; res.round += 1; @@ -307,7 +317,7 @@ public class CtFwSGameStateManager { private synchronized void notifyNow() { mT.cancelPost(futureNotifyNow); Now n = getNow(mT.wallMS()); - if (n.rationale == null || !n.stop) { + if (n.rationale == NowRationale.NR_GAME_IN_PROGRESS || !n.stop) { mT.postDelay(futureNotifyNow, n.roundEnd*1000 - n.wallMS); } for (Observer o : mObsvs) { o.onCtFwSNow(this, n); } diff --git a/mobile/src/main/java/com/acmetensortoys/ctfwstimer/CtFwSDisplayLocal.java b/mobile/src/main/java/com/acmetensortoys/ctfwstimer/CtFwSDisplayLocal.java index 5b8b4ce..e30eb1d 100644 --- a/mobile/src/main/java/com/acmetensortoys/ctfwstimer/CtFwSDisplayLocal.java +++ b/mobile/src/main/java/com/acmetensortoys/ctfwstimer/CtFwSDisplayLocal.java @@ -1,6 +1,7 @@ package com.acmetensortoys.ctfwstimer; import android.app.Activity; +import android.content.res.Resources; import android.graphics.Color; import android.os.Build; import android.os.Bundle; @@ -63,22 +64,51 @@ class CtFwSDisplayLocal implements CtFwSGameStateManager.Observer { if(es.length > 1) { resumeTimer(stun_long, es[1]); } } - private void doSetGameStateLabelText(final CtFwSGameStateManager gs, String rationale) { + private void doSetGameStateLabelText(final CtFwSGameStateManager gs, + final CtFwSGameStateManager.Now now) { + final Resources rs = mAct.getResources(); int gameIndex = gs.getGameIx(); + CtFwSGameStateManager.NowRationale nr; - String pfx = - (gs.isConfigured() && gameIndex != 0) - ? - String.format( - mAct.getResources() - .getString(R.string.header_gamestateN), - gameIndex) - : mAct.getResources().getString(R.string.header_gamestate0); - - if (rationale != null) { - gameStateLabelText = pfx + " " + rationale; + if ((now == null) || !gs.isConfigured()) { + nr = CtFwSGameStateManager.NowRationale.NR_NOT_CONFIG; } else { - gameStateLabelText = pfx; + nr = now.rationale; + } + + if (nr == CtFwSGameStateManager.NowRationale.NR_NOT_CONFIG || gameIndex == 0) { + gameStateLabelText = String.format(rs.getString(R.string.header_gamestate0), + rs.getString(R.string.notify_not_config)); + } else { + + String sfx; + switch (nr) { + case NR_EXPLICIT_END: + sfx = rs.getString(R.string.notify_game_over); + break; + case NR_TIME_UP: + sfx = rs.getString(R.string.notify_game_over); + break; + case NR_START_FUTURE: + sfx = rs.getString(R.string.notify_start_future); + break; + case NR_GAME_IN_PROGRESS: + if (now.round == 0) { + sfx = rs.getString(R.string.notify_game_setup); + } else if (now.round == gs.getRounds()) { + sfx = rs.getString(R.string.notify_game_end_soon); + } else { + sfx = rs.getString(R.string.notify_game_afoot); + } + break; + case NR_NOT_CONFIG: + // Handled above; fallthru to placate static analysers + default: + sfx = ""; + } + + gameStateLabelText = String.format(rs.getString(R.string.header_gamestateN), + gameIndex, sfx); } final TextView gstv = mAct.findViewById(R.id.header_gamestate); @@ -102,9 +132,9 @@ class CtFwSDisplayLocal implements CtFwSGameStateManager.Observer { Log.d("CtFwS", "Display game state; nowMS=" + now.wallMS + " r=" + now.round + " rs=" + now.roundStart + " re=" + now.roundEnd); - doSetGameStateLabelText(gs, now.rationale); + doSetGameStateLabelText(gs, now); - if (now.rationale != null) { + if (now.rationale != CtFwSGameStateManager.NowRationale.NR_GAME_IN_PROGRESS) { Log.d("CtFwS", "Rationale: " + now.rationale + " stop=" + now.stop); doReset(); return; diff --git a/mobile/src/main/java/com/acmetensortoys/ctfwstimer/MainServiceNotification.java b/mobile/src/main/java/com/acmetensortoys/ctfwstimer/MainServiceNotification.java index 9054e5c..a1e21e1 100644 --- a/mobile/src/main/java/com/acmetensortoys/ctfwstimer/MainServiceNotification.java +++ b/mobile/src/main/java/com/acmetensortoys/ctfwstimer/MainServiceNotification.java @@ -64,7 +64,8 @@ class MainServiceNotification { @Override public void onCtFwSNow(CtFwSGameStateManager game, CtFwSGameStateManager.Now now) { - if (now.rationale == null || !now.stop) { + if (now.rationale == CtFwSGameStateManager.NowRationale.NR_GAME_IN_PROGRESS + || now.rationale == CtFwSGameStateManager.NowRationale.NR_START_FUTURE) { // game is afoot or in the future! if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { @@ -76,30 +77,47 @@ class MainServiceNotification { Resources rs = mService.getResources(); - if (now.rationale == null) { - userNoteBuilder.setSubText(rs.getString(R.string.notify_afoot)); + if (now.rationale == CtFwSGameStateManager.NowRationale.NR_GAME_IN_PROGRESS) { + userNoteBuilder.setSubText(rs.getString(R.string.notify_game_afoot)); + String ct; if (now.round == 0) { - userNoteBuilder.setContentTitle(rs.getString(R.string.notify_gamestart)); + ct = rs.getString(R.string.notify_game_setup); } else if (now.round == game.getRounds()) { - userNoteBuilder.setContentTitle(rs.getString(R.string.notify_gameend)); + ct = rs.getString(R.string.notify_game_end_soon); } else { - userNoteBuilder.setContentTitle( - String.format(rs.getString(R.string.notify_jailbreak), - now.round, game.getRounds() - 1)); + ct = String.format(rs.getString(R.string.notify_jailbreak), + now.round, game.getRounds() - 1); } + userNoteBuilder.setContentTitle(ct); } else { - userNoteBuilder.setSubText(now.rationale); + userNoteBuilder.setSubText(rs.getString(R.string.notify_start_future)); } notifyUserSomehow(NotificationSource.BREAK); ensureNotification(); } else { + String txt; + switch(now.rationale) { + default: + case NR_GAME_IN_PROGRESS: + case NR_START_FUTURE: + txt = ""; + break; + case NR_TIME_UP: + case NR_EXPLICIT_END: + txt = mService.getResources().getString(R.string.notify_game_over); + break; + case NR_NOT_CONFIG: + txt = mService.getResources().getString(R.string.notify_not_config); + break; + } + // game no longer afoot if (now.past) { userNoteBuilder.setUsesChronometer(false); userNoteBuilder.setShowWhen(false); - userNoteBuilder.setContentTitle(now.rationale); - userNoteBuilder.setSubText(now.rationale); + userNoteBuilder.setContentTitle(txt); + userNoteBuilder.setSubText(txt); refreshNotification(); } ensureNoNotification(!now.past); diff --git a/mobile/src/main/res/values/strings.xml b/mobile/src/main/res/values/strings.xml index 91bb10d..96fcad5 100644 --- a/mobile/src/main/res/values/strings.xml +++ b/mobile/src/main/res/values/strings.xml @@ -9,16 +9,19 @@ Default - Game State: - Game %1$d State: + Game State: %1$s + Game %1$d State: %2$s DO NOT TAP ON GLASS Game\nTime\nElapsed Messages: - The game\'s afoot! + The game\'s afoot! + Game ending soon + Setup phase + Start time in the future! + Game over! + Game not configured! Flag captured! Red:%1$d Yellow:%2$d - Game ending soon - Setup phase Jailbreak %1$d of %2$d About -- 2.50.1