WPILibC++ 2023.4.3
SimDevice.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <stdint.h>
8
9#ifdef __cplusplus
10#include <initializer_list>
11#include <span>
12#include <string>
13#endif
14
15#include "hal/Types.h"
16#include "hal/Value.h"
17
18/**
19 * @defgroup hal_simdevice Simulator Device Framework
20 * @ingroup hal_capi
21 * HAL Simulator Device Framework. This enables creating simulation-only
22 * variables for higher level device access. For example, a device such as
23 * a SPI gyro can expose angle and rate variables to enable direct access
24 * from simulation extensions or user test code instead of requiring that
25 * the SPI bit-level protocol be implemented in simulation code.
26 *
27 * @{
28 */
29
30/**
31 * Direction of a simulated value (from the perspective of user code).
32 */
33// clang-format off
34HAL_ENUM(HAL_SimValueDirection) {
35 HAL_SimValueInput = 0, /**< input to user code from the simulator */
36 HAL_SimValueOutput, /**< output from user code to the simulator */
37 HAL_SimValueBidir /**< bidirectional between user code and simulator */
38};
39// clang-format on
40
41#ifdef __cplusplus
42extern "C" {
43#endif
44
45/**
46 * Creates a simulated device.
47 *
48 * The device name must be unique. 0 is returned if the device name already
49 * exists. If multiple instances of the same device are desired, recommend
50 * appending the instance/unique identifier in brackets to the base name,
51 * e.g. "device[1]".
52 *
53 * 0 is returned if not in simulation.
54 *
55 * @param name device name
56 * @return simulated device handle
57 */
59
60/**
61 * Frees a simulated device.
62 *
63 * This also allows the same device name to be used again.
64 * This also frees all the simulated values created on the device.
65 *
66 * @param handle simulated device handle
67 */
69
70/**
71 * Get the name of a simulated device
72 *
73 * @param handle simulated device handle
74 * @return name of the simulated device
75 */
77
78/**
79 * Creates a value on a simulated device.
80 *
81 * Returns 0 if not in simulation; this can be used to avoid calls
82 * to Set/Get functions.
83 *
84 * @param device simulated device handle
85 * @param name value name
86 * @param direction input/output/bidir (from perspective of user code)
87 * @param initialValue initial value
88 * @return simulated value handle
89 */
91 const char* name, int32_t direction,
92 const struct HAL_Value* initialValue);
93
94#ifdef __cplusplus
95extern "C++" {
97 const char* name,
98 int32_t direction,
99 const HAL_Value& initialValue) {
100 return HAL_CreateSimValue(device, name, direction, &initialValue);
101}
102} // extern "C++"
103#endif
104
105/**
106 * Creates an int value on a simulated device.
107 *
108 * Returns 0 if not in simulation; this can be used to avoid calls
109 * to Set/Get functions.
110 *
111 * @param device simulated device handle
112 * @param name value name
113 * @param direction input/output/bidir (from perspective of user code)
114 * @param initialValue initial value
115 * @return simulated value handle
116 */
118 const char* name,
119 int32_t direction,
120 int32_t initialValue) {
121 struct HAL_Value v = HAL_MakeInt(initialValue);
122 return HAL_CreateSimValue(device, name, direction, &v);
123}
124
125/**
126 * Creates a long value on a simulated device.
127 *
128 * Returns 0 if not in simulation; this can be used to avoid calls
129 * to Set/Get functions.
130 *
131 * @param device simulated device handle
132 * @param name value name
133 * @param direction input/output/bidir (from perspective of user code)
134 * @param initialValue initial value
135 * @return simulated value handle
136 */
138 const char* name,
139 int32_t direction,
140 int64_t initialValue) {
141 struct HAL_Value v = HAL_MakeLong(initialValue);
142 return HAL_CreateSimValue(device, name, direction, &v);
143}
144
145/**
146 * Creates a double value on a simulated device.
147 *
148 * Returns 0 if not in simulation; this can be used to avoid calls
149 * to Set/Get functions.
150 *
151 * @param device simulated device handle
152 * @param name value name
153 * @param direction input/output/bidir (from perspective of user code)
154 * @param initialValue initial value
155 * @return simulated value handle
156 */
158 const char* name,
159 int32_t direction,
160 double initialValue) {
161 struct HAL_Value v = HAL_MakeDouble(initialValue);
162 return HAL_CreateSimValue(device, name, direction, &v);
163}
164
165/**
166 * Creates an enumerated value on a simulated device.
167 *
168 * Enumerated values are always in the range 0 to numOptions-1.
169 *
170 * Returns 0 if not in simulation; this can be used to avoid calls
171 * to Set/Get functions.
172 *
173 * @param device simulated device handle
174 * @param name value name
175 * @param direction input/output/bidir (from perspective of user code)
176 * @param numOptions number of enumerated value options (length of options)
177 * @param options array of option descriptions
178 * @param initialValue initial value (selection)
179 * @return simulated value handle
180 */
182 const char* name, int32_t direction,
183 int32_t numOptions,
184 const char** options,
185 int32_t initialValue);
186
187/**
188 * Creates an enumerated value on a simulated device with double values.
189 *
190 * Enumerated values are always in the range 0 to numOptions-1.
191 *
192 * Returns 0 if not in simulation; this can be used to avoid calls
193 * to Set/Get functions.
194 *
195 * @param device simulated device handle
196 * @param name value name
197 * @param direction input/output/bidir (from perspective of user code)
198 * @param numOptions number of enumerated value options (length of options)
199 * @param options array of option descriptions
200 * @param optionValues array of option double values
201 * @param initialValue initial value (selection)
202 * @return simulated value handle
203 */
205 HAL_SimDeviceHandle device, const char* name, int32_t direction,
206 int32_t numOptions, const char** options, const double* optionValues,
207 int32_t initialValue);
208
209/**
210 * Creates a boolean value on a simulated device.
211 *
212 * Returns 0 if not in simulation; this can be used to avoid calls
213 * to Set/Get functions.
214 *
215 * @param device simulated device handle
216 * @param name value name
217 * @param direction input/output/bidir (from perspective of user code)
218 * @param initialValue initial value
219 * @return simulated value handle
220 */
222 const char* name,
223 int32_t direction,
224 HAL_Bool initialValue) {
225 struct HAL_Value v = HAL_MakeBoolean(initialValue);
226 return HAL_CreateSimValue(device, name, direction, &v);
227}
228
229/**
230 * Gets a simulated value.
231 *
232 * @param handle simulated value handle
233 * @param value value (output parameter)
234 */
236
237#ifdef __cplusplus
238extern "C++" {
240 HAL_Value v;
241 HAL_GetSimValue(handle, &v);
242 return v;
243}
244} // extern "C++"
245#endif
246
247/**
248 * Gets a simulated value (int).
249 *
250 * @param handle simulated value handle
251 * @return The current value
252 */
254 struct HAL_Value v;
255 HAL_GetSimValue(handle, &v);
256 return v.type == HAL_INT ? v.data.v_int : 0;
257}
258
259/**
260 * Gets a simulated value (long).
261 *
262 * @param handle simulated value handle
263 * @return The current value
264 */
266 struct HAL_Value v;
267 HAL_GetSimValue(handle, &v);
268 return v.type == HAL_LONG ? v.data.v_long : 0;
269}
270
271/**
272 * Gets a simulated value (double).
273 *
274 * @param handle simulated value handle
275 * @return The current value
276 */
278 struct HAL_Value v;
279 HAL_GetSimValue(handle, &v);
280 return v.type == HAL_DOUBLE ? v.data.v_double : 0.0;
281}
282
283/**
284 * Gets a simulated value (enum).
285 *
286 * @param handle simulated value handle
287 * @return The current value
288 */
290 struct HAL_Value v;
291 HAL_GetSimValue(handle, &v);
292 return v.type == HAL_ENUM ? v.data.v_enum : 0;
293}
294
295/**
296 * Gets a simulated value (boolean).
297 *
298 * @param handle simulated value handle
299 * @return The current value
300 */
302 struct HAL_Value v;
303 HAL_GetSimValue(handle, &v);
304 return v.type == HAL_BOOLEAN ? v.data.v_boolean : 0;
305}
306
307/**
308 * Sets a simulated value.
309 *
310 * @param handle simulated value handle
311 * @param value the value to set
312 */
314
315#ifdef __cplusplus
316extern "C++" {
317inline void HAL_SetSimValue(HAL_SimValueHandle handle, const HAL_Value& value) {
318 HAL_SetSimValue(handle, &value);
319}
320} // extern "C++"
321#endif
322
323/**
324 * Sets a simulated value (int).
325 *
326 * @param handle simulated value handle
327 * @param value the value to set
328 */
330 struct HAL_Value v = HAL_MakeInt(value);
331 HAL_SetSimValue(handle, &v);
332}
333
334/**
335 * Sets a simulated value (long).
336 *
337 * @param handle simulated value handle
338 * @param value the value to set
339 */
341 struct HAL_Value v = HAL_MakeLong(value);
342 HAL_SetSimValue(handle, &v);
343}
344
345/**
346 * Sets a simulated value (double).
347 *
348 * @param handle simulated value handle
349 * @param value the value to set
350 */
351inline void HAL_SetSimValueDouble(HAL_SimValueHandle handle, double value) {
352 struct HAL_Value v = HAL_MakeDouble(value);
353 HAL_SetSimValue(handle, &v);
354}
355
356/**
357 * Sets a simulated value (enum).
358 *
359 * @param handle simulated value handle
360 * @param value the value to set
361 */
363 struct HAL_Value v = HAL_MakeEnum(value);
364 HAL_SetSimValue(handle, &v);
365}
366
367/**
368 * Sets a simulated value (boolean).
369 *
370 * @param handle simulated value handle
371 * @param value the value to set
372 */
374 struct HAL_Value v = HAL_MakeBoolean(value);
375 HAL_SetSimValue(handle, &v);
376}
377
378/**
379 * Resets a simulated double or integral value to 0.
380 * Has no effect on other value types.
381 * Use this instead of Set(0) for resetting incremental sensor values like
382 * encoder counts or gyro accumulated angle to ensure correct behavior in a
383 * distributed system (e.g. WebSockets).
384 *
385 * @param handle simulated value handle
386 */
388
389/** @} */
390
391#ifdef __cplusplus
392} // extern "C"
393#endif
394
395#ifdef __cplusplus
396namespace hal {
397
398/**
399 * C++ wrapper around a HAL simulator value handle.
400 */
401class SimValue {
402 public:
403 /**
404 * Default constructor that results in an "empty" object that is false in
405 * a boolean context.
406 */
407 SimValue() = default;
408
409 /**
410 * Wraps a simulated value handle as returned by HAL_CreateSimValue().
411 *
412 * @param handle simulated value handle
413 */
414 /*implicit*/ SimValue(HAL_SimValueHandle val) // NOLINT
415 : m_handle(val) {}
416
417 /**
418 * Determine if handle is empty. Should be used to optimize out code paths
419 * that are taken/not taken in simulation.
420 *
421 * @return False if handle is empty, true if handle is valid.
422 */
423 explicit operator bool() const { return m_handle != HAL_kInvalidHandle; }
424
425 /**
426 * Get the internal device handle.
427 *
428 * @return internal handle
429 */
430 operator HAL_SimValueHandle() const { return m_handle; } // NOLINT
431
432 /**
433 * Gets the simulated value.
434 *
435 * @return The current value
436 */
437 HAL_Value GetValue() const { return HAL_GetSimValue(m_handle); }
438
439 /**
440 * Sets the simulated value.
441 *
442 * @param value the value to set
443 */
444 void SetValue(const HAL_Value& value) { HAL_SetSimValue(m_handle, value); }
445
446 protected:
448};
449
450/**
451 * C++ wrapper around a HAL simulator int value handle.
452 */
453class SimInt : public SimValue {
454 public:
455 /**
456 * Default constructor that results in an "empty" object that is false in
457 * a boolean context.
458 */
459 SimInt() = default;
460
461 /**
462 * Wraps a simulated value handle as returned by HAL_CreateSimValueInt().
463 *
464 * @param handle simulated value handle
465 */
466 /*implicit*/ SimInt(HAL_SimValueHandle val) // NOLINT
467 : SimValue(val) {}
468
469 /**
470 * Gets the simulated value.
471 *
472 * @return The current value
473 */
474 int32_t Get() const { return HAL_GetSimValueInt(m_handle); }
475
476 /**
477 * Sets the simulated value.
478 *
479 * @param value the value to set
480 */
481 void Set(int32_t value) { HAL_SetSimValueInt(m_handle, value); }
482
483 /**
484 * Resets the simulated value to 0. Use this instead of Set(0) for resetting
485 * incremental sensor values like encoder counts or gyro accumulated angle
486 * to ensure correct behavior in a distributed system (e.g. WebSockets).
487 */
488 void Reset() { HAL_ResetSimValue(m_handle); }
489};
490
491/**
492 * C++ wrapper around a HAL simulator long value handle.
493 */
494class SimLong : public SimValue {
495 public:
496 /**
497 * Default constructor that results in an "empty" object that is false in
498 * a boolean context.
499 */
500 SimLong() = default;
501
502 /**
503 * Wraps a simulated value handle as returned by HAL_CreateSimValueLong().
504 *
505 * @param handle simulated value handle
506 */
507 /*implicit*/ SimLong(HAL_SimValueHandle val) // NOLINT
508 : SimValue(val) {}
509
510 /**
511 * Gets the simulated value.
512 *
513 * @return The current value
514 */
515 int64_t Get() const { return HAL_GetSimValueLong(m_handle); }
516
517 /**
518 * Sets the simulated value.
519 *
520 * @param value the value to set
521 */
522 void Set(int64_t value) { HAL_SetSimValueLong(m_handle, value); }
523
524 /**
525 * Resets the simulated value to 0. Use this instead of Set(0) for resetting
526 * incremental sensor values like encoder counts or gyro accumulated angle
527 * to ensure correct behavior in a distributed system (e.g. WebSockets).
528 */
529 void Reset() { HAL_ResetSimValue(m_handle); }
530};
531
532/**
533 * C++ wrapper around a HAL simulator double value handle.
534 */
535class SimDouble : public SimValue {
536 public:
537 /**
538 * Default constructor that results in an "empty" object that is false in
539 * a boolean context.
540 */
541 SimDouble() = default;
542
543 /**
544 * Wraps a simulated value handle as returned by HAL_CreateSimValueDouble().
545 *
546 * @param handle simulated value handle
547 */
548 /*implicit*/ SimDouble(HAL_SimValueHandle val) // NOLINT
549 : SimValue(val) {}
550
551 /**
552 * Gets the simulated value.
553 *
554 * @return The current value
555 */
556 double Get() const { return HAL_GetSimValueDouble(m_handle); }
557
558 /**
559 * Sets the simulated value.
560 *
561 * @param value the value to set
562 */
563 void Set(double value) { HAL_SetSimValueDouble(m_handle, value); }
564
565 /**
566 * Resets the simulated value to 0. Use this instead of Set(0) for resetting
567 * incremental sensor values like encoder counts or gyro accumulated angle
568 * to ensure correct behavior in a distributed system (e.g. WebSockets).
569 */
570 void Reset() { HAL_ResetSimValue(m_handle); }
571};
572
573/**
574 * C++ wrapper around a HAL simulator enum value handle.
575 */
576class SimEnum : public SimValue {
577 public:
578 /**
579 * Default constructor that results in an "empty" object that is false in
580 * a boolean context.
581 */
582 SimEnum() = default;
583
584 /**
585 * Wraps a simulated value handle as returned by HAL_CreateSimValueEnum().
586 *
587 * @param handle simulated value handle
588 */
589 /*implicit*/ SimEnum(HAL_SimValueHandle val) // NOLINT
590 : SimValue(val) {}
591
592 /**
593 * Gets the simulated value.
594 *
595 * @return The current value
596 */
597 int32_t Get() const { return HAL_GetSimValueEnum(m_handle); }
598
599 /**
600 * Sets the simulated value.
601 *
602 * @param value the value to set
603 */
604 void Set(int32_t value) { HAL_SetSimValueEnum(m_handle, value); }
605};
606
607/**
608 * C++ wrapper around a HAL simulator boolean value handle.
609 */
610class SimBoolean : public SimValue {
611 public:
612 /**
613 * Default constructor that results in an "empty" object that is false in
614 * a boolean context.
615 */
616 SimBoolean() = default;
617
618 /**
619 * Wraps a simulated value handle as returned by HAL_CreateSimValueBoolean().
620 *
621 * @param handle simulated value handle
622 */
623 /*implicit*/ SimBoolean(HAL_SimValueHandle val) // NOLINT
624 : SimValue(val) {}
625
626 /**
627 * Gets the simulated value.
628 *
629 * @return The current value
630 */
631 bool Get() const { return HAL_GetSimValueBoolean(m_handle); }
632
633 /**
634 * Sets the simulated value.
635 *
636 * @param value the value to set
637 */
638 void Set(bool value) { HAL_SetSimValueBoolean(m_handle, value); }
639};
640
641/**
642 * A move-only C++ wrapper around a HAL simulator device handle.
643 */
644class SimDevice {
645 public:
646 /**
647 * Direction of a simulated value (from the perspective of user code).
648 */
649 enum Direction {
650 kInput = HAL_SimValueInput,
651 kOutput = HAL_SimValueOutput,
652 kBidir = HAL_SimValueBidir
653 };
654
655 /**
656 * Default constructor that results in an "empty" object that is false in
657 * a boolean context.
658 */
659 SimDevice() = default;
660
661 /**
662 * Creates a simulated device.
663 *
664 * The device name must be unique. Returns null if the device name
665 * already exists. If multiple instances of the same device are desired,
666 * recommend appending the instance/unique identifier in brackets to the base
667 * name, e.g. "device[1]".
668 *
669 * If not in simulation, results in an "empty" object that evaluates to false
670 * in a boolean context.
671 *
672 * @param name device name
673 */
674 explicit SimDevice(const char* name) : m_handle(HAL_CreateSimDevice(name)) {}
675
676 /**
677 * Creates a simulated device.
678 *
679 * The device name must be unique. Returns null if the device name
680 * already exists. This is a convenience method that appends index in
681 * brackets to the device name, e.g. passing index=1 results in "device[1]"
682 * for the device name.
683 *
684 * If not in simulation, results in an "empty" object that evaluates to false
685 * in a boolean context.
686 *
687 * @param name device name
688 * @param index device index number to append to name
689 */
690 SimDevice(const char* name, int index);
691
692 /**
693 * Creates a simulated device.
694 *
695 * The device name must be unique. Returns null if the device name
696 * already exists. This is a convenience method that appends index and
697 * channel in brackets to the device name, e.g. passing index=1 and channel=2
698 * results in "device[1,2]" for the device name.
699 *
700 * If not in simulation, results in an "empty" object that evaluates to false
701 * in a boolean context.
702 *
703 * @param name device name
704 * @param index device index number to append to name
705 * @param channel device channel number to append to name
706 */
707 SimDevice(const char* name, int index, int channel);
708
709 ~SimDevice() {
710 if (m_handle != HAL_kInvalidHandle) {
711 HAL_FreeSimDevice(m_handle);
712 }
713 }
714
715 SimDevice(const SimDevice&) = delete;
716 SimDevice& operator=(const SimDevice&) = delete;
717
718 SimDevice(SimDevice&& rhs) : m_handle(rhs.m_handle) {
719 rhs.m_handle = HAL_kInvalidHandle;
720 }
721
722 SimDevice& operator=(SimDevice&& rhs) {
723 m_handle = rhs.m_handle;
724 rhs.m_handle = HAL_kInvalidHandle;
725 return *this;
726 }
727
728 /**
729 * Determine if handle is empty. Should be used to optimize out code paths
730 * that are taken/not taken in simulation.
731 *
732 * @return False if handle is empty, true if handle is valid.
733 */
734 explicit operator bool() const { return m_handle != HAL_kInvalidHandle; }
735
736 /**
737 * Get the internal device handle.
738 *
739 * @return internal handle
740 */
741 operator HAL_SimDeviceHandle() const { return m_handle; } // NOLINT
742
743 /**
744 * Get the name of the simulated device.
745 *
746 * @return name
747 */
748 std::string GetName() const {
749 return std::string(HAL_GetSimDeviceName(m_handle));
750 }
751
752 /**
753 * Creates a value on the simulated device.
754 *
755 * If not in simulation, results in an "empty" object that evaluates to false
756 * in a boolean context.
757 *
758 * @param name value name
759 * @param direction input/output/bidir (from perspective of user code)
760 * @param initialValue initial value
761 * @return simulated value object
762 */
763 SimValue CreateValue(const char* name, int32_t direction,
764 const HAL_Value& initialValue) {
765 return HAL_CreateSimValue(m_handle, name, direction, &initialValue);
766 }
767
768 /**
769 * Creates an int value on the simulated device.
770 *
771 * If not in simulation, results in an "empty" object that evaluates to false
772 * in a boolean context.
773 *
774 * @param name value name
775 * @param direction input/output/bidir (from perspective of user code)
776 * @param initialValue initial value
777 * @return simulated double value object
778 */
779 SimInt CreateInt(const char* name, int32_t direction, int32_t initialValue) {
780 return HAL_CreateSimValueInt(m_handle, name, direction, initialValue);
781 }
782
783 /**
784 * Creates a long value on the simulated device.
785 *
786 * If not in simulation, results in an "empty" object that evaluates to false
787 * in a boolean context.
788 *
789 * @param name value name
790 * @param direction input/output/bidir (from perspective of user code)
791 * @param initialValue initial value
792 * @return simulated double value object
793 */
794 SimLong CreateLong(const char* name, int32_t direction,
795 int64_t initialValue) {
796 return HAL_CreateSimValueLong(m_handle, name, direction, initialValue);
797 }
798
799 /**
800 * Creates a double value on the simulated device.
801 *
802 * If not in simulation, results in an "empty" object that evaluates to false
803 * in a boolean context.
804 *
805 * @param name value name
806 * @param direction input/output/bidir (from perspective of user code)
807 * @param initialValue initial value
808 * @return simulated double value object
809 */
810 SimDouble CreateDouble(const char* name, int32_t direction,
811 double initialValue) {
812 return HAL_CreateSimValueDouble(m_handle, name, direction, initialValue);
813 }
814
815 /**
816 * Creates an enumerated value on the simulated device.
817 *
818 * Enumerated values are always in the range 0 to numOptions-1.
819 *
820 * If not in simulation, results in an "empty" object that evaluates to false
821 * in a boolean context.
822 *
823 * @param name value name
824 * @param direction input/output/bidir (from perspective of user code)
825 * @param options array of option descriptions
826 * @param initialValue initial value (selection)
827 * @return simulated enum value object
828 */
829 SimEnum CreateEnum(const char* name, int32_t direction,
830 std::initializer_list<const char*> options,
831 int32_t initialValue) {
832 return HAL_CreateSimValueEnum(m_handle, name, direction, options.size(),
833 const_cast<const char**>(options.begin()),
834 initialValue);
835 }
836
837 /**
838 * Creates an enumerated value on the simulated device.
839 *
840 * Enumerated values are always in the range 0 to numOptions-1.
841 *
842 * If not in simulation, results in an "empty" object that evaluates to false
843 * in a boolean context.
844 *
845 * @param name value name
846 * @param direction input/output/bidir (from perspective of user code)
847 * @param options array of option descriptions
848 * @param initialValue initial value (selection)
849 * @return simulated enum value object
850 */
851 SimEnum CreateEnum(const char* name, int32_t direction,
852 std::span<const char* const> options,
853 int32_t initialValue) {
854 return HAL_CreateSimValueEnum(m_handle, name, direction, options.size(),
855 const_cast<const char**>(options.data()),
856 initialValue);
857 }
858
859 /**
860 * Creates an enumerated value on the simulated device with double values.
861 *
862 * Enumerated values are always in the range 0 to numOptions-1.
863 *
864 * If not in simulation, results in an "empty" object that evaluates to false
865 * in a boolean context.
866 *
867 * @param name value name
868 * @param direction input/output/bidir (from perspective of user code)
869 * @param options array of option descriptions
870 * @param optionValues array of option values (must be the same size as
871 * options)
872 * @param initialValue initial value (selection)
873 * @return simulated enum value object
874 */
875 SimEnum CreateEnumDouble(const char* name, int32_t direction,
876 std::initializer_list<const char*> options,
877 std::initializer_list<double> optionValues,
878 int32_t initialValue) {
879 if (options.size() != optionValues.size()) {
880 return {};
881 }
883 m_handle, name, direction, options.size(),
884 const_cast<const char**>(options.begin()), optionValues.begin(),
885 initialValue);
886 }
887
888 /**
889 * Creates an enumerated value on the simulated device with double values.
890 *
891 * Enumerated values are always in the range 0 to numOptions-1.
892 *
893 * If not in simulation, results in an "empty" object that evaluates to false
894 * in a boolean context.
895 *
896 * @param name value name
897 * @param direction input/output/bidir (from perspective of user code)
898 * @param options array of option descriptions
899 * @param optionValues array of option values (must be the same size as
900 * options)
901 * @param initialValue initial value (selection)
902 * @return simulated enum value object
903 */
904 SimEnum CreateEnumDouble(const char* name, int32_t direction,
905 std::span<const char* const> options,
906 std::span<const double> optionValues,
907 int32_t initialValue) {
908 if (options.size() != optionValues.size()) {
909 return {};
910 }
912 m_handle, name, direction, options.size(),
913 const_cast<const char**>(options.data()), optionValues.data(),
914 initialValue);
915 }
916
917 /**
918 * Creates a boolean value on the simulated device.
919 *
920 * If not in simulation, results in an "empty" object that evaluates to false
921 * in a boolean context.
922 *
923 * @param name value name
924 * @param direction input/output/bidir (from perspective of user code)
925 * @param initialValue initial value
926 * @return simulated boolean value object
927 */
928 SimBoolean CreateBoolean(const char* name, int32_t direction,
929 bool initialValue) {
930 return HAL_CreateSimValueBoolean(m_handle, name, direction, initialValue);
931 }
932
933 protected:
935};
936
937} // namespace hal
938#endif // __cplusplus
struct HAL_Value HAL_MakeBoolean(HAL_Bool v)
Definition: Value.h:35
struct HAL_Value HAL_MakeDouble(double v)
Definition: Value.h:63
struct HAL_Value HAL_MakeEnum(int v)
Definition: Value.h:42
struct HAL_Value HAL_MakeInt(int v)
Definition: Value.h:49
struct HAL_Value HAL_MakeLong(int64_t v)
Definition: Value.h:56
@ HAL_DOUBLE
Definition: Value.h:13
@ HAL_LONG
Definition: Value.h:16
@ HAL_BOOLEAN
Definition: Value.h:12
@ HAL_INT
Definition: Value.h:15
Definition: core.h:1240
HAL_SimValueHandle HAL_CreateSimValueEnumDouble(HAL_SimDeviceHandle device, const char *name, int32_t direction, int32_t numOptions, const char **options, const double *optionValues, int32_t initialValue)
Creates an enumerated value on a simulated device with double values.
HAL_SimValueHandle HAL_CreateSimValueInt(HAL_SimDeviceHandle device, const char *name, int32_t direction, int32_t initialValue)
Creates an int value on a simulated device.
Definition: SimDevice.h:117
double HAL_GetSimValueDouble(HAL_SimValueHandle handle)
Gets a simulated value (double).
Definition: SimDevice.h:277
HAL_SimValueHandle HAL_CreateSimValue(HAL_SimDeviceHandle device, const char *name, int32_t direction, const struct HAL_Value *initialValue)
Creates a value on a simulated device.
int32_t HAL_GetSimValueEnum(HAL_SimValueHandle handle)
Gets a simulated value (enum).
Definition: SimDevice.h:289
HAL_SimValueHandle HAL_CreateSimValueBoolean(HAL_SimDeviceHandle device, const char *name, int32_t direction, HAL_Bool initialValue)
Creates a boolean value on a simulated device.
Definition: SimDevice.h:221
void HAL_SetSimValueEnum(HAL_SimValueHandle handle, int32_t value)
Sets a simulated value (enum).
Definition: SimDevice.h:362
void HAL_SetSimValueDouble(HAL_SimValueHandle handle, double value)
Sets a simulated value (double).
Definition: SimDevice.h:351
void HAL_FreeSimDevice(HAL_SimDeviceHandle handle)
Frees a simulated device.
void HAL_SetSimValue(HAL_SimValueHandle handle, const struct HAL_Value *value)
Sets a simulated value.
void HAL_SetSimValueLong(HAL_SimValueHandle handle, int64_t value)
Sets a simulated value (long).
Definition: SimDevice.h:340
HAL_SimDeviceHandle HAL_CreateSimDevice(const char *name)
Creates a simulated device.
HAL_SimValueHandle HAL_CreateSimValueEnum(HAL_SimDeviceHandle device, const char *name, int32_t direction, int32_t numOptions, const char **options, int32_t initialValue)
Creates an enumerated value on a simulated device.
HAL_SimValueHandle HAL_CreateSimValueDouble(HAL_SimDeviceHandle device, const char *name, int32_t direction, double initialValue)
Creates a double value on a simulated device.
Definition: SimDevice.h:157
HAL_SimValueHandle HAL_CreateSimValueLong(HAL_SimDeviceHandle device, const char *name, int32_t direction, int64_t initialValue)
Creates a long value on a simulated device.
Definition: SimDevice.h:137
void HAL_SetSimValueInt(HAL_SimValueHandle handle, int value)
Sets a simulated value (int).
Definition: SimDevice.h:329
HAL_Bool HAL_GetSimValueBoolean(HAL_SimValueHandle handle)
Gets a simulated value (boolean).
Definition: SimDevice.h:301
void HAL_GetSimValue(HAL_SimValueHandle handle, struct HAL_Value *value)
Gets a simulated value.
int64_t HAL_GetSimValueLong(HAL_SimValueHandle handle)
Gets a simulated value (long).
Definition: SimDevice.h:265
HAL_ENUM(HAL_SimValueDirection)
Direction of a simulated value (from the perspective of user code).
Definition: SimDevice.h:34
const char * HAL_GetSimDeviceName(HAL_SimDeviceHandle handle)
Get the name of a simulated device.
void HAL_SetSimValueBoolean(HAL_SimValueHandle handle, HAL_Bool value)
Sets a simulated value (boolean).
Definition: SimDevice.h:373
int32_t HAL_GetSimValueInt(HAL_SimValueHandle handle)
Gets a simulated value (int).
Definition: SimDevice.h:253
void HAL_ResetSimValue(HAL_SimValueHandle handle)
Resets a simulated double or integral value to 0.
int32_t HAL_Bool
Definition: Types.h:73
HAL_Handle HAL_SimDeviceHandle
Definition: Types.h:53
HAL_Handle HAL_SimValueHandle
Definition: Types.h:55
#define HAL_kInvalidHandle
Definition: Types.h:15
::int32_t int32_t
Definition: Meta.h:57
::int64_t int64_t
Definition: Meta.h:59
WPILib Hardware Abstraction Layer (HAL) namespace.
Definition: ChipObject.h:40
constexpr const char * name(const T &)
HAL Entry Value.
Definition: Value.h:20
double v_double
Definition: Value.h:26
int64_t v_long
Definition: Value.h:25
HAL_Bool v_boolean
Definition: Value.h:22
int32_t v_int
Definition: Value.h:24
enum HAL_Type type
Definition: Value.h:28
union HAL_Value::@0 data
int32_t v_enum
Definition: Value.h:23