package teamcomm; import com.jogamp.opengl.GLProfile; import common.ApplicationLock; import java.awt.HeadlessException; import java.io.IOException; import java.net.SocketException; import javax.swing.JOptionPane; import teamcomm.data.GameState; import teamcomm.gui.MainWindow; import teamcomm.net.GameControlDataReceiver; import teamcomm.net.SPLStandardMessageReceiver; import teamcomm.net.logging.LogReplayer; import teamcomm.net.logging.Logger; /** * The team communication monitor starts in this class. * * @author Felix Thielke */ public class TeamCommunicationMonitor { private static boolean silentMode = false; private static boolean shutdown = false; private static final Object shutdownMutex = new Object(); /** * Startup method of the team communication monitor. * * @param args This is ignored. */ public static void main(final String[] args) { GameControlDataReceiver gcDataReceiver = null; SPLStandardMessageReceiver receiver = null; parseArgs(args); // try to acquire the application lock final ApplicationLock applicationLock = new ApplicationLock("TeamCommunicationMonitor"); try { if (!applicationLock.acquire()) { if (silentMode) { System.out.println("An instance of TeamCommunicationMonitor already exists."); } else { JOptionPane.showMessageDialog(null, "An instance of TeamCommunicationMonitor already exists.", "Multiple instances", JOptionPane.WARNING_MESSAGE); } System.exit(0); } } catch (IOException | HeadlessException e) { if (silentMode) { System.out.println("Error while trying to acquire the application lock."); } else { JOptionPane.showMessageDialog(null, "Error while trying to acquire the application lock.", e.getClass().getSimpleName(), JOptionPane.ERROR_MESSAGE); } System.exit(-1); } if (silentMode) { System.out.println("Team Communication Monitor was started in silent mode.\nMessages will be received and logged but not displayed."); } if (!silentMode) { // Initialize the JOGL profile for 3D drawing GLProfile.initSingleton(); } // Initialize listener for GameController messages try { gcDataReceiver = new GameControlDataReceiver(); } catch (SocketException ex) { JOptionPane.showMessageDialog(null, "Error while setting up GameController listener.", "SocketException", JOptionPane.ERROR_MESSAGE); System.exit(-1); } // Initialize listeners for robots receiver = SPLStandardMessageReceiver.getInstance(); // Initialize robot view part of the GUI final MainWindow robotView = silentMode ? null : new MainWindow(); // Start threads gcDataReceiver.start(); receiver.start(); // Wait for shutdown try { synchronized (shutdownMutex) { while (!shutdown) { shutdownMutex.wait(); } } } catch (InterruptedException ex) { } // Release the application lock try { applicationLock.release(); } catch (IOException e) { } // Shutdown threads and clean up GameState.getInstance().shutdown(); receiver.interrupt(); gcDataReceiver.interrupt(); if (robotView != null) { robotView.terminate(); } LogReplayer.getInstance().close(); Logger.getInstance().closeLogfile(); // Try to join receiver threads try { gcDataReceiver.join(1000); receiver.join(1000); } catch (InterruptedException ex) { } // Force exit System.exit(0); } private static final String ARG_HELP_SHORT = "-h"; private static final String ARG_HELP = "--help"; private static final String ARG_SILENT_SHORT = "-s"; private static final String ARG_SILENT = "--silent"; private static void parseArgs(final String[] args) { for (final String arg : args) { switch (arg) { case ARG_HELP_SHORT: case ARG_HELP: System.out.println("Usage: java -jar TeamCommunicationMonitor.jar {options}" + "\n (-h | --help) display help" + "\n (-s | --silent) start in silent mode"); System.exit(0); case ARG_SILENT_SHORT: case ARG_SILENT: silentMode = true; } } } /** * Shuts down the program by notifying the main thread. */ public static void shutdown() { synchronized (shutdownMutex) { shutdown = true; shutdownMutex.notifyAll(); } } }