diff --git a/lib/src/main/java/com/team2813/lib2813/preferences/PersistedConfiguration.java b/lib/src/main/java/com/team2813/lib2813/preferences/PersistedConfiguration.java index 0bbac58b..68491c3a 100644 --- a/lib/src/main/java/com/team2813/lib2813/preferences/PersistedConfiguration.java +++ b/lib/src/main/java/com/team2813/lib2813/preferences/PersistedConfiguration.java @@ -95,6 +95,9 @@ * @since 2.0.0 */ public final class PersistedConfiguration { + static final String REGISTERED_CLASSES_NETWORK_TABLE_KEY = "PersistedConfiguration/registry"; + private static boolean deletedLegacyKeys = false; + // The below package-scope fields are for the self-tests. static boolean throwExceptions = false; static Consumer errorReporter = DataLogManager::log; @@ -158,6 +161,7 @@ public static T fromPreferences(String preferenceName, Class< private static T fromPreferences( String preferenceName, Class recordClass, T configWithDefaults) { + deleteLegacyKeys(); NetworkTableInstance ntInstance = NetworkTableInstance.getDefault(); validatePreferenceName(preferenceName); verifyNotRegisteredToAnotherClass(ntInstance, preferenceName, recordClass); @@ -191,10 +195,11 @@ private static void verifyNotRegisteredToAnotherClass( recordName = recordClass.getName(); } - NetworkTable preferencesTable = ntInstance.getTable("Preferences"); - NetworkTableEntry entry = preferencesTable.getEntry(name + "/.registeredTo"); + NetworkTable registeredClassesTable = ntInstance.getTable(REGISTERED_CLASSES_NETWORK_TABLE_KEY); + NetworkTableEntry entry = registeredClassesTable.getEntry(name); if (!entry.exists()) { entry.setString(recordName); + entry.clearPersistent(); } else { String registeredTo = entry.getString(""); if (!recordName.equals(registeredTo)) { @@ -203,7 +208,6 @@ private static void verifyNotRegisteredToAnotherClass( "Preference with name '%s' already registered to %s", name, registeredTo)); } } - entry.clearPersistent(); } private static T createFromPreferences( @@ -454,6 +458,20 @@ private static Supplier supplierFactory( return () -> factory.create(component, key, null, false); } + private static void deleteLegacyKeys() { + if (!deletedLegacyKeys) { + // Preferences installs a listener that makes all new topics persistent. The ".registeredTo" + // topics used to be placed under /Preferences, so could have been persisted. They are now + // written under a different top-level table. Delete the topics created by the previous code. + for (var key : Preferences.getKeys()) { + if (key.endsWith(".registeredTo")) { + Preferences.remove(key); + } + } + deletedLegacyKeys = true; + } + } + private static void warn(String format, Object... args) { String message = String.format("WARNING: " + format, args); errorReporter.accept(message); diff --git a/lib/src/test/java/com/team2813/lib2813/preferences/PersistedConfigurationTest.java b/lib/src/test/java/com/team2813/lib2813/preferences/PersistedConfigurationTest.java index 91053644..a6f46f2e 100644 --- a/lib/src/test/java/com/team2813/lib2813/preferences/PersistedConfigurationTest.java +++ b/lib/src/test/java/com/team2813/lib2813/preferences/PersistedConfigurationTest.java @@ -2,6 +2,7 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; +import static com.team2813.lib2813.preferences.PersistedConfiguration.REGISTERED_CLASSES_NETWORK_TABLE_KEY; import static java.util.stream.Collectors.toMap; import static org.junit.Assert.assertThrows; @@ -155,10 +156,10 @@ public void preferenceNameMapsToOnlyOneRecordType() { .hasMessageThat() .containsMatch("Preference with name '" + preferenceName + "' already registered"); - // Assert: .registeredTo topic added, and is not persistent + // Assert: topic added under "/PersistedConfiguration", and is not persistent NetworkTable table = - NetworkTableInstance.getDefault().getTable("Preferences").getSubTable(preferenceName); - NetworkTableEntry entry = table.getEntry(".registeredTo"); + NetworkTableInstance.getDefault().getTable(REGISTERED_CLASSES_NETWORK_TABLE_KEY); + NetworkTableEntry entry = table.getEntry(preferenceName); assertThat(entry.exists()).isTrue(); assertThat(entry.isPersistent()).isFalse(); assertThat(entry.getType()).isEqualTo(NetworkTableType.kString);