package teamcomm.net.logging;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import javax.swing.event.EventListenerList;
import teamcomm.data.GameState;
import teamcomm.net.SPLStandardMessageReceiver;
/**
* Singleton class for replaying log files.
*
* @author Felix Thielke
*/
public class LogReplayer {
private static final LogReplayer instance = new LogReplayer();
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private ScheduledFuture<?> taskHandle;
private LogReplayTask task;
private final EventListenerList listeners = new EventListenerList();
/**
* Returns the only instance of this class.
*
* @return instance
*/
public static LogReplayer getInstance() {
return instance;
}
/**
* Opens a log file.
*
* @param logfile file
* @throws FileNotFoundException if the file could not be found
* @throws IOException if an other I/O error happened
*/
public void open(final File logfile) throws FileNotFoundException, IOException {
// Close currently opened log
if (task != null && taskHandle != null) {
taskHandle.cancel(false);
task.close();
for (final LogReplayEventListener listener : listeners.getListeners(LogReplayEventListener.class)) {
listener.logReplayEnded();
}
}
// Drain package queue of SPLStandardMessageReceiver
SPLStandardMessageReceiver.getInstance().clearPackageQueue();
// Reset GameState
GameState.getInstance().reset();
// Open new log
task = new LogReplayTask(logfile, listeners);
taskHandle = scheduler.scheduleAtFixedRate(task, LogReplayTask.PLAYBACK_TASK_DELAY, LogReplayTask.PLAYBACK_TASK_DELAY, TimeUnit.MILLISECONDS);
for (final LogReplayEventListener listener : listeners.getListeners(LogReplayEventListener.class)) {
listener.logReplayStarted();
}
}
/**
* Returns whether a log file is currently opened.
*
* @return boolean
*/
public boolean isReplaying() {
return task != null;
}
/**
* Returns whether the replay of a log file iis currently closed.
*
* @return boolean
*/
public boolean isPaused() {
return task == null || task.isPaused();
}
/**
* Sets the speed of the playback.
*
* @param factor playback speed. 1 is normal speed, 0 is paused.
*/
public void setPlaybackSpeed(final float factor) {
if (task != null) {
task.setPlaybackSpeed(factor);
}
}
/**
* Closes the currently opened log file.
*/
public void close() {
if (task != null) {
// Close currently opened log
taskHandle.cancel(false);
task.close();
task = null;
taskHandle = null;
// Send close event
for (final LogReplayEventListener listener : listeners.getListeners(LogReplayEventListener.class)) {
listener.logReplayEnded();
}
// Drain package queue of SPLStandardMessageReceiver
SPLStandardMessageReceiver.getInstance().clearPackageQueue();
// Reset GameState
GameState.getInstance().reset();
}
}
/**
* Adds a listener to receive events about log replaying.
*
* @param listener listener
* @see LogReplayEvent
*/
public void addListener(final LogReplayEventListener listener) {
listeners.add(LogReplayEventListener.class, listener);
}
/**
* Removes an event listener.
*
* @param listener listener
*/
public void removeListener(final LogReplayEventListener listener) {
listeners.remove(LogReplayEventListener.class, listener);
}
}