/* * Copyright 2010 Aalto University, ComNet * Released under GPLv3. See LICENSE.txt for details. */ package core; import gui.DTNSimGUI; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import ui.ConnectionSimTextUI; import ui.DTNSimTextUI; /** * Simulator's main class */ public class DTNSim { /** If this option ({@value}) is given to program, batch mode and * Text UI are used*/ public static final String BATCH_MODE_FLAG = "-b"; public static final String CONNECTION_MODE_FLAG = "-c"; /** Delimiter for batch mode index range values (colon) */ public static final String RANGE_DELIMETER = ":"; /** Name of the static method that all resettable classes must have * @see #registerForReset(String) */ public static final String RESET_METHOD_NAME = "reset"; /** List of class names that should be reset between batch runs */ private static List> resetList = new ArrayList>(); private static boolean connectionMode; /** * Starts the user interface with given arguments. * If first argument is {@link #BATCH_MODE_FLAG}, the batch mode and text UI * is started. The batch mode option must be followed by the number of runs, * or a with a combination of starting run and the number of runs, * delimited with a {@value #RANGE_DELIMETER}. Different settings from run * arrays are used for different runs (see * {@link Settings#setRunIndex(int)}). Following arguments are the settings * files for the simulation run (if any). For GUI mode, the number before * settings files (if given) is the run index to use for that run. * @param args Command line arguments */ public static void main(String[] args) { boolean batchMode = false; int nrofRuns[] = {0,1}; String confFiles[]; int firstConfIndex = 0; int guiIndex = 0; /* set US locale to parse decimals in consistent way */ java.util.Locale.setDefault(java.util.Locale.US); if (args.length > 0) { if (args[0].equals(BATCH_MODE_FLAG)) { batchMode = true; if (args.length == 1) { firstConfIndex = 1; } else { nrofRuns = parseNrofRuns(args[1]); firstConfIndex = 2; } } else if (args[0].equals(CONNECTION_MODE_FLAG)) { connectionMode = true; if (args.length == 1) { firstConfIndex = 1; } else { nrofRuns = parseNrofRuns(args[1]); firstConfIndex = 2; } } else { /* GUI mode */ try { /* is there a run index for the GUI mode ? */ guiIndex = Integer.parseInt(args[0]); firstConfIndex = 1; } catch (NumberFormatException e) { firstConfIndex = 0; } } confFiles = args; } else { confFiles = new String[] {null}; } initSettings(confFiles, firstConfIndex); if (batchMode) { long startTime = System.currentTimeMillis(); for (int i=nrofRuns[0]; i= confFiles.length) { return; } try { Settings.init(confFiles[i]); for (i=firstIndex+1; icore.SimClock */ public static void registerForReset(String className) { Class c = null; try { c = Class.forName(className); c.getMethod(RESET_METHOD_NAME); } catch (ClassNotFoundException e) { System.err.println("Can't register class " + className + " for resetting; class not found"); System.exit(-1); } catch (NoSuchMethodException e) { System.err.println("Can't register class " + className + " for resetting; class doesn't contain resetting method"); System.exit(-1); } resetList.add(c); } /** * Resets all registered classes. */ private static void resetForNextRun() { for (Class c : resetList) { try { Method m = c.getMethod(RESET_METHOD_NAME); m.invoke(null); } catch (Exception e) { System.err.println("Failed to reset class " + c.getName()); e.printStackTrace(); System.exit(-1); } } } /** * Parses the number of runs, and an optional starting run index, from a * command line argument * @param arg The argument to parse * @return The first and (last_run_index - 1) in an array */ private static int[] parseNrofRuns(String arg) { int val[] = {0,1}; try { if (arg.contains(RANGE_DELIMETER)) { val[0] = Integer.parseInt(arg.substring(0, arg.indexOf(RANGE_DELIMETER))) - 1; val[1] = Integer.parseInt(arg.substring(arg. indexOf(RANGE_DELIMETER) + 1, arg.length())); } else { val[0] = 0; val[1] = Integer.parseInt(arg); } } catch (NumberFormatException e) { System.err.println("Invalid argument '" + arg + "' for" + " number of runs"); System.err.println("The argument must be either a single value, " + "or a range of values (e.g., '2:5'). Note that this " + "option has changed in version 1.3."); System.exit(-1); } if (val[0] < 0) { System.err.println("Starting run value can't be smaller than 1"); System.exit(-1); } if (val[0] >= val[1]) { System.err.println("Starting run value can't be bigger than the " + "last run value"); System.exit(-1); } return val; } /** * Prints text to stdout * @param txt Text to print */ private static void print(String txt) { System.out.println(txt); } }