diff --git a/lib/src/main/java/com/team2813/lib2813/subsystems/lightshow/Lightshow.java b/lib/src/main/java/com/team2813/lib2813/subsystems/lightshow/Lightshow.java index 87d63c24..8c5c7ec7 100644 --- a/lib/src/main/java/com/team2813/lib2813/subsystems/lightshow/Lightshow.java +++ b/lib/src/main/java/com/team2813/lib2813/subsystems/lightshow/Lightshow.java @@ -1,5 +1,5 @@ /* -Copyright 2024-2025 Prospect Robotics SWENext Club +Copyright 2024-2026 Prospect Robotics SWENext Club Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -32,13 +32,13 @@ public Color color() { return new Color(0, 0, 0); } - public boolean apply() { + public boolean isActive() { return true; } }; - protected Set states = new HashSet<>(); - protected Optional defaultState; + protected final Set states = new HashSet<>(); + protected Optional defaultState = Optional.empty(); /** * Creates a new Lightshow subsystem using an enum. Uses the given {@code enumClass} to get a list @@ -60,7 +60,15 @@ protected Lightshow(Set states) { addStates(states); } - protected abstract void useColor(Color c); + /** + * Sets the lights to the provided color. + * + *

Subclasses should override this to display the provided color. For example, the value could + * be passed to {@link com.ctre.phoenix.CANifier#setLEDOutput(double, LEDChannel)}. + * + * @param color Color to display + */ + protected abstract void useColor(Color color); public final & State> void addStates(Class enumClass) { T[] constants = enumClass.getEnumConstants(); diff --git a/lib/src/main/java/com/team2813/lib2813/subsystems/lightshow/QueueLightshow.java b/lib/src/main/java/com/team2813/lib2813/subsystems/lightshow/QueueLightshow.java index 19ac3607..6ad33607 100644 --- a/lib/src/main/java/com/team2813/lib2813/subsystems/lightshow/QueueLightshow.java +++ b/lib/src/main/java/com/team2813/lib2813/subsystems/lightshow/QueueLightshow.java @@ -1,5 +1,5 @@ /* -Copyright 2024-2025 Prospect Robotics SWENext Club +Copyright 2024-2026 Prospect Robotics SWENext Club Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -22,13 +22,18 @@ import java.util.Set; /** - * A lightshow that keeps track of the states that have been applied, and uses the last state. To be - * more specific, all states that return {@code true} on a call to {@link State#apply()} are added - * to the list. States are only removed from the list if they are at the front and {@link - * State#apply()} returns {@code false}, when a state is removed, the next one will be activated if - * {@link State#apply()} returns {@code true}, until either a state returns {@code true} upon a call - * to {@link State#apply()}, in which the color will be used, or there are no states where {@link - * State#apply()} return {@code true}, then the default color is used. + * A lightshow that changes color when a State transitions from inactive to active. + * + *

All states that return {@code true} on a call to {@link State#isActive()} are pushed to a + * deque. States are only removed from the deque if they are at the front and {@link + * State#isActive()} returns {@code false}. When a state is removed, the next one will be activated + * if {@link State#isActive()} returns {@code true}, until either a state returns {@code true} upon + * a call to {@link State#isActive()}, in which the color will be used, or there are no states where + * {@link State#isActive()} return {@code true}, then the default color is used. + * + *

For example usage, see FRC Team 2813's 2024 robot code. */ public abstract class QueueLightshow extends Lightshow { private final Deque activatedStates = new ArrayDeque<>(); @@ -45,18 +50,28 @@ public QueueLightshow(Set states) { @Override protected Optional update() { + // NOTE: Even though this class is called QueueLightshow, we are treating activatedStates as a + // stack, not a queue. + + // If new States become active, push them, so we change the color. for (State s : states) { - if (!activatedStates.contains(s) && s.apply()) { - activatedStates.addFirst(s); + if (!activatedStates.contains(s) && s.isActive()) { + activatedStates.addFirst(s); // Push } } - while (!activatedStates.isEmpty()) { - State s = activatedStates.poll(); - if (s.apply()) { - activatedStates.addFirst(s); + + // Pick the color to display. We start with the State that was most recently pushed, so the + // color returned changes when a either a State transitions to active or when the State + // associated with the previous color transitioned to inactive. + do { + State s = activatedStates.peekFirst(); + if (s == null) { + return Optional.empty(); // No states active. The lightshow is over. 😿 + } + if (s.isActive()) { return Optional.of(s.color()); } - } - return Optional.empty(); + activatedStates.removeFirst(); // Pop + } while (true); } } diff --git a/lib/src/main/java/com/team2813/lib2813/subsystems/lightshow/State.java b/lib/src/main/java/com/team2813/lib2813/subsystems/lightshow/State.java index 22b19ad2..27045293 100644 --- a/lib/src/main/java/com/team2813/lib2813/subsystems/lightshow/State.java +++ b/lib/src/main/java/com/team2813/lib2813/subsystems/lightshow/State.java @@ -1,5 +1,5 @@ /* -Copyright 2024-2025 Prospect Robotics SWENext Club +Copyright 2024-2026 Prospect Robotics SWENext Club Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,16 +19,16 @@ public interface State { /** - * gets the color of this State. + * Gets the color of this State. * * @return the color of this State */ Color color(); /** - * Checks if the current state should be applied + * Checks if the current state is active. * - * @return {@code true} if the state should be applied + * @return {@code true} if the state is active */ - boolean apply(); + boolean isActive(); }