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 identifer 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  private static native int createSimValueNative(
037      int device, String name, int direction, int type, long value1, double value2);
038
039  /**
040   * Creates a value on a simulated device.
041   *
042   * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
043   *
044   * @param device simulated device handle
045   * @param name value name
046   * @param readonly if the value should not be written from simulation side
047   * @param initialValue initial value
048   * @return simulated value handle
049   * @deprecated Use direction-taking function instead
050   */
051  @Deprecated
052  public static int createSimValue(
053      int device, String name, boolean readonly, HALValue initialValue) {
054    return createSimValueNative(
055        device,
056        name,
057        readonly ? kOutput : kInput,
058        initialValue.getType(),
059        initialValue.getNativeLong(),
060        initialValue.getNativeDouble());
061  }
062
063  /**
064   * Creates a value on a simulated device.
065   *
066   * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
067   *
068   * @param device simulated device handle
069   * @param name value name
070   * @param direction input/output/bidir (from perspective of user code)
071   * @param initialValue initial value
072   * @return simulated value handle
073   */
074  public static int createSimValue(int device, String name, int direction, HALValue initialValue) {
075    return createSimValueNative(
076        device,
077        name,
078        direction,
079        initialValue.getType(),
080        initialValue.getNativeLong(),
081        initialValue.getNativeDouble());
082  }
083
084  /**
085   * Creates an int value on a simulated device.
086   *
087   * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
088   *
089   * @param device simulated device handle
090   * @param name value name
091   * @param direction input/output/bidir (from perspective of user code)
092   * @param initialValue initial value
093   * @return simulated value handle
094   */
095  public static int createSimValueInt(int device, String name, int direction, int initialValue) {
096    return createSimValueNative(device, name, direction, HALValue.kInt, initialValue, 0.0);
097  }
098
099  /**
100   * Creates a long value on a simulated device.
101   *
102   * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
103   *
104   * @param device simulated device handle
105   * @param name value name
106   * @param direction input/output/bidir (from perspective of user code)
107   * @param initialValue initial value
108   * @return simulated value handle
109   */
110  public static int createSimValueLong(int device, String name, int direction, long initialValue) {
111    return createSimValueNative(device, name, direction, HALValue.kLong, initialValue, 0.0);
112  }
113
114  /**
115   * Creates a double value on a simulated device.
116   *
117   * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
118   *
119   * @param device simulated device handle
120   * @param name value name
121   * @param readonly if the value should not be written from simulation side
122   * @param initialValue initial value
123   * @return simulated value handle
124   * @deprecated Use direction-taking function instead
125   */
126  @Deprecated
127  public static int createSimValueDouble(
128      int device, String name, boolean readonly, double initialValue) {
129    return createSimValueNative(
130        device, name, readonly ? kOutput : kInput, HALValue.kDouble, 0, initialValue);
131  }
132
133  /**
134   * Creates a double value on a simulated device.
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 initialValue initial value
142   * @return simulated value handle
143   */
144  public static int createSimValueDouble(
145      int device, String name, int direction, double initialValue) {
146    return createSimValueNative(device, name, direction, HALValue.kDouble, 0, initialValue);
147  }
148
149  /**
150   * Creates an enumerated value on a simulated device.
151   *
152   * <p>Enumerated values are always in the range 0 to numOptions-1.
153   *
154   * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
155   *
156   * @param device simulated device handle
157   * @param name value name
158   * @param readonly if the value should not be written from simulation side
159   * @param options array of option descriptions
160   * @param initialValue initial value (selection)
161   * @return simulated value handle
162   * @deprecated Use direction-taking function instead
163   */
164  @Deprecated
165  public static int createSimValueEnum(
166      int device, String name, boolean readonly, String[] options, int initialValue) {
167    return createSimValueEnum(device, name, readonly ? kOutput : kInput, options, initialValue);
168  }
169
170  /**
171   * Creates an enumerated value on a simulated device.
172   *
173   * <p>Enumerated values are always in the range 0 to numOptions-1.
174   *
175   * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
176   *
177   * @param device simulated device handle
178   * @param name value name
179   * @param direction input/output/bidir (from perspective of user code)
180   * @param options array of option descriptions
181   * @param initialValue initial value (selection)
182   * @return simulated value handle
183   */
184  public static native int createSimValueEnum(
185      int device, String name, int direction, String[] options, int initialValue);
186
187  /**
188   * Creates an enumerated value on a simulated device with double values.
189   *
190   * <p>Enumerated values are always in the range 0 to numOptions-1.
191   *
192   * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
193   *
194   * @param device simulated device handle
195   * @param name value name
196   * @param direction input/output/bidir (from perspective of user code)
197   * @param options array of option descriptions
198   * @param optionValues array of option values (must be the same size as options)
199   * @param initialValue initial value (selection)
200   * @return simulated value handle
201   */
202  public static native int createSimValueEnumDouble(
203      int device,
204      String name,
205      int direction,
206      String[] options,
207      double[] optionValues,
208      int initialValue);
209
210  /**
211   * Creates a boolean value on a simulated device.
212   *
213   * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
214   *
215   * @param device simulated device handle
216   * @param name value name
217   * @param readonly if the value should not be written from simulation side
218   * @param initialValue initial value
219   * @return simulated value handle
220   * @deprecated Use direction-taking function instead
221   */
222  @Deprecated
223  public static int createSimValueBoolean(
224      int device, String name, boolean readonly, boolean initialValue) {
225    return createSimValueNative(
226        device, name, readonly ? kOutput : kInput, HALValue.kBoolean, initialValue ? 1 : 0, 0.0);
227  }
228
229  /**
230   * Creates a boolean value on a simulated device.
231   *
232   * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
233   *
234   * @param device simulated device handle
235   * @param name value name
236   * @param direction input/output/bidir (from perspective of user code)
237   * @param initialValue initial value
238   * @return simulated value handle
239   */
240  public static int createSimValueBoolean(
241      int device, String name, int direction, boolean initialValue) {
242    return createSimValueNative(
243        device, name, direction, HALValue.kBoolean, initialValue ? 1 : 0, 0.0);
244  }
245
246  /**
247   * Gets a simulated value.
248   *
249   * @param handle simulated value handle
250   * @return The current value
251   */
252  public static native HALValue getSimValue(int handle);
253
254  /**
255   * Gets a simulated value (int).
256   *
257   * @param handle simulated value handle
258   * @return The current value
259   */
260  public static native int getSimValueInt(int handle);
261
262  /**
263   * Gets a simulated value (long).
264   *
265   * @param handle simulated value handle
266   * @return The current value
267   */
268  public static native long getSimValueLong(int handle);
269
270  /**
271   * Gets a simulated value (double).
272   *
273   * @param handle simulated value handle
274   * @return The current value
275   */
276  public static native double getSimValueDouble(int handle);
277
278  /**
279   * Gets a simulated value (enum).
280   *
281   * @param handle simulated value handle
282   * @return The current value
283   */
284  public static native int getSimValueEnum(int handle);
285
286  /**
287   * Gets a simulated value (boolean).
288   *
289   * @param handle simulated value handle
290   * @return The current value
291   */
292  public static native boolean getSimValueBoolean(int handle);
293
294  private static native void setSimValueNative(int handle, int type, long value1, double value2);
295
296  /**
297   * Sets a simulated value.
298   *
299   * @param handle simulated value handle
300   * @param value the value to set
301   */
302  public static void setSimValue(int handle, HALValue value) {
303    setSimValueNative(handle, value.getType(), value.getNativeLong(), value.getNativeDouble());
304  }
305
306  /**
307   * Sets a simulated value (int).
308   *
309   * @param handle simulated value handle
310   * @param value the value to set
311   */
312  public static void setSimValueInt(int handle, int value) {
313    setSimValueNative(handle, HALValue.kInt, value, 0.0);
314  }
315
316  /**
317   * Sets a simulated value (long).
318   *
319   * @param handle simulated value handle
320   * @param value the value to set
321   */
322  public static void setSimValueLong(int handle, long value) {
323    setSimValueNative(handle, HALValue.kLong, value, 0.0);
324  }
325
326  /**
327   * Sets a simulated value (double).
328   *
329   * @param handle simulated value handle
330   * @param value the value to set
331   */
332  public static void setSimValueDouble(int handle, double value) {
333    setSimValueNative(handle, HALValue.kDouble, 0, value);
334  }
335
336  /**
337   * Sets a simulated value (enum).
338   *
339   * @param handle simulated value handle
340   * @param value the value to set
341   */
342  public static void setSimValueEnum(int handle, int value) {
343    setSimValueNative(handle, HALValue.kEnum, value, 0.0);
344  }
345
346  /**
347   * Sets a simulated value (boolean).
348   *
349   * @param handle simulated value handle
350   * @param value the value to set
351   */
352  public static void setSimValueBoolean(int handle, boolean value) {
353    setSimValueNative(handle, HALValue.kBoolean, value ? 1 : 0, 0.0);
354  }
355
356  /**
357   * Resets a simulated double or integral value to 0. Has no effect on other value types. Use this
358   * instead of Set(0) for resetting incremental sensor values like encoder counts or gyro
359   * accumulated angle to ensure correct behavior in a distributed system (e.g. WebSockets).
360   *
361   * @param handle simulated value handle
362   */
363  public static native void resetSimValue(int handle);
364}