001/*----------------------------------------------------------------------------*/
002/* Copyright (c) FIRST 2008-2017. All Rights Reserved.                        */
003/* Open Source Software - may be modified and shared by FRC teams. The code   */
004/* must be accompanied by the FIRST BSD license file in the root directory of */
005/* the project.                                                               */
006/*----------------------------------------------------------------------------*/
007
008package edu.wpi.first.wpilibj.smartdashboard;
009
010import java.nio.ByteBuffer;
011import java.util.Hashtable;
012import java.util.NoSuchElementException;
013import java.util.Set;
014
015import edu.wpi.first.wpilibj.HLUsageReporting;
016import edu.wpi.first.wpilibj.NamedSendable;
017import edu.wpi.first.wpilibj.Sendable;
018import edu.wpi.first.wpilibj.networktables.NetworkTable;
019import edu.wpi.first.wpilibj.networktables.NetworkTableKeyNotDefined;
020import edu.wpi.first.wpilibj.tables.ITable;
021import edu.wpi.first.wpilibj.tables.TableKeyNotDefinedException;
022
023/**
024 * The {@link SmartDashboard} class is the bridge between robot programs and the SmartDashboard on
025 * the laptop.
026 *
027 * <p>When a value is put into the SmartDashboard here, it pops up on the SmartDashboard on the
028 * laptop. Users can put values into and get values from the SmartDashboard.
029 */
030public class SmartDashboard {
031  /**
032   * The {@link NetworkTable} used by {@link SmartDashboard}.
033   */
034  private static final NetworkTable table = NetworkTable.getTable("SmartDashboard");
035  /**
036   * A table linking tables in the SmartDashboard to the {@link Sendable} objects they
037   * came from.
038   */
039  private static final Hashtable tablesToData = new Hashtable();
040
041  static {
042    HLUsageReporting.reportSmartDashboard();
043  }
044
045  /**
046   * Maps the specified key to the specified value in this table. The key can not be null. The value
047   * can be retrieved by calling the get method with a key that is equal to the original key.
048   *
049   * @param key  the key
050   * @param data the value
051   * @throws IllegalArgumentException If key is null
052   */
053  public static void putData(String key, Sendable data) {
054    ITable dataTable = table.getSubTable(key);
055    dataTable.putString("~TYPE~", data.getSmartDashboardType());
056    data.initTable(dataTable);
057    tablesToData.put(data, key);
058  }
059
060
061  // TODO should we reimplement NamedSendable?
062
063  /**
064   * Maps the specified key (where the key is the name of the {@link NamedSendable}
065   * SmartDashboardNamedData to the specified value in this table. The value can be retrieved by
066   * calling the get method with a key that is equal to the original key.
067   *
068   * @param value the value
069   * @throws IllegalArgumentException If key is null
070   */
071  public static void putData(NamedSendable value) {
072    putData(value.getName(), value);
073  }
074
075  /**
076   * Returns the value at the specified key.
077   *
078   * @param key the key
079   * @return the value
080   * @throws NetworkTableKeyNotDefined if there is no value mapped to by the key
081   * @throws IllegalArgumentException  if the key is null
082   */
083  public static Sendable getData(String key) {
084    ITable subtable = table.getSubTable(key);
085    Object data = tablesToData.get(subtable);
086    if (data == null) {
087      throw new IllegalArgumentException("SmartDashboard data does not exist: " + key);
088    } else {
089      return (Sendable) data;
090    }
091  }
092
093  /**
094   * Checks the table and tells if it contains the specified key.
095   *
096   * @param key the key to search for
097   * @return true if the table as a value assigned to the given key
098   */
099  public static boolean containsKey(String key) {
100    return table.containsKey(key);
101  }
102
103  /**
104   * @param types bitmask of types; 0 is treated as a "don't care".
105   * @return keys currently in the table
106   */
107  public Set<String> getKeys(int types) {
108    return table.getKeys(types);
109  }
110
111  /**
112   * @return keys currently in the table.
113   */
114  public Set<String> getKeys() {
115    return table.getKeys();
116  }
117
118  /**
119   * Makes a key's value persistent through program restarts.
120   * The key cannot be null.
121   *
122   * @param key the key name
123   */
124  public void setPersistent(String key) {
125    table.setPersistent(key);
126  }
127
128  /**
129   * Stop making a key's value persistent through program restarts.
130   * The key cannot be null.
131   *
132   * @param key the key name
133   */
134  public void clearPersistent(String key) {
135    table.clearPersistent(key);
136  }
137
138  /**
139   * Returns whether the value is persistent through program restarts.
140   * The key cannot be null.
141   *
142   * @param key the key name
143   * @return True if the value is persistent.
144   */
145  public boolean isPersistent(String key) {
146    return table.isPersistent(key);
147  }
148
149  /**
150   * Sets flags on the specified key in this table. The key can
151   * not be null.
152   *
153   * @param key the key name
154   * @param flags the flags to set (bitmask)
155   */
156  public void setFlags(String key, int flags) {
157    table.setFlags(key, flags);
158  }
159
160  /**
161   * Clears flags on the specified key in this table. The key can
162   * not be null.
163   *
164   * @param key the key name
165   * @param flags the flags to clear (bitmask)
166   */
167  public void clearFlags(String key, int flags) {
168    table.clearFlags(key, flags);
169  }
170
171  /**
172   * Returns the flags for the specified key.
173   *
174   * @param key the key name
175   * @return the flags, or 0 if the key is not defined
176   */
177  public int getFlags(String key) {
178    return table.getFlags(key);
179  }
180
181  /**
182   * Deletes the specified key in this table. The key can
183   * not be null.
184   *
185   * @param key the key name
186   */
187  public void delete(String key) {
188    table.delete(key);
189  }
190
191  /**
192   * Put a boolean in the table.
193   * @param key the key to be assigned to
194   * @param value the value that will be assigned
195   * @return False if the table key already exists with a different type
196   */
197  public static boolean putBoolean(String key, boolean value) {
198    return table.putBoolean(key, value);
199  }
200
201  /**
202   * Gets the current value in the table, setting it if it does not exist.
203   * @param key the key
204   * @param defaultValue the default value to set if key doens't exist.
205   * @return False if the table key exists with a different type
206   */
207  public boolean setDefaultBoolean(String key, boolean defaultValue) {
208    return table.setDefaultBoolean(key, defaultValue);
209  }
210
211  /**
212   * Returns the boolean the key maps to.
213   * @param key the key to look up
214   * @return the value associated with the given key
215   * @throws TableKeyNotDefinedException if there is no value associated with
216   *     the given key
217   * @deprecated This exception-raising method has been replaced by the
218   *     default-taking method {@link #getBoolean(String, boolean)}.
219   */
220  @Deprecated
221  public static boolean getBoolean(String key) throws TableKeyNotDefinedException {
222    return table.getBoolean(key);
223  }
224
225  /**
226   * Returns the boolean the key maps to. If the key does not exist or is of
227   *     different type, it will return the default value.
228   * @param key the key to look up
229   * @param defaultValue the value to be returned if no value is found
230   * @return the value associated with the given key or the given default value
231   *     if there is no value associated with the key
232   */
233  public static boolean getBoolean(String key, boolean defaultValue) {
234    return table.getBoolean(key, defaultValue);
235  }
236
237  /**
238   * Put a number in the table.
239   * @param key the key to be assigned to
240   * @param value the value that will be assigned
241   * @return False if the table key already exists with a different type
242   */
243  public static boolean putNumber(String key, double value) {
244    return table.putNumber(key, value);
245  }
246
247  /**
248   * Gets the current value in the table, setting it if it does not exist.
249   * @param key the key
250   * @param defaultValue the default value to set if key doens't exist.
251   * @return False if the table key exists with a different type
252   */
253  public boolean setDefaultNumber(String key, double defaultValue) {
254    return table.setDefaultNumber(key, defaultValue);
255  }
256
257  /**
258   * Returns the number the key maps to.
259   * @param key the key to look up
260   * @return the value associated with the given key
261   * @throws TableKeyNotDefinedException if there is no value associated with
262   *     the given key
263   * @deprecated This exception-raising method has been replaced by the
264   *     default-taking method {@link #getNumber(String, double)}.
265   */
266  @Deprecated
267  public static double getNumber(String key) throws TableKeyNotDefinedException {
268    return table.getNumber(key);
269  }
270
271  /**
272   * Returns the number the key maps to. If the key does not exist or is of
273   *     different type, it will return the default value.
274   * @param key the key to look up
275   * @param defaultValue the value to be returned if no value is found
276   * @return the value associated with the given key or the given default value
277   *     if there is no value associated with the key
278   */
279  public static double getNumber(String key, double defaultValue) {
280    return table.getNumber(key, defaultValue);
281  }
282
283  /**
284   * Put a string in the table.
285   * @param key the key to be assigned to
286   * @param value the value that will be assigned
287   * @return False if the table key already exists with a different type
288   */
289  public static boolean putString(String key, String value) {
290    return table.putString(key, value);
291  }
292
293  /**
294   * Gets the current value in the table, setting it if it does not exist.
295   * @param key the key
296   * @param defaultValue the default value to set if key doens't exist.
297   * @return False if the table key exists with a different type
298   */
299  public boolean setDefaultString(String key, String defaultValue) {
300    return table.setDefaultString(key, defaultValue);
301  }
302
303  /**
304   * Returns the string the key maps to.
305   * @param key the key to look up
306   * @return the value associated with the given key
307   * @throws TableKeyNotDefinedException if there is no value associated with
308   *     the given key
309   * @deprecated This exception-raising method has been replaced by the
310   *     default-taking method {@link #getString(String, String)}.
311   */
312  @Deprecated
313  public static String getString(String key) throws TableKeyNotDefinedException {
314    return table.getString(key);
315  }
316
317  /**
318   * Returns the string the key maps to. If the key does not exist or is of
319   *     different type, it will return the default value.
320   * @param key the key to look up
321   * @param defaultValue the value to be returned if no value is found
322   * @return the value associated with the given key or the given default value
323   *     if there is no value associated with the key
324   */
325  public static String getString(String key, String defaultValue) {
326    return table.getString(key, defaultValue);
327  }
328
329  /**
330   * Put a boolean array in the table.
331   * @param key the key to be assigned to
332   * @param value the value that will be assigned
333   * @return False if the table key already exists with a different type
334   */
335  public boolean putBooleanArray(String key, boolean[] value) {
336    return table.putBooleanArray(key, value);
337  }
338
339  /**
340   * Put a boolean array in the table.
341   * @param key the key to be assigned to
342   * @param value the value that will be assigned
343   * @return False if the table key already exists with a different type
344   */
345  public boolean putBooleanArray(String key, Boolean[] value) {
346    return table.putBooleanArray(key, value);
347  }
348
349  /**
350   * Gets the current value in the table, setting it if it does not exist.
351   * @param key the key
352   * @param defaultValue the default value to set if key doens't exist.
353   * @return False if the table key exists with a different type
354   */
355  public boolean setDefaultBooleanArray(String key, boolean[] defaultValue) {
356    return table.setDefaultBooleanArray(key, defaultValue);
357  }
358
359  /**
360   * Gets the current value in the table, setting it if it does not exist.
361   * @param key the key
362   * @param defaultValue the default value to set if key doens't exist.
363   * @return False if the table key exists with a different type
364   */
365  public boolean setDefaultBooleanArray(String key, Boolean[] defaultValue) {
366    return table.setDefaultBooleanArray(key, defaultValue);
367  }
368
369  /**
370   * Returns the boolean array the key maps to.
371   * @param key the key to look up
372   * @return the value associated with the given key
373   * @throws TableKeyNotDefinedException if there is no value associated with
374   *     the given key
375   * @deprecated This exception-raising method has been replaced by the
376   *     default-taking method {@link #getBooleanArray(String, boolean[])}.
377   */
378  @Deprecated
379  public boolean[] getBooleanArray(String key) throws TableKeyNotDefinedException {
380    return table.getBooleanArray(key);
381  }
382
383  /**
384   * Returns the boolean array the key maps to. If the key does not exist or is
385   *     of different type, it will return the default value.
386   * @param key the key to look up
387   * @param defaultValue the value to be returned if no value is found
388   * @return the value associated with the given key or the given default value
389   *     if there is no value associated with the key
390   */
391  public boolean[] getBooleanArray(String key, boolean[] defaultValue) {
392    return table.getBooleanArray(key, defaultValue);
393  }
394
395  /**
396   * Returns the boolean array the key maps to. If the key does not exist or is
397   *     of different type, it will return the default value.
398   * @param key the key to look up
399   * @param defaultValue the value to be returned if no value is found
400   * @return the value associated with the given key or the given default value
401   *     if there is no value associated with the key
402   */
403  public Boolean[] getBooleanArray(String key, Boolean[] defaultValue) {
404    return table.getBooleanArray(key, defaultValue);
405  }
406
407  /**
408   * Put a number array in the table.
409   * @param key the key to be assigned to
410   * @param value the value that will be assigned
411   * @return False if the table key already exists with a different type
412   */
413  public boolean putNumberArray(String key, double[] value) {
414    return table.putNumberArray(key, value);
415  }
416
417  /**
418   * Put a number array in the table.
419   * @param key the key to be assigned to
420   * @param value the value that will be assigned
421   * @return False if the table key already exists with a different type
422   */
423  public boolean putNumberArray(String key, Double[] value) {
424    return table.putNumberArray(key, value);
425  }
426
427  /**
428   * Gets the current value in the table, setting it if it does not exist.
429   * @param key the key
430   * @param defaultValue the default value to set if key doens't exist.
431   * @return False if the table key exists with a different type
432   */
433  public boolean setDefaultNumberArray(String key, double[] defaultValue) {
434    return table.setDefaultNumberArray(key, defaultValue);
435  }
436
437  /**
438   * Gets the current value in the table, setting it if it does not exist.
439   * @param key the key
440   * @param defaultValue the default value to set if key doens't exist.
441   * @return False if the table key exists with a different type
442   */
443  public boolean setDefaultNumberArray(String key, Double[] defaultValue) {
444    return table.setDefaultNumberArray(key, defaultValue);
445  }
446
447  /**
448   * Returns the number array the key maps to.
449   * @param key the key to look up
450   * @return the value associated with the given key
451   * @throws TableKeyNotDefinedException if there is no value associated with
452   *     the given key
453   * @deprecated This exception-raising method has been replaced by the
454   *     default-taking method {@link #getNumberArray(String, double[])}.
455   */
456  @Deprecated
457  public double[] getNumberArray(String key) throws TableKeyNotDefinedException {
458    return table.getNumberArray(key);
459  }
460
461  /**
462   * Returns the number array the key maps to. If the key does not exist or is
463   *     of different type, it will return the default value.
464   * @param key the key to look up
465   * @param defaultValue the value to be returned if no value is found
466   * @return the value associated with the given key or the given default value
467   *     if there is no value associated with the key
468   */
469  public double[] getNumberArray(String key, double[] defaultValue) {
470    return table.getNumberArray(key, defaultValue);
471  }
472
473  /**
474   * Returns the number array the key maps to. If the key does not exist or is
475   *     of different type, it will return the default value.
476   * @param key the key to look up
477   * @param defaultValue the value to be returned if no value is found
478   * @return the value associated with the given key or the given default value
479   *     if there is no value associated with the key
480   */
481  public Double[] getNumberArray(String key, Double[] defaultValue) {
482    return table.getNumberArray(key, defaultValue);
483  }
484
485  /**
486   * Put a string array in the table.
487   * @param key the key to be assigned to
488   * @param value the value that will be assigned
489   * @return False if the table key already exists with a different type
490   */
491  public boolean putStringArray(String key, String[] value) {
492    return table.putStringArray(key, value);
493  }
494
495  /**
496   * Gets the current value in the table, setting it if it does not exist.
497   * @param key the key
498   * @param defaultValue the default value to set if key doens't exist.
499   * @return False if the table key exists with a different type
500   */
501  public boolean setDefaultStringArray(String key, String[] defaultValue) {
502    return table.setDefaultStringArray(key, defaultValue);
503  }
504
505  /**
506   * Returns the string array the key maps to.
507   * @param key the key to look up
508   * @return the value associated with the given key
509   * @throws TableKeyNotDefinedException if there is no value associated with
510   *     the given key
511   * @deprecated This exception-raising method has been replaced by the
512   *     default-taking method {@link #getStringArray(String, String[])}.
513   */
514  @Deprecated
515  public String[] getStringArray(String key) throws TableKeyNotDefinedException {
516    return table.getStringArray(key);
517  }
518
519  /**
520   * Returns the string array the key maps to. If the key does not exist or is
521   *     of different type, it will return the default value.
522   * @param key the key to look up
523   * @param defaultValue the value to be returned if no value is found
524   * @return the value associated with the given key or the given default value
525   *     if there is no value associated with the key
526   */
527  public String[] getStringArray(String key, String[] defaultValue) {
528    return table.getStringArray(key, defaultValue);
529  }
530
531  /**
532   * Put a raw value (byte array) in the table.
533   * @param key the key to be assigned to
534   * @param value the value that will be assigned
535   * @return False if the table key already exists with a different type
536   */
537  public boolean putRaw(String key, byte[] value) {
538    return table.putRaw(key, value);
539  }
540
541  /**
542   * Put a raw value (bytes from a byte buffer) in the table.
543   * @param key the key to be assigned to
544   * @param value the value that will be assigned
545   * @param len the length of the value
546   * @return False if the table key already exists with a different type
547   */
548  public boolean putRaw(String key, ByteBuffer value, int len) {
549    return table.putRaw(key, value, len);
550  }
551
552  /**
553   * Gets the current value in the table, setting it if it does not exist.
554   * @param key the key
555   * @param defaultValue the default value to set if key doens't exist.
556   * @return False if the table key exists with a different type
557   */
558  public boolean setDefaultRaw(String key, byte[] defaultValue) {
559    return table.setDefaultRaw(key, defaultValue);
560  }
561
562  /**
563   * Returns the raw value (byte array) the key maps to.
564   * @param key the key to look up
565   * @return the value associated with the given key
566   * @throws TableKeyNotDefinedException if there is no value associated with
567   *     the given key
568   * @deprecated This exception-raising method has been replaced by the
569   *     default-taking method {@link #getRaw(String, byte[])}.
570   */
571  @Deprecated
572  public byte[] getRaw(String key) throws TableKeyNotDefinedException {
573    return table.getRaw(key);
574  }
575
576  /**
577   * Returns the raw value (byte array) the key maps to. If the key does not
578   *     exist or is of different type, it will return the default value.
579   * @param key the key to look up
580   * @param defaultValue the value to be returned if no value is found
581   * @return the value associated with the given key or the given default value
582   *     if there is no value associated with the key
583   */
584  public byte[] getRaw(String key, byte[] defaultValue) {
585    return table.getRaw(key, defaultValue);
586  }
587
588  /*
589   * Deprecated Methods
590   */
591
592  /**
593   * Maps the specified key to the specified value in this table.
594   *
595   * <p>The key can not be null. The value can be retrieved by calling the get method with a key
596   * that is equal to the original key.
597   *
598   * @param key   the key
599   * @param value the value
600   * @throws IllegalArgumentException if key is null
601   * @deprecated Use {@link #putNumber(java.lang.String, double) putNumber method} instead
602   */
603  @Deprecated
604  public static void putInt(String key, int value) {
605    table.putNumber(key, value);
606  }
607
608  /**
609   * Returns the value at the specified key.
610   *
611   * @param key the key
612   * @return the value
613   * @throws TableKeyNotDefinedException if there is no value mapped to by the key
614   * @throws IllegalArgumentException    if the value mapped to by the key is not an int
615   * @throws IllegalArgumentException    if the key is null
616   * @deprecated Use {@link #getNumber(java.lang.String) getNumber} instead
617   */
618  @Deprecated
619  public static int getInt(String key) throws TableKeyNotDefinedException {
620    return (int) table.getNumber(key);
621  }
622
623  /**
624   * Returns the value at the specified key.
625   *
626   * @param key          the key
627   * @param defaultValue the value returned if the key is undefined
628   * @return the value
629   * @throws TableKeyNotDefinedException if there is no value mapped to by the key
630   * @throws IllegalArgumentException    if the value mapped to by the key is not an int
631   * @throws IllegalArgumentException    if the key is null
632   * @deprecated Use {@link #getNumber(java.lang.String, double) getNumber} instead
633   */
634  @Deprecated
635  public static int getInt(String key, int defaultValue) throws TableKeyNotDefinedException {
636    try {
637      return (int) table.getNumber(key);
638    } catch (NoSuchElementException ex) {
639      return defaultValue;
640    }
641  }
642
643  /**
644   * Maps the specified key to the specified value in this table.
645   *
646   * <p>The key can not be null. The value can be retrieved by calling the get method with a key
647   * that is equal to the original key.
648   *
649   * @param key   the key
650   * @param value the value
651   * @throws IllegalArgumentException if key is null
652   * @deprecated Use{@link #putNumber(java.lang.String, double) putNumber} instead
653   */
654  @Deprecated
655  public static void putDouble(String key, double value) {
656    table.putNumber(key, value);
657  }
658
659  /**
660   * Returns the value at the specified key.
661   *
662   * @param key the key
663   * @return the value
664   * @throws TableKeyNotDefinedException if there is no value mapped to by the key
665   * @throws IllegalArgumentException    if the value mapped to by the key is not a double
666   * @throws IllegalArgumentException    if the key is null
667   * @deprecated Use {@link #getNumber(java.lang.String) getNumber} instead
668   */
669  @Deprecated
670  public static double getDouble(String key) throws TableKeyNotDefinedException {
671    return table.getNumber(key);
672  }
673
674  /**
675   * Returns the value at the specified key.
676   *
677   * @param key          the key
678   * @param defaultValue the value returned if the key is undefined
679   * @return the value
680   * @throws IllegalArgumentException if the value mapped to by the key is not a double
681   * @throws IllegalArgumentException if the key is null
682   * @deprecated Use {@link #getNumber(java.lang.String, double) getNumber} instead.
683   */
684  @Deprecated
685  public static double getDouble(String key, double defaultValue) {
686    return table.getNumber(key, defaultValue);
687  }
688
689}