diff --git a/wpilibc/src/main/native/cpp/simulation/SendableChooserSim.cpp b/wpilibc/src/main/native/cpp/simulation/SendableChooserSim.cpp new file mode 100644 index 0000000000..0b15b878e3 --- /dev/null +++ b/wpilibc/src/main/native/cpp/simulation/SendableChooserSim.cpp @@ -0,0 +1,24 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#include "frc/simulation/SendableChooserSim.h" + +using namespace frc::sim; + +SendableChooserSim::SendableChooserSim(std::string_view path) + : SendableChooserSim(nt::NetworkTableInstance::GetDefault(), path) {} + +SendableChooserSim::SendableChooserSim(nt::NetworkTableInstance inst, + std::string_view path) { + if constexpr (RobotBase::IsSimulation()) { + m_publisher = + inst.GetStringTopic(fmt::format("{}{}", path, "selected")).Publish(); + } +} + +void SendableChooserSim::SetSelected(std::string_view option) { + if constexpr (RobotBase::IsSimulation()) { + m_publisher.Set(option); + } +} diff --git a/wpilibc/src/main/native/include/frc/simulation/SendableChooserSim.h b/wpilibc/src/main/native/include/frc/simulation/SendableChooserSim.h new file mode 100644 index 0000000000..6d4b605332 --- /dev/null +++ b/wpilibc/src/main/native/include/frc/simulation/SendableChooserSim.h @@ -0,0 +1,46 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#pragma once + +#include + +#include +#include + +#include "frc/RobotBase.h" + +namespace frc::sim { + +/** + * Class that facilitates control of a SendableChooser's selected option in + * simulation. + */ +class SendableChooserSim { + public: + /** + * Constructs a SendableChooserSim. + * + * @param path The path where the SendableChooser is published. + */ + explicit SendableChooserSim(std::string_view path); + + /** + * Constructs a SendableChooserSim. + * + * @param inst The NetworkTables instance. + * @param path The path where the SendableChooser is published. + */ + SendableChooserSim(nt::NetworkTableInstance inst, std::string_view path); + + /** + * Set the selected option. + * @param option The option. + */ + void SetSelected(std::string_view option); + + private: + nt::StringPublisher m_publisher; +}; +} // namespace frc::sim diff --git a/wpilibc/src/test/native/cpp/smartdashboard/SendableChooserTest.cpp b/wpilibc/src/test/native/cpp/smartdashboard/SendableChooserTest.cpp index fdcf1d127a..702735c3ea 100644 --- a/wpilibc/src/test/native/cpp/smartdashboard/SendableChooserTest.cpp +++ b/wpilibc/src/test/native/cpp/smartdashboard/SendableChooserTest.cpp @@ -2,6 +2,7 @@ // Open Source Software; you can modify and/or share it under the terms of // the WPILib BSD license file in the root directory of this project. +#include #include #include @@ -16,22 +17,18 @@ class SendableChooserTest : public ::testing::TestWithParam {}; TEST_P(SendableChooserTest, ReturnsSelected) { frc::SendableChooser chooser; + frc::sim::SendableChooserSim chooserSim{ + fmt::format("/SmartDashboard/ReturnsSelectedChooser{}/", GetParam())}; for (int i = 1; i <= 3; i++) { chooser.AddOption(std::to_string(i), i); } chooser.SetDefaultOption("0", 0); - auto pub = - nt::NetworkTableInstance::GetDefault() - .GetStringTopic(fmt::format( - "/SmartDashboard/ReturnsSelectedChooser{}/selected", GetParam())) - .Publish(); - frc::SmartDashboard::PutData( fmt::format("ReturnsSelectedChooser{}", GetParam()), &chooser); frc::SmartDashboard::UpdateValues(); - pub.Set(std::to_string(GetParam())); + chooserSim.SetSelected(std::to_string(GetParam())); frc::SmartDashboard::UpdateValues(); EXPECT_EQ(GetParam(), chooser.GetSelected()); } @@ -62,6 +59,8 @@ TEST(SendableChooserTest, TEST(SendableChooserTest, ChangeListener) { frc::SendableChooser chooser; + frc::sim::SendableChooserSim chooserSim{ + "/SmartDashboard/ChangeListenerChooser/"}; for (int i = 1; i <= 3; i++) { chooser.AddOption(std::to_string(i), i); @@ -71,7 +70,7 @@ TEST(SendableChooserTest, ChangeListener) { frc::SmartDashboard::PutData("ChangeListenerChooser", &chooser); frc::SmartDashboard::UpdateValues(); - frc::SmartDashboard::PutString("ChangeListenerChooser/selected", "3"); + chooserSim.SetSelected("3"); frc::SmartDashboard::UpdateValues(); EXPECT_EQ(3, currentVal); diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SendableChooserSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SendableChooserSim.java new file mode 100644 index 0000000000..81422c99bc --- /dev/null +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SendableChooserSim.java @@ -0,0 +1,53 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +package edu.wpi.first.wpilibj.simulation; + +import edu.wpi.first.networktables.NetworkTableInstance; +import edu.wpi.first.networktables.StringPublisher; +import edu.wpi.first.wpilibj.RobotBase; + +/** Class that facilitates control of a SendableChooser's selected option in simulation. */ +public class SendableChooserSim implements AutoCloseable { + private StringPublisher m_publisher; + + /** + * Constructs a SendableChooserSim. + * + * @param path The path where the SendableChooser is published. + */ + public SendableChooserSim(String path) { + this(NetworkTableInstance.getDefault(), path); + } + + /** + * Constructs a SendableChooserSim. + * + * @param inst The NetworkTables instance. + * @param path The path where the SendableChooser is published. + */ + public SendableChooserSim(NetworkTableInstance inst, String path) { + if (RobotBase.isSimulation()) { + m_publisher = inst.getStringTopic(path + "selected").publish(); + } + } + + @Override + public void close() { + if (RobotBase.isSimulation()) { + m_publisher.close(); + } + } + + /** + * Set the selected option. + * + * @param option The option. + */ + public void setSelected(String option) { + if (RobotBase.isSimulation()) { + m_publisher.set(option); + } + } +} diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooserTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooserTest.java index d97d54c243..d8e3f8fbb9 100644 --- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooserTest.java +++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooserTest.java @@ -8,6 +8,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import edu.wpi.first.networktables.NetworkTableInstance; +import edu.wpi.first.wpilibj.simulation.SendableChooserSim; import java.util.concurrent.atomic.AtomicInteger; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -28,10 +29,9 @@ class SendableChooserTest { @ParameterizedTest void returnsSelected(int toSelect) { try (var chooser = new SendableChooser(); - var publisher = - m_inst - .getStringTopic("/SmartDashboard/returnsSelectedChooser" + toSelect + "/selected") - .publish()) { + var chooserSim = + new SendableChooserSim( + m_inst, "/SmartDashboard/returnsSelectedChooser" + toSelect + "/")) { for (int i = 1; i <= 3; i++) { chooser.addOption(String.valueOf(i), i); } @@ -39,7 +39,7 @@ class SendableChooserTest { SmartDashboard.putData("returnsSelectedChooser" + toSelect, chooser); SmartDashboard.updateValues(); - publisher.set(String.valueOf(toSelect)); + chooserSim.setSelected(String.valueOf(toSelect)); SmartDashboard.updateValues(); assertEquals(toSelect, chooser.getSelected()); } @@ -70,7 +70,8 @@ class SendableChooserTest { @Test void testChangeListener() { - try (var chooser = new SendableChooser()) { + try (var chooser = new SendableChooser(); + var chooserSim = new SendableChooserSim(m_inst, "/SmartDashboard/changeListenerChooser/")) { for (int i = 1; i <= 3; i++) { chooser.addOption(String.valueOf(i), i); } @@ -79,7 +80,7 @@ class SendableChooserTest { SmartDashboard.putData("changeListenerChooser", chooser); SmartDashboard.updateValues(); - SmartDashboard.putString("changeListenerChooser/selected", "3"); + chooserSim.setSelected("3"); SmartDashboard.updateValues(); assertEquals(3, currentVal.get()); }