package com.badlogic.gdx.automation.recorder.io; import java.util.Iterator; import java.util.NoSuchElementException; import com.badlogic.gdx.Input.Orientation; import com.badlogic.gdx.automation.recorder.InputProperty.AsyncProperty; import com.badlogic.gdx.automation.recorder.InputProperty.AsyncProperty.PlaceholderText; import com.badlogic.gdx.automation.recorder.InputProperty.AsyncProperty.Text; import com.badlogic.gdx.automation.recorder.InputProperty.AsyncPropertyVisitor; import com.badlogic.gdx.automation.recorder.InputProperty.StaticProperties; import com.badlogic.gdx.automation.recorder.InputProperty.SyncProperty; import com.badlogic.gdx.automation.recorder.InputProperty.SyncProperty.Accelerometer; import com.badlogic.gdx.automation.recorder.InputProperty.SyncProperty.Button; import com.badlogic.gdx.automation.recorder.InputProperty.SyncProperty.KeyEvent; import com.badlogic.gdx.automation.recorder.InputProperty.SyncProperty.KeyPressed; import com.badlogic.gdx.automation.recorder.InputProperty.SyncProperty.Pointer; import com.badlogic.gdx.automation.recorder.InputProperty.SyncProperty.PointerEvent; import com.badlogic.gdx.automation.recorder.InputProperty.SyncPropertyVisitor; import com.badlogic.gdx.automation.recorder.RecordProperties; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.utils.JsonReader; import com.badlogic.gdx.utils.JsonValue; import com.badlogic.gdx.utils.JsonValue.JsonIterator; /** * Simple implementation of a {@link InputRecordReader} reading input data from * a json formatted file, most likely generated using * {@link JsonInputRecordWriter}. * * @author Lukas Böhm */ public class JsonInputRecordReader extends JsonInputRecord implements InputRecordReader { private final RecordProperties recordProperties; private final StaticProperties staticProperties; private final JsonReader reader; private JsonValue syncValues; private JsonValue asyncValues; public JsonInputRecordReader(FileHandle input) { super(input); reader = new JsonReader(); recordProperties = readRecordProperties(new RecordProperties()); staticProperties = readStaticValues(new StaticProperties()); readSyncProperties(); readAsyncProperties(); } private StaticProperties readStaticValues(StaticProperties values) { JsonValue json = reader.parse(staticPropertiesFile.reader()); values.accelerometerAvailable = json .getBoolean("accelerometerAvailable"); values.compassAvailable = json.getBoolean("compassAvailable"); values.hasMultitouch = json.getBoolean("hasMultitouch"); values.keyboardAvailable = json.getBoolean("keyboardAvailable"); values.nativeOrientation = Orientation.valueOf((json .getString("nativeOrientation"))); values.onscreenKeyboard = json.getBoolean("onscreenKeyboard"); values.vibrator = json.getBoolean("vibrator"); return values; } private RecordProperties readRecordProperties(RecordProperties properties) { JsonValue json = reader.parse(recordPropertiesFile.reader()); properties.absouluteCoords = json.getBoolean("absouluteCoords"); return recordProperties; } private void readSyncProperties() { syncValues = reader.parse(syncPropertiesFile.reader()); } private void readAsyncProperties() { asyncValues = reader.parse(asyncPropertiesFile.reader()); } @Override public Iterator<Text> getTextIterator() { return new AsyncFilterIterator<Text>(Text.class, "Text"); } @Override public Iterator<PlaceholderText> getPlaceholderTextIterator() { return new AsyncFilterIterator<PlaceholderText>(PlaceholderText.class, "PlaceholderText"); } private class AsyncFilterIterator<T extends AsyncProperty> implements Iterator<T> { private final Class<?> filter; private final String name; private final JsonIterator it; private final ValueBuilder builder; private T next; public AsyncFilterIterator(Class<?> classFilter, String namefilter) { builder = new ValueBuilder(); filter = classFilter; name = namefilter; it = asyncValues.iterator(); findNext(); } @Override public boolean hasNext() { return next != null; } @Override public T next() { if (next == null) { throw new NoSuchElementException(); } T current = next; findNext(); return current; } @SuppressWarnings("unchecked") private void findNext() { JsonValue nextJson = null; JsonValue testedJson; while (it.hasNext()) { testedJson = it.next(); if (testedJson.getString("class").equals(name)) { nextJson = testedJson; break; } } if (nextJson == null) { next = null; } else { try { next = (T) filter.newInstance(); builder.build(next, nextJson); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } @Override public void remove() { throw new UnsupportedOperationException(); } private class ValueBuilder implements AsyncPropertyVisitor { private JsonValue json; public void build(AsyncProperty val, JsonValue json) { this.json = json; val.accept(this); } @Override public void visitText(Text text) { text.input = json.getString("input"); } @Override public void visitPlaceholderText(PlaceholderText text) { text.input = json.getString("input"); } } } @Override public Iterator<SyncProperty> getSyncValueIterator() { return new SyncIterator(); } private class SyncIterator implements Iterator<SyncProperty> { private final JsonIterator it = syncValues.iterator(); private final ValueBuilder builder = new ValueBuilder(); @Override public boolean hasNext() { return it.hasNext(); } @Override public SyncProperty next() { JsonValue val = it.next(); String clazz = val.getString("class"); SyncProperty result = null; if (clazz.equals("Accelerometer")) { result = new SyncProperty.Accelerometer(); } else if (clazz.equals("KeyPressed")) { result = new SyncProperty.KeyPressed(); } else if (clazz.equals("PointerEvent")) { result = new SyncProperty.PointerEvent(); } else if (clazz.equals("KeyEvent")) { result = new SyncProperty.KeyEvent(); } else if (clazz.equals("Orientation")) { result = new SyncProperty.Orientation(); } else if (clazz.equals("Pointer")) { result = new SyncProperty.Pointer(); } else if (clazz.equals("Button")) { result = new SyncProperty.Button(); } builder.build(result, val); return result; } @Override public void remove() { throw new UnsupportedOperationException(); } private class ValueBuilder implements SyncPropertyVisitor { private JsonValue json; public void build(SyncProperty val, JsonValue json) { if (val == null) { return; } this.json = json; val.timeDelta = json.getLong("timeDelta"); val.accept(this); } @Override public void visitAccelerometer(Accelerometer accelerometer) { accelerometer.accelerometerX = json.getLong("accelerometerX"); accelerometer.accelerometerY = json.getLong("accelerometerY"); accelerometer.accelerometerZ = json.getLong("accelerometerZ"); } @Override public void visitKeyPressed(KeyPressed keyPressed) { keyPressed.keyCode = json.getInt("keyCode"); keyPressed.type = KeyPressed.Type.valueOf(json .getString("type")); } @Override public void visitPointerEvent(PointerEvent pointerEvent) { pointerEvent.button = json.getInt("button"); pointerEvent.pointer = json.getInt("pointer"); pointerEvent.scrollAmount = json.getInt("scrollAmount"); pointerEvent.type = PointerEvent.Type.valueOf(json .getString("type")); pointerEvent.x = json.getFloat("x"); pointerEvent.y = json.getFloat("y"); } @Override public void visitKeyEvent(KeyEvent keyEvent) { keyEvent.keyChar = json.getString("keyChar").charAt(0); keyEvent.keyCode = json.getInt("keyCode"); keyEvent.type = KeyEvent.Type.valueOf(json.getString("type")); } @Override public void visitOrientation(SyncProperty.Orientation orientation) { orientation.azimuth = json.getFloat("azimuth"); orientation.orientation = json.getInt("orientation"); orientation.pitch = json.getFloat("pitch"); orientation.roll = json.getFloat("roll"); JsonValue matrixJson = json.get("rotationMatrix"); float[] matrix = new float[16]; int i = 0; for (JsonValue value : matrixJson) { matrix[i] = value.asFloat(); i++; } orientation.rotationMatrix = matrix; } @Override public void visitPointer(Pointer pointer) { pointer.deltaX = json.getFloat("deltaX"); pointer.deltaY = json.getFloat("deltaY"); pointer.pointer = json.getInt("pointer"); pointer.x = json.getFloat("x"); pointer.y = json.getFloat("y"); } @Override public void visitButton(Button button) { button.button0 = json.getBoolean("button0"); button.button1 = json.getBoolean("button1"); button.button2 = json.getBoolean("button2"); } } } @Override public StaticProperties getStaticValues() { return staticProperties; } public void reset() { readRecordProperties(recordProperties); readStaticValues(staticProperties); readSyncProperties(); readAsyncProperties(); } @Override public void close() { } @Override public RecordProperties getRecordProperties() { return recordProperties; } }