119 lines
2.7 KiB
Java
119 lines
2.7 KiB
Java
package com.thebrokenrail.mtudining.activity.task;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
/**
|
|
* An asynchronous task (usually a network call).
|
|
*/
|
|
public abstract class Task<E> {
|
|
/**
|
|
* Current status of the task.
|
|
*/
|
|
public enum Status {
|
|
NOT_STARTED,
|
|
IN_PROGRESS,
|
|
DONE,
|
|
ERROR
|
|
}
|
|
private Status status = Status.NOT_STARTED;
|
|
|
|
/**
|
|
* Last time when {@link #start()} was called.
|
|
*/
|
|
private Long lastStart = null;
|
|
|
|
/**
|
|
* Start task.
|
|
*/
|
|
public void start() {
|
|
lastStart = System.currentTimeMillis();
|
|
status = Status.IN_PROGRESS;
|
|
result = null;
|
|
startImpl(lastStart);
|
|
// Update Listeners
|
|
sendDataToListeners();
|
|
}
|
|
/**
|
|
* Implementation of {@link #start()}.
|
|
* @param id Unique id for each call of {@link #start()}
|
|
*/
|
|
protected abstract void startImpl(long id);
|
|
|
|
/**
|
|
* Currently stored result (or null if none).
|
|
*/
|
|
private E result = null;
|
|
|
|
/**
|
|
* Store result.
|
|
* @param id ID from {@link #startImpl(long)}
|
|
* @param obj Result (or null if error)
|
|
*/
|
|
protected void done(long id, E obj) {
|
|
// Check ID
|
|
if (lastStart == null || id != lastStart) {
|
|
// Ignore
|
|
return;
|
|
}
|
|
// Store
|
|
result = obj;
|
|
// Update Status
|
|
if (obj == null) {
|
|
// Error
|
|
status = Status.ERROR;
|
|
} else {
|
|
// Done
|
|
status = Status.DONE;
|
|
}
|
|
// Update Listeners
|
|
sendDataToListeners();
|
|
// Ignore Future Responses From This API Call
|
|
lastStart = null;
|
|
}
|
|
|
|
/**
|
|
* Event listener.
|
|
*/
|
|
public interface Listener<E> {
|
|
/**
|
|
* Handle task update.
|
|
* @param status The task's status
|
|
* @param result The task's result (or null if none)
|
|
*/
|
|
void update(Status status, E result);
|
|
}
|
|
|
|
/**
|
|
* Stored event listeners.
|
|
*/
|
|
private final List<Listener<E>> listeners = new ArrayList<>();
|
|
|
|
/**
|
|
* Add new listener and send existing data to it.
|
|
* @param listener The new listener
|
|
*/
|
|
public void addListener(Listener<E> listener) {
|
|
if (!listeners.contains(listener)) {
|
|
listeners.add(listener);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Send data to all listeners.
|
|
*/
|
|
public void sendDataToListeners() {
|
|
for (Listener<E> listener : listeners) {
|
|
listener.update(status, status == Status.DONE ? result : null);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove listener.
|
|
* @param listener The listener to remove
|
|
*/
|
|
public void removeListener(Listener<E> listener) {
|
|
listeners.remove(listener);
|
|
}
|
|
}
|