Skip to content

Commit

Permalink
Refactor LogTable struct writes
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinclark committed Jan 13, 2024
1 parent 57fad96 commit 790571b
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 33 deletions.
45 changes: 27 additions & 18 deletions junction/core/src/main/org/littletonrobotics/junction/LogTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -338,15 +338,7 @@ private void addStructSchema(Struct<?> struct, Set<String> seen) {
@SuppressWarnings("unchecked")
public <T> void put(String key, Struct<T> struct, T value) {
if (writeAllowed(key, LoggableType.Raw)) {
addStructSchema(struct, new HashSet<>());
if (!structBuffers.containsKey(struct.getTypeString())) {
structBuffers.put(struct.getTypeString(), StructBuffer.create(struct));
}
StructBuffer<T> buffer = (StructBuffer<T>) structBuffers.get(struct.getTypeString());
ByteBuffer bb = buffer.write(value);
byte[] array = new byte[bb.position()];
bb.position(0);
bb.get(array);
byte[] array = pack(struct, value);
put(key, new LogValue(array, struct.getTypeString()));
}
}
Expand All @@ -358,19 +350,36 @@ public <T> void put(String key, Struct<T> struct, T value) {
@SuppressWarnings("unchecked")
public <T> void put(String key, Struct<T> struct, T... value) {
if (writeAllowed(key, LoggableType.Raw)) {
addStructSchema(struct, new HashSet<>());
if (!structBuffers.containsKey(struct.getTypeString())) {
structBuffers.put(struct.getTypeString(), StructBuffer.create(struct));
}
StructBuffer<T> buffer = (StructBuffer<T>) structBuffers.get(struct.getTypeString());
ByteBuffer bb = buffer.writeArray(value);
byte[] array = new byte[bb.position()];
bb.position(0);
bb.get(array);
byte[] array = pack(struct, value);
put(key, new LogValue(array, struct.getTypeString() + "[]"));
}
}

private <T> StructBuffer<T> bufferForStruct(Struct<T> struct) {
addStructSchema(struct, new HashSet<>());
if (!structBuffers.containsKey(struct.getTypeString())) {
structBuffers.put(struct.getTypeString(), StructBuffer.create(struct));
}
return (StructBuffer<T>) structBuffers.get(struct.getTypeString());
}

private <T> byte[] pack(Struct<T> struct, T[] value) {
StructBuffer<T> buffer = bufferForStruct(struct);
return copyBytes(buffer.writeArray(value));
}

private <T> byte[] pack(Struct<T> struct, T value) {
StructBuffer<T> buffer = bufferForStruct(struct);
return copyBytes(buffer.write(value));
}

private byte[] copyBytes(ByteBuffer bb) {
byte[] array = new byte[bb.position()];
bb.position(0);
bb.get(array);
return array;
}

/**
* Writes a new protobuf value to the table. Skipped if the key already exists
* as a different type.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,61 +1,69 @@
package org.littletonrobotics.junction;

import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.math.geometry.proto.Rotation2dProto;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.littletonrobotics.junction.LogTable.LogValue;

public class LogTableTest {
private LogTable table;

@BeforeEach
void setup() {
table = new LogTable(0);
}

@Test
void supportsIntegers() {
LogTable table = new LogTable(0);
table.put("int", 5);
LogValue val = table.get("int");
Assertions.assertEquals(5, val.getInteger());
Assertions.assertEquals(5, table.get("int").getInteger());
}

@Test
void supportsIntArrays() {
long[] expected = { 1, 2, 3 };

LogTable table = new LogTable(0);
table.put("int-array", expected);

LogValue val = table.get("int-array");
Assertions.assertArrayEquals(expected, val.getIntegerArray());
Assertions.assertArrayEquals(expected, table.get("int-array").getIntegerArray());
}

@Test
void supportsProtobufSerialization() {
Rotation2d expected = new Rotation2d(1, 2);

LogTable table = new LogTable(0);
// We're forcing protobuf based serialization so Struct based doesn't run
table.put("rot", Rotation2d.proto, expected);

Rotation2d actual = table.get("rot", Rotation2d.proto, new Rotation2d());
Assertions.assertEquals(expected, actual);
Assertions.assertEquals(expected, table.get("rot", Rotation2d.proto, new Rotation2d()));
}

@Test
void protobufIsntWrittenIfKeyAlreadyInUse() {
Rotation2d rot = new Rotation2d(1, 2);

table.put("rot", 5);
table.put("rot", Rotation2d.proto, rot); // This should be skipped

Assertions.assertNotEquals(rot, table.get("rot", Rotation2d.proto, new Rotation2d()));
Assertions.assertEquals(5, table.get("rot").getInteger());
}

@Test
void supportsStructSerialization() {
Rotation2d expected = new Rotation2d(1, 2);

LogTable table = new LogTable(0);
// We're forcing Struct based serialization so Protobuf based doesn't run
table.put("rot", Rotation2d.struct, expected);

Rotation2d actual = table.get("rot", Rotation2d.struct, new Rotation2d());
Assertions.assertEquals(expected, actual);
Assertions.assertEquals(expected, table.get("rot", Rotation2d.struct, new Rotation2d()));
}

@Test
void supportsStructArraySerialization() {
Rotation2d first = new Rotation2d(1, 2);
Rotation2d second = new Rotation2d(3, 4);

LogTable table = new LogTable(0);
// We're forcing Struct serialization
table.put("rot", Rotation2d.struct, first, second);

Expand Down

0 comments on commit 790571b

Please sign in to comment.