diff --git a/wpilibc/src/main/native/cpp/simulation/AlertSim.cpp b/wpilibc/src/main/native/cpp/simulation/AlertSim.cpp index 0a1ba556e7..3f6b437093 100644 --- a/wpilibc/src/main/native/cpp/simulation/AlertSim.cpp +++ b/wpilibc/src/main/native/cpp/simulation/AlertSim.cpp @@ -4,6 +4,7 @@ #include "wpi/simulation/AlertSim.hpp" +#include #include #include @@ -35,6 +36,12 @@ std::vector AlertSim::GetAll() { return infos; } +std::vector AlertSim::GetActive() { + auto infos = GetAll(); + std::erase_if(infos, [](const AlertInfo& info) { return !info.isActive(); }); + return infos; +} + void AlertSim::ResetData() { HALSIM_ResetAlertData(); } diff --git a/wpilibc/src/main/native/include/wpi/simulation/AlertSim.hpp b/wpilibc/src/main/native/include/wpi/simulation/AlertSim.hpp index 2f6aea6057..cba0c6c7e2 100644 --- a/wpilibc/src/main/native/include/wpi/simulation/AlertSim.hpp +++ b/wpilibc/src/main/native/include/wpi/simulation/AlertSim.hpp @@ -55,12 +55,19 @@ class AlertSim final { static int32_t GetCount(); /** - * Gets detailed information about each alert. + * Gets detailed information about each alert (including inactive ones). * * @return Alerts */ static std::vector GetAll(); + /** + * Gets detailed information about all active alerts. + * + * @return Alerts + */ + static std::vector GetActive(); + /** * Resets all alert simulation data. */ diff --git a/wpilibc/src/main/python/semiwrap/simulation/AlertSim.yml b/wpilibc/src/main/python/semiwrap/simulation/AlertSim.yml index 97b49840e1..d4f9a264af 100644 --- a/wpilibc/src/main/python/semiwrap/simulation/AlertSim.yml +++ b/wpilibc/src/main/python/semiwrap/simulation/AlertSim.yml @@ -3,6 +3,7 @@ classes: methods: GetCount: GetAll: + GetActive: ResetData: wpi::sim::AlertSim::AlertInfo: attributes: diff --git a/wpilibc/src/test/native/cpp/simulation/AlertSimTest.cpp b/wpilibc/src/test/native/cpp/simulation/AlertSimTest.cpp index 78be8c0aff..b00730cd8d 100644 --- a/wpilibc/src/test/native/cpp/simulation/AlertSimTest.cpp +++ b/wpilibc/src/test/native/cpp/simulation/AlertSimTest.cpp @@ -155,4 +155,28 @@ TEST_F(AlertSimTest, SetTextWhileSet) { EXPECT_TRUE(IsAlertActive("AFTER", Alert::Level::LOW)); } +TEST_F(AlertSimTest, GetActive) { + auto a = MakeAlert("A", Alert::Level::HIGH); + auto b = MakeAlert("B", Alert::Level::HIGH); + auto c = MakeAlert("C", Alert::Level::HIGH); + a.Set(true); + b.Set(true); + c.Set(false); + + auto active = AlertSim::GetActive(); + auto all = AlertSim::GetAll(); + EXPECT_EQ(active.size(), 2u); + EXPECT_EQ(all.size(), 3u); + EXPECT_TRUE((active[0].text == "A" && active[1].text == "B") || + (active[0].text == "B" && active[1].text == "A")); + + a.Set(false); + + active = AlertSim::GetActive(); + all = AlertSim::GetAll(); + EXPECT_EQ(active.size(), 1u); + EXPECT_EQ(all.size(), 3u); + EXPECT_EQ(active[0].text, "B"); +} + } // namespace wpi::sim diff --git a/wpilibc/src/test/python/test_alert.py b/wpilibc/src/test/python/test_alert.py index 6241da8733..7c791a5700 100644 --- a/wpilibc/src/test/python/test_alert.py +++ b/wpilibc/src/test/python/test_alert.py @@ -143,3 +143,30 @@ def test_set_text_while_set(group_name): assert alert.getText() == "AFTER" assert not is_alert_active("BEFORE", Alert.Level.LOW) assert is_alert_active("AFTER", Alert.Level.LOW) + +def test_get_active(group_name): + with ( + Alert(group_name, "A", Alert.Level.HIGH) as a, + Alert(group_name, "B", Alert.Level.HIGH) as b, + Alert(group_name, "C", Alert.Level.HIGH) as c, + ): + + a.set(True) + b.set(True) + c.set(False) + + active = AlertSim.getActive() + allAlerts = AlertSim.getAll() + + assert len(active) == 2 + assert len(allAlerts) == 3 + + activeTexts = [a.text for a in active] + assert set(activeTexts) == {"A", "B"} + + a.set(False) + active = AlertSim.getActive() + allAlerts = AlertSim.getAll() + assert len(active) == 1 + assert len(allAlerts) == 3 + assert active[0].text == "B" \ No newline at end of file diff --git a/wpilibj/src/main/java/org/wpilib/simulation/AlertSim.java b/wpilibj/src/main/java/org/wpilib/simulation/AlertSim.java index eba775a994..b3eee54011 100644 --- a/wpilibj/src/main/java/org/wpilib/simulation/AlertSim.java +++ b/wpilibj/src/main/java/org/wpilib/simulation/AlertSim.java @@ -71,7 +71,7 @@ public final class AlertSim { } /** - * Gets detailed information about each alert. + * Gets detailed information about each alert (including inactive ones). * * @return Alerts */ @@ -84,6 +84,18 @@ public final class AlertSim { return infos; } + /** + * Gets detailed information about all active alerts. + * + * @return Alerts + */ + public static AlertInfo[] getActive() { + AlertInfo[] alertInfos = getAll(); + return java.util.Arrays.stream(alertInfos) + .filter(info -> info.activeStartTime != 0) + .toArray(AlertInfo[]::new); + } + /** Resets all alert simulation data. */ public static void resetData() { AlertDataJNI.resetData(); diff --git a/wpilibj/src/test/java/org/wpilib/simulation/AlertSimTest.java b/wpilibj/src/test/java/org/wpilib/simulation/AlertSimTest.java index 05ed2bc4fd..1963abf413 100644 --- a/wpilibj/src/test/java/org/wpilib/simulation/AlertSimTest.java +++ b/wpilibj/src/test/java/org/wpilib/simulation/AlertSimTest.java @@ -157,4 +157,29 @@ class AlertSimTest { assertTrue(isAlertActive("AFTER", Level.LOW)); } } + + @Test + void getActive() { + try (var a = makeAlert("A", Level.HIGH); + var b = makeAlert("B", Level.HIGH); + var c = makeAlert("C", Level.HIGH)) { + a.set(true); + b.set(true); + c.set(false); + + var active = AlertSim.getActive(); + var all = AlertSim.getAll(); + assertEquals(2, active.length); + assertEquals(3, all.length); + assertTrue(Arrays.stream(active).anyMatch(x -> "A".equals(x.text))); + assertTrue(Arrays.stream(active).anyMatch(x -> "B".equals(x.text))); + + a.set(false); + active = AlertSim.getActive(); + all = AlertSim.getAll(); + assertEquals(1, active.length); + assertEquals(3, all.length); + assertEquals(active[0].text, "B"); + } + } }