package br.com.etyllica.awt.core.input; import java.awt.event.KeyListener; import java.util.HashMap; import java.util.Map; import java.util.Set; import br.com.etyllica.core.event.KeyEvent; import br.com.etyllica.core.event.KeyEventListener; import br.com.etyllica.core.event.KeyState; import br.com.etyllica.core.input.keyboard.Keyboard; import br.com.etyllica.util.concurrency.ConcurrentList; import br.com.etyllica.util.concurrency.ConcurrentSet; /** * * @author yuripourre * */ public class AWTKeyboard implements KeyListener, Keyboard { private KeyEventListener listener; private ConcurrentList<KeyEvent> keyEvents = new ConcurrentList<KeyEvent>(); private Map<Integer, Boolean> keys = new HashMap<Integer, Boolean>(); private Map<Integer, KeyState> keyStates = new HashMap<Integer, KeyState>(); private ConcurrentSet<Integer> changed = new ConcurrentSet<Integer>(); public AWTKeyboard(KeyEventListener listener) { super(); this.listener = listener; } @Override public void init() {} public void update(long now) { Set<Integer> changedCopy = changed.lock(); for(Integer key: changedCopy) { KeyState keyState = getState(key); boolean pressed = keys.get(key); if (pressed) { if (keyState == KeyState.RELEASED) { keyStates.put(key,KeyState.ONCE); addKeyEvent(new KeyEvent(key, KeyState.PRESSED)); } else if (keyState != KeyState.PRESSED) { keyStates.put(key, KeyState.PRESSED); } } else { if ((keyState == KeyState.ONCE) || (keyState == KeyState.PRESSED)) { keyStates.put(key,KeyState.FIRST_RELEASED); } else if (keyState == KeyState.FIRST_RELEASED) { keyStates.put(key, KeyState.RELEASED); addKeyEvent(new KeyEvent(key, KeyState.RELEASED)); changed.remove(key); } } } poll(listener); changed.unlock(); } private KeyState getState(Integer key) { KeyState state = keyStates.get(key); if (state == null) { state = KeyState.RELEASED; } return state; } public void poll(KeyEventListener listener) { for (KeyEvent event: keyEvents.lock()) { if (event == null) { System.err.println("AWTKeyboard ERROR!"); continue; } listener.updateKeyEvent(event); } keyEvents.unlock(); } public void keyPressed( java.awt.event.KeyEvent ke ) { int code = getKeyFromEvent(ke); keys.put(code, true); changed.add(code); ke.consume(); } public void keyReleased( java.awt.event.KeyEvent ke ) { int code = getKeyFromEvent(ke); keys.put(code, false); changed.add(code); ke.consume(); } @Override public void keyTyped( java.awt.event.KeyEvent ke) { int code = getKeyFromEvent(ke); char c = ke.getKeyChar(); //TODO Fix typed if ( c != KeyEvent.CHAR_UNDEFINED ) { addKeyEvent(new KeyEvent(code, c, KeyState.TYPED)); } ke.consume(); } private int getKeyFromEvent(java.awt.event.KeyEvent ke) { int code = ke.getKeyCode(); if (ke.getKeyLocation() != java.awt.event.KeyEvent.KEY_LOCATION_STANDARD) { code += ke.getKeyLocation()*100; } return code; } public boolean hasPendingEvent() { return changed.getSet().size() > 0; } private void addKeyEvent(KeyEvent event) { long now = System.currentTimeMillis(); event.setTimestamp(now); keyEvents.add(event); } }