package com.badlogic.gdx.automation.recorder; import java.util.Iterator; import com.badlogic.gdx.Input; import com.badlogic.gdx.InputProcessor; import com.badlogic.gdx.automation.recorder.EventBufferAccessHelper.KeyEvent; import com.badlogic.gdx.automation.recorder.EventBufferAccessHelper.PointerEvent; 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.StaticProperties; import com.badlogic.gdx.automation.recorder.InputProperty.SyncProperty; /** * A simple implementation of the {@link Input} interface, designed to simply * play back what is stored in an enclosed {@link InputState} * * @author Lukas Böhm */ class PlaybackInput extends InputProxy { private final Iterator<Text> textIterator; private final Iterator<PlaceholderText> placeholderTextIterator; private final StaticProperties features; private InputProcessor processor = null; private final InputState state; private long currentEventTimeStamp; public PlaybackInput(Iterator<Text> textIterator, Iterator<PlaceholderText> placeholderTextIterator, StaticProperties features) { state = new InputState(20); this.textIterator = textIterator; this.placeholderTextIterator = placeholderTextIterator; this.features = features; } InputState getState() { return state; } @Override public void setInputProcessor(InputProcessor processor) { this.processor = processor; } @Override public InputProcessor getInputProcessor() { return processor; } @Override public boolean isPeripheralAvailable(Peripheral peripheral) { switch (peripheral) { case Accelerometer: return features.accelerometerAvailable; case Compass: return features.compassAvailable; case HardwareKeyboard: return features.keyboardAvailable; case MultitouchScreen: return features.hasMultitouch; case OnscreenKeyboard: return features.onscreenKeyboard; case Vibrator: return features.vibrator; default: return false; } } @Override public Orientation getNativeOrientation() { return features.nativeOrientation; } @Override public float getAccelerometerX() { return state.accelerometerX; } @Override public float getAccelerometerY() { return state.accelerometerY; } @Override public float getAccelerometerZ() { return state.accelerometerX; } @Override public int getX() { return state.getX(); } @Override public int getX(int pointer) { return state.getX(pointer); } @Override public int getDeltaX() { return state.getDeltaX(); } @Override public int getDeltaX(int pointer) { return state.getDeltaX(pointer); } @Override public int getY() { return state.getY(); } @Override public int getY(int pointer) { return state.getY(pointer); } @Override public int getDeltaY() { return state.getDeltaY(); } @Override public int getDeltaY(int pointer) { return state.getDeltaY(pointer); } @Override public boolean isTouched() { return state.isTouched(); } @Override public boolean justTouched() { return state.justTouched(); } @Override public boolean isTouched(int pointer) { return state.isTouched(pointer); } @Override public boolean isButtonPressed(int button) { return state.isButtonPressed(button); } @Override public boolean isKeyPressed(int key) { return state.isKeyPressed(key); } @Override public float getAzimuth() { return state.azimuth; } @Override public float getPitch() { return state.pitch; } @Override public float getRoll() { return state.roll; } @Override public void getRotationMatrix(float[] matrix) { if (matrix.length >= 9 && matrix.length < 16) { System.arraycopy(state.rotationMatrix, 0, matrix, 0, 3); System.arraycopy(state.rotationMatrix, 4, matrix, 3, 3); System.arraycopy(state.rotationMatrix, 8, matrix, 6, 3); } else if (matrix.length >= 16) { System.arraycopy(state.rotationMatrix, 0, matrix, 0, 16); } } @Override public long getCurrentEventTime() { return currentEventTimeStamp; } @Override public int getRotation() { return state.orientation; } @Override public void getTextInput(TextInputListener listener, String title, String text) { if (textIterator.hasNext()) { String answer = textIterator.next().input; if (answer == null) { listener.canceled(); } else { listener.input(answer); } } else { listener.canceled(); } } @Override public void getPlaceholderTextInput(TextInputListener listener, String title, String placeholder) { if (placeholderTextIterator.hasNext()) { String answer = placeholderTextIterator.next().input; if (answer == null) { listener.canceled(); } else { listener.input(answer); } } else { listener.canceled(); } } /** * Code mainly stolen from AndroidInput and LwjglInput, adapted to work with * the remaining recorder code. */ void processEvents() { synchronized (state) { state.justTouched = false; if (processor != null) { final InputProcessor processor = this.processor; int len = state.keyEvents.size(); for (int i = 0; i < len; i++) { KeyEvent e = state.keyEvents.get(i); currentEventTimeStamp = e.timeStamp; switch (e.type) { case KEY_DOWN: { processor.keyDown(e.keyCode); break; } case KEY_UP: { processor.keyUp(e.keyCode); break; } case KEY_TYPED: { processor.keyTyped(e.keyChar); break; } } } len = state.pointerEvents.size(); for (int i = 0; i < len; i++) { PointerEvent e = state.pointerEvents.get(i); currentEventTimeStamp = e.timeStamp; switch (e.type) { case TOUCH_DOWN: { processor.touchDown(e.x, e.y, e.pointer, e.button); break; } case TOUCH_UP: { processor.touchUp(e.x, e.y, e.pointer, e.button); break; } case TOUCH_DRAGGED: { processor.touchDragged(e.x, e.y, e.pointer); break; } case TOUCH_MOVED: { processor.mouseMoved(e.x, e.y); break; } case TOUCH_SCROLLED: { processor.scrolled(e.scrollAmount); break; } } } } else { int len = state.pointerEvents.size(); for (int i = 0; i < len; i++) { PointerEvent e = state.pointerEvents.get(i); if (e.type == SyncProperty.PointerEvent.Type.TOUCH_DOWN) { state.justTouched = true; } } } if (state.pointerEvents.size() == 0) { for (int i = 0; i < state.deltaX.length; i++) { state.deltaX[0] = 0; state.deltaY[0] = 0; } } state.keyEvents.clear(); state.pointerEvents.clear(); } } }