package jaci.openrio.toast.core; import jaci.openrio.toast.core.script.js.JavaScript; import jaci.openrio.toast.lib.Version; import java.io.File; import java.util.ArrayList; /** * The Environment Class is used as a set of hooks to obtain data regarding the Environment the Robot is working in. * This is where modules should check for Verification/Simulated environments, check if FMS is attached, as well as * operated depending on the Operating System the Robot or Simulation is present in. * * @author Jaci */ public class Environment { /** * Is this a Verification Environment? A Verification Environment is launched with args --verify to test * the Robot's behaviour in a generic competition (15 sec Auto, 2 min Teleop). All state changes are done * in this mode, and any uncaught exceptions render the build as 'failed' */ public static boolean isVerification() { return ToastBootstrap.isVerification; } /** * Is this a Simulation Environment? A Simulation Environment is launched with args --sim (--search) as a * means for Developers to test their code in their IDE without having a robot present. This is used very commonly, * and in most cases all the Class Patching is done for you, but special cases may require this hook. */ public static boolean isSimulation() { return ToastBootstrap.isSimulation; } /** * Get the Toast home directory (in local storage) from the ToastBootstrap class. This does NOT account for USB * Mass Storage. */ public static File getHome() { return ToastBootstrap.toastHome; } /** * Is this an Embedded Environment? Embedded environments are simply described as 'non-simulation' environments, and * are therefore assumed to be running on the NI RoboRIO or standard FRC competition computer onboard the Robot. The * only time a robot program is embedded is when it has been deployed to a robot and is running. */ public static boolean isEmbedded() { return !isSimulation(); } /** * Is this a competition? This returns true if the Robot and Driver Station have adequate communication to the * Field Management System (FMS). This is NOT a substitute for {@link #isEmbedded()}, as the program can be * both embedded and not connected to FMS during times when an FRC regulation field is not present. */ public static boolean isCompetition() { return Toast.getToast().station().isFMSAttached(); } /** * Get the Environmental Type in String form. This formats {@link #isSimulation()}, {@link #isVerification()} and * {@link #isEmbedded()} into their String form for writing to a console or other human-readable resources. */ public static String getEnvironmentalType() { if (isVerification()) return "Verification"; else if (isSimulation()) return "Simulation"; else if (isEmbedded()) return "Embedded"; return "Unknown"; } /** * Get the architecture of the Operating System. This usually contains x86, 32 or 64 bit systems depending on the * OS. */ public static String getOS_Architecture() { return System.getProperty("os.arch"); } /** * Get the OS Name. This returns things such as 'Linux', 'Mac OS X' or 'Windows'. Best practise is to use .contains() * on the return value, as Windows contains the version number (7, 8, 8.1, 10) in this String and uses os.version * as the build ID. */ public static String getOS_Name() { return System.getProperty("os.name"); } /** * Get the Operating System version. On Mac, this is the OS version such as 10.10, while on Windows this is the OS * build number such as 6.3. This changes per system, so it is most useful in Crash Logs and debugging. */ public static String getOS_Version() { return System.getProperty("os.version"); } /** * Get the Java Vendor. This is usually 'Oracle Corporation' or something similar, unless the user is using some * bootleg version of Java they got from the shady guy in the street called 'Big Moe' */ public static String getJava_vendor() { return System.getProperty("java.vendor"); } /** * Get the Operating System as an Enumeration. This is for when you want if statements without checking for String * constants or regex. In most cases, 'unknown' can be assumed to be Linux or Unix systems. */ public static OS getOS() { String nm = getOS_Name(); for (OS os : OS.values()) { if (os.equals(nm)) return os; } return OS.UNKNOWN; } /** * Get the Java Version. This follows the standard '1.8.0_33' system. This should be prefixed with '1.8.x_', otherwise * chances are Java is out of date and Toast won't work properly. Update 25 or above is usually required for proper * usage. */ public static String getJava_version() { return System.getProperty("java.version"); } /** * Get the Java Home Directory. This is the location of the JRE and JDK. This is used to keep track of System .jar * files present on the system to make sure we don't load them for Module candidacy. */ public static String getJava_home() { return System.getProperty("java.home"); } /** * Get a String List of all the Environment Details, nicely formatted for Command Output or Crash Logs. */ public static ArrayList<String> toLines() { ArrayList<String> list = new ArrayList<>(); list.add(String.format("%10s %s", "Toast:", Version.version().get())); list.add(String.format("%10s %s (%s)", "Git:", Version.getShortCommitHash(), Version.getCommitHash())); list.add(String.format("%10s %s", "Type:", getEnvironmentalType())); list.add(String.format("%10s %s", "FMS:", isCompetition())); list.add(String.format("%10s %s %s (%s)", "OS:", getOS_Name(), getOS_Version(), getOS_Architecture())); list.add(String.format("%10s %s (%s)", "Java:", getJava_version(), getJava_vendor())); list.add(String.format("%10s %s", "Java Path:", getJava_home())); if (JavaScript.supported()) list.add(String.format("%10s %s", "JScript:", "Supported (" + JavaScript.engineType() + ")")); else list.add(String.format("%10s %s", "JScript:", "Unsupported")); return list; } /** * Get all the environment details as a single String with newlines. */ public static String asString() { return String.join("\n", toLines()); } public static enum OS { WINDOWS("Win", false), MAC("Mac", true), LINUX("Nux", true), UNKNOWN("", false); String m; boolean u; OS(String match, boolean isUnix) { u = isUnix; m = match; } /** * Return true if the OS is a Unix system. In most cases, the union of this and the UNKNOWN key will * count towards Unix or Linux systems. */ public boolean isUnix() { return u; } /** * Get the matching string for this enum. If the OS name contains this string, it will be detected as that OS. */ public String getMatcher() { return m; } /** * Checks if the given OS string is equal to this enum. This is used in {@link #getOS()} to check the operating system * type. */ public boolean equals(String s) { return s.toLowerCase().contains(m.toLowerCase()); } } }