001// Copyright (c) FIRST and other WPILib contributors.
002// Open Source Software; you can modify and/or share it under the terms of
003// the WPILib BSD license file in the root directory of this project.
004
005package org.wpilib.driverstation;
006
007import org.wpilib.hardware.hal.AlertJNI;
008
009/**
010 * Persistent alert to be sent via NetworkTables. Alerts are tagged with a type of {@code HIGH},
011 * {@code MEDIUM}, or {@code LOW} to denote urgency. See {@link org.wpilib.driverstation.Alert.Level
012 * Level} for suggested usage of each type. Alerts can be displayed on supported dashboards, and are
013 * shown in a priority order based on type and recency of activation, with newly activated alerts
014 * first.
015 *
016 * <p>Alerts should be created once and stored persistently, then updated to "active" or "inactive"
017 * as necessary. {@link #set(boolean)} can be safely called periodically.
018 *
019 * <pre>
020 * class Robot {
021 *   Alert alert = new Alert("Something went wrong", Alert.Level.MEDIUM);
022 *
023 *   periodic() {
024 *     alert.set(...);
025 *   }
026 * }
027 * </pre>
028 *
029 * <p>Alternatively, alerts which are only used once at startup can be created and activated inline.
030 *
031 * <pre>
032 * public Robot() {
033 *   new Alert("Failed to load auto paths", Alert.Level.HIGH).set(true);
034 * }
035 * </pre>
036 */
037public class Alert implements AutoCloseable {
038  /** Represents an alert's level of urgency. */
039  public enum Level {
040    /**
041     * High priority alert - displayed first with a red "X" symbol. Use this type for problems which
042     * will seriously affect the robot's functionality and thus require immediate attention.
043     */
044    HIGH(AlertJNI.LEVEL_HIGH),
045
046    /**
047     * Medium priority alert - displayed second with a yellow "!" symbol. Use this type for problems
048     * which could affect the robot's functionality but do not necessarily require immediate
049     * attention.
050     */
051    MEDIUM(AlertJNI.LEVEL_MEDIUM),
052
053    /**
054     * Low priority alert - displayed last with a green "i" symbol. Use this type for problems which
055     * are unlikely to affect the robot's functionality, or any other alerts which do not fall under
056     * the other categories.
057     */
058    LOW(AlertJNI.LEVEL_LOW);
059
060    private final int m_value;
061
062    Level(int value) {
063      m_value = value;
064    }
065  }
066
067  private final Level m_type;
068  private int m_handle;
069
070  /**
071   * Creates a new alert in the default group - "Alerts". If this is the first to be instantiated,
072   * the appropriate entries will be added to NetworkTables.
073   *
074   * @param text Text to be displayed when the alert is active.
075   * @param type Alert urgency level.
076   */
077  public Alert(String text, Level type) {
078    this("Alerts", text, type);
079  }
080
081  /**
082   * Creates a new alert. If this is the first to be instantiated in its group, the appropriate
083   * entries will be added to NetworkTables.
084   *
085   * @param group Group identifier, used as the entry name in NetworkTables.
086   * @param text Text to be displayed when the alert is active.
087   * @param type Alert urgency level.
088   */
089  public Alert(String group, String text, Level type) {
090    m_type = type;
091    m_handle = AlertJNI.createAlert(group, text, type.m_value);
092  }
093
094  /**
095   * Sets whether the alert should currently be displayed. This method can be safely called
096   * periodically.
097   *
098   * @param active Whether to display the alert.
099   */
100  public void set(boolean active) {
101    AlertJNI.setAlertActive(m_handle, active);
102  }
103
104  /**
105   * Gets whether the alert is active.
106   *
107   * @return whether the alert is active.
108   */
109  public boolean get() {
110    return AlertJNI.isAlertActive(m_handle);
111  }
112
113  /**
114   * Updates current alert text. Use this method to dynamically change the displayed alert, such as
115   * including more details about the detected problem.
116   *
117   * @param text Text to be displayed when the alert is active.
118   */
119  public void setText(String text) {
120    AlertJNI.setAlertText(m_handle, text);
121  }
122
123  /**
124   * Gets the current alert text.
125   *
126   * @return the current text.
127   */
128  public String getText() {
129    return AlertJNI.getAlertText(m_handle);
130  }
131
132  /**
133   * Get the type of this alert.
134   *
135   * @return the type
136   */
137  public Level getType() {
138    return m_type;
139  }
140
141  @Override
142  public void close() {
143    AlertJNI.destroyAlert(m_handle);
144    m_handle = 0;
145  }
146}