diff --git a/build.gradle b/build.gradle
index 7db24d5..3ec6c86 100644
--- a/build.gradle
+++ b/build.gradle
@@ -4,17 +4,13 @@ buildscript {
mavenCentral()
maven { url 'https://jitpack.io' }
}
- dependencies {
- classpath "com.github.ionicbond-9738.gversion-plugin:build:master-SNAPSHOT"
- }
}
-
plugins {
id "java"
id "edu.wpi.first.GradleRIO" version "2025.3.2"
id 'com.diffplug.spotless' version '7.2.1'
- id 'com.peterabeles.gversion' version 'master-SNAPSHOT'
+ id "com.peterabeles.gversion" version "1.10"
}
apply plugin: 'com.peterabeles.gversion'
@@ -136,8 +132,6 @@ dependencies {
implementation 'com.jcraft:jsch:0.1.55'
implementation 'com.diffplug.spotless:spotless-lib:3.3.1'
- implementation 'com.github.ionicbond-9738.gversion-plugin:build:master-SNAPSHOT'
-
def akitJson = new groovy.json.JsonSlurper().parseText(new File(projectDir.getAbsolutePath() + "/vendordeps/AdvantageKit.json").text)
annotationProcessor "org.littletonrobotics.akit:akit-autolog:$akitJson.version"
diff --git a/settings.gradle b/settings.gradle
index 4f49860..223f363 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -28,9 +28,6 @@ pluginManagement {
resolutionStrategy {
eachPlugin { details ->
- if (details.requested.id.toString() == 'com.peterabeles.gversion') {
- details.useModule("com.github.ionicbond-9738.gversion-plugin:build:master-SNAPSHOT")
- }
}
}
}
diff --git a/src/main/java/frc/robot/Robot.java b/src/main/java/frc/robot/Robot.java
index abdbb38..9960299 100644
--- a/src/main/java/frc/robot/Robot.java
+++ b/src/main/java/frc/robot/Robot.java
@@ -61,11 +61,8 @@ public Robot() {
Logger.recordOutput("BuildConstants/version", BuildConstants.VERSION);
Logger.recordOutput("BuildConstants/gitRevision", BuildConstants.GIT_REVISION);
Logger.recordOutput("BuildConstants/gitBranch", BuildConstants.GIT_BRANCH);
- Logger.recordOutput("BuildConstants/lastCommitAuthor", BuildConstants.LAST_COMMIT_AUTHOR);
- Logger.recordOutput("BuildConstants/buildUser", BuildConstants.BUILD_USER);
Logger.recordOutput("BuildConstants/buildDate", BuildConstants.BUILD_DATE);
- Logger.recordOutput(
- "BuildConstants/hasUncommittedChanges", BuildConstants.HAS_UNCOMMITTED_CHANGES);
+ Logger.recordOutput("BuildConstants/sha", BuildConstants.GIT_SHA);
}
public static Robot getInstance() {
diff --git a/src/main/java/monologue/Annotations.java b/src/main/java/monologue/Annotations.java
deleted file mode 100644
index 9605a4d..0000000
--- a/src/main/java/monologue/Annotations.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package monologue;
-
-import java.lang.annotation.Annotation;
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@SuppressWarnings("unchecked")
-public class Annotations {
- static final Class extends Annotation>[] ALL_ANNOTATIONS =
- new Class[] {Log.class, Log.Once.class};
-
- /**
- * Logs the annotated field/method to NetworkTables if inside a {@link Logged} class.
- *
- *
Static fields and methods will emit a warning and not be logged.
- *
- * @param key [optional] the key to log the variable as. If empty, the key will be the name of the
- * field/method
- * @param sink [optional] the log sink to use
- */
- @Documented
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ElementType.FIELD, ElementType.METHOD})
- public @interface Log {
-
- /** The relative path to log to. If empty, the path will be the name of the field/method. */
- public String key() default "";
-
- /** The {@link LogSink} to use. */
- public LogSink sink() default LogSink.NT;
-
- /**
- * Logs the annotated field/method to NetworkTables if inside a {@link Logged} class.
- *
- * @param key [optional] the key to log the variable as. If empty, the key will be the name of
- * the field/method
- */
- @Documented
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ElementType.FIELD, ElementType.METHOD})
- public @interface Once {
- /** The relative path to log to. If empty, the path will be the name of the field/method. */
- public String key() default "";
-
- /** The {@link LogSink} to use. */
- public LogSink sink() default LogSink.NT;
- }
- }
-
- /**
- * Makes the annotated field containing a {@link Logged} class not be recursed into.
- *
- * @apiNote this will also make fields inside the object in the field not be logged
- */
- @Documented
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ElementType.FIELD})
- public @interface IgnoreLogged {}
-
- /**
- * Allows singletons to be logged only once with a predefined key.
- *
- *
This also allows static variables to be logged under the singleton's key.
- *
- * @param key the key to log at, still appends the class name
- */
- @Documented
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ElementType.TYPE})
- public @interface SingletonLogged {
- public String key();
- }
-
- /**
- * Will cause the internal fields of the annotated field to be logged as if they were fields of
- * the object this field is in. This is useful for flattening complex objects into a single path.
- */
- @Documented
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ElementType.FIELD})
- public @interface FlattenedLogged {}
-
- /**
- * Will make Monologue aware that this field could contain an object that implements {@link
- * Logged} but the type of the field itself does not implement {@link Logged}.
- */
- @Documented
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ElementType.FIELD})
- public @interface MaybeLoggedType {}
-
- @Documented
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ElementType.FIELD})
- public @interface OptionalLogged {
- public Class extends Logged> type();
- }
-}
diff --git a/src/main/java/monologue/Eval.java b/src/main/java/monologue/Eval.java
deleted file mode 100644
index 4305517..0000000
--- a/src/main/java/monologue/Eval.java
+++ /dev/null
@@ -1,371 +0,0 @@
-package monologue;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.VarHandle;
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
-import monologue.Annotations.FlattenedLogged;
-import monologue.Annotations.IgnoreLogged;
-import monologue.Annotations.Log;
-import monologue.Annotations.MaybeLoggedType;
-import monologue.Annotations.OptionalLogged;
-import monologue.Annotations.SingletonLogged;
-import monologue.LoggingTree.*;
-import monologue.Primatives.BooleanVarHandle;
-import monologue.Primatives.DoubleVarHandle;
-import monologue.Primatives.LongVarHandle;
-
-public class Eval {
- /**
- * Simplifies the user specified annotations on a field/method to a quanery conditiion expressed
- * as an Optional {@link LogSink}.
- *
- * @param element The field/method to simplify
- * @return The simplified condition
- */
- static Optional annoEval(AccessibleObject element) {
- if (element.isAnnotationPresent(Log.class)) {
- return Optional.of(element.getAnnotation(Log.class).sink());
- } else if (element.isAnnotationPresent(Log.Once.class)) {
- return Optional.of(element.getAnnotation(Log.Once.class).sink());
- } else {
- return Optional.empty();
- }
- }
-
- /**
- * Checks if their are multiple logging annotations on one field/method.
- *
- * @param element The field/method to check
- * @return If there are too many logging annotations
- */
- static boolean overloadedAnno(AccessibleObject element) {
- int count = 0;
- for (var anno : Annotations.ALL_ANNOTATIONS) {
- if (element.isAnnotationPresent(anno)) {
- count++;
- }
- }
- return count > 1;
- }
-
- /** Checks if the class is a singleton and returns its key if it is. */
- static Optional singletonKey(Class> clazz) {
- if (clazz.isAnnotationPresent(SingletonLogged.class)) {
- return Optional.of(clazz.getAnnotation(SingletonLogged.class).key());
- } else {
- return Optional.empty();
- }
- }
-
- /** A condensed packaged of what describes a singular logged field/method */
- static class LogMetadata {
- public final boolean annotated;
- public final LogSink sink;
- public final boolean once;
- public final String relativePath;
-
- private LogMetadata(boolean annotated, LogSink sink, boolean once, String path) {
- this.annotated = annotated;
- this.sink = sink;
- this.once = once;
- this.relativePath = "/" + path;
- }
-
- /**
- * Derives the metadata from an annotated field/method, if there are no logging annotations this
- * returns null.
- *
- * @param element The field/method to derive the metadata from
- * @return The metadata
- */
- static LogMetadata from(AccessibleObject element) {
- String name;
- if (element instanceof java.lang.reflect.Field) {
- name = ((java.lang.reflect.Field) element).getName();
- } else if (element instanceof java.lang.reflect.Method) {
- name = ((java.lang.reflect.Method) element).getName();
- } else {
- throw new IllegalArgumentException("Only fields and methods can be logged");
- }
- if (element.isAnnotationPresent(Log.class)) {
- Log anno = element.getAnnotation(Log.class);
- return new LogMetadata(true, anno.sink(), false, anno.key().isEmpty() ? name : anno.key());
- } else if (element.isAnnotationPresent(Log.Once.class)) {
- Log.Once anno = element.getAnnotation(Log.Once.class);
- return new LogMetadata(true, anno.sink(), true, anno.key().isEmpty() ? name : anno.key());
- } else {
- return new LogMetadata(false, LogSink.OP, false, name);
- }
- }
- }
-
- static List> getLoggedInHierarchy(Class> type, Class> stop) {
- ArrayList> result = new ArrayList>();
-
- Class> i = type;
- while (i != stop && Logged.class.isAssignableFrom(i)) {
- result.add(i);
- i = i.getSuperclass();
- }
-
- return result;
- }
-
- static List getAllFields(List> classes) {
- ArrayList result = new ArrayList();
- for (Class> clazz : classes) {
- Collections.addAll(result, clazz.getDeclaredFields());
- }
- return result;
- }
-
- static List getAllMethods(List> classes) {
- ArrayList result = new ArrayList();
- for (Class> clazz : classes) {
- Collections.addAll(result, clazz.getDeclaredMethods());
- }
- return result;
- }
-
- static List> getLoggedClasses(Class> type) {
- return getLoggedInHierarchy(type, Object.class);
- }
-
- static boolean isNestedLogged(Field field) {
- final boolean optional = Optional.class.isAssignableFrom(field.getType());
- final boolean optionalAnnotated = field.isAnnotationPresent(OptionalLogged.class);
- final Class> type =
- optional && optionalAnnotated
- ? field.getAnnotation(OptionalLogged.class).type()
- : field.getType();
- final boolean fieldTyLogged =
- Logged.class.isAssignableFrom(type)
- || (type.isArray() && Logged.class.isAssignableFrom(type.getComponentType()));
- final boolean maybeLoggedAnnotation = field.isAnnotationPresent(MaybeLoggedType.class);
- final boolean ignoreLoggedAnnotation = field.isAnnotationPresent(IgnoreLogged.class);
- if (fieldTyLogged && maybeLoggedAnnotation) {
- RuntimeLog.warn(
- field.getName()
- + " of type "
- + field.getType().getSimpleName()
- + " is a Logged type, @MaybeLoggedType is redundant");
- }
- return (fieldTyLogged || maybeLoggedAnnotation) && !ignoreLoggedAnnotation;
- }
-
- static VarHandle getHandle(Field field, MethodHandles.Lookup lookup) {
- try {
- var privateLookup = MethodHandles.privateLookupIn(field.getDeclaringClass(), lookup);
- return privateLookup.unreflectVarHandle(field);
- } catch (IllegalAccessException e) {
- RuntimeLog.warn(
- "Could not access field "
- + field.getName()
- + " of type "
- + field.getType().getSimpleName()
- + " in "
- + field.getDeclaringClass().getSimpleName()
- + ": "
- + e.getMessage());
- return null;
- }
- }
-
- static MethodHandle getHandle(Method method, MethodHandles.Lookup lookup) {
- try {
- var privateLookup = MethodHandles.privateLookupIn(method.getDeclaringClass(), lookup);
- return privateLookup.unreflect(method);
- } catch (IllegalAccessException e) {
- RuntimeLog.warn(
- "Could not access field "
- + method.getName()
- + " in "
- + method.getDeclaringClass().getSimpleName()
- + ": "
- + e.getMessage());
- return null;
- }
- }
-
- static LN exploreNodes(List> types, final LN rootNode) {
- final List fields = getAllFields(types);
- final List methods = getAllMethods(types);
- final MethodHandles.Lookup lookup = MethodHandles.lookup();
- final String rootPath = rootNode.getPath();
-
- for (final Field field : fields) {
- final boolean isNestedLogged = isNestedLogged(field);
- final boolean isValidLiteralType = TypeChecker.isValidLiteralType(field.getType());
- final boolean isStatic = Modifier.isStatic(field.getModifiers());
- final boolean isArray = field.getType().isArray();
- final LogMetadata metadata = LogMetadata.from(field);
- final boolean optional = Optional.class.isAssignableFrom(field.getType());
- final boolean optionalAnnotated = field.isAnnotationPresent(OptionalLogged.class);
- if (!isNestedLogged && !isValidLiteralType) {
- continue;
- }
- if ((optional && !isNestedLogged) || (optional && !optionalAnnotated)) {
- continue;
- }
- final VarHandle handle = getHandle(field, lookup);
- if (handle == null) {
- continue;
- }
-
- // handle singletons
- if (isNestedLogged && isStatic) {
- Optional singletonKey = singletonKey(field.getType());
- if (singletonKey.isPresent() && !Logged.singletonAlreadyAdded(field.getType())) {
- try {
- Monologue.logTree((Logged) field.get(null), singletonKey.get());
- Logged.addSingleton(
- field.getType(), new SingletonNode(singletonKey.get(), field.getType(), handle));
- } catch (IllegalAccessException e) {
- RuntimeLog.warn("Issue with singleton " + field.getType().getSimpleName());
- }
- }
- continue;
- } else if (metadata.annotated && isStatic) {
- RuntimeLog.warn(
- "Static field "
- + field.getName()
- + " of type "
- + field.getType().getSimpleName()
- + " in "
- + rootPath
- + " is will not be logged");
- continue;
- }
-
- final Class> type;
- if (optional && optionalAnnotated) {
- type = field.getAnnotation(OptionalLogged.class).type();
- } else {
- type = field.getType();
- }
-
- if (isArray && isNestedLogged) {
- ComposableNode node = new ObjectArrayNode(rootPath + metadata.relativePath, handle::get);
- rootNode.addChild(exploreNodes(getLoggedClasses(type.getComponentType()), node));
- } else if (isNestedLogged) {
- boolean isFlattened = field.isAnnotationPresent(FlattenedLogged.class);
- String relativePath = isFlattened ? "" : metadata.relativePath;
- final ObjectNode node;
- if (optional) {
- node = new OptionalNode(rootPath + relativePath, metadata.sink, handle::get, type);
- } else {
- node = new ObjectNode(rootPath + relativePath, handle::get, type);
- }
- rootNode.addChild(exploreNodes(getLoggedClasses(type), node));
- } else if (isValidLiteralType) {
- if (!metadata.annotated || overloadedAnno(field)) {
- continue;
- }
- final boolean isFinal = Modifier.isFinal(field.getModifiers());
- final boolean isPrimitive = type.isPrimitive();
- LoggingNode node;
- if (type.isArray()) {
- node =
- new ValueArrayNode(
- rootPath + metadata.relativePath,
- metadata.sink,
- obj -> (Object[]) handle.get(obj),
- type);
- } else if (type == double.class
- || type == Double.TYPE
- || type == float.class
- || type == Float.TYPE) {
- node =
- new DoubleValueNode(
- rootPath + metadata.relativePath,
- metadata.sink,
- new DoubleVarHandle(handle)::get);
- } else if ((type == long.class
- || type == Long.TYPE
- || type == int.class
- || type == Integer.TYPE)) {
- node =
- new LongValueNode(
- rootPath + metadata.relativePath, metadata.sink, new LongVarHandle(handle)::get);
- } else if (type == boolean.class || type == Boolean.TYPE) {
- node =
- new BooleanValueNode(
- rootPath + metadata.relativePath,
- metadata.sink,
- new BooleanVarHandle(handle)::get);
- } else {
- node =
- new ValueNode(
- rootPath + metadata.relativePath, metadata.sink, handle::get, field.getType());
- }
- if (isFinal && isPrimitive) {
- node = node.asImmutable();
- } else if (!isPrimitive) {
- node = node.asNullable();
- }
- rootNode.addChild(node);
- }
- }
-
- for (final Method method : methods) {
- LogMetadata metadata = LogMetadata.from(method);
- if (!metadata.annotated
- || method.getParameterCount() > 0
- || !TypeChecker.isValidLiteralType(method.getReturnType())) {
- continue;
- }
- MethodHandle handle = getHandle(method, lookup);
- if (handle == null) {
- continue;
- }
-
- final String err = "Could not invoke method " + method.getName() + " in " + rootPath + ": ";
-
- boolean isPrimitive = method.getReturnType().isPrimitive();
- LoggingNode node;
- if (method.getReturnType().isArray()) {
- node =
- new ValueArrayNode(
- metadata.relativePath,
- metadata.sink,
- obj -> {
- try {
- return (Object[]) handle.invoke(obj);
- } catch (Throwable e) {
- RuntimeLog.warn(err + e.getMessage());
- return null;
- }
- },
- method.getReturnType());
- } else {
- node =
- new ValueNode(
- rootPath + metadata.relativePath,
- metadata.sink,
- obj -> {
- try {
- return handle.invoke(obj);
- } catch (Throwable e) {
- RuntimeLog.warn(err + e.getMessage());
- return null;
- }
- },
- method.getReturnType());
- }
- if (!isPrimitive) {
- node = node.asNullable();
- }
- rootNode.addChild(node);
- }
-
- return rootNode;
- }
-}
diff --git a/src/main/java/monologue/GlobalField.java b/src/main/java/monologue/GlobalField.java
deleted file mode 100644
index c3c0875..0000000
--- a/src/main/java/monologue/GlobalField.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package monologue;
-
-import edu.wpi.first.math.geometry.Pose2d;
-import edu.wpi.first.wpilibj.smartdashboard.Field2d;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-public class GlobalField {
- private static final AtomicBoolean initialized = new AtomicBoolean(false);
- private static final Field2d field = new Field2d();
-
- static void publish() {
- if (initialized.getAndSet(true)) {
- return;
- }
- Monologue.publishSendable("/Field", field, LogSink.NT);
- }
-
- public static synchronized void setObject(String name, Pose2d pose) {
- field.getObject(name).setPose(pose);
- }
-
- public static synchronized void setObject(String name, Pose2d... pose) {
- field.getObject(name).setPoses(pose);
- }
-
- public static synchronized void setObject(String name, List pose) {
- field.getObject(name).setPoses(pose);
- }
-}
diff --git a/src/main/java/monologue/GlobalLogged.java b/src/main/java/monologue/GlobalLogged.java
deleted file mode 100644
index 3394893..0000000
--- a/src/main/java/monologue/GlobalLogged.java
+++ /dev/null
@@ -1,583 +0,0 @@
-package monologue;
-
-import edu.wpi.first.networktables.NetworkTable;
-import edu.wpi.first.util.sendable.Sendable;
-import edu.wpi.first.util.struct.Struct;
-import edu.wpi.first.util.struct.StructSerializable;
-import edu.wpi.first.wpilibj.smartdashboard.Field2d;
-import edu.wpi.first.wpilibj.smartdashboard.Mechanism2d;
-import monologue.MonoSendableLayer.NtSendableCompat;
-
-/**
- * The GlobalLogged class is a utility class that provides a simple way to use Monologue's logging
- * tooling from any part of your robot code. It provides a set of log methods that allow you to log
- * data to the NetworkTables and DataLog.
- *
- * @see Monologue
- * @see LogSink
- */
-class GlobalLogged {
- static String ROOT_PATH = "";
-
- static void setRootPath(String rootPath) {
- ROOT_PATH = NetworkTable.normalizeKey(rootPath, true);
- }
-
- /**
- * Logs a boolean using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- */
- public static boolean log(String entryName, boolean value) {
- return log(entryName, value, LogSink.NT);
- }
-
- /**
- * Logs a boolean using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- * @param sink The log sink to use.
- */
- public static boolean log(String entryName, boolean value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.log(entryNameFinal, value, sink));
- return value;
- }
- MonoEntryLayer.MonologueEntry.createBoolean(entryName, sink).logBoolean(value);
-
- return value;
- }
-
- /**
- * Logs a int using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- */
- public static int log(String entryName, int value) {
- return log(entryName, value, LogSink.NT);
- }
-
- /**
- * Logs a int using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- * @param sink The log sink to use.
- */
- public static int log(String entryName, int value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.log(entryNameFinal, value, sink));
- return value;
- }
- MonoEntryLayer.MonologueEntry.createLong(entryName, sink).logLong(value);
-
- return value;
- }
-
- /**
- * Logs a long using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- */
- public static long log(String entryName, long value) {
- return log(entryName, value, LogSink.NT);
- }
-
- /**
- * Logs a long using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- * @param sink The log sink to use.
- */
- public static long log(String entryName, long value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.log(entryNameFinal, value, sink));
- return value;
- }
- MonoEntryLayer.MonologueEntry.createLong(entryName, sink).logLong(value);
-
- return value;
- }
-
- /**
- * Logs a float using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- */
- public static float log(String entryName, float value) {
- return log(entryName, value, LogSink.NT);
- }
-
- /**
- * Logs a float using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- * @param sink The log sink to use.
- */
- public static float log(String entryName, float value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.log(entryNameFinal, value, sink));
- return value;
- }
- MonoEntryLayer.MonologueEntry.createDouble(entryName, sink).logDouble(value);
-
- return value;
- }
-
- /**
- * Logs a double using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- */
- public static double log(String entryName, double value) {
- return log(entryName, value, LogSink.NT);
- }
-
- /**
- * Logs a double using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- * @param sink The log sink to use.
- */
- public static double log(String entryName, double value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.log(entryNameFinal, value, sink));
- return value;
- }
- MonoEntryLayer.MonologueEntry.createDouble(entryName, sink).logDouble(value);
-
- return value;
- }
-
- /**
- * Logs a String using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- */
- public static String log(String entryName, String value) {
- return log(entryName, value, LogSink.NT);
- }
-
- /**
- * Logs a String using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- * @param sink The log sink to use.
- */
- public static String log(String entryName, String value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.log(entryNameFinal, value, sink));
- return value;
- }
- MonoEntryLayer.MonologueEntry.create(entryName, String.class, sink).log(value);
-
- return value;
- }
-
- /**
- * Logs a byte[] using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- */
- public static byte[] log(String entryName, byte[] value) {
- return log(entryName, value, LogSink.NT);
- }
-
- /**
- * Logs a byte[] using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- * @param sink The log sink to use.
- */
- public static byte[] log(String entryName, byte[] value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.log(entryNameFinal, value, sink));
- return value;
- }
- MonoEntryLayer.MonologueEntry.create(entryName, byte[].class, sink).log(value);
-
- return value;
- }
-
- /**
- * Logs a boolean[] using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- */
- public static boolean[] log(String entryName, boolean[] value) {
- return log(entryName, value, LogSink.NT);
- }
-
- /**
- * Logs a boolean[] using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- * @param sink The log sink to use.
- */
- public static boolean[] log(String entryName, boolean[] value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.log(entryNameFinal, value, sink));
- return value;
- }
- MonoEntryLayer.MonologueEntry.create(entryName, boolean[].class, sink).log(value);
-
- return value;
- }
-
- /**
- * Logs a int[] using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- */
- public static int[] log(String entryName, int[] value) {
- return log(entryName, value, LogSink.NT);
- }
-
- /**
- * Logs a int[] using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- * @param sink The log sink to use.
- */
- public static int[] log(String entryName, int[] value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.log(entryNameFinal, value, sink));
- return value;
- }
- MonoEntryLayer.MonologueEntry.create(entryName, int[].class, sink).log(value);
-
- return value;
- }
-
- /**
- * Logs a long[] using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- */
- public static long[] log(String entryName, long[] value) {
- return log(entryName, value, LogSink.NT);
- }
-
- /**
- * Logs a long[] using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- * @param sink The log sink to use.
- */
- public static long[] log(String entryName, long[] value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.log(entryNameFinal, value, sink));
- return value;
- }
- MonoEntryLayer.MonologueEntry.create(entryName, long[].class, sink).log(value);
-
- return value;
- }
-
- /**
- * Logs a float[] using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- */
- public static float[] log(String entryName, float[] value) {
- return log(entryName, value, LogSink.NT);
- }
-
- /**
- * Logs a float[] using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- * @param sink The log sink to use.
- */
- public static float[] log(String entryName, float[] value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.log(entryNameFinal, value, sink));
- return value;
- }
- MonoEntryLayer.MonologueEntry.create(entryName, float[].class, sink).log(value);
-
- return value;
- }
-
- /**
- * Logs a double[] using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- */
- public static double[] log(String entryName, double[] value) {
- return log(entryName, value, LogSink.NT);
- }
-
- /**
- * Logs a double[] using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- * @param sink The log sink to use.
- */
- public static double[] log(String entryName, double[] value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.log(entryNameFinal, value, sink));
- return value;
- }
- MonoEntryLayer.MonologueEntry.create(entryName, double[].class, sink).log(value);
-
- return value;
- }
-
- /**
- * Logs a String[] using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- */
- public static String[] log(String entryName, String[] value) {
- return log(entryName, value, LogSink.NT);
- }
-
- /**
- * Logs a String[] using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- * @param sink The log sink to use.
- */
- public static String[] log(String entryName, String[] value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.log(entryNameFinal, value, sink));
- return value;
- }
- MonoEntryLayer.MonologueEntry.create(entryName, String[].class, sink).log(value);
-
- return value;
- }
-
- /**
- * Logs a Serializable Struct using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- */
- public static R log(String entryName, R value) {
- return log(entryName, value, LogSink.NT);
- }
-
- /**
- * Logs a Serializable Struct using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- * @param sink The log sink to use.
- */
- @SuppressWarnings("unchecked")
- public static R log(String entryName, R value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.log(entryNameFinal, value, sink));
- return value;
- }
- Class clazz = (Class) value.getClass();
- Struct struct =
- ProceduralStructGenerator.extractClassStruct(clazz)
- .orElseThrow(
- () ->
- new IllegalArgumentException(
- "Class " + clazz.getName() + " does not have a struct."));
- MonoEntryLayer.MonologueEntry.create(entryName, struct, sink).log(value);
-
- return value;
- }
-
- /**
- * Logs an array of Serializable Structs using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- */
- public static R[] log(String entryName, R[] value) {
- return log(entryName, value, LogSink.NT);
- }
-
- /**
- * Logs an array of Serializable Structs using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- * @param sink The log sink to use.
- */
- @SuppressWarnings("unchecked")
- public static R[] log(String entryName, R[] value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.log(entryNameFinal, value, sink));
- return value;
- }
- Class clazz = (Class) value.getClass();
- Struct struct =
- (Struct)
- ProceduralStructGenerator.extractClassStructDynamic(clazz.getComponentType()).get();
- MonoEntryLayer.MonologueEntry.create(entryName, struct, clazz, sink).log(value);
-
- return value;
- }
-
- /**
- * Logs a Serializable Struct using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param struct The struct type to log.
- * @param value The value to log.
- */
- public static R log(String entryName, Struct struct, R value) {
- return log(entryName, struct, value, LogSink.NT);
- }
-
- /**
- * Logs a Serializable Struct using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param struct The struct type to log.
- * @param value The value to log.
- * @param sink The log sink to use.
- */
- public static R log(String entryName, Struct struct, R value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.log(entryNameFinal, struct, value, sink));
- return value;
- }
- MonoEntryLayer.MonologueEntry.create(entryName, struct, sink).log(value);
-
- return value;
- }
-
- /**
- * Logs an array of Serializable Structs using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param struct The struct type to log.
- * @param value The value to log.
- */
- public static R[] log(String entryName, Struct struct, R[] value) {
- return log(entryName, struct, value, LogSink.NT);
- }
-
- /**
- * Logs an array of Serializable Structs using the Monologue machinery.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param struct The struct type to log.
- * @param value The value to log.
- * @param sink The log sink to use.
- */
- @SuppressWarnings("unchecked")
- public static R[] log(String entryName, Struct struct, R[] value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.log(entryNameFinal, struct, value, sink));
- return value;
- }
- Class clazz = (Class) value.getClass();
- MonoEntryLayer.MonologueEntry.create(entryName, struct, clazz, sink).log(value);
-
- return value;
- }
-
- static R[] logStructArray(String entryName, Struct struct, R[] value, LogSink sink) {
- return log(entryName, struct, value, sink);
- }
-
- /**
- * Logs a Sendable using the Monologue machinery.
- *
- *
Monologue only supports data going 1 way, from the robot to the driver station. This means
- * that Sendables that are updated by the driver station will not be updated on the robot.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- */
- public static void publishSendable(String entryName, Sendable value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.publishSendable(entryNameFinal, value, sink));
- return;
- }
- entryName = NetworkTable.normalizeKey(entryName, true);
- var builder = new MonoSendableLayer.Builder(entryName, sink);
- value.initSendable(builder);
- builder.finish();
- }
-
- /**
- * Logs a Sendable using the Monologue machinery.
- *
- *
This method is used to log a Sendable that is a Field2d. Field2d is an {@code NTSendable}
- * which require specialized code to log to Datalog.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- */
- public static void publishSendable(String entryName, Field2d value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.publishSendable(entryNameFinal, value, sink));
- return;
- }
- entryName = NetworkTable.normalizeKey(entryName, true);
- NtSendableCompat.addField2d(entryName, value, sink);
- }
-
- /**
- * Logs a Sendable using the Monologue machinery.
- *
- *
This method is used to log a Sendable that is a Mechanism2d. Mechanism2d is an {@code
- * NTSendable} which require specialized code to log to Datalog.
- *
- * @param entryName The name of the entry to log, this is an absolute path.
- * @param value The value to log.
- */
- public static void publishSendable(String entryName, Mechanism2d value, LogSink sink) {
- if (!Monologue.hasBeenSetup() || Monologue.isMonologueDisabled()) {
- String entryNameFinal = entryName;
- Monologue.prematureLog(() -> GlobalLogged.publishSendable(entryNameFinal, value, sink));
- return;
- }
- entryName = NetworkTable.normalizeKey(entryName, true);
- NtSendableCompat.addMechanism2d(entryName, value, sink);
- }
-}
diff --git a/src/main/java/monologue/LogSink.java b/src/main/java/monologue/LogSink.java
deleted file mode 100644
index 12090da..0000000
--- a/src/main/java/monologue/LogSink.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package monologue;
-
-public enum LogSink {
- /** Logs will be sent to NetworkTables and then mirrored to DataLog */
- NT,
- /** Logs will be sent to DataLog only */
- DL,
- /**
- * Will behave like {@link #DL} if {@link Monologue#isBandwidthOptimizationEnabled()} is true,
- * otherwise will behave like {@link #NT}
- */
- OP;
-
- /**
- * Whether or not to log under the current library/logger flags
- *
- * @param fileOnly If the library is in fileOnly mode
- * @param nt If the logger asking is the nt logger
- * @return
- */
- boolean shouldLog(boolean fileOnly, boolean nt) {
- switch (this) {
- case NT:
- return !nt;
- case DL:
- return !nt;
- case OP:
- if (fileOnly) {
- DL.shouldLog(fileOnly, nt);
- } else {
- NT.shouldLog(fileOnly, nt);
- }
- default:
- return false;
- }
- }
-}
diff --git a/src/main/java/monologue/Logged.java b/src/main/java/monologue/Logged.java
deleted file mode 100644
index 7132fcd..0000000
--- a/src/main/java/monologue/Logged.java
+++ /dev/null
@@ -1,617 +0,0 @@
-package monologue;
-
-import edu.wpi.first.util.sendable.Sendable;
-import edu.wpi.first.util.struct.Struct;
-import edu.wpi.first.util.struct.StructSerializable;
-import edu.wpi.first.wpilibj.smartdashboard.Field2d;
-import edu.wpi.first.wpilibj.smartdashboard.Mechanism2d;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.WeakHashMap;
-import monologue.LoggingTree.LoggingNode;
-
-/**
- * Interface for classes that can hold {@link Monologue} annotated fields for {@link
- * Monologue#setupMonologue} and {@link Monologue#logObj} to log.
- *
- *
This class also allows for an imperative way to log values with the {@link #log} methods.
- *
- * @see Monologue
- * @see Annotations.Log
- * @see Annotations.Log.Once
- */
-public interface Logged {
-
- static final WeakHashMap