mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-23 22:19:13 +00:00
# flag bitmaps are getting cached (no more stuttering)
This commit is contained in:
+1
-1
@@ -140,7 +140,7 @@ public class GateStartRacingProcedureImpl extends BaseRacingProcedure implements
|
||||
gateShutdownTime);
|
||||
} else {
|
||||
return new FlagPoleState(
|
||||
Arrays.asList(new FlagPole(Flags.CLASS, Flags.GOLF, false)));
|
||||
Arrays.asList(new FlagPole(Flags.GOLF, false)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+33
-10
@@ -3,7 +3,6 @@ package com.sap.sailing.racecommittee.app.ui.fragments.raceinfo;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.util.Pair;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
@@ -19,15 +18,36 @@ import com.sap.sailing.racecommittee.app.ui.fragments.RaceFragment;
|
||||
import com.sap.sailing.racecommittee.app.utils.TimeUtils;
|
||||
|
||||
public abstract class BaseRaceInfoRaceFragment<ProcedureType extends RacingProcedure> extends RaceFragment {
|
||||
|
||||
private class FlagPoleCache {
|
||||
public final FlagPole flagPole;
|
||||
public final TimePoint timePoint;
|
||||
public final boolean hasNextFlag;
|
||||
|
||||
public FlagPoleCache() {
|
||||
this(null, null, false);
|
||||
}
|
||||
|
||||
public FlagPoleCache(FlagPole flagPole, TimePoint timePoint) {
|
||||
this(flagPole, timePoint, true);
|
||||
}
|
||||
|
||||
private FlagPoleCache(FlagPole flagPole, TimePoint timePoint, boolean hasNextFlag) {
|
||||
this.flagPole = flagPole;
|
||||
this.timePoint = timePoint;
|
||||
this.hasNextFlag = hasNextFlag;
|
||||
}
|
||||
}
|
||||
|
||||
private FlagPoleCache flagPoleCache;
|
||||
|
||||
private final ProcedureChangedListener procedureListener;
|
||||
|
||||
private Pair<FlagPole, TimePoint> cachedNextFlag;
|
||||
|
||||
protected RaceInfoListener infoListener;
|
||||
|
||||
public BaseRaceInfoRaceFragment() {
|
||||
this.procedureListener = new ProcedureChangedListener();
|
||||
this.flagPoleCache = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,8 +85,8 @@ public abstract class BaseRaceInfoRaceFragment<ProcedureType extends RacingProce
|
||||
|
||||
|
||||
protected boolean updateFlagChangesCountdown(TextView targetView) {
|
||||
if (cachedNextFlag == null) {
|
||||
ExLog.i(BaseRaceInfoRaceFragment.class.getName(), "Refilling next-flag cache.");
|
||||
if (flagPoleCache == null) {
|
||||
ExLog.i(BaseRaceInfoRaceFragment.class.getSimpleName(), "Refilling next-flag cache.");
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
TimePoint startTime = getRaceState().getStartTime();
|
||||
FlagPoleState flagState = getRaceState().getRacingProcedure().getActiveFlags(startTime, now);
|
||||
@@ -76,17 +96,20 @@ public abstract class BaseRaceInfoRaceFragment<ProcedureType extends RacingProce
|
||||
FlagPole changePole = getMostInterestingFlagPole(flagChanges);
|
||||
|
||||
renderFlagChangesCountdown(targetView, changeAt, changePole);
|
||||
cachedNextFlag = new Pair<FlagPole, TimePoint>(changePole, changeAt);
|
||||
flagPoleCache = new FlagPoleCache(changePole, changeAt);
|
||||
return true;
|
||||
} else {
|
||||
flagPoleCache = new FlagPoleCache();
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
TimePoint changeAt = cachedNextFlag.second;
|
||||
FlagPole changePole = cachedNextFlag.first;
|
||||
} else if(flagPoleCache.hasNextFlag) {
|
||||
TimePoint changeAt = flagPoleCache.timePoint;
|
||||
FlagPole changePole = flagPoleCache.flagPole;
|
||||
|
||||
renderFlagChangesCountdown(targetView, changeAt, changePole);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private FlagPole getMostInterestingFlagPole(List<FlagPole> poles) {
|
||||
@@ -115,7 +138,7 @@ public abstract class BaseRaceInfoRaceFragment<ProcedureType extends RacingProce
|
||||
@Override
|
||||
public void onActiveFlagsChanged(RacingProcedure racingProcedure) {
|
||||
setupUi();
|
||||
cachedNextFlag = null;
|
||||
flagPoleCache = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.AbortTypeSelection
|
||||
import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.RaceDialogFragment;
|
||||
import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.RaceFinishingTimeDialog;
|
||||
import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.BaseRaceInfoRaceFragment;
|
||||
import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.FlagPoleStateRenderer;
|
||||
import com.sap.sailing.racecommittee.app.utils.FlagPoleStateRenderer;
|
||||
import com.sap.sailing.racecommittee.app.utils.TimeUtils;
|
||||
|
||||
public abstract class BaseRunningRaceFragment<ProcedureType extends RacingProcedure> extends BaseRaceInfoRaceFragment<ProcedureType> {
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ import com.sap.sailing.racecommittee.app.R;
|
||||
import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.AbortModeSelectionDialog;
|
||||
import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.RaceDialogFragment;
|
||||
import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.BaseRaceInfoRaceFragment;
|
||||
import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.FlagPoleStateRenderer;
|
||||
import com.sap.sailing.racecommittee.app.utils.FlagPoleStateRenderer;
|
||||
import com.sap.sailing.racecommittee.app.utils.TimeUtils;
|
||||
|
||||
public abstract class BaseStartphaseRaceFragment<ProcedureType extends RacingProcedure> extends BaseRaceInfoRaceFragment<ProcedureType> {
|
||||
|
||||
+7
-77
@@ -1,8 +1,6 @@
|
||||
package com.sap.sailing.racecommittee.app.ui.fragments.raceinfo;
|
||||
package com.sap.sailing.racecommittee.app.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
@@ -14,7 +12,6 @@ import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
import com.sap.sailing.domain.common.racelog.FlagPole;
|
||||
import com.sap.sailing.domain.common.racelog.Flags;
|
||||
import com.sap.sailing.domain.racelog.state.racingprocedure.FlagPoleState;
|
||||
import com.sap.sailing.racecommittee.app.R;
|
||||
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
||||
import com.sap.sailing.racecommittee.app.logging.ExLog;
|
||||
|
||||
@@ -25,6 +22,7 @@ public class FlagPoleStateRenderer {
|
||||
private final LinearLayout displayedFlagsViewGroup;
|
||||
private final LinearLayout removedFlagsViewGroup;
|
||||
|
||||
private final FlagsBitmapCache bitmapCache;
|
||||
private FlagPoleState previousState;
|
||||
|
||||
public FlagPoleStateRenderer(Context context, ManagedRace race,
|
||||
@@ -33,6 +31,8 @@ public class FlagPoleStateRenderer {
|
||||
this.race = race;
|
||||
this.displayedFlagsViewGroup = upperFlagsViewGroup;
|
||||
this.removedFlagsViewGroup = lowerFlagsViewGroup;
|
||||
|
||||
this.bitmapCache = new FlagsBitmapCache(context);
|
||||
this.previousState = null;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public class FlagPoleStateRenderer {
|
||||
if (previousState != null && FlagPoleState.describesSameState(previousState, state)) {
|
||||
return;
|
||||
}
|
||||
ExLog.i(FlagPoleStateRenderer.class.getSimpleName(), "Rendering flags.");
|
||||
ExLog.i(FlagPoleStateRenderer.class.getSimpleName(), "Re-Rendering flags.");
|
||||
previousState = state;
|
||||
|
||||
displayedFlagsViewGroup.removeAllViews();
|
||||
@@ -61,11 +61,11 @@ public class FlagPoleStateRenderer {
|
||||
|
||||
ImageView flagView = new ImageView(context);
|
||||
flagView.setLayoutParams(layout);
|
||||
flagView.setImageBitmap(getFlagBitmap(upperFlag));
|
||||
flagView.setImageBitmap(bitmapCache.getBitmap(upperFlag, lowerFlag));
|
||||
flagView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Toast.makeText(v.getContext(), upperFlag.toString(), Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(v.getContext(), upperFlag.toString() + "|" + lowerFlag.toString(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
if (upperFlag == Flags.CLASS) {
|
||||
@@ -75,76 +75,6 @@ public class FlagPoleStateRenderer {
|
||||
return flagView;
|
||||
}
|
||||
|
||||
private Bitmap getFlagBitmap(Flags flag) {
|
||||
int resourceId = 0;
|
||||
switch (flag) {
|
||||
case CLASS:
|
||||
resourceId = R.drawable.generic_class;
|
||||
break;
|
||||
case ALPHA:
|
||||
resourceId = R.drawable.alpha_flag;
|
||||
break;
|
||||
case AP:
|
||||
resourceId = R.drawable.ap_flag_mini;
|
||||
break;
|
||||
case BLACK:
|
||||
resourceId = R.drawable.black_flag_mini;
|
||||
break;
|
||||
case BLUE:
|
||||
resourceId = R.drawable.blue_flag_mini;
|
||||
break;
|
||||
case BRAVO:
|
||||
resourceId = R.drawable.bravo_mini;
|
||||
break;
|
||||
case ESSONE:
|
||||
resourceId = R.drawable.one_min_flag;
|
||||
break;
|
||||
case ESSTHREE:
|
||||
resourceId = R.drawable.three_min_flag;
|
||||
break;
|
||||
case ESSTWO:
|
||||
resourceId = R.drawable.two_min_flag;
|
||||
break;
|
||||
case FIRSTSUBSTITUTE:
|
||||
resourceId = R.drawable.first_substitute_flag;
|
||||
break;
|
||||
case FOXTROTT:
|
||||
resourceId = R.drawable.foxtrott_flag;
|
||||
break;
|
||||
case GOLF:
|
||||
resourceId = R.drawable.golf_flag;
|
||||
break;
|
||||
case HOTEL:
|
||||
resourceId = R.drawable.hotel_flag;
|
||||
break;
|
||||
case INDIA:
|
||||
resourceId = R.drawable.india_flag_mini;
|
||||
break;
|
||||
case JURY:
|
||||
resourceId = R.drawable.jury_flag_mini;
|
||||
break;
|
||||
case NONE:
|
||||
resourceId = R.drawable.jury_flag_mini;
|
||||
break;
|
||||
case NOVEMBER:
|
||||
resourceId = R.drawable.november_flag;
|
||||
break;
|
||||
case PAPA:
|
||||
resourceId = R.drawable.papa_flag_mini;
|
||||
break;
|
||||
case XRAY:
|
||||
resourceId = R.drawable.xray_flag;
|
||||
break;
|
||||
case ZULU:
|
||||
resourceId = R.drawable.zulu_flag_mini;
|
||||
break;
|
||||
default:
|
||||
resourceId = R.drawable.india_flag_mini;
|
||||
break;
|
||||
}
|
||||
return BitmapFactory.decodeResource(context.getResources(), resourceId);
|
||||
}
|
||||
|
||||
private int getFleetColorId() {
|
||||
Triple<Integer, Integer, Integer> rgb = race.getFleet().getColor().getAsRGB();
|
||||
return Color.rgb(rgb.getA(), rgb.getB(), rgb.getC());
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
package com.sap.sailing.racecommittee.app.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.sap.sailing.domain.common.racelog.Flags;
|
||||
import com.sap.sailing.racecommittee.app.R;
|
||||
import com.sap.sailing.racecommittee.app.logging.ExLog;
|
||||
|
||||
public class FlagsBitmapCache {
|
||||
|
||||
private static final Map<Pair<Flags, Flags>, Bitmap> bitmapCache = new HashMap<Pair<Flags,Flags>, Bitmap>();
|
||||
private final Context context;
|
||||
|
||||
public FlagsBitmapCache(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public void clearCache() {
|
||||
bitmapCache.clear();
|
||||
}
|
||||
|
||||
public Bitmap getBitmap(Flags upperFlag, Flags lowerFlag) {
|
||||
Pair<Flags, Flags> query = new Pair<Flags, Flags>(upperFlag, lowerFlag);
|
||||
Bitmap flagBitmap = bitmapCache.get(query);
|
||||
if (flagBitmap == null) {
|
||||
ExLog.i(FlagsBitmapCache.class.getSimpleName(),
|
||||
String.format("Creating Bitmap for %s|%s flag.", upperFlag, lowerFlag));
|
||||
flagBitmap = createFlagBitmap(upperFlag, lowerFlag);
|
||||
bitmapCache.put(query, flagBitmap);
|
||||
}
|
||||
return flagBitmap;
|
||||
}
|
||||
|
||||
private Bitmap createFlagBitmap(Flags flag, Flags lowerFlag) {
|
||||
int resourceId = 0;
|
||||
switch (flag) {
|
||||
case CLASS:
|
||||
resourceId = R.drawable.generic_class;
|
||||
break;
|
||||
case ALPHA:
|
||||
resourceId = R.drawable.alpha_flag;
|
||||
break;
|
||||
case AP:
|
||||
resourceId = R.drawable.ap_flag;
|
||||
break;
|
||||
case BLACK:
|
||||
resourceId = R.drawable.black_flag_mini;
|
||||
break;
|
||||
case BLUE:
|
||||
resourceId = R.drawable.blue_flag_mini;
|
||||
break;
|
||||
case BRAVO:
|
||||
resourceId = R.drawable.bravo_mini;
|
||||
break;
|
||||
case ESSONE:
|
||||
resourceId = R.drawable.one_min_flag;
|
||||
break;
|
||||
case ESSTHREE:
|
||||
resourceId = R.drawable.three_min_flag;
|
||||
break;
|
||||
case ESSTWO:
|
||||
resourceId = R.drawable.two_min_flag;
|
||||
break;
|
||||
case FIRSTSUBSTITUTE:
|
||||
resourceId = R.drawable.first_substitute_flag;
|
||||
break;
|
||||
case FOXTROTT:
|
||||
resourceId = R.drawable.foxtrott_flag;
|
||||
break;
|
||||
case GOLF:
|
||||
resourceId = R.drawable.golf_flag;
|
||||
break;
|
||||
case HOTEL:
|
||||
resourceId = R.drawable.hotel_flag;
|
||||
break;
|
||||
case INDIA:
|
||||
resourceId = R.drawable.india_flag_mini;
|
||||
break;
|
||||
case JURY:
|
||||
resourceId = R.drawable.jury_flag_mini;
|
||||
break;
|
||||
case NONE:
|
||||
resourceId = R.drawable.jury_flag_mini;
|
||||
break;
|
||||
case NOVEMBER:
|
||||
resourceId = R.drawable.november_flag;
|
||||
break;
|
||||
case PAPA:
|
||||
resourceId = R.drawable.papa_flag_mini;
|
||||
break;
|
||||
case XRAY:
|
||||
resourceId = R.drawable.xray_flag;
|
||||
break;
|
||||
case ZULU:
|
||||
resourceId = R.drawable.zulu_flag_mini;
|
||||
break;
|
||||
default:
|
||||
resourceId = R.drawable.india_flag_mini;
|
||||
break;
|
||||
}
|
||||
return BitmapFactory.decodeResource(context.getResources(), resourceId);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user