00001 package edu.stanford.hci.r3.events.replay;
00002
00003 import java.io.BufferedReader;
00004 import java.io.File;
00005 import java.io.FileNotFoundException;
00006 import java.io.FileOutputStream;
00007 import java.io.FileReader;
00008 import java.io.IOException;
00009 import java.io.PrintWriter;
00010 import java.util.ArrayList;
00011 import java.util.List;
00012
00013 import edu.stanford.hci.r3.PaperToolkit;
00014 import edu.stanford.hci.r3.events.EventEngine;
00015 import edu.stanford.hci.r3.events.PenEvent;
00016 import edu.stanford.hci.r3.events.PenEvent.PenEventModifier;
00017 import edu.stanford.hci.r3.pen.PenSample;
00018 import edu.stanford.hci.r3.util.DebugUtils;
00019 import edu.stanford.hci.r3.util.files.FileUtils;
00020
00034 public class EventReplayManager {
00035
00039 public static final String[] FILE_EXTENSION = new String[] { "eventData" };
00040
00044 private static final String SEPARATOR = "\t";
00045
00049 private EventEngine eventEngine;
00050
00054 private ArrayList<PenEvent> loadedEvents = new ArrayList<PenEvent>();
00055
00059 private PrintWriter output;
00060
00064 private File outputFile;
00065
00066 private boolean playEventsInRealTime = true;
00067
00071 public EventReplayManager(EventEngine engine) {
00072 eventEngine = engine;
00073 }
00074
00078 public void clearLoadedEvents() {
00079 loadedEvents = new ArrayList<PenEvent>();
00080 }
00081
00089 public PenEvent createEventFromString(String eventString) {
00090
00091 final String[] fields = eventString.split(SEPARATOR);
00092 final PenEventModifier modifier = PenEventModifier.valueOf(fields[0]);
00093 final String penName = fields[2];
00094 final int penID = Integer.parseInt(fields[1]);
00095 final long time = Long.parseLong(fields[3]);
00096 final double x = Double.parseDouble(fields[4]);
00097 final double y = Double.parseDouble(fields[5]);
00098 final long ts = Long.parseLong(fields[6]);
00099 final int f = Integer.parseInt(fields[7]);
00100
00101 final PenEvent event = new PenEvent(penID, penName, time, new PenSample(x, y, f, ts));
00102 event.setModifier(modifier);
00103 return event;
00104 }
00105
00110 private String createStringFromEvent(PenEvent event) {
00111 final PenSample sample = event.getOriginalSample();
00112 return event.getType() + SEPARATOR + event.getPenID() + SEPARATOR + event.getPenName()
00113 + SEPARATOR + event.getTimestamp() + SEPARATOR + sample.getX() + SEPARATOR
00114 + sample.getY() + SEPARATOR + sample.getTimestamp() + SEPARATOR + sample.getForce();
00115 }
00116
00120 private File getEventStoragePath() {
00121 return new File(PaperToolkit.getToolkitRootPath(), "eventData/");
00122 }
00123
00128 private PrintWriter getOutput() {
00129 if (output == null) {
00130 try {
00131 outputFile = new File(getEventStoragePath(), FileUtils
00132 .getCurrentTimeForUseInASortableFileName()
00133 + ".eventData");
00134 output = new PrintWriter(new FileOutputStream(outputFile), true );
00135 } catch (FileNotFoundException e) {
00136 e.printStackTrace();
00137 }
00138 }
00139 return output;
00140 }
00141
00145 public void loadEventDataFrom(File eventDataFile) {
00146 BufferedReader br;
00147 try {
00148 br = new BufferedReader(new FileReader(eventDataFile));
00149 String inputLine = null;
00150 while ((inputLine = br.readLine()) != null) {
00151 PenEvent event = createEventFromString(inputLine);
00152 loadedEvents.add(event);
00153 }
00154 DebugUtils.println("Loaded " + loadedEvents.size() + " events.");
00155 br.close();
00156 } catch (FileNotFoundException e) {
00157 e.printStackTrace();
00158 } catch (IOException e) {
00159 e.printStackTrace();
00160 }
00161
00162 }
00163
00167 public void loadMostRecentEventData() {
00168 final List<File> eventFiles = FileUtils.listVisibleFiles(getEventStoragePath(),
00169 FILE_EXTENSION);
00170 if (eventFiles.size() > 0) {
00171 final File mostRecentFile = eventFiles.get(eventFiles.size() - 1);
00172 DebugUtils.println(mostRecentFile);
00173 loadEventDataFrom(mostRecentFile);
00174 } else {
00175 DebugUtils.println("No Event Data Files Found in " + getEventStoragePath());
00176 }
00177 }
00178
00188 public void replay(final List<PenEvent> events) {
00189 new Thread(new Runnable() {
00190 public void run() {
00191 long lastTimeStamp = 0;
00192 for (PenEvent event : events) {
00193 if (playEventsInRealTime && lastTimeStamp != 0) {
00194 try {
00195
00196 long diff = event.getTimestamp() - lastTimeStamp;
00197 if (diff > 0) {
00198
00199
00200 Thread.sleep(diff);
00201 }
00202 } catch (InterruptedException e) {
00203 e.printStackTrace();
00204 }
00205
00206 }
00207
00208
00209 if (event.isTypePenUp()) {
00210 eventEngine.handlePenUpEvent(event);
00211 } else {
00212 eventEngine.handlePenEvent(event);
00213 }
00214
00215 lastTimeStamp = event.getTimestamp();
00216 }
00217 DebugUtils.println("Done. Replayed " + events.size() + " Events");
00218 }
00219 }).start();
00220 }
00221
00225 public void replayLoadedEvents() {
00226 replay(loadedEvents);
00227 }
00228
00236 public void saveEvent(PenEvent event) {
00237 getOutput().println(createStringFromEvent(event));
00238 }
00239 }