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; 009 010import java.util.Vector; 011 012import edu.wpi.first.wpilibj.hal.FRCNetComm.tResourceType; 013import edu.wpi.first.wpilibj.hal.HAL; 014import edu.wpi.first.wpilibj.networktables.NetworkTable; 015import edu.wpi.first.wpilibj.tables.ITable; 016import edu.wpi.first.wpilibj.tables.ITableListener; 017import edu.wpi.first.wpilibj.tables.TableKeyNotDefinedException; 018 019/** 020 * The preferences class provides a relatively simple way to save important values to the roboRIO to 021 * access the next time the roboRIO is booted. 022 * 023 * <p> This class loads and saves from a file inside the roboRIO. The user can not access the file 024 * directly, but may modify values at specific fields which will then be automatically saved to the 025 * file by the NetworkTables server. </p> 026 * 027 * <p> This class is thread safe. </p> 028 * 029 * <p> This will also interact with {@link NetworkTable} by creating a table called "Preferences" 030 * with all the key-value pairs. </p> 031 */ 032public class Preferences { 033 034 /** 035 * The Preferences table name. 036 */ 037 private static final String TABLE_NAME = "Preferences"; 038 /** 039 * The singleton instance. 040 */ 041 private static Preferences instance; 042 /** 043 * The network table. 044 */ 045 private final NetworkTable m_table; 046 /** 047 * Listener to set all Preferences values to persistent (for backwards compatibility with old 048 * dashboards). 049 */ 050 private final ITableListener m_listener = new ITableListener() { 051 @Override 052 public void valueChanged(ITable table, String key, Object value, boolean isNew) { 053 // unused 054 } 055 056 @Override 057 public void valueChangedEx(ITable table, String key, Object value, int flags) { 058 table.setPersistent(key); 059 } 060 }; 061 062 /** 063 * Returns the preferences instance. 064 * 065 * @return the preferences instance 066 */ 067 public static synchronized Preferences getInstance() { 068 if (instance == null) { 069 instance = new Preferences(); 070 } 071 return instance; 072 } 073 074 /** 075 * Creates a preference class. 076 */ 077 private Preferences() { 078 m_table = NetworkTable.getTable(TABLE_NAME); 079 m_table.addTableListenerEx(m_listener, ITable.NOTIFY_NEW | ITable.NOTIFY_IMMEDIATE); 080 HAL.report(tResourceType.kResourceType_Preferences, 0); 081 } 082 083 /** 084 * Gets the vector of keys. 085 * @return a vector of the keys 086 */ 087 public Vector getKeys() { 088 Vector<String> keys = new Vector<String>(); 089 for (String key : m_table.getKeys()) { 090 keys.add(key); 091 } 092 return keys; 093 } 094 095 /** 096 * Puts the given string into the preferences table. 097 * 098 * @param key the key 099 * @param value the value 100 * @throws NullPointerException if value is null 101 */ 102 public void putString(String key, String value) { 103 if (value == null) { 104 throw new NullPointerException("Value is null"); 105 } 106 m_table.putString(key, value); 107 m_table.setPersistent(key); 108 } 109 110 /** 111 * Puts the given int into the preferences table. 112 * 113 * @param key the key 114 * @param value the value 115 */ 116 public void putInt(String key, int value) { 117 m_table.putNumber(key, value); 118 m_table.setPersistent(key); 119 } 120 121 /** 122 * Puts the given double into the preferences table. 123 * 124 * @param key the key 125 * @param value the value 126 */ 127 public void putDouble(String key, double value) { 128 m_table.putNumber(key, value); 129 m_table.setPersistent(key); 130 } 131 132 /** 133 * Puts the given float into the preferences table. 134 * 135 * @param key the key 136 * @param value the value 137 */ 138 public void putFloat(String key, float value) { 139 m_table.putNumber(key, value); 140 m_table.setPersistent(key); 141 } 142 143 /** 144 * Puts the given boolean into the preferences table. 145 * 146 * @param key the key 147 * @param value the value 148 */ 149 public void putBoolean(String key, boolean value) { 150 m_table.putBoolean(key, value); 151 m_table.setPersistent(key); 152 } 153 154 /** 155 * Puts the given long into the preferences table. 156 * 157 * @param key the key 158 * @param value the value 159 */ 160 public void putLong(String key, long value) { 161 m_table.putNumber(key, value); 162 m_table.setPersistent(key); 163 } 164 165 /** 166 * Returns whether or not there is a key with the given name. 167 * 168 * @param key the key 169 * @return if there is a value at the given key 170 */ 171 public boolean containsKey(String key) { 172 return m_table.containsKey(key); 173 } 174 175 /** 176 * Remove a preference. 177 * 178 * @param key the key 179 */ 180 public void remove(String key) { 181 m_table.delete(key); 182 } 183 184 /** 185 * Returns the string at the given key. If this table does not have a value for that position, 186 * then the given backup value will be returned. 187 * 188 * @param key the key 189 * @param backup the value to return if none exists in the table 190 * @return either the value in the table, or the backup 191 */ 192 public String getString(String key, String backup) { 193 return m_table.getString(key, backup); 194 } 195 196 /** 197 * Returns the int at the given key. If this table does not have a value for that position, then 198 * the given backup value will be returned. 199 * 200 * @param key the key 201 * @param backup the value to return if none exists in the table 202 * @return either the value in the table, or the backup 203 */ 204 public int getInt(String key, int backup) { 205 try { 206 return (int) m_table.getNumber(key); 207 } catch (TableKeyNotDefinedException ex) { 208 return backup; 209 } 210 } 211 212 /** 213 * Returns the double at the given key. If this table does not have a value for that position, 214 * then the given backup value will be returned. 215 * 216 * @param key the key 217 * @param backup the value to return if none exists in the table 218 * @return either the value in the table, or the backup 219 */ 220 public double getDouble(String key, double backup) { 221 return m_table.getDouble(key, backup); 222 } 223 224 /** 225 * Returns the boolean at the given key. If this table does not have a value for that position, 226 * then the given backup value will be returned. 227 * 228 * @param key the key 229 * @param backup the value to return if none exists in the table 230 * @return either the value in the table, or the backup 231 */ 232 public boolean getBoolean(String key, boolean backup) { 233 return m_table.getBoolean(key, backup); 234 } 235 236 /** 237 * Returns the float at the given key. If this table does not have a value for that position, then 238 * the given backup value will be returned. 239 * 240 * @param key the key 241 * @param backup the value to return if none exists in the table 242 * @return either the value in the table, or the backup 243 */ 244 public float getFloat(String key, float backup) { 245 try { 246 return (float) m_table.getNumber(key); 247 } catch (TableKeyNotDefinedException ex) { 248 return backup; 249 } 250 } 251 252 /** 253 * Returns the long at the given key. If this table does not have a value for that position, then 254 * the given backup value will be returned. 255 * 256 * @param key the key 257 * @param backup the value to return if none exists in the table 258 * @return either the value in the table, or the backup 259 */ 260 public long getLong(String key, long backup) { 261 try { 262 return (long) m_table.getNumber(key); 263 } catch (TableKeyNotDefinedException ex) { 264 return backup; 265 } 266 } 267 268 /** 269 * This function is no longer required, as NetworkTables automatically saves persistent values 270 * (which all Preferences values are) periodically when running as a server. 271 * 272 * @deprecated backwards compatibility shim 273 */ 274 @Deprecated 275 public void save() { 276 } 277}