mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[epilogue] Improve support for robot base classes in epilogue (#8886)
Generate an `update` method for any logged Robot class, not just TimedRobot Continue to generate a `bind` method for TimedRobot subclasses Also removes unnecessary import statements for generated loggers, since they're using fully-qualified names in the generated Epilogue class now.
This commit is contained in:
@@ -382,9 +382,12 @@ public class AnnotationProcessor extends AbstractProcessor {
|
|||||||
|
|
||||||
List<String> loggerClassNames = new ArrayList<>();
|
List<String> loggerClassNames = new ArrayList<>();
|
||||||
var mainRobotClasses = new ArrayList<TypeElement>();
|
var mainRobotClasses = new ArrayList<TypeElement>();
|
||||||
|
var timedRobotClasses = new ArrayList<TypeElement>();
|
||||||
|
|
||||||
// Used to check for a main robot class
|
// Used to check for a main robot class
|
||||||
var robotBaseClass =
|
var robotBaseClass =
|
||||||
|
processingEnv.getElementUtils().getTypeElement("org.wpilib.framework.RobotBase").asType();
|
||||||
|
var timedRobotClass =
|
||||||
processingEnv.getElementUtils().getTypeElement("org.wpilib.framework.TimedRobot").asType();
|
processingEnv.getElementUtils().getTypeElement("org.wpilib.framework.TimedRobot").asType();
|
||||||
|
|
||||||
boolean validFields = validateFields(annotatedElements);
|
boolean validFields = validateFields(annotatedElements);
|
||||||
@@ -403,6 +406,9 @@ public class AnnotationProcessor extends AbstractProcessor {
|
|||||||
if (processingEnv.getTypeUtils().isAssignable(clazz.getSuperclass(), robotBaseClass)) {
|
if (processingEnv.getTypeUtils().isAssignable(clazz.getSuperclass(), robotBaseClass)) {
|
||||||
mainRobotClasses.add(clazz);
|
mainRobotClasses.add(clazz);
|
||||||
}
|
}
|
||||||
|
if (processingEnv.getTypeUtils().isAssignable(clazz.getSuperclass(), timedRobotClass)) {
|
||||||
|
timedRobotClasses.add(clazz);
|
||||||
|
}
|
||||||
|
|
||||||
loggerClassNames.add(StringUtils.loggerClassName(clazz));
|
loggerClassNames.add(StringUtils.loggerClassName(clazz));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -417,8 +423,10 @@ public class AnnotationProcessor extends AbstractProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sort alphabetically
|
// Sort alphabetically
|
||||||
mainRobotClasses.sort(Comparator.comparing(c -> c.getSimpleName().toString()));
|
loggerClassNames.sort(Comparator.naturalOrder());
|
||||||
m_epilogueGenerator.writeEpilogueFile(loggerClassNames, mainRobotClasses);
|
mainRobotClasses.sort(Comparator.comparing(TypeElement::toString));
|
||||||
|
timedRobotClasses.sort(Comparator.comparing(TypeElement::toString));
|
||||||
|
m_epilogueGenerator.writeEpilogueFile(loggerClassNames, mainRobotClasses, timedRobotClasses);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void warnOfNonLoggableElements(TypeElement clazz) {
|
private void warnOfNonLoggableElements(TypeElement clazz) {
|
||||||
|
|||||||
@@ -38,12 +38,16 @@ public class EpilogueGenerator {
|
|||||||
*
|
*
|
||||||
* @param loggerClassNames the names of the generated logger classes. Each of these will be
|
* @param loggerClassNames the names of the generated logger classes. Each of these will be
|
||||||
* instantiated in a public static field on the Epilogue class.
|
* instantiated in a public static field on the Epilogue class.
|
||||||
* @param mainRobotClasses the main robot classes. May be empty. Used to generate a {@code bind()}
|
* @param mainRobotClasses the main robot classes. May be empty. Used to generate a {@code
|
||||||
* method to add a callback hook to a TimedRobot to log itself.
|
* update()} method for an easy entry point.
|
||||||
|
* @param timedRobotClasses the main robot classes that extend from TimedRobot. Used to generate a
|
||||||
|
* {@code bind()} method to add a callback hook to a TimedRobot to log itself.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("checkstyle:LineLength") // Source code templates exceed the line length limit
|
@SuppressWarnings("checkstyle:LineLength") // Source code templates exceed the line length limit
|
||||||
public void writeEpilogueFile(
|
public void writeEpilogueFile(
|
||||||
List<String> loggerClassNames, Collection<TypeElement> mainRobotClasses) {
|
List<String> loggerClassNames,
|
||||||
|
Collection<TypeElement> mainRobotClasses,
|
||||||
|
Collection<TypeElement> timedRobotClasses) {
|
||||||
try {
|
try {
|
||||||
var centralStore =
|
var centralStore =
|
||||||
m_processingEnv.getFiler().createSourceFile("org.wpilib.epilogue.Epilogue");
|
m_processingEnv.getFiler().createSourceFile("org.wpilib.epilogue.Epilogue");
|
||||||
@@ -58,30 +62,6 @@ public class EpilogueGenerator {
|
|||||||
out.println("import org.wpilib.hardware.hal.HAL;");
|
out.println("import org.wpilib.hardware.hal.HAL;");
|
||||||
out.println();
|
out.println();
|
||||||
|
|
||||||
loggerClassNames.stream()
|
|
||||||
.sorted()
|
|
||||||
.forEach(
|
|
||||||
name -> {
|
|
||||||
if (!name.contains(".")) {
|
|
||||||
// Logger is in the global namespace, don't need to import
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
out.println("import " + name + ";");
|
|
||||||
});
|
|
||||||
m_customLoggers.values().stream()
|
|
||||||
.distinct()
|
|
||||||
.forEach(
|
|
||||||
loggerType -> {
|
|
||||||
var name = loggerType.asElement().toString();
|
|
||||||
if (!name.contains(".")) {
|
|
||||||
// Logger is in the global namespace, don't need to import
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
out.println("import " + name + ";");
|
|
||||||
});
|
|
||||||
out.println();
|
|
||||||
|
|
||||||
out.println("public final class Epilogue {");
|
out.println("public final class Epilogue {");
|
||||||
|
|
||||||
// Usage reporting
|
// Usage reporting
|
||||||
@@ -136,8 +116,6 @@ public class EpilogueGenerator {
|
|||||||
"""
|
"""
|
||||||
.stripTrailing());
|
.stripTrailing());
|
||||||
|
|
||||||
// Only generate a binding if the robot class is a TimedRobot
|
|
||||||
if (!mainRobotClasses.isEmpty()) {
|
|
||||||
for (TypeElement mainRobotClass : mainRobotClasses) {
|
for (TypeElement mainRobotClass : mainRobotClasses) {
|
||||||
String robotClassName = mainRobotClass.getQualifiedName().toString();
|
String robotClassName = mainRobotClass.getQualifiedName().toString();
|
||||||
|
|
||||||
@@ -159,6 +137,10 @@ public class EpilogueGenerator {
|
|||||||
out.println(
|
out.println(
|
||||||
" config.backend.log(\"Epilogue/Stats/Last Run\", (System.nanoTime() - start) / 1e6);");
|
" config.backend.log(\"Epilogue/Stats/Last Run\", (System.nanoTime() - start) / 1e6);");
|
||||||
out.println(" }");
|
out.println(" }");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (TypeElement timedRobotClass : timedRobotClasses) {
|
||||||
|
String robotClassName = timedRobotClass.getQualifiedName().toString();
|
||||||
|
|
||||||
out.println();
|
out.println();
|
||||||
out.print(
|
out.print(
|
||||||
@@ -186,7 +168,6 @@ public class EpilogueGenerator {
|
|||||||
" }, config.loggingPeriod.in(Seconds), config.loggingPeriodOffset.in(Seconds));");
|
" }, config.loggingPeriod.in(Seconds), config.loggingPeriodOffset.in(Seconds));");
|
||||||
out.println(" }");
|
out.println(" }");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
out.println("}");
|
out.println("}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,8 +35,6 @@ class EpilogueGeneratorTest {
|
|||||||
|
|
||||||
import org.wpilib.hardware.hal.HAL;
|
import org.wpilib.hardware.hal.HAL;
|
||||||
|
|
||||||
import org.wpilib.epilogue.ExampleLogger;
|
|
||||||
|
|
||||||
public final class Epilogue {
|
public final class Epilogue {
|
||||||
static {
|
static {
|
||||||
HAL.reportUsage("Epilogue", "");
|
HAL.reportUsage("Epilogue", "");
|
||||||
@@ -90,8 +88,6 @@ class EpilogueGeneratorTest {
|
|||||||
|
|
||||||
import org.wpilib.hardware.hal.HAL;
|
import org.wpilib.hardware.hal.HAL;
|
||||||
|
|
||||||
import org.wpilib.epilogue.ExampleLogger;
|
|
||||||
|
|
||||||
public final class Epilogue {
|
public final class Epilogue {
|
||||||
static {
|
static {
|
||||||
HAL.reportUsage("Epilogue", "");
|
HAL.reportUsage("Epilogue", "");
|
||||||
@@ -115,6 +111,17 @@ class EpilogueGeneratorTest {
|
|||||||
public static boolean shouldLog(Logged.Importance importance) {
|
public static boolean shouldLog(Logged.Importance importance) {
|
||||||
return importance.compareTo(config.minimumImportance) >= 0;
|
return importance.compareTo(config.minimumImportance) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates Epilogue. This must be called periodically in order for Epilogue to record
|
||||||
|
* new values. Alternatively, {@code bind()} can be used to update at an offset from
|
||||||
|
* the main robot loop.
|
||||||
|
*/
|
||||||
|
public static void update(org.wpilib.epilogue.Example robot) {
|
||||||
|
long start = System.nanoTime();
|
||||||
|
org_wpilib_epilogue_ExampleLogger.tryUpdate(config.backend.getNested(config.root), robot, config.errorHandler);
|
||||||
|
config.backend.log("Epilogue/Stats/Last Run", (System.nanoTime() - start) / 1e6);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
""";
|
""";
|
||||||
|
|
||||||
@@ -140,8 +147,6 @@ class EpilogueGeneratorTest {
|
|||||||
|
|
||||||
import org.wpilib.hardware.hal.HAL;
|
import org.wpilib.hardware.hal.HAL;
|
||||||
|
|
||||||
import org.wpilib.epilogue.ExampleLogger;
|
|
||||||
|
|
||||||
public final class Epilogue {
|
public final class Epilogue {
|
||||||
static {
|
static {
|
||||||
HAL.reportUsage("Epilogue", "");
|
HAL.reportUsage("Epilogue", "");
|
||||||
@@ -224,9 +229,6 @@ class EpilogueGeneratorTest {
|
|||||||
|
|
||||||
import org.wpilib.hardware.hal.HAL;
|
import org.wpilib.hardware.hal.HAL;
|
||||||
|
|
||||||
import org.wpilib.epilogue.AlphaBotLogger;
|
|
||||||
import org.wpilib.epilogue.BetaBotLogger;
|
|
||||||
|
|
||||||
public final class Epilogue {
|
public final class Epilogue {
|
||||||
static {
|
static {
|
||||||
HAL.reportUsage("Epilogue", "");
|
HAL.reportUsage("Epilogue", "");
|
||||||
@@ -263,6 +265,17 @@ class EpilogueGeneratorTest {
|
|||||||
config.backend.log("Epilogue/Stats/Last Run", (System.nanoTime() - start) / 1e6);
|
config.backend.log("Epilogue/Stats/Last Run", (System.nanoTime() - start) / 1e6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates Epilogue. This must be called periodically in order for Epilogue to record
|
||||||
|
* new values. Alternatively, {@code bind()} can be used to update at an offset from
|
||||||
|
* the main robot loop.
|
||||||
|
*/
|
||||||
|
public static void update(org.wpilib.epilogue.BetaBot robot) {
|
||||||
|
long start = System.nanoTime();
|
||||||
|
org_wpilib_epilogue_BetaBotLogger.tryUpdate(config.backend.getNested(config.root), robot, config.errorHandler);
|
||||||
|
config.backend.log("Epilogue/Stats/Last Run", (System.nanoTime() - start) / 1e6);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Binds Epilogue updates to a timed robot's update period. Log calls will be made at the
|
* Binds Epilogue updates to a timed robot's update period. Log calls will be made at the
|
||||||
* same update rate as the robot's loop function, but will be offset by a full phase
|
* same update rate as the robot's loop function, but will be offset by a full phase
|
||||||
@@ -284,17 +297,6 @@ class EpilogueGeneratorTest {
|
|||||||
}, config.loggingPeriod.in(Seconds), config.loggingPeriodOffset.in(Seconds));
|
}, config.loggingPeriod.in(Seconds), config.loggingPeriodOffset.in(Seconds));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates Epilogue. This must be called periodically in order for Epilogue to record
|
|
||||||
* new values. Alternatively, {@code bind()} can be used to update at an offset from
|
|
||||||
* the main robot loop.
|
|
||||||
*/
|
|
||||||
public static void update(org.wpilib.epilogue.BetaBot robot) {
|
|
||||||
long start = System.nanoTime();
|
|
||||||
org_wpilib_epilogue_BetaBotLogger.tryUpdate(config.backend.getNested(config.root), robot, config.errorHandler);
|
|
||||||
config.backend.log("Epilogue/Stats/Last Run", (System.nanoTime() - start) / 1e6);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Binds Epilogue updates to a timed robot's update period. Log calls will be made at the
|
* Binds Epilogue updates to a timed robot's update period. Log calls will be made at the
|
||||||
* same update rate as the robot's loop function, but will be offset by a full phase
|
* same update rate as the robot's loop function, but will be offset by a full phase
|
||||||
@@ -357,9 +359,6 @@ class EpilogueGeneratorTest {
|
|||||||
|
|
||||||
import org.wpilib.hardware.hal.HAL;
|
import org.wpilib.hardware.hal.HAL;
|
||||||
|
|
||||||
import org.wpilib.epilogue.ExampleLogger;
|
|
||||||
import org.wpilib.epilogue.CustomLogger;
|
|
||||||
|
|
||||||
public final class Epilogue {
|
public final class Epilogue {
|
||||||
static {
|
static {
|
||||||
HAL.reportUsage("Epilogue", "");
|
HAL.reportUsage("Epilogue", "");
|
||||||
|
|||||||
Reference in New Issue
Block a user