mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-27 02:01:42 +00:00
[epilogue] Fix lazy logging of mutable arrays (#7665)
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
// 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.epilogue.logging;
|
||||
|
||||
import edu.wpi.first.util.struct.Struct;
|
||||
import edu.wpi.first.util.struct.StructSerializable;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public record CustomStruct(int x) implements StructSerializable {
|
||||
public static final Serializer struct = new Serializer();
|
||||
|
||||
public static final class Serializer implements Struct<CustomStruct> {
|
||||
@Override
|
||||
public Class<CustomStruct> getTypeClass() {
|
||||
return CustomStruct.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return "CustomStruct";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return kSizeInt32;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSchema() {
|
||||
return "int32 x;";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomStruct unpack(ByteBuffer bb) {
|
||||
return new CustomStruct(bb.getInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(ByteBuffer bb, CustomStruct value) {
|
||||
bb.putInt(value.x);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
package edu.wpi.first.epilogue.logging;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
|
||||
@@ -53,4 +54,135 @@ class LazyBackendTest {
|
||||
backend.getEntries());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void inPlaceByteArray() {
|
||||
var backend = new TestBackend();
|
||||
var lazy = new LazyBackend(backend);
|
||||
|
||||
byte[] arr = new byte[] {0};
|
||||
lazy.log("arr", arr);
|
||||
|
||||
arr[0] = 1;
|
||||
lazy.log("arr", arr);
|
||||
|
||||
assertEquals(2, backend.getEntries().size());
|
||||
assertArrayEquals(new byte[] {0}, (byte[]) backend.getEntries().get(0).value());
|
||||
assertArrayEquals(new byte[] {1}, (byte[]) backend.getEntries().get(1).value());
|
||||
}
|
||||
|
||||
@Test
|
||||
void inPlaceIntArray() {
|
||||
var backend = new TestBackend();
|
||||
var lazy = new LazyBackend(backend);
|
||||
|
||||
int[] arr = new int[] {0};
|
||||
lazy.log("arr", arr);
|
||||
|
||||
arr[0] = 1;
|
||||
lazy.log("arr", arr);
|
||||
|
||||
assertEquals(2, backend.getEntries().size());
|
||||
assertArrayEquals(new int[] {0}, (int[]) backend.getEntries().get(0).value());
|
||||
assertArrayEquals(new int[] {1}, (int[]) backend.getEntries().get(1).value());
|
||||
}
|
||||
|
||||
@Test
|
||||
void inPlaceLongArray() {
|
||||
var backend = new TestBackend();
|
||||
var lazy = new LazyBackend(backend);
|
||||
|
||||
long[] arr = new long[] {0};
|
||||
lazy.log("arr", arr);
|
||||
|
||||
arr[0] = 1;
|
||||
lazy.log("arr", arr);
|
||||
|
||||
assertEquals(2, backend.getEntries().size());
|
||||
assertArrayEquals(new long[] {0}, (long[]) backend.getEntries().get(0).value());
|
||||
assertArrayEquals(new long[] {1}, (long[]) backend.getEntries().get(1).value());
|
||||
}
|
||||
|
||||
@Test
|
||||
void inPlaceFloatArray() {
|
||||
var backend = new TestBackend();
|
||||
var lazy = new LazyBackend(backend);
|
||||
|
||||
float[] arr = new float[] {0};
|
||||
lazy.log("arr", arr);
|
||||
|
||||
arr[0] = 1;
|
||||
lazy.log("arr", arr);
|
||||
|
||||
assertEquals(2, backend.getEntries().size());
|
||||
assertArrayEquals(new float[] {0}, (float[]) backend.getEntries().get(0).value());
|
||||
assertArrayEquals(new float[] {1}, (float[]) backend.getEntries().get(1).value());
|
||||
}
|
||||
|
||||
@Test
|
||||
void inPlaceDoubleArray() {
|
||||
var backend = new TestBackend();
|
||||
var lazy = new LazyBackend(backend);
|
||||
|
||||
double[] arr = new double[] {0};
|
||||
lazy.log("arr", arr);
|
||||
|
||||
arr[0] = 1;
|
||||
lazy.log("arr", arr);
|
||||
|
||||
assertEquals(2, backend.getEntries().size());
|
||||
assertArrayEquals(new double[] {0}, (double[]) backend.getEntries().get(0).value());
|
||||
assertArrayEquals(new double[] {1}, (double[]) backend.getEntries().get(1).value());
|
||||
}
|
||||
|
||||
@Test
|
||||
void inPlaceBooleanArray() {
|
||||
var backend = new TestBackend();
|
||||
var lazy = new LazyBackend(backend);
|
||||
|
||||
boolean[] arr = new boolean[] {false};
|
||||
lazy.log("arr", arr);
|
||||
|
||||
arr[0] = true;
|
||||
lazy.log("arr", arr);
|
||||
|
||||
assertEquals(2, backend.getEntries().size());
|
||||
assertArrayEquals(new boolean[] {false}, (boolean[]) backend.getEntries().get(0).value());
|
||||
assertArrayEquals(new boolean[] {true}, (boolean[]) backend.getEntries().get(1).value());
|
||||
}
|
||||
|
||||
@Test
|
||||
void inPlaceStringArray() {
|
||||
var backend = new TestBackend();
|
||||
var lazy = new LazyBackend(backend);
|
||||
|
||||
String[] arr = new String[] {"0"};
|
||||
lazy.log("arr", arr);
|
||||
|
||||
arr[0] = "1";
|
||||
lazy.log("arr", arr);
|
||||
|
||||
assertEquals(2, backend.getEntries().size());
|
||||
assertArrayEquals(new String[] {"0"}, (String[]) backend.getEntries().get(0).value());
|
||||
assertArrayEquals(new String[] {"1"}, (String[]) backend.getEntries().get(1).value());
|
||||
}
|
||||
|
||||
@Test
|
||||
void inPlaceStructArray() {
|
||||
var backend = new TestBackend();
|
||||
var lazy = new LazyBackend(backend);
|
||||
|
||||
CustomStruct[] arr = new CustomStruct[] {new CustomStruct(0)};
|
||||
|
||||
lazy.log("arr", arr, CustomStruct.struct);
|
||||
|
||||
arr[0] = new CustomStruct(1);
|
||||
lazy.log("arr", arr, CustomStruct.struct);
|
||||
|
||||
assertEquals(2, backend.getEntries().size());
|
||||
assertArrayEquals(
|
||||
new byte[] {0x00, 0x00, 0x00, 0x00}, (byte[]) backend.getEntries().get(0).value());
|
||||
assertArrayEquals(
|
||||
new byte[] {0x01, 0x00, 0x00, 0x00}, (byte[]) backend.getEntries().get(1).value());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,32 +55,32 @@ public class TestBackend implements EpilogueBackend {
|
||||
|
||||
@Override
|
||||
public void log(String identifier, byte[] value) {
|
||||
m_entries.add(new LogEntry<>(identifier, value));
|
||||
m_entries.add(new LogEntry<>(identifier, value.clone()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String identifier, int[] value) {
|
||||
m_entries.add(new LogEntry<>(identifier, value));
|
||||
m_entries.add(new LogEntry<>(identifier, value.clone()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String identifier, long[] value) {
|
||||
m_entries.add(new LogEntry<>(identifier, value));
|
||||
m_entries.add(new LogEntry<>(identifier, value.clone()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String identifier, float[] value) {
|
||||
m_entries.add(new LogEntry<>(identifier, value));
|
||||
m_entries.add(new LogEntry<>(identifier, value.clone()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String identifier, double[] value) {
|
||||
m_entries.add(new LogEntry<>(identifier, value));
|
||||
m_entries.add(new LogEntry<>(identifier, value.clone()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String identifier, boolean[] value) {
|
||||
m_entries.add(new LogEntry<>(identifier, value));
|
||||
m_entries.add(new LogEntry<>(identifier, value.clone()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -90,19 +90,27 @@ public class TestBackend implements EpilogueBackend {
|
||||
|
||||
@Override
|
||||
public void log(String identifier, String[] value) {
|
||||
m_entries.add(new LogEntry<>(identifier, value));
|
||||
m_entries.add(new LogEntry<>(identifier, value.clone()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> void log(String identifier, S value, Struct<S> struct) {
|
||||
var serialized = StructBuffer.create(struct).write(value).array();
|
||||
var buffer = StructBuffer.create(struct).write(value).position(0);
|
||||
var serialized = new byte[buffer.capacity()];
|
||||
for (int i = 0; i < buffer.capacity(); i++) {
|
||||
serialized[i] = buffer.get();
|
||||
}
|
||||
|
||||
m_entries.add(new LogEntry<>(identifier, serialized));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> void log(String identifier, S[] value, Struct<S> struct) {
|
||||
var serialized = StructBuffer.create(struct).writeArray(value).array();
|
||||
var buffer = StructBuffer.create(struct).writeArray(value).position(0);
|
||||
var serialized = new byte[buffer.capacity()];
|
||||
for (int i = 0; i < buffer.capacity(); i++) {
|
||||
serialized[i] = buffer.get();
|
||||
}
|
||||
|
||||
m_entries.add(new LogEntry<>(identifier, serialized));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user