Skip to content

Commit

Permalink
small changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel1464 committed Dec 9, 2024
1 parent 95135ec commit 3d8958d
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,10 @@

package edu.wpi.first.epilogue.util;

import edu.wpi.first.epilogue.Logged;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.WeakHashMap;

/**
* A utility interface that allows you to infer epilogue log paths for manual logging.
*
* <h5>InferLogPath.Parser.enable(this) must be called in your Robot class first before using this
* interface.</h5>
* <code>LogPathInference.enable(this);</code> must be called within the constructor of
* your Robot class before using this interface.
*/
public interface InferLogPath {
/**
Expand All @@ -23,60 +17,8 @@ public interface InferLogPath {
* @return An absolute log path that follows epilogue conventions.
*/
default String logPath(String logUnder) {
return Parser.logPathMap.getOrDefault(this, Parser.DEFAULT_NAMESPACE) + "/" + logUnder;
}

@SuppressWarnings("PMD.AvoidAccessibilityAlteration")
final class Parser {
private static final Map<Object, String> logPathMap = new WeakHashMap<>();
private static final String DEFAULT_NAMESPACE = "UNKNOWN";
private static boolean enabled;

/**
* Enables log path parsing. This must be called in your robot class to use this interface.
*
* @param robotInstance The TimedRobot instance
*/
public static void enable(Object robotInstance) {
if (enabled) {
return;
}
enabled = true;
recurseLogPaths(robotInstance, "");
}

private Parser() {}

private static void recurseLogPaths(Object obj, String currentPath) {
logPathMap.put(obj, currentPath);
var clazz = obj.getClass();
for (var field : clazz.getDeclaredFields()) {
try {
if (InferLogPath.class.isAssignableFrom(field.getType())) {
field.setAccessible(true);
recurseLogPaths(field.get(obj), currentPath + "/" + computeLogName(field));
} else {
var arraySubtype = field.getType().getComponentType();
if (arraySubtype == null || !InferLogPath.class.isAssignableFrom(arraySubtype)) {
continue;
}
field.setAccessible(true);
int index = 0;
var name = computeLogName(field);
for (Object value : (Object[]) field.get(obj)) {
recurseLogPaths(value, currentPath + "/" + name + "/" + index);
index++;
}
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}

private static String computeLogName(Field field) {
Logged logAnno = field.getAnnotation(Logged.class);
return logAnno == null || logAnno.name().isEmpty() ? field.getName() : logAnno.name();
}
return LogPathInference.logPathMap.getOrDefault(this, LogPathInference.DEFAULT_NAMESPACE)
+ "/"
+ logUnder;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package edu.wpi.first.epilogue.util;

import edu.wpi.first.epilogue.Logged;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.WeakHashMap;

/**
* The parser for usage of the {@link InferLogPath} interface. To start, call <code>
* LogPathInference.start(this);</code> in your robot class.
*/
@SuppressWarnings("PMD.AvoidAccessibilityAlteration")
public final class LogPathInference {
static final Map<Object, String> logPathMap = new WeakHashMap<>();
static final String DEFAULT_NAMESPACE = "UNKNOWN";
private static boolean enabled;

/**
* Enables log path parsing. This must be called in your robot class to use this interface.
*
* @param robotInstance The TimedRobot instance
*/
public static void enable(Object robotInstance) {
if (enabled) {
return;
}
enabled = true;
recurseLogPaths(robotInstance, "");
}

private LogPathInference() {}

private static void recurseLogPaths(Object obj, String currentPath) {
logPathMap.put(obj, currentPath);
var clazz = obj.getClass();
for (var field : clazz.getDeclaredFields()) {
try {
if (InferLogPath.class.isAssignableFrom(field.getType())) {
field.setAccessible(true);
recurseLogPaths(field.get(obj), currentPath + "/" + computeLogName(field));
} else {
var arraySubtype = field.getType().getComponentType();
if (arraySubtype == null || !InferLogPath.class.isAssignableFrom(arraySubtype)) {
continue;
}
field.setAccessible(true);
int index = 0;
var name = computeLogName(field);
for (Object value : (Object[]) field.get(obj)) {
recurseLogPaths(value, currentPath + "/" + name + "/" + index);
index++;
}
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}

private static String computeLogName(Field field) {
Logged logAnno = field.getAnnotation(Logged.class);
return logAnno == null || logAnno.name().isEmpty() ? field.getName() : logAnno.name();
}
}

0 comments on commit 3d8958d

Please sign in to comment.