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 edu.wpi.first.hal;
006
007public class SimDeviceJNI extends JNIWrapper {
008  public static final int kInput = 0;
009  public static final int kOutput = 1;
010  public static final int kBidir = 2;
011
012  /**
013   * Creates a simulated device.
014   *
015   * <p>The device name must be unique. 0 is returned if the device name already exists. If multiple
016   * instances of the same device are desired, recommend appending the instance/unique identifier in
017   * brackets to the base name, e.g. "device[1]".
018   *
019   * <p>0 is returned if not in simulation.
020   *
021   * @param name device name
022   * @return simulated device handle
023   */
024  public static native int createSimDevice(String name);
025
026  /**
027   * Frees a simulated device.
028   *
029   * <p>This also allows the same device name to be used again. This also frees all the simulated
030   * values created on the device.
031   *
032   * @param handle simulated device handle
033   */
034  public static native void freeSimDevice(int handle);
035
036  /**
037   * Get the name of a simulated device.
038   *
039   * @param handle simulated device handle
040   * @return name of the simulated device
041   */
042  public static native String getSimDeviceName(int handle);
043
044  private static native int createSimValueNative(
045      int device, String name, int direction, int type, long value1, double value2);
046
047  /**
048   * Creates a value on a simulated device.
049   *
050   * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
051   *
052   * @param device simulated device handle
053   * @param name value name
054   * @param direction input/output/bidir (from perspective of user code)
055   * @param initialValue initial value
056   * @return simulated value handle
057   */
058  public static int createSimValue(int device, String name, int direction, HALValue initialValue) {
059    return createSimValueNative(
060        device,
061        name,
062        direction,
063        initialValue.getType(),
064        initialValue.getNativeLong(),
065        initialValue.getNativeDouble());
066  }
067
068  /**
069   * Creates an int value on a simulated device.
070   *
071   * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
072   *
073   * @param device simulated device handle
074   * @param name value name
075   * @param direction input/output/bidir (from perspective of user code)
076   * @param initialValue initial value
077   * @return simulated value handle
078   */
079  public static int createSimValueInt(int device, String name, int direction, int initialValue) {
080    return createSimValueNative(device, name, direction, HALValue.kInt, initialValue, 0.0);
081  }
082
083  /**
084   * Creates a long value on a simulated device.
085   *
086   * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
087   *
088   * @param device simulated device handle
089   * @param name value name
090   * @param direction input/output/bidir (from perspective of user code)
091   * @param initialValue initial value
092   * @return simulated value handle
093   */
094  public static int createSimValueLong(int device, String name, int direction, long initialValue) {
095    return createSimValueNative(device, name, direction, HALValue.kLong, initialValue, 0.0);
096  }
097
098  /**
099   * Creates a double value on a simulated device.
100   *
101   * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
102   *
103   * @param device simulated device handle
104   * @param name value name
105   * @param direction input/output/bidir (from perspective of user code)
106   * @param initialValue initial value
107   * @return simulated value handle
108   */
109  public static int createSimValueDouble(
110      int device, String name, int direction, double initialValue) {
111    return createSimValueNative(device, name, direction, HALValue.kDouble, 0, initialValue);
112  }
113
114  /**
115   * Creates an enumerated value on a simulated device.
116   *
117   * <p>Enumerated values are always in the range 0 to numOptions-1.
118   *
119   * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
120   *
121   * @param device simulated device handle
122   * @param name value name
123   * @param direction input/output/bidir (from perspective of user code)
124   * @param options array of option descriptions
125   * @param initialValue initial value (selection)
126   * @return simulated value handle
127   */
128  public static native int createSimValueEnum(
129      int device, String name, int direction, String[] options, int initialValue);
130
131  /**
132   * Creates an enumerated value on a simulated device with double values.
133   *
134   * <p>Enumerated values are always in the range 0 to numOptions-1.
135   *
136   * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
137   *
138   * @param device simulated device handle
139   * @param name value name
140   * @param direction input/output/bidir (from perspective of user code)
141   * @param options array of option descriptions
142   * @param optionValues array of option values (must be the same size as options)
143   * @param initialValue initial value (selection)
144   * @return simulated value handle
145   */
146  public static native int createSimValueEnumDouble(
147      int device,
148      String name,
149      int direction,
150      String[] options,
151      double[] optionValues,
152      int initialValue);
153
154  /**
155   * Creates a boolean value on a simulated device.
156   *
157   * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
158   *
159   * @param device simulated device handle
160   * @param name value name
161   * @param direction input/output/bidir (from perspective of user code)
162   * @param initialValue initial value
163   * @return simulated value handle
164   */
165  public static int createSimValueBoolean(
166      int device, String name, int direction, boolean initialValue) {
167    return createSimValueNative(
168        device, name, direction, HALValue.kBoolean, initialValue ? 1 : 0, 0.0);
169  }
170
171  /**
172   * Gets a simulated value.
173   *
174   * @param handle simulated value handle
175   * @return The current value
176   */
177  public static native HALValue getSimValue(int handle);
178
179  /**
180   * Gets a simulated value (int).
181   *
182   * @param handle simulated value handle
183   * @return The current value
184   */
185  public static native int getSimValueInt(int handle);
186
187  /**
188   * Gets a simulated value (long).
189   *
190   * @param handle simulated value handle
191   * @return The current value
192   */
193  public static native long getSimValueLong(int handle);
194
195  /**
196   * Gets a simulated value (double).
197   *
198   * @param handle simulated value handle
199   * @return The current value
200   */
201  public static native double getSimValueDouble(int handle);
202
203  /**
204   * Gets a simulated value (enum).
205   *
206   * @param handle simulated value handle
207   * @return The current value
208   */
209  public static native int getSimValueEnum(int handle);
210
211  /**
212   * Gets a simulated value (boolean).
213   *
214   * @param handle simulated value handle
215   * @return The current value
216   */
217  public static native boolean getSimValueBoolean(int handle);
218
219  private static native void setSimValueNative(int handle, int type, long value1, double value2);
220
221  /**
222   * Sets a simulated value.
223   *
224   * @param handle simulated value handle
225   * @param value the value to set
226   */
227  public static void setSimValue(int handle, HALValue value) {
228    setSimValueNative(handle, value.getType(), value.getNativeLong(), value.getNativeDouble());
229  }
230
231  /**
232   * Sets a simulated value (int).
233   *
234   * @param handle simulated value handle
235   * @param value the value to set
236   */
237  public static void setSimValueInt(int handle, int value) {
238    setSimValueNative(handle, HALValue.kInt, value, 0.0);
239  }
240
241  /**
242   * Sets a simulated value (long).
243   *
244   * @param handle simulated value handle
245   * @param value the value to set
246   */
247  public static void setSimValueLong(int handle, long value) {
248    setSimValueNative(handle, HALValue.kLong, value, 0.0);
249  }
250
251  /**
252   * Sets a simulated value (double).
253   *
254   * @param handle simulated value handle
255   * @param value the value to set
256   */
257  public static void setSimValueDouble(int handle, double value) {
258    setSimValueNative(handle, HALValue.kDouble, 0, value);
259  }
260
261  /**
262   * Sets a simulated value (enum).
263   *
264   * @param handle simulated value handle
265   * @param value the value to set
266   */
267  public static void setSimValueEnum(int handle, int value) {
268    setSimValueNative(handle, HALValue.kEnum, value, 0.0);
269  }
270
271  /**
272   * Sets a simulated value (boolean).
273   *
274   * @param handle simulated value handle
275   * @param value the value to set
276   */
277  public static void setSimValueBoolean(int handle, boolean value) {
278    setSimValueNative(handle, HALValue.kBoolean, value ? 1 : 0, 0.0);
279  }
280
281  /**
282   * Resets a simulated double or integral value to 0. Has no effect on other value types. Use this
283   * instead of Set(0) for resetting incremental sensor values like encoder counts or gyro
284   * accumulated angle to ensure correct behavior in a distributed system (e.g. WebSockets).
285   *
286   * @param handle simulated value handle
287   */
288  public static native void resetSimValue(int handle);
289
290  /** Utility class. */
291  private SimDeviceJNI() {}
292}