session-android/src/org/thoughtcrime/securesms/mediasend/OrderEnforcer.java

92 lines
1.9 KiB
Java
Raw Normal View History

2019-03-15 00:01:23 +00:00
package org.thoughtcrime.securesms.mediasend;
import android.support.annotation.NonNull;
2019-03-15 00:01:23 +00:00
import android.support.annotation.Nullable;
2018-10-12 16:30:01 +00:00
import java.util.LinkedHashMap;
import java.util.Map;
2019-03-15 00:01:23 +00:00
import java.util.Stack;
2018-10-12 16:30:01 +00:00
@SuppressWarnings("ConstantConditions")
public class OrderEnforcer<E> {
2018-10-12 16:30:01 +00:00
private final Map<E, StageDetails> stages = new LinkedHashMap<>();
public OrderEnforcer(@NonNull E... stages) {
2018-10-12 16:30:01 +00:00
for (E stage : stages) {
this.stages.put(stage, new StageDetails());
}
}
public synchronized void run(@NonNull E stage, Runnable r) {
if (isCompletedThrough(stage)) {
r.run();
} else {
2019-03-15 00:01:23 +00:00
stages.get(stage).addAction(r);
}
}
public synchronized void markCompleted(@NonNull E stage) {
2019-03-15 00:01:23 +00:00
stages.get(stage).markCompleted();
2018-10-12 16:30:01 +00:00
for (E s : stages.keySet()) {
StageDetails details = stages.get(s);
2018-10-12 16:30:01 +00:00
if (details.isCompleted()) {
2019-03-15 00:01:23 +00:00
while (details.hasAction()) {
details.popAction().run();
}
2018-10-12 16:30:01 +00:00
} else {
break;
}
}
}
public synchronized void reset() {
2018-10-12 16:30:01 +00:00
for (StageDetails details : stages.values()) {
2019-03-15 00:01:23 +00:00
details.reset();
}
}
private boolean isCompletedThrough(@NonNull E stage) {
2018-10-12 16:30:01 +00:00
for (E s : stages.keySet()) {
if (s.equals(stage)) {
return stages.get(s).isCompleted();
} else if (!stages.get(s).isCompleted()) {
return false;
}
}
2018-10-12 16:30:01 +00:00
return false;
}
private static class StageDetails {
2019-03-15 00:01:23 +00:00
private boolean completed = false;
private Stack<Runnable> actions = new Stack<>();
2018-10-12 16:30:01 +00:00
2019-03-15 00:01:23 +00:00
boolean hasAction() {
return !actions.isEmpty();
}
@Nullable Runnable popAction() {
return actions.pop();
}
void addAction(@NonNull Runnable runnable) {
actions.push(runnable);
}
void reset() {
actions.clear();
completed = false;
2018-10-12 16:30:01 +00:00
}
boolean isCompleted() {
return completed;
}
2019-03-15 00:01:23 +00:00
void markCompleted() {
completed = true;
2018-10-12 16:30:01 +00:00
}
}
}