package squidpony.squidgrid.gui.gdx; import com.badlogic.gdx.InputProcessor; import com.badlogic.gdx.utils.IntArray; /** * This wraps an InputProcessor, storing all key events and allowing them to be processed one at a time using next() or * all at once using drain(). To have an effect, it needs to be registered by calling Input.setInputProcessor(SquidKey). * <br> * It does not perform the blocking functionality of the now-removed Swing SquidKey implementation, because this is * meant to run in an event-driven libGDX game and should not step on the toes of libGDX's input handling. To block game * logic until an event has been received, check hasNext() in the game's render() method and effectively "block" by not * running game logic if hasNext() returns false. You can get an event if hasNext() returns true by calling next(). * * @author Eben Howard - http://squidpony.com - howard@squidpony.com * @author Nathan Sweet * @author Tommy Ettinger * */ public class SquidKey implements InputProcessor { private static final int KEY_DOWN = 0; private static final int KEY_UP = 1; private static final int KEY_TYPED = 2; private InputProcessor processor; private final IntArray queue = new IntArray(); private final IntArray processingQueue = new IntArray(); private boolean ignoreInput = false; /** * Constructs a SquidKey with no InputProcessor; for this to do anything, setProcessor() must be called. */ public SquidKey () { } /** * Constructs a SquidKey with the given InputProcessor. * @param processor An InputProcessor that will handle keyDown(), keyUp(), and keyTyped() events */ public SquidKey (InputProcessor processor) { this.processor = processor; } /** * Constructs a SquidKey with the given InputProcessor. * @param processor An InputProcessor that will handle keyDown(), keyUp(), and keyTyped() events * @param ignoreInput the starting value for the ignore status; true to ignore input, false to process it. */ public SquidKey (InputProcessor processor, boolean ignoreInput) { this.processor = processor; this.ignoreInput = ignoreInput; } /** * Sets the InputProcessor that this object will use to make sense of Key events. * @param processor An InputProcessor that will handle keyDown(), keyUp(), and keyTyped() events */ public void setProcessor (InputProcessor processor) { this.processor = processor; } /** * Gets this object's InputProcessor. * @return this object's InputProcessor */ public InputProcessor getProcessor () { return processor; } /** * Get the status for whether this should ignore input right now or not. True means this object will ignore and not * queue keypresses, false means it should process them normally. Useful to pause processing or delegate it to * another object temporarily. * @return true if this object currently ignores input, false otherwise. */ public boolean getIgnoreInput() { return ignoreInput; } /** * Set the status for whether this should ignore input right now or not. True means this object will ignore and not * queue keypresses, false means it should process them normally. Useful to pause processing or delegate it to * another object temporarily. * @param ignoreInput true if this should object should ignore and not queue input, false otherwise. */ public void setIgnoreInput(boolean ignoreInput) { this.ignoreInput = ignoreInput; } /** * Processes all events queued up, passing them to this object's InputProcessor. */ public void drain () { IntArray q = processingQueue; if (processor == null) { queue.clear(); return; } q.addAll(queue); queue.clear(); for (int i = 0, n = q.size; i < n; ) { switch (q.get(i++)) { case KEY_DOWN: processor.keyDown(q.get(i++)); break; case KEY_UP: processor.keyUp(q.get(i++)); break; case KEY_TYPED: processor.keyTyped((char) q.get(i++)); break; } } q.clear(); } /** * Returns true if at least one event is queued. * @return true if there is an event queued, false otherwise. */ public boolean hasNext() { return queue.size >= 2; } /** * Processes the first event queued up, passing it to this object's InputProcessor. */ public void next() { IntArray q = processingQueue; if (processor == null || queue.size < 2) { queue.clear(); return; } q.addAll(queue, 0, 2); queue.removeRange(0, 1); if (q.size >= 2) { int e = q.get(0), n = q.get(1); switch (e) { case KEY_DOWN: processor.keyDown(n); break; case KEY_UP: processor.keyUp(n); break; case KEY_TYPED: processor.keyTyped((char) n); break; } } q.clear(); } /** * Empties the backing queue of data. */ public void flush() { queue.clear(); } @Override public boolean keyDown (int keycode) { if(ignoreInput) return false; queue.add(KEY_DOWN); queue.add(keycode); return false; } @Override public boolean keyUp (int keycode) { if(ignoreInput) return false; queue.add(KEY_UP); queue.add(keycode); return false; } @Override public boolean keyTyped (char character) { if(ignoreInput) return false; queue.add(KEY_TYPED); queue.add(character); return false; } @Override public boolean touchDown (int screenX, int screenY, int pointer, int button) { return false; } @Override public boolean touchUp (int screenX, int screenY, int pointer, int button) { return false; } @Override public boolean touchDragged (int screenX, int screenY, int pointer) { return false; } @Override public boolean mouseMoved (int screenX, int screenY) { return false; } @Override public boolean scrolled (int amount) { return false; } }