Refactor OrderEnforcer.

This commit is contained in:
Greyson Parrelli 2018-10-12 09:30:01 -07:00
parent 50eb8f2322
commit 20c059280c

View File

@ -2,26 +2,19 @@ package org.thoughtcrime.securesms.camera;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import java.util.HashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
@SuppressWarnings("ConstantConditions")
public class OrderEnforcer<E> { public class OrderEnforcer<E> {
private final E[] stages; private final Map<E, StageDetails> stages = new LinkedHashMap<>();
private final Map<E, Integer> stageIndices;
private final Map<E, List<Runnable>> actions;
private final boolean[] completion;
public OrderEnforcer(@NonNull E... stages) { public OrderEnforcer(@NonNull E... stages) {
this.stages = stages; for (E stage : stages) {
this.stageIndices = new HashMap<>(); this.stages.put(stage, new StageDetails());
this.actions = new HashMap<>();
this.completion = new boolean[stages.length];
for (int i = 0; i < stages.length; i++) {
stageIndices.put(stages[i], i);
} }
} }
@ -29,46 +22,59 @@ public class OrderEnforcer<E> {
if (isCompletedThrough(stage)) { if (isCompletedThrough(stage)) {
r.run(); r.run();
} else { } else {
List<Runnable> stageActions = actions.containsKey(stage) ? actions.get(stage) : new CopyOnWriteArrayList<>(); stages.get(stage).getActions().add(r);
stageActions.add(r);
actions.put(stage, stageActions);
} }
} }
public synchronized void markCompleted(@NonNull E stage) { public synchronized void markCompleted(@NonNull E stage) {
completion[stageIndices.get(stage)] = true; stages.get(stage).setCompleted(true);
int i = 0; for (E s : stages.keySet()) {
while (i < completion.length && completion[i]) { StageDetails details = stages.get(s);
List<Runnable> stageActions = actions.get(stages[i]);
if (stageActions != null) { if (details.isCompleted()) {
for (Runnable r : stageActions) { for (Runnable r : details.getActions()) {
r.run(); r.run();
} }
stageActions.clear(); details.getActions().clear();
} else {
break;
} }
i++;
} }
} }
public synchronized void reset() { public synchronized void reset() {
for (int i = 0; i < completion.length; i++) { for (StageDetails details : stages.values()) {
completion[i] = false; details.setCompleted(false);
details.getActions().clear();
} }
actions.clear();
} }
private boolean isCompletedThrough(@NonNull E stage) { private boolean isCompletedThrough(@NonNull E stage) {
int index = stageIndices.get(stage); for (E s : stages.keySet()) {
int i = 0; if (s.equals(stage)) {
return stages.get(s).isCompleted();
while (i <= index && i < completion.length) { } else if (!stages.get(s).isCompleted()) {
if (!completion[i]) {
return false; return false;
} }
i++;
} }
return true; return false;
}
private static class StageDetails {
private boolean completed = false;
private List<Runnable> actions = new CopyOnWriteArrayList<>();
@NonNull List<Runnable> getActions() {
return actions;
}
boolean isCompleted() {
return completed;
}
void setCompleted(boolean completed) {
this.completed = completed;
}
} }
} }