/* * 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.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"; /** Delimiter for batch mode index range values (colon) */ public static final String RANGE_DELIMETER = ":"; public static final String SETTING_DEF_FLAG = "-d"; public static final String CMD_SETTING_DELIMITER = "@@"; /** 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>(); /** * 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; String cmdSettings = null; /* 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 { /* GUI mode try { /* is there a run index for the GUI mode ? * guiIndex = Integer.parseInt(args[0]); firstConfIndex = 1; } catch (NumberFormatException e) { firstConfIndex = 0; } }*/ // int i = 0; boolean haveRunIndex = false; for(; firstConfIndex < args.length;) { if (args[firstConfIndex].equals(BATCH_MODE_FLAG)) { batchMode = true; nrofRuns = parseNrofRuns(args[firstConfIndex+1]); // firstConfIndex = 2; firstConfIndex += 2; haveRunIndex = true; } else if(args[firstConfIndex].equals(SETTING_DEF_FLAG)) { cmdSettings = args[firstConfIndex+1]; firstConfIndex += 2; } else if(!haveRunIndex) { try { guiIndex = Integer.parseInt(args[firstConfIndex]); firstConfIndex++; haveRunIndex = true; } catch(NumberFormatException e) { System.err.print("Error parsing command args. Expected run index. Got: "); System.err.println(args[firstConfIndex]); System.exit(-1); } } else break; } confFiles = args; } else { confFiles = new String[] {null}; } initSettings(confFiles, firstConfIndex); if(cmdSettings != null) { parseCmdSettings(cmdSettings); cmdSettings = null; } 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; } private static void parseCmdSettings(String arg) { String[] set; if(arg.contains(CMD_SETTING_DELIMITER)) set = arg.split(CMD_SETTING_DELIMITER); else set = new String[] {arg}; for(String setting : set) { String[] nameVal = setting.split("="); if(nameVal.length != 2) { System.err.println("Improperly formated command line Setting: " + setting); System.exit(-1); } Settings.addSetting(nameVal[0].trim(), nameVal[1].trim()); } } /** * Prints text to stdout * @param txt Text to print */ public static void print(String txt) { System.out.println(txt); } }