From e39552c5402726bb00af7ebc069d8b84faa58d0a Mon Sep 17 00:00:00 2001 From: Daniel Chen Date: Fri, 13 Dec 2024 20:14:52 -0500 Subject: [PATCH 1/4] initial --- .../processor/AnnotationProcessor.java | 9 ++- .../processor/AnnotationProcessorTest.java | 55 ++++++++++++++++ epilogue-runtime/build.gradle | 1 + .../first/epilogue/EpilogueConfiguration.java | 5 +- .../first/epilogue/logging/FileBackend.java | 6 ++ ...{NTEpilogueBackend.java => NTBackend.java} | 66 ++++++++++++++++++- 6 files changed, 136 insertions(+), 6 deletions(-) rename epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/{NTEpilogueBackend.java => NTBackend.java} (72%) diff --git a/epilogue-processor/src/main/java/edu/wpi/first/epilogue/processor/AnnotationProcessor.java b/epilogue-processor/src/main/java/edu/wpi/first/epilogue/processor/AnnotationProcessor.java index 2781c055c8c..abae9b7aeae 100644 --- a/epilogue-processor/src/main/java/edu/wpi/first/epilogue/processor/AnnotationProcessor.java +++ b/epilogue-processor/src/main/java/edu/wpi/first/epilogue/processor/AnnotationProcessor.java @@ -143,12 +143,19 @@ private Set getLoggedTypes(RoundEnvironment roundEnv) { annotatedElements.stream() .filter(e -> e instanceof TypeElement) .map(e -> (TypeElement) e), - // 2. All type elements containing a field or method with the @Logged annotation + // 2. All type elements containing a field or method with the @Logged annotation, + // or interfaces which have an implementing class with an @Logged annotation annotatedElements.stream() .filter(e -> e instanceof VariableElement || e instanceof ExecutableElement) .map(Element::getEnclosingElement) .filter(e -> e instanceof TypeElement) .map(e -> (TypeElement) e)) + .flatMap( + e -> + Stream.concat( + Stream.of(e), + e.getInterfaces().stream() + .map(i -> (TypeElement) ((DeclaredType) i).asElement()))) .sorted(Comparator.comparing(e -> e.getSimpleName().toString())) .collect( Collectors.toCollection(LinkedHashSet::new)); // Collect to a set to avoid duplicates diff --git a/epilogue-processor/src/test/java/edu/wpi/first/epilogue/processor/AnnotationProcessorTest.java b/epilogue-processor/src/test/java/edu/wpi/first/epilogue/processor/AnnotationProcessorTest.java index ec4e52d5f4f..4661fe83a19 100644 --- a/epilogue-processor/src/test/java/edu/wpi/first/epilogue/processor/AnnotationProcessorTest.java +++ b/epilogue-processor/src/test/java/edu/wpi/first/epilogue/processor/AnnotationProcessorTest.java @@ -99,6 +99,61 @@ public void update(EpilogueBackend backend, Example object) { assertLoggerGenerates(source, expectedGeneratedSource); } + @Test + void optInInheritance() { + String source = + """ + package edu.wpi.first.epilogue; + + class Example { + @Logged public ABC inst = new Base2(); + } + + class Base implements ABC { + double x; + } + + class Base2 implements ABC { + @Logged double x; + } + + interface ABC { + default double a() { return 2.0; } + } + """; + + String expectedGeneratedSource = + """ + package edu.wpi.first.epilogue; + + import edu.wpi.first.epilogue.Logged; + import edu.wpi.first.epilogue.Epilogue; + import edu.wpi.first.epilogue.logging.ClassSpecificLogger; + import edu.wpi.first.epilogue.logging.EpilogueBackend; + + public class ExampleLogger extends ClassSpecificLogger { + public ExampleLogger() { + super(Example.class); + } + + @Override + public void update(EpilogueBackend backend, Example object) { + if (Epilogue.shouldLog(Logged.Importance.DEBUG)) { + var $$inst = object.inst; + if ($$inst instanceof edu.wpi.first.epilogue.Base2 edu_wpi_first_epilogue_Base2) { + Epilogue.base2Logger.tryUpdate(backend.getNested("inst"), edu_wpi_first_epilogue_Base2, Epilogue.getConfig().errorHandler); + } else { + // Base type edu.wpi.first.epilogue.ABC + Epilogue.abcLogger.tryUpdate(backend.getNested("inst"), $$inst, Epilogue.getConfig().errorHandler); + }; + } + } + } + """; + + assertLoggerGenerates(source, expectedGeneratedSource); + } + @Test void optInMethods() { String source = diff --git a/epilogue-runtime/build.gradle b/epilogue-runtime/build.gradle index fb96095a0a5..303c090c9c7 100644 --- a/epilogue-runtime/build.gradle +++ b/epilogue-runtime/build.gradle @@ -13,4 +13,5 @@ dependencies { api(project(':ntcore')) api(project(':wpiutil')) api(project(':wpiunits')) + api(project(':wpilibj')) } diff --git a/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/EpilogueConfiguration.java b/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/EpilogueConfiguration.java index a35f98d41a4..96111dea531 100644 --- a/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/EpilogueConfiguration.java +++ b/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/EpilogueConfiguration.java @@ -5,10 +5,9 @@ package edu.wpi.first.epilogue; import edu.wpi.first.epilogue.logging.EpilogueBackend; -import edu.wpi.first.epilogue.logging.NTEpilogueBackend; +import edu.wpi.first.epilogue.logging.NTBackend; import edu.wpi.first.epilogue.logging.errors.ErrorHandler; import edu.wpi.first.epilogue.logging.errors.ErrorPrinter; -import edu.wpi.first.networktables.NetworkTableInstance; import edu.wpi.first.units.measure.Time; /** @@ -22,7 +21,7 @@ public class EpilogueConfiguration { * NetworkTables. NetworkTable data can be mirrored to a log file on disk by calling {@code * DataLogManager.start()} in your {@code robotInit} method. */ - public EpilogueBackend backend = new NTEpilogueBackend(NetworkTableInstance.getDefault()); + public EpilogueBackend backend = new NTBackend(); /** * The period Epilogue will log at. By default this is the period that the robot runs at. This is diff --git a/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/FileBackend.java b/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/FileBackend.java index 2b5b6b2071b..6b6a82b3a09 100644 --- a/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/FileBackend.java +++ b/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/FileBackend.java @@ -22,6 +22,7 @@ import edu.wpi.first.util.datalog.StructArrayLogEntry; import edu.wpi.first.util.datalog.StructLogEntry; import edu.wpi.first.util.struct.Struct; +import edu.wpi.first.wpilibj.DataLogManager; import java.util.HashMap; import java.util.Map; import java.util.function.BiFunction; @@ -41,6 +42,11 @@ public FileBackend(DataLog dataLog) { this.m_dataLog = requireNonNullParam(dataLog, "dataLog", "FileBackend"); } + /** Creates a new file-based backend. */ + public FileBackend() { + this(DataLogManager.getLog()); + } + @Override public EpilogueBackend getNested(String path) { return m_subLoggers.computeIfAbsent(path, k -> new NestedBackend(k, this)); diff --git a/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/NTEpilogueBackend.java b/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/NTBackend.java similarity index 72% rename from epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/NTEpilogueBackend.java rename to epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/NTBackend.java index cf381a2f021..22406bfc303 100644 --- a/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/NTEpilogueBackend.java +++ b/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/NTBackend.java @@ -22,13 +22,15 @@ import edu.wpi.first.util.struct.Struct; import java.util.HashMap; import java.util.Map; +import java.util.function.BooleanSupplier; /** * A backend implementation that sends data over network tables. Be careful when using this, since * sending too much data may cause bandwidth or CPU starvation. */ -public class NTEpilogueBackend implements EpilogueBackend { +public class NTBackend implements EpilogueBackend { private final NetworkTableInstance m_nt; + private BooleanSupplier m_enabledSupplier; private final Map m_publishers = new HashMap<>(); private final Map m_nestedBackends = new HashMap<>(); @@ -38,10 +40,25 @@ public class NTEpilogueBackend implements EpilogueBackend { * * @param nt the NetworkTable instance to use to send data to */ - public NTEpilogueBackend(NetworkTableInstance nt) { + public NTBackend(NetworkTableInstance nt) { this.m_nt = nt; } + /** Creates a logging backend that sends information to NetworkTables. */ + public NTBackend() { + this.m_nt = NetworkTableInstance.getDefault(); + } + + /** + * Creates a logging backend that sends information to NetworkTables. + * + * @param enabledSupplier whether to enable networktables logging + */ + public NTBackend(BooleanSupplier enabledSupplier) { + this.m_nt = NetworkTableInstance.getDefault(); + this.m_enabledSupplier = enabledSupplier; + } + @Override public EpilogueBackend getNested(String path) { return m_nestedBackends.computeIfAbsent(path, k -> new NestedBackend(k, this)); @@ -49,6 +66,9 @@ public EpilogueBackend getNested(String path) { @Override public void log(String identifier, int value) { + if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + return; + } ((IntegerPublisher) m_publishers.computeIfAbsent(identifier, k -> m_nt.getIntegerTopic(k).publish())) .set(value); @@ -56,6 +76,9 @@ public void log(String identifier, int value) { @Override public void log(String identifier, long value) { + if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + return; + } ((IntegerPublisher) m_publishers.computeIfAbsent(identifier, k -> m_nt.getIntegerTopic(k).publish())) .set(value); @@ -63,6 +86,9 @@ public void log(String identifier, long value) { @Override public void log(String identifier, float value) { + if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + return; + } ((FloatPublisher) m_publishers.computeIfAbsent(identifier, k -> m_nt.getFloatTopic(k).publish())) .set(value); @@ -70,6 +96,9 @@ public void log(String identifier, float value) { @Override public void log(String identifier, double value) { + if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + return; + } ((DoublePublisher) m_publishers.computeIfAbsent(identifier, k -> m_nt.getDoubleTopic(k).publish())) .set(value); @@ -77,6 +106,9 @@ public void log(String identifier, double value) { @Override public void log(String identifier, boolean value) { + if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + return; + } ((BooleanPublisher) m_publishers.computeIfAbsent(identifier, k -> m_nt.getBooleanTopic(k).publish())) .set(value); @@ -84,6 +116,9 @@ public void log(String identifier, boolean value) { @Override public void log(String identifier, byte[] value) { + if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + return; + } ((RawPublisher) m_publishers.computeIfAbsent(identifier, k -> m_nt.getRawTopic(k).publish("raw"))) .set(value); @@ -92,6 +127,9 @@ public void log(String identifier, byte[] value) { @Override @SuppressWarnings("PMD.UnnecessaryCastRule") public void log(String identifier, int[] value) { + if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + return; + } // NT backend only supports int64[], so we have to manually widen to 64 bits before sending long[] widened = new long[value.length]; @@ -106,6 +144,9 @@ public void log(String identifier, int[] value) { @Override public void log(String identifier, long[] value) { + if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + return; + } ((IntegerArrayPublisher) m_publishers.computeIfAbsent(identifier, k -> m_nt.getIntegerArrayTopic(k).publish())) .set(value); @@ -113,6 +154,9 @@ public void log(String identifier, long[] value) { @Override public void log(String identifier, float[] value) { + if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + return; + } ((FloatArrayPublisher) m_publishers.computeIfAbsent(identifier, k -> m_nt.getFloatArrayTopic(k).publish())) .set(value); @@ -120,6 +164,9 @@ public void log(String identifier, float[] value) { @Override public void log(String identifier, double[] value) { + if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + return; + } ((DoubleArrayPublisher) m_publishers.computeIfAbsent(identifier, k -> m_nt.getDoubleArrayTopic(k).publish())) .set(value); @@ -127,6 +174,9 @@ public void log(String identifier, double[] value) { @Override public void log(String identifier, boolean[] value) { + if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + return; + } ((BooleanArrayPublisher) m_publishers.computeIfAbsent(identifier, k -> m_nt.getBooleanArrayTopic(k).publish())) .set(value); @@ -134,6 +184,9 @@ public void log(String identifier, boolean[] value) { @Override public void log(String identifier, String value) { + if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + return; + } ((StringPublisher) m_publishers.computeIfAbsent(identifier, k -> m_nt.getStringTopic(k).publish())) .set(value); @@ -141,6 +194,9 @@ public void log(String identifier, String value) { @Override public void log(String identifier, String[] value) { + if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + return; + } ((StringArrayPublisher) m_publishers.computeIfAbsent(identifier, k -> m_nt.getStringArrayTopic(k).publish())) .set(value); @@ -149,6 +205,9 @@ public void log(String identifier, String[] value) { @Override @SuppressWarnings("unchecked") public void log(String identifier, S value, Struct struct) { + if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + return; + } m_nt.addSchema(struct); ((StructPublisher) m_publishers.computeIfAbsent(identifier, k -> m_nt.getStructTopic(k, struct).publish())) @@ -158,6 +217,9 @@ public void log(String identifier, S value, Struct struct) { @Override @SuppressWarnings("unchecked") public void log(String identifier, S[] value, Struct struct) { + if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + return; + } m_nt.addSchema(struct); ((StructArrayPublisher) m_publishers.computeIfAbsent( From 06b4233114911b2f8006e9cd9c5ae125040d32d0 Mon Sep 17 00:00:00 2001 From: Daniel Chen Date: Sat, 14 Dec 2024 11:58:17 -0500 Subject: [PATCH 2/4] Improved api --- .../wpi/first/epilogue/logging/NTBackend.java | 50 ++++++++++--------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/NTBackend.java b/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/NTBackend.java index 22406bfc303..ba2b4de4ff3 100644 --- a/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/NTBackend.java +++ b/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/NTBackend.java @@ -30,7 +30,7 @@ */ public class NTBackend implements EpilogueBackend { private final NetworkTableInstance m_nt; - private BooleanSupplier m_enabledSupplier; + private BooleanSupplier m_disabledSupplier; private final Map m_publishers = new HashMap<>(); private final Map m_nestedBackends = new HashMap<>(); @@ -49,14 +49,16 @@ public NTBackend() { this.m_nt = NetworkTableInstance.getDefault(); } - /** - * Creates a logging backend that sends information to NetworkTables. - * - * @param enabledSupplier whether to enable networktables logging - */ - public NTBackend(BooleanSupplier enabledSupplier) { - this.m_nt = NetworkTableInstance.getDefault(); - this.m_enabledSupplier = enabledSupplier; + /** Creates a new NTBackend that is disabled whenever the disabledSupplier returns true. */ + public NTBackend disableWhen(BooleanSupplier disabledSupplier) { + var newBackend = new NTBackend(this.m_nt); + if (m_disabledSupplier == null) { + newBackend.m_disabledSupplier = disabledSupplier; + } else { + newBackend.m_disabledSupplier = + () -> m_disabledSupplier.getAsBoolean() || disabledSupplier.getAsBoolean(); + } + return newBackend; } @Override @@ -66,7 +68,7 @@ public EpilogueBackend getNested(String path) { @Override public void log(String identifier, int value) { - if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + if (m_disabledSupplier != null && m_disabledSupplier.getAsBoolean()) { return; } ((IntegerPublisher) @@ -76,7 +78,7 @@ public void log(String identifier, int value) { @Override public void log(String identifier, long value) { - if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + if (m_disabledSupplier != null && m_disabledSupplier.getAsBoolean()) { return; } ((IntegerPublisher) @@ -86,7 +88,7 @@ public void log(String identifier, long value) { @Override public void log(String identifier, float value) { - if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + if (m_disabledSupplier != null && m_disabledSupplier.getAsBoolean()) { return; } ((FloatPublisher) @@ -96,7 +98,7 @@ public void log(String identifier, float value) { @Override public void log(String identifier, double value) { - if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + if (m_disabledSupplier != null && m_disabledSupplier.getAsBoolean()) { return; } ((DoublePublisher) @@ -106,7 +108,7 @@ public void log(String identifier, double value) { @Override public void log(String identifier, boolean value) { - if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + if (m_disabledSupplier != null && m_disabledSupplier.getAsBoolean()) { return; } ((BooleanPublisher) @@ -116,7 +118,7 @@ public void log(String identifier, boolean value) { @Override public void log(String identifier, byte[] value) { - if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + if (m_disabledSupplier != null && m_disabledSupplier.getAsBoolean()) { return; } ((RawPublisher) @@ -127,7 +129,7 @@ public void log(String identifier, byte[] value) { @Override @SuppressWarnings("PMD.UnnecessaryCastRule") public void log(String identifier, int[] value) { - if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + if (m_disabledSupplier != null && m_disabledSupplier.getAsBoolean()) { return; } // NT backend only supports int64[], so we have to manually widen to 64 bits before sending @@ -144,7 +146,7 @@ public void log(String identifier, int[] value) { @Override public void log(String identifier, long[] value) { - if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + if (m_disabledSupplier != null && m_disabledSupplier.getAsBoolean()) { return; } ((IntegerArrayPublisher) @@ -154,7 +156,7 @@ public void log(String identifier, long[] value) { @Override public void log(String identifier, float[] value) { - if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + if (m_disabledSupplier != null && m_disabledSupplier.getAsBoolean()) { return; } ((FloatArrayPublisher) @@ -164,7 +166,7 @@ public void log(String identifier, float[] value) { @Override public void log(String identifier, double[] value) { - if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + if (m_disabledSupplier != null && m_disabledSupplier.getAsBoolean()) { return; } ((DoubleArrayPublisher) @@ -174,7 +176,7 @@ public void log(String identifier, double[] value) { @Override public void log(String identifier, boolean[] value) { - if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + if (m_disabledSupplier != null && m_disabledSupplier.getAsBoolean()) { return; } ((BooleanArrayPublisher) @@ -184,7 +186,7 @@ public void log(String identifier, boolean[] value) { @Override public void log(String identifier, String value) { - if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + if (m_disabledSupplier != null && m_disabledSupplier.getAsBoolean()) { return; } ((StringPublisher) @@ -194,7 +196,7 @@ public void log(String identifier, String value) { @Override public void log(String identifier, String[] value) { - if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + if (m_disabledSupplier != null && m_disabledSupplier.getAsBoolean()) { return; } ((StringArrayPublisher) @@ -205,7 +207,7 @@ public void log(String identifier, String[] value) { @Override @SuppressWarnings("unchecked") public void log(String identifier, S value, Struct struct) { - if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + if (m_disabledSupplier != null && m_disabledSupplier.getAsBoolean()) { return; } m_nt.addSchema(struct); @@ -217,7 +219,7 @@ public void log(String identifier, S value, Struct struct) { @Override @SuppressWarnings("unchecked") public void log(String identifier, S[] value, Struct struct) { - if (m_enabledSupplier != null && !m_enabledSupplier.getAsBoolean()) { + if (m_disabledSupplier != null && m_disabledSupplier.getAsBoolean()) { return; } m_nt.addSchema(struct); From 9ed9912ceadef9dbab64b820344a169fc3bef536 Mon Sep 17 00:00:00 2001 From: Daniel Chen Date: Sat, 14 Dec 2024 12:21:21 -0500 Subject: [PATCH 3/4] Added forgotten docs --- .../main/java/edu/wpi/first/epilogue/logging/NTBackend.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/NTBackend.java b/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/NTBackend.java index ba2b4de4ff3..3a7e675baf1 100644 --- a/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/NTBackend.java +++ b/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/NTBackend.java @@ -49,7 +49,11 @@ public NTBackend() { this.m_nt = NetworkTableInstance.getDefault(); } - /** Creates a new NTBackend that is disabled whenever the disabledSupplier returns true. */ + /** + * Creates a new NTBackend that is disabled whenever the disabledSupplier returns true. + * + * @param disabledSupplier the disable condition for NT logging + */ public NTBackend disableWhen(BooleanSupplier disabledSupplier) { var newBackend = new NTBackend(this.m_nt); if (m_disabledSupplier == null) { From 4aadccb51fbdfada518e2e9d7a6b1ff8907b7cf2 Mon Sep 17 00:00:00 2001 From: Daniel Chen <108989218+Daniel1464@users.noreply.github.com> Date: Sat, 14 Dec 2024 13:12:03 -0500 Subject: [PATCH 4/4] Added forgotten @return --- .../src/main/java/edu/wpi/first/epilogue/logging/NTBackend.java | 1 + 1 file changed, 1 insertion(+) diff --git a/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/NTBackend.java b/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/NTBackend.java index 3a7e675baf1..aaac8dfa27d 100644 --- a/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/NTBackend.java +++ b/epilogue-runtime/src/main/java/edu/wpi/first/epilogue/logging/NTBackend.java @@ -53,6 +53,7 @@ public NTBackend() { * Creates a new NTBackend that is disabled whenever the disabledSupplier returns true. * * @param disabledSupplier the disable condition for NT logging + * @return a new NTBackend */ public NTBackend disableWhen(BooleanSupplier disabledSupplier) { var newBackend = new NTBackend(this.m_nt);