Skip to content

Commit

Permalink
Change OffsetLEDReader to a more generic RemappedReader implementation
Browse files Browse the repository at this point in the history
Now operates on arbitrary remapping functions, not just a fixed offset
  • Loading branch information
SamCarlberg committed Nov 8, 2024
1 parent b73607a commit 3c62119
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 13 deletions.
8 changes: 4 additions & 4 deletions wpilibj/src/main/java/edu/wpi/first/wpilibj/LEDPattern.java
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ default LEDPattern offsetBy(int offset) {
return (reader, writer) -> {
int bufLen = reader.getLength();
applyTo(
new LEDReader.OffsetLEDReader(reader, offset),
LEDReader.RemappedReader.offset(reader, offset),
(i, r, g, b) -> {
int shiftedIndex = Math.floorMod(i + offset, bufLen);
writer.setRGB(shiftedIndex, r, g, b);
Expand Down Expand Up @@ -220,7 +220,7 @@ default LEDPattern scrollAtRelativeSpeed(Frequency velocity) {
int offset = (int) (t * bufLen);

applyTo(
new LEDReader.OffsetLEDReader(reader, offset),
LEDReader.RemappedReader.offset(reader, offset),
(i, r, g, b) -> {
// floorMod so if the offset is negative, we still get positive outputs
int shiftedIndex = Math.floorMod(i + offset, bufLen);
Expand Down Expand Up @@ -267,10 +267,10 @@ default LEDPattern scrollAtAbsoluteSpeed(LinearVelocity velocity, Distance ledSp
long now = WPIUtilJNI.now();

// every step in time that's a multiple of microsPerLED will increment the offset by 1
var offset = now / microsPerLED;
var offset = (int) (now / microsPerLED);

applyTo(
new LEDReader.OffsetLEDReader(reader, offset),
LEDReader.RemappedReader.offset(reader, offset),
(i, r, g, b) -> {
// floorMod so if the offset is negative, we still get positive outputs
int shiftedIndex = Math.floorMod(i + offset, bufLen);
Expand Down
33 changes: 24 additions & 9 deletions wpilibj/src/main/java/edu/wpi/first/wpilibj/LEDReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import edu.wpi.first.util.ErrorMessages;
import edu.wpi.first.wpilibj.util.Color;
import edu.wpi.first.wpilibj.util.Color8Bit;
import java.util.function.IntUnaryOperator;

/** Generic interface for reading data from an LED buffer. */
public interface LEDReader {
Expand Down Expand Up @@ -99,22 +100,36 @@ default void forEach(IndexedColorIterator iterator) {
}

/**
* An LED reader implementation that operates on offset indexes. Offsets are circular and will
* wrap around the end of the base reader back to the start.
* An LED reader implementation that operates on remapped indices. Remapping can be done using
* arbitrary mapping functions; a static factory function is also provided for the common use case
* of offset readers for things like scrolling animations.
*/
class OffsetLEDReader implements LEDReader {
class RemappedReader implements LEDReader {
private final LEDReader m_reader;
private final long m_offset;
private final IntUnaryOperator m_mapping;

/**
* Creates a new offset LED reader based on an existing reader and the integer offset.
* Creates a new remapping reader for a backing reader and an arbitrary index remapping
* function.
*
* @param reader the backing reader to use
* @param offset the offset to use when reading data
*/
public OffsetLEDReader(LEDReader reader, long offset) {
m_reader = ErrorMessages.requireNonNullParam(reader, "reader", "OffsetLEDReader");
m_offset = offset;
public RemappedReader(LEDReader reader, IntUnaryOperator mapping) {
m_reader = ErrorMessages.requireNonNullParam(reader, "reader", "RemappedReader");
m_mapping = ErrorMessages.requireNonNullParam(mapping, "mapping", "RemappedReader");
}

/**
* Creates a new offset LED reader based on an existing reader and integer offset. The offset
* reader will be circular and wrap around.
*
* @param reader the backing reader to use
* @param offset the offset to use when reading data
*/
public static RemappedReader offset(LEDReader reader, int offset) {
return new RemappedReader(
reader, (original) -> Math.floorMod(original + offset, reader.getLength()));
}

@Override
Expand Down Expand Up @@ -144,7 +159,7 @@ public int getBlue(int index) {
* @return the remapped index
*/
public int remapIndex(int index) {
return Math.floorMod(index + m_offset, getLength());
return m_mapping.applyAsInt(index);
}
}
}

0 comments on commit 3c62119

Please sign in to comment.