diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/SimDeviceSim.java b/hal/src/main/java/edu/wpi/first/hal/sim/SimDeviceSim.java new file mode 100644 index 0000000000..e46c811167 --- /dev/null +++ b/hal/src/main/java/edu/wpi/first/hal/sim/SimDeviceSim.java @@ -0,0 +1,94 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2019 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +package edu.wpi.first.hal.sim; + +import edu.wpi.first.hal.SimBoolean; +import edu.wpi.first.hal.SimDouble; +import edu.wpi.first.hal.SimEnum; +import edu.wpi.first.hal.SimValue; +import edu.wpi.first.hal.sim.mockdata.SimDeviceDataJNI; + +public class SimDeviceSim { + private final int m_handle; + + public SimDeviceSim(String name) { + m_handle = SimDeviceDataJNI.getSimDeviceHandle(name); + } + + public SimValue getValue(String name) { + int handle = SimDeviceDataJNI.getSimValueHandle(m_handle, name); + if (handle <= 0) { + return null; + } + return new SimValue(handle); + } + + public SimDouble getDouble(String name) { + int handle = SimDeviceDataJNI.getSimValueHandle(m_handle, name); + if (handle <= 0) { + return null; + } + return new SimDouble(handle); + } + + public SimEnum getEnum(String name) { + int handle = SimDeviceDataJNI.getSimValueHandle(m_handle, name); + if (handle <= 0) { + return null; + } + return new SimEnum(handle); + } + + public SimBoolean getBoolean(String name) { + int handle = SimDeviceDataJNI.getSimValueHandle(m_handle, name); + if (handle <= 0) { + return null; + } + return new SimBoolean(handle); + } + + public static String[] getEnumOptions(SimEnum val) { + return SimDeviceDataJNI.getSimValueEnumOptions(val.getNativeHandle()); + } + + public SimDeviceDataJNI.SimValueInfo[] enumerateValues() { + return SimDeviceDataJNI.enumerateSimValues(m_handle); + } + + public int getNativeHandle() { + return m_handle; + } + + public CallbackStore registerValueCreatedCallback(SimValueCallback callback, boolean initialNotify) { + int uid = SimDeviceDataJNI.registerSimValueCreatedCallback(m_handle, callback, initialNotify); + return new CallbackStore(uid, SimDeviceDataJNI::cancelSimValueCreatedCallback); + } + + public CallbackStore registerValueChangedCallback(SimValueCallback callback, boolean initialNotify) { + int uid = SimDeviceDataJNI.registerSimValueChangedCallback(m_handle, callback, initialNotify); + return new CallbackStore(uid, SimDeviceDataJNI::cancelSimValueChangedCallback); + } + + public static SimDeviceDataJNI.SimDeviceInfo[] enumerateDevices(String prefix) { + return SimDeviceDataJNI.enumerateSimDevices(prefix); + } + + public CallbackStore registerDeviceCreatedCallback(String prefix, SimDeviceCallback callback, boolean initialNotify) { + int uid = SimDeviceDataJNI.registerSimDeviceCreatedCallback(prefix, callback, initialNotify); + return new CallbackStore(uid, SimDeviceDataJNI::cancelSimDeviceCreatedCallback); + } + + public CallbackStore registerDeviceFreedCallback(String prefix, SimDeviceCallback callback) { + int uid = SimDeviceDataJNI.registerSimDeviceFreedCallback(prefix, callback); + return new CallbackStore(uid, SimDeviceDataJNI::cancelSimDeviceFreedCallback); + } + + public static void resetData() { + SimDeviceDataJNI.resetSimDeviceData(); + } +} diff --git a/hal/src/main/native/include/simulation/SimDeviceSim.h b/hal/src/main/native/include/simulation/SimDeviceSim.h new file mode 100644 index 0000000000..5705a08227 --- /dev/null +++ b/hal/src/main/native/include/simulation/SimDeviceSim.h @@ -0,0 +1,79 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2019 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +#pragma once + +#include +#include +#include +#include +#include + +#include "CallbackStore.h" +#include "hal/SimDevice.h" +#include "mockdata/SimDeviceData.h" + +namespace frc { +namespace sim { +class SimDeviceSim { + public: + explicit SimDeviceSim(const char* name) + : m_handle{HALSIM_GetSimDeviceHandle(name)} {} + + hal::SimValue GetValue(const char* name) const { + return HALSIM_GetSimValueHandle(m_handle, name); + } + + hal::SimDouble GetDouble(const char* name) const { + return HALSIM_GetSimValueHandle(m_handle, name); + } + + hal::SimEnum GetEnum(const char* name) const { + return HALSIM_GetSimValueHandle(m_handle, name); + } + + hal::SimBoolean GetBoolean(const char* name) const { + return HALSIM_GetSimValueHandle(m_handle, name); + } + + static std::vector GetEnumOptions(hal::SimEnum val) { + int32_t numOptions; + const char** options = HALSIM_GetSimValueEnumOptions(val, &numOptions); + std::vector rv; + rv.reserve(numOptions); + for (int32_t i = 0; i < numOptions; ++i) rv.emplace_back(options[i]); + return rv; + } + + template + void EnumerateValues(F callback) const { + return HALSIM_EnumerateSimValues( + m_handle, &callback, + [](const char* name, void* param, HAL_SimValueHandle handle, + HAL_Bool readonly, const struct HAL_Value* value) { + std::invoke(*static_cast(param), name, handle, readonly, value); + }); + } + + operator HAL_SimDeviceHandle() const { return m_handle; } + + template + static void EnumerateDevices(const char* prefix, F callback) { + return HALSIM_EnumerateSimDevices( + prefix, &callback, + [](const char* name, void* param, HAL_SimDeviceHandle handle) { + std::invoke(*static_cast(param), name, handle); + }); + } + + static void ResetData() { HALSIM_ResetSimDeviceData(); } + + private: + HAL_SimDeviceHandle m_handle; +}; +} // namespace sim +} // namespace frc diff --git a/hal/src/test/java/edu/wpi/first/hal/sim/SimDeviceSimTest.java b/hal/src/test/java/edu/wpi/first/hal/sim/SimDeviceSimTest.java new file mode 100644 index 0000000000..29452a0c76 --- /dev/null +++ b/hal/src/test/java/edu/wpi/first/hal/sim/SimDeviceSimTest.java @@ -0,0 +1,31 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2019 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +package edu.wpi.first.hal.sim; + +import org.junit.jupiter.api.Test; + +import edu.wpi.first.hal.SimBoolean; +import edu.wpi.first.hal.SimDevice; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class SimDeviceSimTest { + @Test + void testBasic() { + SimDevice dev = SimDevice.create("test"); + SimBoolean devBool = dev.createBoolean("bool", false, false); + + SimDeviceSim sim = new SimDeviceSim("test"); + SimBoolean simBool = sim.getBoolean("bool"); + + assertFalse(simBool.get()); + simBool.set(true); + assertTrue(devBool.get()); + } +} diff --git a/hal/src/test/native/cpp/sim/SimDeviceSimTest.cpp b/hal/src/test/native/cpp/sim/SimDeviceSimTest.cpp new file mode 100644 index 0000000000..ba0646d0da --- /dev/null +++ b/hal/src/test/native/cpp/sim/SimDeviceSimTest.cpp @@ -0,0 +1,40 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2019 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +#include + +#include "gtest/gtest.h" +#include "hal/SimDevice.h" +#include "simulation/SimDeviceSim.h" + +using namespace frc::sim; + +namespace hal { + +TEST(SimDeviceSimTests, TestBasic) { + SimDevice dev{"test"}; + SimBoolean devBool = dev.CreateBoolean("bool", false, false); + + SimDeviceSim sim{"test"}; + SimBoolean simBool = sim.GetBoolean("bool"); + EXPECT_FALSE(simBool.Get()); + simBool.Set(true); + EXPECT_TRUE(devBool.Get()); +} + +TEST(SimDeviceSimTests, TestEnumerateDevices) { + SimDevice dev{"test"}; + + bool foundit = false; + SimDeviceSim::EnumerateDevices( + "te", [&](const char* name, HAL_SimDeviceHandle handle) { + if (wpi::StringRef(name) == "test") foundit = true; + }); + EXPECT_TRUE(foundit); +} + +} // namespace hal