📄 tictactoegamecontrol.java
字号:
} } } public void destroy() { if (this.getProtocolState() != TicTacToeGameControl.SESSION_DISCONNECTED) { this.localActionMessageGoneUnAcknowledged(); } if (this.generalTimer != null) { this.generalTimer.cancel(); } } protected void localActionSendConfigAccept() { final HashMap<String, MessageElement> configMap = getConfigElements(); setProtocolState(TicTacToeGameControl.SESSION_CONFIG_ACCEPT_SENT); sendCommand(TicTacToeGameControl.COMMAND_CONFIG_ACCEPT, null, configMap); } public Image getFileImage(final String fileName) { BufferedImage bufImage = null; try { final int index = fileName.lastIndexOf("."); final String ext = fileName.substring(index + 1, fileName.length()); final Iterator readers = ImageIO.getImageReadersByFormatName(ext); final ImageReader reader = (ImageReader) readers.next(); //File fileImage = new File("D:\\home\\Media\\my media\\PICS\\COMIC\\64X64\\head1.png"); final File fileImage = new File(fileName);//""C:\\Documents and Settings\\polo\\Desktop\\pictures\\doubleheart2.jpg"); final FileImageInputStream imageInputStream = new FileImageInputStream(fileImage); reader.setInput(imageInputStream); bufImage = reader.read(0); imageInputStream.close(); } catch (final Exception x) { x.printStackTrace(); } return bufImage; } public Image getMemImage(final byte[] imageBytes) { BufferedImage bufImage = null; if (imageBytes != null) { try { final Iterator readers = ImageIO.getImageReadersByFormatName("jpg"); final ImageReader reader = (ImageReader) readers.next(); final ByteArrayInputStream in = new ByteArrayInputStream(imageBytes); final MemoryCacheImageInputStream imageInputStream = new MemoryCacheImageInputStream(in); reader.setInput(imageInputStream); bufImage = reader.read(0); imageInputStream.close(); } catch (final Exception x) { x.printStackTrace(); } } return bufImage; } public byte[] getImageFileBytes() { byte[] b = null; try { final String fileName = this.tttView.getLocalPlayerIconFileName(); final File fileImage = new File(fileName); if (fileImage.exists()) { final FileInputStream in = new FileInputStream(fileImage); b = new byte[in.available()]; int bytesRead=in.read(b); //todo thats not correct, in.available is NOT the filesize! } } catch (final Exception x) { x.printStackTrace(); } return b; } private HashMap<String, MessageElement> getConfigElements() { final HashMap<String, MessageElement> elementMap = new HashMap<String, MessageElement>(); final StringMessageElement iconTypeElement = new StringMessageElement( TicTacToeGameControl.TAG_ICON_TYPE, this.tttView.getLocalPlayerIconType(), null); elementMap.put(TicTacToeGameControl.TAG_ICON_TYPE, iconTypeElement); if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("IconType Sent : " + this.tttView.getLocalPlayerIconType()); } if (TicTacToeDialogView.ICON_TYPE_CUSTOM.equals(this.tttView.getLocalPlayerIconType())) { final byte[] imageBytes = this.getImageFileBytes(); final ByteArrayMessageElement iconDataElement = new ByteArrayMessageElement( TicTacToeGameControl.TAG_ICON_DATA, null, imageBytes, 0, imageBytes.length, null); elementMap.put(TicTacToeGameControl.TAG_ICON_DATA, iconDataElement); } return elementMap; } private void localActionSendConfigRequest() { this.setProtocolState(TicTacToeGameControl.SESSION_CONFIG_REQUEST_SENT); this.sendCommand(TicTacToeGameControl.COMMAND_CONFIG_REQUEST, TicTacToeGameControl.COMMAND_CONFIG_ACCEPT, this.getConfigElements()); } public int getSessionState() { return this.sessionState; } private void setRemotePlayerName(final String remotePlayerName) { this.remotePlayerName = remotePlayerName; } public void receive(final DialogMessage msg) { if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { //LOG.info ("Begin receive (DialogMessage)"); } setRemotePlayerName(msg.getOriginator()); //retrieve the messages command final String sessionCommand = getMessageSessionCommand(msg); // TTT data is processed and sent to audio out // this will be the dominant command by far so lets get this out immediately if (sessionCommand.equals(COMMAND_NEW_MOVE)) { if (getProtocolState() == SESSION_PLAYING) { receiveTTTPositionData(msg); } } else { gameControl(sessionCommand, msg); } } public void receiveTTTPositionData(final DialogMessage msg) { final String position = getMessagePositionData(msg); if (position != null) { remoteMoveMade(position); } else { if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("reveicePositionData : position data is null"); } } } /** * Retrieves the command (as String) from this DialogMessage. A command can * denote Session State and Voice Data Messages * * @param msg DialogMessage containing the command string * @return String command */ private String getMessageSessionCommand(final DialogMessage msg) { String command = null; final MessageElement commandMessageElement = msg.getMessageElement(TicTacToeGameControl.TAG_SESSION_COMMAND); if (commandMessageElement != null) { command = commandMessageElement.toString(); } else { if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("sessionMessageCommandElement is null"); } } if (command.equals("StartGameAccept")){ System.out.println("StartGameAccept"); } return command; } /** * Retrieves the data element from this DialogMessage and returns the speex * encoded bytes. * * @param msg The DialogMessage containing voice data * @return byte[] actual speex encoded bytes */ private String getMessagePositionData(final DialogMessage msg) { String position = null; final MessageElement positionMessageElement = msg.getMessageElement(TicTacToeGameControl.TAG_POSITION_DATA); if (positionMessageElement != null) { position = positionMessageElement.toString(); } else { if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("sessionMessagePositionData is null"); } } return position; } /** * After a message is sent this thread is instantiated, started and will * wait till it's lock is notified of an incoming message or till a timeout * is reached. The idea being each commmand message dispatched will return * an accept response. If that response is received then +1 if not this thread * will notify us and shutdown the session as gracefully as possible. A new * Thread is started for each command message sent. * TODO * Better option then creating a new thread for each command. Reuse of a single * thread maybe. */ class MessageAckThread extends Thread { private final AckWaitLock ackWaitLock; private String commandName = null; private boolean threadEnded = false; private boolean threadStarted = false; public MessageAckThread(final String commandName) { if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("MessageAckThread waiting for command " + commandName); } this.ackWaitLock = new AckWaitLock(); this.commandName = commandName; this.setPriority(Thread.MIN_PRIORITY); //this.setDaemon (true); } public void waitForStart() { if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("MessageAckThread waiting for threadstart"); } while (!this.threadStarted) { try { Thread.sleep(100); } catch (final InterruptedException ix) { ix.printStackTrace(); } } if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("MessageAckThread thread started"); } } public void run() { this.threadStarted = true; if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("MessageAckThread : Run "); } try { synchronized (this.ackWaitLock) { if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("MessageAckThread : waiting for"+this.commandName); } this.ackWaitLock.wait(getMessageAckTimeout()); if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("MessageAckThread : DONE waiting for "+this.commandName); } } } catch (final InterruptedException ix) { ix.printStackTrace(); } synchronized (this.ackWaitLock) { if (!this.ackWaitLock.isAcknowledged()) { if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("MessageAckThread : " + this.commandName + " command NOT acknowledged"); } localActionMessageGoneUnAcknowledged(); } } this.threadEnded = true; } /** * Avoids a race condition... needs to be reworked. */ public boolean isThreadEnded() { while (!this.threadEnded) { try { Thread.sleep(100); } catch (final InterruptedException ix) { ix.printStackTrace(); } } return this.threadEnded; } /** * A message was received and this thread is alerted. */ public void setMessageAcknowledged(final String commandName) { synchronized (this.ackWaitLock) { if (this.commandName.equals(commandName)) { if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("MessageAckThread : Received RIGHT Ack " + commandName + " for " + this.commandName + " : Command Ack"); } this.ackWaitLock.setAcknowledged(true); } else { if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("MessageAckThread : Received WRONG Ack " + commandName + " for " + this.commandName + " : Command Ack"); } } this.ackWaitLock.notifyAll(); } } class AckWaitLock { private boolean acknowledged = false; public boolean isAcknowledged() { return this.acknowledged; } public void setAcknowledged(final boolean acked) { this.acknowledged = acked; if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("AckWaitLock : SetAcknowldge " + this.acknowledged); } } } } class MyLock { private boolean locked = false; public boolean isLocked() { return this.locked; } public void setLocked(final boolean locked) { this.locked = locked; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -