From e504b3ecbd1e9126006a103e8b3967b51aa96f1a Mon Sep 17 00:00:00 2001 From: Austin Shalit Date: Sun, 5 Apr 2020 23:07:17 -0700 Subject: [PATCH] [command] Add NetworkButton (#2373) Closes #2371 --- .../command/button/NetworkButton.java | 53 +++++++++++++++++++ .../cpp/frc2/command/button/NetworkButton.cpp | 23 ++++++++ .../frc2/command/button/NetworkButton.h | 48 +++++++++++++++++ .../command/button/NetworkButtonTest.java | 52 ++++++++++++++++++ .../frc2/command/button/NetworkButtonTest.cpp | 46 ++++++++++++++++ 5 files changed, 222 insertions(+) create mode 100644 wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/button/NetworkButton.java create mode 100644 wpilibNewCommands/src/main/native/cpp/frc2/command/button/NetworkButton.cpp create mode 100644 wpilibNewCommands/src/main/native/include/frc2/command/button/NetworkButton.h create mode 100644 wpilibNewCommands/src/test/java/edu/wpi/first/wpilibj2/command/button/NetworkButtonTest.java create mode 100644 wpilibNewCommands/src/test/native/cpp/frc2/command/button/NetworkButtonTest.cpp diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/button/NetworkButton.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/button/NetworkButton.java new file mode 100644 index 0000000000..4cb1859fc6 --- /dev/null +++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/button/NetworkButton.java @@ -0,0 +1,53 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2008-2020 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.wpilibj2.command.button; + +import edu.wpi.first.networktables.NetworkTable; +import edu.wpi.first.networktables.NetworkTableEntry; +import edu.wpi.first.networktables.NetworkTableInstance; + +/** + * A {@link Button} that uses a {@link NetworkTable} boolean field. + */ +public class NetworkButton extends Button { + private final NetworkTableEntry m_entry; + + /** + * Creates a NetworkButton that commands can be bound to. + * + * @param entry The entry that is the value. + */ + public NetworkButton(NetworkTableEntry entry) { + m_entry = entry; + } + + /** + * Creates a NetworkButton that commands can be bound to. + * + * @param table The table where the networktable value is located. + * @param field The field that is the value. + */ + public NetworkButton(NetworkTable table, String field) { + this(table.getEntry(field)); + } + + /** + * Creates a NetworkButton that commands can be bound to. + * + * @param table The table where the networktable value is located. + * @param field The field that is the value. + */ + public NetworkButton(String table, String field) { + this(NetworkTableInstance.getDefault().getTable(table), field); + } + + @Override + public boolean get() { + return m_entry.getInstance().isConnected() && m_entry.getBoolean(false); + } +} diff --git a/wpilibNewCommands/src/main/native/cpp/frc2/command/button/NetworkButton.cpp b/wpilibNewCommands/src/main/native/cpp/frc2/command/button/NetworkButton.cpp new file mode 100644 index 0000000000..01214e025f --- /dev/null +++ b/wpilibNewCommands/src/main/native/cpp/frc2/command/button/NetworkButton.cpp @@ -0,0 +1,23 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2011-2020 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 "frc2/command/button/NetworkButton.h" + +using namespace frc2; + +NetworkButton::NetworkButton(nt::NetworkTableEntry entry) + : Button([entry] { + return entry.GetInstance().IsConnected() && entry.GetBoolean(false); + }) {} + +NetworkButton::NetworkButton(std::shared_ptr table, + const wpi::Twine& field) + : NetworkButton(table->GetEntry(field)) {} + +NetworkButton::NetworkButton(const wpi::Twine& table, const wpi::Twine& field) + : NetworkButton(nt::NetworkTableInstance::GetDefault().GetTable(table), + field) {} diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/button/NetworkButton.h b/wpilibNewCommands/src/main/native/include/frc2/command/button/NetworkButton.h new file mode 100644 index 0000000000..9c09dd1d58 --- /dev/null +++ b/wpilibNewCommands/src/main/native/include/frc2/command/button/NetworkButton.h @@ -0,0 +1,48 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2011-2020 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 "Button.h" + +namespace frc2 { +/** + * A {@link Button} that uses a {@link NetworkTable} boolean field. + */ +class NetworkButton : public Button { + public: + /** + * Creates a NetworkButton that commands can be bound to. + * + * @param entry The entry that is the value. + */ + explicit NetworkButton(nt::NetworkTableEntry entry); + + /** + * Creates a NetworkButton that commands can be bound to. + * + * @param table The table where the networktable value is located. + * @param field The field that is the value. + */ + NetworkButton(std::shared_ptr table, + const wpi::Twine& field); + + /** + * Creates a NetworkButton that commands can be bound to. + * + * @param table The table where the networktable value is located. + * @param field The field that is the value. + */ + NetworkButton(const wpi::Twine& table, const wpi::Twine& field); +}; +} // namespace frc2 diff --git a/wpilibNewCommands/src/test/java/edu/wpi/first/wpilibj2/command/button/NetworkButtonTest.java b/wpilibNewCommands/src/test/java/edu/wpi/first/wpilibj2/command/button/NetworkButtonTest.java new file mode 100644 index 0000000000..26a4a1cfd2 --- /dev/null +++ b/wpilibNewCommands/src/test/java/edu/wpi/first/wpilibj2/command/button/NetworkButtonTest.java @@ -0,0 +1,52 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2020 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.wpilibj2.command.button; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import edu.wpi.first.networktables.NetworkTableInstance; +import edu.wpi.first.wpilibj2.command.CommandScheduler; +import edu.wpi.first.wpilibj2.command.CommandTestBase; + +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +class NetworkButtonTest extends CommandTestBase { + @BeforeEach + void setup() { + NetworkTableInstance.getDefault().startLocal(); + } + + @AfterEach + void teardown() { + NetworkTableInstance.getDefault().deleteAllEntries(); + NetworkTableInstance.getDefault().stopLocal(); + } + + @Test + void setNetworkButtonTest() { + var scheduler = CommandScheduler.getInstance(); + var commandHolder = new MockCommandHolder(true); + var command = commandHolder.getMock(); + var entry = NetworkTableInstance.getDefault() + .getTable("TestTable") + .getEntry("Test"); + + var button = new NetworkButton("TestTable", "Test"); + entry.setBoolean(false); + button.whenPressed(command); + scheduler.run(); + verify(command, never()).schedule(true); + entry.setBoolean(true); + scheduler.run(); + scheduler.run(); + verify(command).schedule(true); + } +} diff --git a/wpilibNewCommands/src/test/native/cpp/frc2/command/button/NetworkButtonTest.cpp b/wpilibNewCommands/src/test/native/cpp/frc2/command/button/NetworkButtonTest.cpp new file mode 100644 index 0000000000..18fef35886 --- /dev/null +++ b/wpilibNewCommands/src/test/native/cpp/frc2/command/button/NetworkButtonTest.cpp @@ -0,0 +1,46 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2020 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 "../CommandTestBase.h" +#include "frc2/command/CommandScheduler.h" +#include "frc2/command/RunCommand.h" +#include "frc2/command/WaitUntilCommand.h" +#include "frc2/command/button/NetworkButton.h" +#include "gtest/gtest.h" + +using namespace frc2; + +class NetworkButtonTest : public CommandTestBase { + void SetUp() override { nt::NetworkTableInstance::GetDefault().StartLocal(); } + + void TearDown() override { + nt::NetworkTableInstance::GetDefault().DeleteAllEntries(); + nt::NetworkTableInstance::GetDefault().StopLocal(); + } +}; + +TEST_F(NetworkButtonTest, SetNetworkButtonTest) { + auto& scheduler = CommandScheduler::GetInstance(); + auto entry = nt::NetworkTableInstance::GetDefault() + .GetTable("TestTable") + ->GetEntry("Test"); + bool finished = false; + + WaitUntilCommand command([&finished] { return finished; }); + + NetworkButton("TestTable", "Test").WhenActive(&command); + scheduler.Run(); + EXPECT_FALSE(scheduler.IsScheduled(&command)); + entry.SetBoolean(true); + scheduler.Run(); + EXPECT_TRUE(scheduler.IsScheduled(&command)); + finished = true; + scheduler.Run(); + EXPECT_FALSE(scheduler.IsScheduled(&command)); +}