2019-03-15 00:01:23 +00:00
|
|
|
package org.thoughtcrime.securesms.mediasend;
|
2018-09-20 20:25:40 +00:00
|
|
|
|
|
|
|
import android.support.annotation.NonNull;
|
2019-03-15 00:01:23 +00:00
|
|
|
import android.support.annotation.Nullable;
|
2018-09-20 20:25:40 +00:00
|
|
|
|
2018-10-12 16:30:01 +00:00
|
|
|
import java.util.LinkedHashMap;
|
2018-09-20 20:25:40 +00:00
|
|
|
import java.util.Map;
|
2019-03-15 00:01:23 +00:00
|
|
|
import java.util.Stack;
|
2018-09-20 20:25:40 +00:00
|
|
|
|
2018-10-12 16:30:01 +00:00
|
|
|
@SuppressWarnings("ConstantConditions")
|
2018-09-20 20:25:40 +00:00
|
|
|
public class OrderEnforcer<E> {
|
|
|
|
|
2018-10-12 16:30:01 +00:00
|
|
|
private final Map<E, StageDetails> stages = new LinkedHashMap<>();
|
2018-09-20 20:25:40 +00:00
|
|
|
|
|
|
|
public OrderEnforcer(@NonNull E... stages) {
|
2018-10-12 16:30:01 +00:00
|
|
|
for (E stage : stages) {
|
|
|
|
this.stages.put(stage, new StageDetails());
|
2018-09-20 20:25:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2018-09-20 20:25:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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-09-20 20:25:40 +00:00
|
|
|
|
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-09-20 20:25:40 +00:00
|
|
|
}
|
2018-10-12 16:30:01 +00:00
|
|
|
} else {
|
|
|
|
break;
|
2018-09-20 20:25:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
2018-09-20 20:25:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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()) {
|
2018-09-20 20:25:40 +00:00
|
|
|
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
|
|
|
}
|
2018-09-20 20:25:40 +00:00
|
|
|
}
|
|
|
|
}
|