diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000000..97b12d00e3
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "networktables/ntcore"]
+ path = networktables/ntcore
+ url = ../ntcore
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 45bc24cb53..9c66469d0e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -57,3 +57,4 @@ include_directories("build")
add_subdirectory(simulation/gz_msgs)
add_subdirectory(wpilibc/wpilibC++Sim)
add_subdirectory(simulation/frc_gazebo_plugins)
+add_subdirectory(networktables/ntcore)
diff --git a/networktables/OutlineViewer/build.gradle b/networktables/OutlineViewer/build.gradle
index 6bcbe75891..57df0727d8 100644
--- a/networktables/OutlineViewer/build.gradle
+++ b/networktables/OutlineViewer/build.gradle
@@ -34,6 +34,6 @@ sourceSets {
}
dependencies {
- compile project(":networktables:java")
+ compile project(":networktables:ntcore")
compile 'uk.gov.nationalarchives.thirdparty.netbeans:org-netbeans-swing-outline:7.2'
}
diff --git a/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/AbstractTreeNode.java b/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/AbstractTreeNode.java
index f491d47aed..00d0697ff2 100644
--- a/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/AbstractTreeNode.java
+++ b/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/AbstractTreeNode.java
@@ -5,8 +5,7 @@
package edu.wpi.first.tableviewer;
import edu.wpi.first.wpilibj.tables.ITable;
-import edu.wpi.first.wpilibj.networktables.NetworkTableProvider;
-import edu.wpi.first.wpilibj.networktables2.NetworkTableNode;
+import edu.wpi.first.wpilibj.networktables.NetworkTable;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import org.netbeans.swing.outline.Outline;
@@ -30,13 +29,13 @@ public abstract class AbstractTreeNode extends DefaultMutableTreeNode {
AbstractTreeNode.outline = outline;
}
- public AbstractTreeNode(NetworkTableNode node, String key, TableEntryData data) {
+ public AbstractTreeNode(String key, TableEntryData data) {
super(data);
this.data = data;
if (treeModel != null) {
treeModel.reload(this);
}
- table = new NetworkTableProvider(node).getTable(key);
+ table = NetworkTable.getTable(key);
}
/**
diff --git a/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/BranchNode.java b/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/BranchNode.java
index eafce855c1..601d0ea904 100644
--- a/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/BranchNode.java
+++ b/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/BranchNode.java
@@ -8,7 +8,6 @@ import edu.wpi.first.tableviewer.dialog.AddArrayDialog;
import edu.wpi.first.tableviewer.dialog.AddBooleanDialog;
import edu.wpi.first.tableviewer.dialog.AddNumberDialog;
import edu.wpi.first.tableviewer.dialog.AddStringDialog;
-import edu.wpi.first.wpilibj.networktables2.NetworkTableNode;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
@@ -25,8 +24,8 @@ public class BranchNode extends AbstractTreeNode {
private final String name;
- public BranchNode(NetworkTableNode node, String key, String name) {
- super(node, key, new TableEntryData(name, null));
+ public BranchNode(String key, String name) {
+ super(key, new TableEntryData(name, null));
this.name = name;
}
diff --git a/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/LeafNode.java b/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/LeafNode.java
index 9d7bf44239..561b677a75 100644
--- a/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/LeafNode.java
+++ b/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/LeafNode.java
@@ -4,8 +4,7 @@
*/
package edu.wpi.first.tableviewer;
-import edu.wpi.first.wpilibj.networktables.NetworkTableProvider;
-import edu.wpi.first.wpilibj.networktables2.NetworkTableNode;
+import edu.wpi.first.wpilibj.networktables.NetworkTable;
import javax.swing.event.TableModelEvent;
/**
@@ -16,9 +15,9 @@ import javax.swing.event.TableModelEvent;
*/
public class LeafNode extends AbstractTreeNode {
- public LeafNode(NetworkTableNode node, String key, TableEntryData data) {
- super(node, key, data);
- table = new NetworkTableProvider(node).getTable(key.substring(0, key.lastIndexOf('/')));
+ public LeafNode(String key, TableEntryData data) {
+ super(key, data);
+ table = NetworkTable.getTable(key.substring(0, key.lastIndexOf('/')));
}
/**
diff --git a/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/OutlineFrame.java b/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/OutlineFrame.java
index ec5f2eba4e..d635a0ad3e 100644
--- a/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/OutlineFrame.java
+++ b/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/OutlineFrame.java
@@ -6,7 +6,7 @@ package edu.wpi.first.tableviewer;
import edu.wpi.first.tableviewer.TableEntryData.EntryType;
import edu.wpi.first.tableviewer.dialog.AbstractAddDialog;
-import edu.wpi.first.wpilibj.networktables2.NetworkTableNode;
+import edu.wpi.first.wpilibj.networktables.NetworkTable;
import edu.wpi.first.wpilibj.tables.ITable;
import edu.wpi.first.wpilibj.tables.ITableListener;
import java.awt.BorderLayout;
@@ -29,18 +29,16 @@ public class OutlineFrame extends JFrame implements ITableListener {
private final Outline outline;
private final BranchNode rootBranch;
- private final NetworkTableNode node;
private final boolean showMetadata;
private final Preferences prefs = Preferences.userNodeForPackage(getClass());
- public OutlineFrame(String title, NetworkTableNode node, boolean showMetadata) {
- this.node = node;
+ public OutlineFrame(String title, boolean showMetadata) {
this.showMetadata = showMetadata;
setTitle(title);
setDefaultCloseOperation(EXIT_ON_CLOSE);
- rootBranch = new BranchNode(node, "", "Root");
+ rootBranch = new BranchNode("", "Root");
DefaultTreeModel outlineTreeModel = new DefaultTreeModel(rootBranch);
OutlineModel outlineModel = DefaultOutlineModel.createOutlineModel(
@@ -99,7 +97,7 @@ public class OutlineFrame extends JFrame implements ITableListener {
scrollPane.setViewportView(outline);
add(scrollPane, BorderLayout.CENTER);
- node.addTableListener(this, true);
+ NetworkTable.getTable("").addTableListener(this, true);
}
@@ -125,7 +123,7 @@ public class OutlineFrame extends JFrame implements ITableListener {
key += "/" + name;
if (subTableNames.getLast() == name) { // leaf
if (currentNode == null) {
- currentNode = new LeafNode(node, key, new TableEntryData(name, value));
+ currentNode = new LeafNode(key, new TableEntryData(name, value));
if (currentNode.data.isMetadata() && !showMetadata) {
// don't show metadata directly
// instead, show the value in the branch's "Type" field
@@ -140,7 +138,7 @@ public class OutlineFrame extends JFrame implements ITableListener {
}
} else if (currentNode == null) {
- currentNode = new BranchNode(node, key, name);
+ currentNode = new BranchNode(key, name);
parentNode.add(currentNode);
}
}
diff --git a/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/dialog/AddArrayDialog.java b/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/dialog/AddArrayDialog.java
index 6a139a9597..842d96814f 100644
--- a/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/dialog/AddArrayDialog.java
+++ b/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/dialog/AddArrayDialog.java
@@ -4,12 +4,8 @@
*/
package edu.wpi.first.tableviewer.dialog;
-import edu.wpi.first.wpilibj.networktables.NetworkTable;
-import edu.wpi.first.wpilibj.networktables2.type.ArrayData;
-import edu.wpi.first.wpilibj.networktables2.type.BooleanArray;
-import edu.wpi.first.wpilibj.networktables2.type.NumberArray;
-import edu.wpi.first.wpilibj.networktables2.type.StringArray;
import edu.wpi.first.wpilibj.tables.ITable;
+import java.util.ArrayList;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;
@@ -219,60 +215,78 @@ public class AddArrayDialog extends AbstractAddDialog {
}
/**
- * Creates a new {@code ArrayData} object containing the values in the
- * table, which will then be put into the {@link NetworkTable} associated
+ * Creates a new array object containing the values in the
+ * table, which will then be put into the Network Table associated
* with this dialog.
*
* @param arrayType The type of array: Boolean, Number, or String.
- * @return An {@link ArrayData} object containing the data in the table, or
+ * @return An array object containing the data in the table, or
* null if an error is present in the table (such as an invalid double
* value).
*/
- private ArrayData createArrayData(String arrayType) {
- ArrayData ad;
+ private Object createArrayData(String arrayType) {
+ int n = 0;
+ for (int i = 0; i < valueTable.getRowCount(); i++) {
+ Object data = valueTable.getValueAt(i, 0);
+ if (data != null) {
+ n++;
+ }
+ }
switch (arrayType) {
case "Boolean":
- ad = new BooleanArray();
- for (int i = 0; i < valueTable.getRowCount(); i++) {
- Object data = valueTable.getValueAt(i, 0);
- if (data != null) {
- ((BooleanArray) ad).add(data.toString().equalsIgnoreCase("true"));
- }
- }
- break;
- case "Number":
- ad = new NumberArray();
- for (int i = 0; i < valueTable.getRowCount(); i++) {
- Object data = valueTable.getValueAt(i, 0);
- try {
+ {
+ boolean[] arr = new boolean[n];
+ n = 0;
+ for (int i = 0; i < valueTable.getRowCount(); i++) {
+ Object data = valueTable.getValueAt(i, 0);
if (data != null) {
- Double d = Double.parseDouble(data.toString());
- ((NumberArray) ad).add(d);
+ arr[n] = data.toString().equalsIgnoreCase("true");
+ n++;
}
- } catch (NumberFormatException e) {
- JOptionPane.showMessageDialog(
- this,
- "Invalid double value \"" + data + "\" in row " + (i + 1),
- "Invalid number",
- JOptionPane.ERROR_MESSAGE);
- return null;
}
+ return arr;
+ }
+
+ case "Number":
+ {
+ double[] arr = new double[n];
+ n = 0;
+ for (int i = 0; i < valueTable.getRowCount(); i++) {
+ Object data = valueTable.getValueAt(i, 0);
+ try {
+ if (data != null) {
+ arr[n] = Double.parseDouble(data.toString());
+ n++;
+ }
+ } catch (NumberFormatException e) {
+ JOptionPane.showMessageDialog(
+ this,
+ "Invalid double value \"" + data + "\" in row " + (i + 1),
+ "Invalid number",
+ JOptionPane.ERROR_MESSAGE);
+ return null;
+ }
+ }
+ return arr;
}
- break;
case "String":
- ad = new StringArray();
- for (int i = 0; i < valueTable.getRowCount(); i++) {
- Object data = valueTable.getValueAt(i, 0);
- if (data != null) {
- ((StringArray) ad).add(data.toString());
+ {
+ String[] arr = new String[n];
+ n = 0;
+ for (int i = 0; i < valueTable.getRowCount(); i++) {
+ Object data = valueTable.getValueAt(i, 0);
+ if (data != null) {
+ arr[n] = data.toString();
+ n++;
+ }
}
+ return arr;
}
- break;
+
default:
throw new IllegalArgumentException(arrayType + " is not a valid array type");
}
- return ad;
}
// Variables declaration - do not modify
private javax.swing.JButton addRowButton;
diff --git a/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/dialog/PreferencesDialog.java b/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/dialog/PreferencesDialog.java
index 5f3e729cfe..591b020ef5 100644
--- a/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/dialog/PreferencesDialog.java
+++ b/networktables/OutlineViewer/src/main/java/edu/wpi/first/tableviewer/dialog/PreferencesDialog.java
@@ -2,12 +2,8 @@ package edu.wpi.first.tableviewer.dialog;
import edu.wpi.first.tableviewer.OutlineFrame;
-import edu.wpi.first.wpilibj.networktables2.NetworkTableNode;
-import edu.wpi.first.wpilibj.networktables2.client.NetworkTableClient;
-import edu.wpi.first.wpilibj.networktables2.server.NetworkTableServer;
-import edu.wpi.first.wpilibj.networktables2.stream.IOStreamFactory;
-import edu.wpi.first.wpilibj.networktables2.stream.IOStreamProvider;
-import edu.wpi.first.wpilibj.networktables2.stream.SocketStreams;
+import edu.wpi.first.wpilibj.networktables.NetworkTable;
+import edu.wpi.first.wpilibj.networktables.NetworkTablesJNI;
import java.util.prefs.Preferences;
import javax.swing.JOptionPane;
@@ -114,24 +110,28 @@ public class PreferencesDialog extends javax.swing.JDialog {
private void startButtonPressed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_startButtonPressed
try {
- NetworkTableNode node;
+ NetworkTablesJNI.setLogger(new NetworkTablesJNI.LoggerFunction() {
+ public void apply(int level, String file, int line, String msg) {
+ System.err.println(msg);
+ }
+ }, 0);
if (evt.getSource() == clientButton) { // start client
String host = hostField.getText();
if (host.isEmpty()) {
return;
}
- IOStreamFactory streamFactory = SocketStreams.newStreamFactory(host, 1735);
- NetworkTableClient client = new NetworkTableClient(streamFactory);
- client.reconnect();
- node = client;
+ NetworkTable.setIPAddress(host);
+ NetworkTable.setClientMode();
+ NetworkTable.initialize();
prefs.put("host", host);
} else { // start server
- IOStreamProvider streamProvider = SocketStreams.newStreamProvider(1735);
- node = new NetworkTableServer(streamProvider);
+ NetworkTable.setIPAddress("");
+ NetworkTable.setServerMode();
+ NetworkTable.initialize();
prefs.put("host", "");
}
prefs.putBoolean("metadata", metadataBox.isSelected());
- new OutlineFrame("Network Table Viewer", node, metadataBox.isSelected()).setVisible(true);
+ new OutlineFrame("Network Table Viewer", metadataBox.isSelected()).setVisible(true);
dispose();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.getClass() + ": " + e.getMessage(), "Error creating table node", JOptionPane.ERROR_MESSAGE);
diff --git a/networktables/ntcore b/networktables/ntcore
new file mode 160000
index 0000000000..e42f9b0603
--- /dev/null
+++ b/networktables/ntcore
@@ -0,0 +1 @@
+Subproject commit e42f9b060315a9d5e29b0105813a620133754eca
diff --git a/ni-libraries/libwpi_2015.so b/ni-libraries/libwpi_2015.so
index 3589af2ceb..06dcbe4c85 100644
--- a/ni-libraries/libwpi_2015.so
+++ b/ni-libraries/libwpi_2015.so
@@ -1,3 +1,3 @@
/* GNU ld script */
OUTPUT_FORMAT(elf32-littlearm)
-GROUP ( AS_NEEDED ( -lwpilib_nonshared -lHALAthena -lNetworkTables -lFRC_NetworkCommunication -li2c -lni_emb -lNiFpgaLv -lNiFpga -lnirio_emb_can -lNiRioSrv -lni_rtlog -lRoboRIO_FRC_ChipObject -lspi -lvisa -ldl -lpthread -lrt -lGCBase_gcc-4.4-arm_v2_3 -lGenApi_gcc-4.4-arm_v2_3 -lLog_gcc-4.4-arm_v2_3 -lMathParser_gcc-4.4-arm_v2_3 -llog4cpp_gcc-4.4-arm_v2_3 -lniimaqdx -lnivision -lnivissvc ) )
+GROUP ( AS_NEEDED ( -lwpilib_nonshared -lHALAthena -lntcore -lFRC_NetworkCommunication -li2c -lni_emb -lNiFpgaLv -lNiFpga -lnirio_emb_can -lNiRioSrv -lni_rtlog -lRoboRIO_FRC_ChipObject -lspi -lvisa -ldl -lpthread -lrt -lGCBase_gcc-4.4-arm_v2_3 -lGenApi_gcc-4.4-arm_v2_3 -lLog_gcc-4.4-arm_v2_3 -lMathParser_gcc-4.4-arm_v2_3 -llog4cpp_gcc-4.4-arm_v2_3 -lniimaqdx -lnivision -lnivissvc ) )
diff --git a/settings.gradle b/settings.gradle
index 0b8394c4a3..1edf81a743 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,5 +1,4 @@
-include 'networktables:java',
- 'networktables:cpp',
+include 'networktables:ntcore',
'networktables:OutlineViewer',
'hal',
'wpilibj',
@@ -7,4 +6,4 @@ include 'networktables:java',
'simulation:JavaGazebo',
'simulation:SimDS',
'jenkins',
- 'driver-station'
\ No newline at end of file
+ 'driver-station'
diff --git a/wpilibc/build.gradle b/wpilibc/build.gradle
index cb5881e76e..4cb6f8aa2b 100644
--- a/wpilibc/build.gradle
+++ b/wpilibc/build.gradle
@@ -18,7 +18,7 @@ def sim = 'wpilibC++Sim'
// Ensure that both hal and networktables are evaluated, so that they have the binaries property. We need this to
// properly copy their archives into the final zip
evaluationDependsOn(':hal')
-evaluationDependsOn(':networktables:cpp')
+evaluationDependsOn(':networktables:ntcore')
publishing {
publications {
@@ -57,7 +57,7 @@ model {
includes = ['**/*.h']
}
lib project: ':hal', library: 'HALAthena', linkage: 'static'
- lib project: ':networktables:cpp', library: 'NetworkTables', linkage: 'static'
+ lib project: ':networktables:ntcore', library: 'ntcore', linkage: 'static'
}
}
}
@@ -86,12 +86,12 @@ model {
include 'gtest-all.cc', 'gtest_main.cc'
}
exportedHeaders {
- srcDirs = ["${dir}/include", "${dir}/src/gtest", "${dir}/src/gtest/include", "${devices}/include", "${shared}/include", '../hal/include/HAL', '../networktables/cpp/include']
+ srcDirs = ["${dir}/include", "${dir}/src/gtest", "${dir}/src/gtest/include", "${devices}/include", "${shared}/include", '../hal/include/HAL', '../networktables/ntcore/include']
include '**/*.h'
}
lib library: 'wpilib_nonshared', linkage: 'static'
- lib project: ':networktables:cpp', library: 'NetworkTables', linkage: 'static'
+ lib project: ':networktables:ntcore', library: 'ntcore', linkage: 'static'
lib project: ':hal', library: 'HALAthena', linkage: 'static'
}
}
@@ -104,7 +104,7 @@ doxygen {
source file("${shared}/include")
source file("${devices}/src")
source file("${devices}/include")
- def netTablesLoc = '../networktables/cpp'
+ def netTablesLoc = '../networktables/ntcore'
source file("${netTablesLoc}/include")
source file("${netTablesLoc}/lib/Athena")
source file("${netTablesLoc}/lib/share")
@@ -139,7 +139,7 @@ task wpilibcZip(type: Zip) {
}
// Include the static library file and header files from the networktables project
- def netTables = project(':networktables:cpp')
+ def netTables = project(':networktables:ntcore')
netTables.binaries.withType(StaticLibraryBinarySpec) { spec ->
spec.headerDirs.each {
from(it) {
@@ -190,7 +190,7 @@ task wpilibcSimZip(type: Zip) {
from "${sim}/include"
from "${shared}/include"
from "../build/simulation/gz_msgs/generated"
- from '../networktables/cpp/include'
+ from '../networktables/ntcore/include'
from '../hal/include'
}
@@ -204,7 +204,7 @@ tasks.whenTaskAdded { task ->
}
// Add the networktables static library as a dependency
-project(':networktables:cpp').tasks.whenTaskAdded { task ->
+project(':networktables:ntcore').tasks.whenTaskAdded { task ->
if (task.name == 'networkTablesStaticLibrary') {
wpilibcZip.dependsOn task
}
diff --git a/wpilibc/wpilibC++/include/Commands/Command.h b/wpilibc/wpilibC++/include/Commands/Command.h
index 815399d711..5497701109 100644
--- a/wpilibc/wpilibC++/include/Commands/Command.h
+++ b/wpilibc/wpilibC++/include/Commands/Command.h
@@ -10,6 +10,7 @@
#include "ErrorBase.h"
#include "SmartDashboard/NamedSendable.h"
+#include "tables/ITableListener.h"
#include
#include
#include
@@ -179,8 +180,8 @@ class Command : public ErrorBase, public NamedSendable, public ITableListener {
virtual void InitTable(std::shared_ptr table);
virtual std::shared_ptr GetTable() const;
virtual std::string GetSmartDashboardType() const;
- virtual void ValueChanged(std::shared_ptr source, const std::string &key,
- EntryValue value, bool isNew);
+ virtual void ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew);
protected:
std::shared_ptr m_table = nullptr;
diff --git a/wpilibc/wpilibC++/include/Commands/Scheduler.h b/wpilibc/wpilibC++/include/Commands/Scheduler.h
index 200c9517e2..1bd4affc03 100644
--- a/wpilibc/wpilibC++/include/Commands/Scheduler.h
+++ b/wpilibc/wpilibC++/include/Commands/Scheduler.h
@@ -12,13 +12,12 @@
#include "ErrorBase.h"
#include "SmartDashboard/NamedSendable.h"
#include "networktables/NetworkTable.h"
-#include "networktables2/type/NumberArray.h"
-#include "networktables2/type/StringArray.h"
#include "SmartDashboard/SmartDashboard.h"
#include
#include
*
*
This class is thread safe.
*
*
This will also interact with {@link NetworkTable} by creating a table
- * called "Preferences" with all the
- * key-value pairs. To save using {@link NetworkTable}, simply set the boolean
- * at position "~S A V E~" to true.
- * Also, if the value of any variable is " in the {@link NetworkTable}, then
- * that represents non-existence in the
- * {@link Preferences} table
+ * called "Preferences" with all the key-value pairs.
*/
-class Preferences : public ErrorBase, public ITableListener {
+class Preferences : public ErrorBase {
public:
static Preferences *GetInstance();
std::vector GetKeys();
- std::string GetString(const char *key, const char *defaultValue = "");
- int GetString(const char *key, char *value, int valueSize,
- const char *defaultValue = "");
- int GetInt(const char *key, int defaultValue = 0);
- double GetDouble(const char *key, double defaultValue = 0.0);
- float GetFloat(const char *key, float defaultValue = 0.0);
- bool GetBoolean(const char *key, bool defaultValue = false);
- int64_t GetLong(const char *key, int64_t defaultValue = 0);
- void PutString(const char *key, const char *value);
- void PutInt(const char *key, int value);
- void PutDouble(const char *key, double value);
- void PutFloat(const char *key, float value);
- void PutBoolean(const char *key, bool value);
- void PutLong(const char *key, int64_t value);
+ std::string GetString(llvm::StringRef key, llvm::StringRef defaultValue = "");
+ int GetInt(llvm::StringRef key, int defaultValue = 0);
+ double GetDouble(llvm::StringRef key, double defaultValue = 0.0);
+ float GetFloat(llvm::StringRef key, float defaultValue = 0.0);
+ bool GetBoolean(llvm::StringRef key, bool defaultValue = false);
+ int64_t GetLong(llvm::StringRef key, int64_t defaultValue = 0);
+ void PutString(llvm::StringRef key, llvm::StringRef value);
+ void PutInt(llvm::StringRef key, int value);
+ void PutDouble(llvm::StringRef key, double value);
+ void PutFloat(llvm::StringRef key, float value);
+ void PutBoolean(llvm::StringRef key, bool value);
+ void PutLong(llvm::StringRef key, int64_t value);
+ [[deprecated(
+ "Saving is now automatically performed by the NetworkTables server.")]]
void Save();
- bool ContainsKey(const char *key);
- void Remove(const char *key);
-
- void ValueChanged(std::shared_ptr source, const std::string &key, EntryValue value,
- bool isNew) override;
+ bool ContainsKey(llvm::StringRef key);
+ void Remove(llvm::StringRef key);
protected:
Preferences();
virtual ~Preferences() = default;
private:
- std::string Get(const char *key);
- void Put(const char *key, std::string value);
-
- void ReadTaskRun();
- void WriteTaskRun();
-
- /** The semaphore for accessing the file */
- priority_recursive_mutex m_fileLock;
- /** The semaphore for beginning reads and writes to the file */
- Semaphore m_fileOpStarted{Semaphore::kEmpty};
- /** The semaphore for reading from the table */
- priority_recursive_mutex m_tableLock;
- typedef std::map StringMap;
- /** The actual values (String->String) */
- StringMap m_values;
- /** The keys in the order they were read from the file */
- std::vector m_keys;
- /** The comments that were in the file sorted by which key they appeared over
- * (String->Comment) */
- StringMap m_comments;
- /** The comment at the end of the file */
- std::string m_endComment;
- Task m_readTask;
- Task m_writeTask;
+ std::shared_ptr m_table;
};
diff --git a/wpilibc/wpilibC++Devices/include/Relay.h b/wpilibc/wpilibC++Devices/include/Relay.h
index edf8eb3f6a..de21f0764a 100644
--- a/wpilibc/wpilibC++Devices/include/Relay.h
+++ b/wpilibc/wpilibC++Devices/include/Relay.h
@@ -40,8 +40,8 @@ class Relay : public SensorBase,
void Set(Value value);
Value Get() const;
- void ValueChanged(std::shared_ptr source, const std::string& key, EntryValue value,
- bool isNew) override;
+ void ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) override;
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
diff --git a/wpilibc/wpilibC++Devices/include/Servo.h b/wpilibc/wpilibC++Devices/include/Servo.h
index 821a0caa4e..4669835932 100644
--- a/wpilibc/wpilibC++Devices/include/Servo.h
+++ b/wpilibc/wpilibC++Devices/include/Servo.h
@@ -30,8 +30,8 @@ class Servo : public SafePWM {
static float GetMaxAngle() { return kMaxServoAngle; }
static float GetMinAngle() { return kMinServoAngle; }
- void ValueChanged(std::shared_ptr source, const std::string& key,
- EntryValue value, bool isNew) override;
+ void ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) override;
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
diff --git a/wpilibc/wpilibC++Devices/include/Solenoid.h b/wpilibc/wpilibC++Devices/include/Solenoid.h
index 897bc67355..fd550037a1 100644
--- a/wpilibc/wpilibC++Devices/include/Solenoid.h
+++ b/wpilibc/wpilibC++Devices/include/Solenoid.h
@@ -30,8 +30,8 @@ class Solenoid : public SolenoidBase,
virtual bool Get() const;
bool IsBlackListed() const;
- void ValueChanged(std::shared_ptr source, const std::string& key, EntryValue value,
- bool isNew);
+ void ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew);
void UpdateTable();
void StartLiveWindowMode();
void StopLiveWindowMode();
diff --git a/wpilibc/wpilibC++Devices/src/CANJaguar.cpp b/wpilibc/wpilibC++Devices/src/CANJaguar.cpp
index ddfba620f2..8f7a4aeada 100644
--- a/wpilibc/wpilibC++Devices/src/CANJaguar.cpp
+++ b/wpilibc/wpilibC++Devices/src/CANJaguar.cpp
@@ -216,6 +216,8 @@ CANJaguar::~CANJaguar() {
FRC_NetworkCommunication_CANSessionMux_sendMessage(
m_deviceNumber | LM_API_VCOMP_T_SET, nullptr, 0,
CAN_SEND_PERIOD_STOP_REPEATING, &status);
+
+ if (m_table != nullptr) m_table->RemoveTableListener(this);
}
/**
@@ -1935,9 +1937,9 @@ uint8_t CANJaguar::GetDeviceID() const { return m_deviceNumber; }
*/
void CANJaguar::StopMotor() { DisableControl(); }
-void CANJaguar::ValueChanged(std::shared_ptr source, const std::string &key,
- EntryValue value, bool isNew) {
- Set(value.f);
+void CANJaguar::ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) {
+ if (value->type() == NT_DOUBLE) Set(value->GetDouble());
}
void CANJaguar::UpdateTable() {
diff --git a/wpilibc/wpilibC++Devices/src/CANTalon.cpp b/wpilibc/wpilibC++Devices/src/CANTalon.cpp
index a7bc529d59..509d7a9e49 100644
--- a/wpilibc/wpilibC++Devices/src/CANTalon.cpp
+++ b/wpilibc/wpilibC++Devices/src/CANTalon.cpp
@@ -44,6 +44,7 @@ CANTalon::CANTalon(int deviceNumber, int controlPeriodMs)
}
CANTalon::~CANTalon() {
+ if (m_table != nullptr) m_table->RemoveTableListener(this);
if (m_hasBeenMoved) return;
Disable();
}
@@ -1275,9 +1276,10 @@ bool CANTalon::GetInverted() const { return m_isInverted; }
*/
void CANTalon::StopMotor() { Disable(); }
-void CANTalon::ValueChanged(std::shared_ptr source, const std::string& key,
- EntryValue value, bool isNew) {
- Set(value.f);
+void CANTalon::ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) {
+ if (!value->IsDouble()) return;
+ Set(value->GetDouble());
}
void CANTalon::UpdateTable() {
diff --git a/wpilibc/wpilibC++Devices/src/Compressor.cpp b/wpilibc/wpilibC++Devices/src/Compressor.cpp
index 5435b32b20..9ab89e0584 100644
--- a/wpilibc/wpilibC++Devices/src/Compressor.cpp
+++ b/wpilibc/wpilibC++Devices/src/Compressor.cpp
@@ -267,9 +267,10 @@ void Compressor::InitTable(std::shared_ptr subTable) {
std::shared_ptr Compressor::GetTable() const { return m_table; }
-void Compressor::ValueChanged(std::shared_ptr source, const std::string& key,
- EntryValue value, bool isNew) {
- if (value.b)
+void Compressor::ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) {
+ if (!value->IsBoolean()) return;
+ if (value->GetBoolean())
Start();
else
Stop();
diff --git a/wpilibc/wpilibC++Devices/src/DigitalOutput.cpp b/wpilibc/wpilibC++Devices/src/DigitalOutput.cpp
index b1692b8074..3cbb39fe67 100644
--- a/wpilibc/wpilibC++Devices/src/DigitalOutput.cpp
+++ b/wpilibc/wpilibC++Devices/src/DigitalOutput.cpp
@@ -40,6 +40,7 @@ DigitalOutput::DigitalOutput(uint32_t channel) {
* Free the resources associated with a digital output.
*/
DigitalOutput::~DigitalOutput() {
+ if (m_table != nullptr) m_table->RemoveTableListener(this);
if (StatusIsFatal()) return;
// Disable the PWM in case it was running.
DisablePWM();
@@ -196,9 +197,10 @@ uint32_t DigitalOutput::GetModuleForRouting() const { return 0; }
*/
bool DigitalOutput::GetAnalogTriggerForRouting() const { return false; }
-void DigitalOutput::ValueChanged(std::shared_ptr source, const std::string &key,
- EntryValue value, bool isNew) {
- Set(value.b);
+void DigitalOutput::ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) {
+ if (!value->IsBoolean()) return;
+ Set(value->GetBoolean());
}
void DigitalOutput::UpdateTable() {}
diff --git a/wpilibc/wpilibC++Devices/src/DoubleSolenoid.cpp b/wpilibc/wpilibC++Devices/src/DoubleSolenoid.cpp
index 1ef56916db..56f180c589 100644
--- a/wpilibc/wpilibC++Devices/src/DoubleSolenoid.cpp
+++ b/wpilibc/wpilibC++Devices/src/DoubleSolenoid.cpp
@@ -91,6 +91,7 @@ DoubleSolenoid::~DoubleSolenoid() {
m_allocated->Free(m_moduleNumber * kSolenoidChannels + m_forwardChannel);
m_allocated->Free(m_moduleNumber * kSolenoidChannels + m_reverseChannel);
}
+ if (m_table != nullptr) m_table->RemoveTableListener(this);
}
/**
@@ -155,13 +156,14 @@ bool DoubleSolenoid::IsRevSolenoidBlackListed() const {
return (blackList & m_reverseMask) ? 1 : 0;
}
-void DoubleSolenoid::ValueChanged(std::shared_ptr source, const std::string &key,
- EntryValue value, bool isNew) {
+void DoubleSolenoid::ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value,
+ bool isNew) {
+ if (!value->IsString()) return;
Value lvalue = kOff;
- std::string *val = (std::string *)value.ptr;
- if (*val == "Forward")
+ if (value->GetString() == "Forward")
lvalue = kForward;
- else if (*val == "Reverse")
+ else if (value->GetString() == "Reverse")
lvalue = kReverse;
Set(lvalue);
}
diff --git a/wpilibc/wpilibC++Devices/src/PIDController.cpp b/wpilibc/wpilibC++Devices/src/PIDController.cpp
index 6fb55f1484..e9a25f752a 100644
--- a/wpilibc/wpilibC++Devices/src/PIDController.cpp
+++ b/wpilibc/wpilibC++Devices/src/PIDController.cpp
@@ -73,6 +73,10 @@ void PIDController::Initialize(float Kp, float Ki, float Kd, float Kf,
HALReport(HALUsageReporting::kResourceType_PIDController, instances);
}
+PIDController::~PIDController() {
+ if (m_table != nullptr) m_table->RemoveTableListener(this);
+}
+
/**
* Call the Calculate method as a non-static method. This avoids having to
* prepend
@@ -551,18 +555,22 @@ void PIDController::InitTable(std::shared_ptr table) {
std::shared_ptr PIDController::GetTable() const { return m_table; }
-void PIDController::ValueChanged(std::shared_ptr source, const std::string &key,
- EntryValue value, bool isNew) {
+void PIDController::ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) {
if (key == kP || key == kI || key == kD || key == kF) {
- if (m_P != m_table->GetNumber(kP) || m_I != m_table->GetNumber(kI) ||
- m_D != m_table->GetNumber(kD) || m_F != m_table->GetNumber(kF)) {
+ if (m_P != m_table->GetNumber(kP, 0.0) ||
+ m_I != m_table->GetNumber(kI, 0.0) ||
+ m_D != m_table->GetNumber(kD, 0.0) ||
+ m_F != m_table->GetNumber(kF, 0.0)) {
SetPID(m_table->GetNumber(kP, 0.0), m_table->GetNumber(kI, 0.0),
m_table->GetNumber(kD, 0.0), m_table->GetNumber(kF, 0.0));
}
- } else if (key == kSetpoint && m_setpoint != value.f) {
- SetSetpoint(value.f);
- } else if (key == kEnabled && m_enabled != value.b) {
- if (value.b) {
+ } else if (key == kSetpoint && value->IsDouble() &&
+ m_setpoint != value->GetDouble()) {
+ SetSetpoint(value->GetDouble());
+ } else if (key == kEnabled && value->IsBoolean() &&
+ m_enabled != value->GetBoolean()) {
+ if (value->GetBoolean()) {
Enable();
} else {
Disable();
diff --git a/wpilibc/wpilibC++Devices/src/PWM.cpp b/wpilibc/wpilibC++Devices/src/PWM.cpp
index b0c8c8cb31..5a70932424 100644
--- a/wpilibc/wpilibC++Devices/src/PWM.cpp
+++ b/wpilibc/wpilibC++Devices/src/PWM.cpp
@@ -65,6 +65,8 @@ PWM::~PWM() {
freePWMChannel(m_pwm_ports[m_channel], &status);
wpi_setErrorWithContext(status, getHALErrorMessage(status));
+
+ if (m_table != nullptr) m_table->RemoveTableListener(this);
}
/**
@@ -337,9 +339,10 @@ void PWM::SetZeroLatch() {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
-void PWM::ValueChanged(std::shared_ptr source, const std::string& key, EntryValue value,
- bool isNew) {
- SetSpeed(value.f);
+void PWM::ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) {
+ if (!value->IsDouble()) return;
+ SetSpeed(value->GetDouble());
}
void PWM::UpdateTable() {
diff --git a/wpilibc/wpilibC++Devices/src/Preferences.cpp b/wpilibc/wpilibC++Devices/src/Preferences.cpp
index 840aa2ef88..cb6d1001e3 100644
--- a/wpilibc/wpilibC++Devices/src/Preferences.cpp
+++ b/wpilibc/wpilibC++Devices/src/Preferences.cpp
@@ -15,25 +15,8 @@
/** The Preferences table name */
static const char *kTableName = "Preferences";
-/** The value of the save field */
-static const char *kSaveField = "~S A V E~";
-/** The file to save to */
-static const char *kFileName = "/home/lvuser/wpilib-preferences.ini";
-/** The characters to put between a field and value */
-static const char *kValuePrefix = "=\"";
-/** The characters to put after the value */
-static const char *kValueSuffix = "\"\n";
-
-Preferences::Preferences() {
- std::unique_lock sync(m_fileLock);
- m_readTask = Task("PreferencesReadTask", &Preferences::ReadTaskRun, this);
-
- /* The main thread initially blocks on the semaphore. The read task signals
- * the main thread to continue after it has locked the table mutex (so the
- * table will be fully populated when the main thread can finally access it).
- */
- m_fileOpStarted.take();
+Preferences::Preferences() : m_table(NetworkTable::GetTable(kTableName)) {
HALReport(HALUsageReporting::kResourceType_Preferences, 0);
}
@@ -50,7 +33,7 @@ Preferences *Preferences::GetInstance() {
* Returns a vector of all the keys
* @return a vector of the keys
*/
-std::vector Preferences::GetKeys() { return m_keys; }
+std::vector Preferences::GetKeys() { return m_table->GetKeys(); }
/**
* Returns the string at the given key. If this table does not have a value
@@ -59,25 +42,9 @@ std::vector Preferences::GetKeys() { return m_keys; }
* @param defaultValue the value to return if none exists in the table
* @return either the value in the table, or the defaultValue
*/
-std::string Preferences::GetString(const char *key, const char *defaultValue) {
- std::string value = Get(key);
- return value.empty() ? defaultValue : value;
-}
-
-/**
- * Returns the string at the given key. If this table does not have a value
- * for that position, then the given defaultValue will be returned.
- * @param key the key
- * @param value the buffer to copy the value into
- * @param valueSize the size of value
- * @param defaultValue the value to return if none exists in the table
- * @return The size of the returned string
- */
-int Preferences::GetString(const char *key, char *value, int valueSize,
- const char *defaultValue) {
- std::string stringValue = GetString(key, defaultValue);
- stringValue.copy(value, valueSize);
- return stringValue.size();
+std::string Preferences::GetString(llvm::StringRef key,
+ llvm::StringRef defaultValue) {
+ return m_table->GetString(key, defaultValue);
}
/**
@@ -87,11 +54,8 @@ int Preferences::GetString(const char *key, char *value, int valueSize,
* @param defaultValue the value to return if none exists in the table
* @return either the value in the table, or the defaultValue
*/
-int Preferences::GetInt(const char *key, int defaultValue) {
- std::string value = Get(key);
- if (value.empty()) return defaultValue;
-
- return strtol(value.c_str(), nullptr, 0);
+int Preferences::GetInt(llvm::StringRef key, int defaultValue) {
+ return static_cast(m_table->GetNumber(key, defaultValue));
}
/**
@@ -101,11 +65,8 @@ int Preferences::GetInt(const char *key, int defaultValue) {
* @param defaultValue the value to return if none exists in the table
* @return either the value in the table, or the defaultValue
*/
-double Preferences::GetDouble(const char *key, double defaultValue) {
- std::string value = Get(key);
- if (value.empty()) return defaultValue;
-
- return strtod(value.c_str(), nullptr);
+double Preferences::GetDouble(llvm::StringRef key, double defaultValue) {
+ return m_table->GetNumber(key, defaultValue);
}
/**
@@ -115,11 +76,8 @@ double Preferences::GetDouble(const char *key, double defaultValue) {
* @param defaultValue the value to return if none exists in the table
* @return either the value in the table, or the defaultValue
*/
-float Preferences::GetFloat(const char *key, float defaultValue) {
- std::string value = Get(key);
- if (value.empty()) return defaultValue;
-
- return strtod(value.c_str(), nullptr);
+float Preferences::GetFloat(llvm::StringRef key, float defaultValue) {
+ return static_cast(m_table->GetNumber(key, defaultValue));
}
/**
@@ -129,19 +87,8 @@ float Preferences::GetFloat(const char *key, float defaultValue) {
* @param defaultValue the value to return if none exists in the table
* @return either the value in the table, or the defaultValue
*/
-bool Preferences::GetBoolean(const char *key, bool defaultValue) {
- std::string value = Get(key);
- if (value.empty()) return defaultValue;
-
- if (value.compare("true") == 0)
- return true;
- else if (value.compare("false") == 0)
- return false;
-
- wpi_setWPIErrorWithContext(
- ParameterOutOfRange,
- "Boolean value does not contain \"true\" or \"false\"");
- return false;
+bool Preferences::GetBoolean(llvm::StringRef key, bool defaultValue) {
+ return m_table->GetBoolean(key, defaultValue);
}
/**
@@ -152,15 +99,8 @@ bool Preferences::GetBoolean(const char *key, bool defaultValue) {
* @param defaultValue the value to return if none exists in the table
* @return either the value in the table, or the defaultValue
*/
-int64_t Preferences::GetLong(const char *key, int64_t defaultValue) {
- std::string value = Get(key);
- if (value.empty()) return defaultValue;
-
- // Ummm... not available in our VxWorks...
- // return strtoll(value.c_str(), nullptr, 0);
- int64_t intVal;
- sscanf(value.c_str(), "%lld", &intVal);
- return intVal;
+int64_t Preferences::GetLong(llvm::StringRef key, int64_t defaultValue) {
+ return static_cast(m_table->GetNumber(key, defaultValue));
}
/**
@@ -169,24 +109,12 @@ int64_t Preferences::GetLong(const char *key, int64_t defaultValue) {
*
The value may not have quotation marks, nor may the key
* have any whitespace nor an equals sign
*
- *
This will NOT save the value to memory between power cycles,
- * to do that you must call {@link Preferences#Save() Save()} (which must be
- * used with care).
- * at some point after calling this.
The key may not have any whitespace nor an equals sign
*
- *
This will NOT save the value to memory between power cycles,
- * to do that you must call {@link Preferences#Save() Save()} (which must be
- * used with care)
- * at some point after calling this.
* @param key the key
* @param value the value
*/
-void Preferences::PutInt(const char *key, int value) {
- char buf[32];
- snprintf(buf, 32, "%d", value);
- Put(key, buf);
+void Preferences::PutInt(llvm::StringRef key, int value) {
+ m_table->PutNumber(key, value);
+ m_table->SetPersistent(key);
}
/**
@@ -212,17 +135,12 @@ void Preferences::PutInt(const char *key, int value) {
*
*
The key may not have any whitespace nor an equals sign
*
- *
This will NOT save the value to memory between power cycles,
- * to do that you must call {@link Preferences#Save() Save()} (which must be
- * used with care)
- * at some point after calling this.
The key may not have any whitespace nor an equals sign
*
- *
This will NOT save the value to memory between power cycles,
- * to do that you must call {@link Preferences#Save() Save()} (which must be
- * used with care)
- * at some point after calling this.
The key may not have any whitespace nor an equals sign
*
- *
This will NOT save the value to memory between power cycles,
- * to do that you must call {@link Preferences#Save() Save()} (which must be
- * used with care)
- * at some point after calling this.
The key may not have any whitespace nor an equals sign
*
- *
This will NOT save the value to memory between power cycles,
- * to do that you must call {@link Preferences#Save() Save()} (which must be
- * used with care)
- * at some point after calling this.
* @param key the key
* @param value the value
*/
-void Preferences::PutLong(const char *key, int64_t value) {
- char buf[32];
- snprintf(buf, 32, "%lld", value);
- Put(key, buf);
+void Preferences::PutLong(llvm::StringRef key, int64_t value) {
+ m_table->PutNumber(key, value);
+ m_table->SetPersistent(key);
}
/**
- * Saves the preferences to a file on the RoboRIO.
- *
- *
This should NOT be called often.
- * Too many writes can damage the RoboRIO's flash memory.
- * While it is ok to save once or twice a match, this should never
- * be called every run of {@link IterativeRobot#TeleopPeriodic()}, etc.
- *
- *
The actual writing of the file is done in a separate thread.
- * However, any call to a get or put method will wait until the table is fully
- * saved before continuing.
+ * This function is no longer required, as NetworkTables automatically
+ * saves persistent values (which all Preferences values are) periodically
+ * when running as a server.
+ * @deprecated backwards compatibility shim
*/
-void Preferences::Save() {
- std::unique_lock sync(m_fileLock);
- m_writeTask = Task("PreferencesWriteTask", &Preferences::WriteTaskRun, this);
- m_fileOpStarted.take();
-}
+void Preferences::Save() {}
/**
* Returns whether or not there is a key with the given name.
* @param key the key
* @return if there is a value at the given key
*/
-bool Preferences::ContainsKey(const char *key) { return !Get(key).empty(); }
+bool Preferences::ContainsKey(llvm::StringRef key) {
+ return m_table->ContainsKey(key);
+}
/**
* Remove a preference
* @param key the key
*/
-void Preferences::Remove(const char *key) {
- m_values.erase(std::string(key));
- auto it = m_keys.begin();
- for (; it != m_keys.end(); it++) {
- if (it->compare(key) == 0) {
- m_keys.erase(it);
- break;
- }
- }
-}
-
-/**
- * Returns the value at the given key.
- * @param key the key
- * @return the value (or empty if none exists)
- */
-std::string Preferences::Get(const char *key) {
- std::unique_lock sync(m_tableLock);
- if (key == nullptr) {
- wpi_setWPIErrorWithContext(NullParameter, "key");
- return "";
- }
- return m_values[key];
-}
-
-/**
- * Puts the given value into the given key position
- * @param key the key
- * @param value the value
- */
-void Preferences::Put(const char *key, std::string value) {
- std::unique_lock sync(m_tableLock);
- if (key == nullptr) {
- wpi_setWPIErrorWithContext(NullParameter, "key");
- return;
- }
-
- if (std::string(key).find_first_of("=\n\r \t\"") != std::string::npos) {
- wpi_setWPIErrorWithContext(ParameterOutOfRange,
- "key contains illegal characters");
- return;
- }
-
- std::pair ret =
- m_values.insert(StringMap::value_type(key, value));
- if (ret.second)
- m_keys.push_back(key);
- else
- ret.first->second = value;
-
- NetworkTable* table = NetworkTable::GetTable(kTableName);
- table->PutString(key, value);
-}
-
-/**
- * The internal method to read from a file.
- * This will be called in its own thread when the preferences singleton is
- * first created.
- */
-void Preferences::ReadTaskRun() {
- std::unique_lock sync(m_tableLock);
- m_fileOpStarted.give();
-
- std::string comment;
-
- FILE *file = nullptr;
- file = fopen(kFileName, "r");
-
- if (file != nullptr) {
- std::string buffer;
- while (true) {
- char value;
- do {
- value = fgetc(file);
- } while (value == ' ' || value == '\t');
-
- if (value == '\n' || value == ';') {
- if (value == '\n') {
- comment += "\n";
- } else {
- buffer.clear();
- for (; value != '\n' && !feof(file); value = fgetc(file))
- buffer += value;
- buffer += '\n';
- comment += buffer;
- }
- } else if (value == '[') {
- // Find the end of the section and the new line after it and throw it
- // away
- for (; value != ']' && !feof(file); value = fgetc(file))
- ;
- for (; value != '\n' && !feof(file); value = fgetc(file))
- ;
- } else {
- buffer.clear();
- for (; value != '=' && !feof(file);) {
- buffer += value;
- do {
- value = fgetc(file);
- } while (value == ' ' || value == '\t');
- }
- std::string name = buffer;
- buffer.clear();
-
- bool shouldBreak = false;
-
- do {
- value = fgetc(file);
- } while (value == ' ' || value == '\t');
-
- if (value == '"') {
- for (value = fgetc(file); value != '"' && !feof(file);
- value = fgetc(file))
- buffer += value;
-
- // Clear the line
- while (fgetc(file) != '\n' && !feof(file))
- ;
- } else {
- for (; value != '\n' && !feof(file);) {
- buffer += value;
- do {
- value = fgetc(file);
- } while (value == ' ' || value == '\t');
- }
- if (feof(file)) shouldBreak = true;
- }
-
- std::string value = buffer;
-
- if (!name.empty() && !value.empty()) {
- m_keys.push_back(name);
- m_values.insert(std::pair(name, value));
- NetworkTable::GetTable(kTableName)->PutString(name, value);
-
- if (!comment.empty()) {
- m_comments.insert(
- std::pair(name, comment));
- comment.clear();
- }
- }
-
- if (shouldBreak) break;
- }
- }
- } else {
- wpi_setErrnoErrorWithContext("Opening preferences file");
- }
-
- if (file != nullptr) fclose(file);
-
- if (!comment.empty()) m_endComment = comment;
-
- NetworkTable::GetTable(kTableName)->PutBoolean(kSaveField, false);
- NetworkTable::GetTable(kTableName)->AddTableListener(this);
-}
-
-/**
- * Internal method that actually writes the table to a file.
- * This is called in its own thread when {@link Preferences#Save() Save()} is
- * called.
- */
-void Preferences::WriteTaskRun() {
- std::unique_lock sync(m_tableLock);
- m_fileOpStarted.give();
-
- FILE *file = nullptr;
- file = fopen(kFileName, "w");
-
- fputs("[Preferences]\n", file);
- auto it = m_keys.begin();
- for (; it != m_keys.end(); it++) {
- std::string key = *it;
- std::string value = m_values[key];
- std::string comment = m_comments[key];
-
- if (!comment.empty()) fputs(comment.c_str(), file);
-
- fputs(key.c_str(), file);
- fputs(kValuePrefix, file);
- fputs(value.c_str(), file);
- fputs(kValueSuffix, file);
- }
-
- if (!m_endComment.empty()) fputs(m_endComment.c_str(), file);
-
- if (file != nullptr) fclose(file);
-
- NetworkTable::GetTable(kTableName)->PutBoolean(kSaveField, false);
-}
-
-static bool isKeyAcceptable(const std::string &value) {
- for (auto letter : value) {
- switch (letter) {
- case '=':
- case '\n':
- case '\r':
- case ' ':
- case '\t':
- case '[':
- case ']':
- return false;
- }
- }
- return true;
-}
-
-void Preferences::ValueChanged(std::shared_ptr table, const std::string &key,
- EntryValue value, bool isNew) {
- if (key == kSaveField) {
- if (table->GetBoolean(kSaveField, false)) Save();
- } else {
- std::unique_lock sync(m_tableLock);
-
- if (!isKeyAcceptable(key) ||
- table->GetString(key, "").find('"') != std::string::npos) {
- if (m_values.find(key) != m_values.end()) {
- m_values.erase(key);
- auto it = m_keys.begin();
- for (; it != m_keys.end(); it++) {
- if (key == *it) {
- m_keys.erase(it);
- break;
- }
- }
- table->PutString(key, "\"");
- }
- } else {
- std::pair ret = m_values.insert(
- StringMap::value_type(key, table->GetString(key, "")));
- if (ret.second)
- m_keys.push_back(key);
- else
- ret.first->second = table->GetString(key, "");
- }
- }
+void Preferences::Remove(llvm::StringRef key) {
+ m_table->Delete(key);
}
diff --git a/wpilibc/wpilibC++Devices/src/Relay.cpp b/wpilibc/wpilibC++Devices/src/Relay.cpp
index 8d48812755..3977dd978f 100644
--- a/wpilibc/wpilibC++Devices/src/Relay.cpp
+++ b/wpilibc/wpilibC++Devices/src/Relay.cpp
@@ -81,6 +81,7 @@ Relay::~Relay() {
if (m_direction == kBothDirections || m_direction == kReverseOnly) {
relayChannels->Free(m_channel * 2 + 1);
}
+ if (m_table != nullptr) m_table->RemoveTableListener(this);
}
/**
@@ -189,16 +190,16 @@ Relay::Value Relay::Get() const {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
-void Relay::ValueChanged(std::shared_ptr source, const std::string &key,
- EntryValue value, bool isNew) {
- std::string *val = (std::string *)value.ptr;
- if (*val == "Off")
+void Relay::ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) {
+ if (!value->IsString()) return;
+ if (value->GetString() == "Off")
Set(kOff);
- else if (*val == "On")
+ else if (value->GetString() == "On")
Set(kOn);
- else if (*val == "Forward")
+ else if (value->GetString() == "Forward")
Set(kForward);
- else if (*val == "Reverse")
+ else if (value->GetString() == "Reverse")
Set(kReverse);
}
diff --git a/wpilibc/wpilibC++Devices/src/RobotBase.cpp b/wpilibc/wpilibC++Devices/src/RobotBase.cpp
index 9adc51f638..07f2c8ce46 100644
--- a/wpilibc/wpilibC++Devices/src/RobotBase.cpp
+++ b/wpilibc/wpilibC++Devices/src/RobotBase.cpp
@@ -15,6 +15,7 @@
#include "HLUsageReporting.h"
#include "Internal/HardwareHLReporting.h"
#include "Utility.h"
+#include "networktables/NetworkTable.h"
#include
#include "HAL/HAL.hpp"
#include
@@ -51,6 +52,8 @@ RobotBase::RobotBase() : m_ds(DriverStation::GetInstance()) {
RobotBase::setInstance(this);
+ NetworkTable::SetNetworkIdentity("Robot");
+
FILE *file = nullptr;
file = fopen("/tmp/frc_versions/FRC_Lib_Version.ini", "w");
diff --git a/wpilibc/wpilibC++Devices/src/Servo.cpp b/wpilibc/wpilibC++Devices/src/Servo.cpp
index e2ff60e854..72a35260ea 100644
--- a/wpilibc/wpilibC++Devices/src/Servo.cpp
+++ b/wpilibc/wpilibC++Devices/src/Servo.cpp
@@ -30,7 +30,11 @@ Servo::Servo(uint32_t channel) : SafePWM(channel) {
// printf("Done initializing servo %d\n", channel);
}
-Servo::~Servo() {}
+Servo::~Servo() {
+ if (m_table != nullptr) {
+ m_table->RemoveTableListener(this);
+ }
+}
/**
* Set the servo position.
@@ -95,9 +99,10 @@ float Servo::GetAngle() const {
return (float)GetPosition() * GetServoAngleRange() + kMinServoAngle;
}
-void Servo::ValueChanged(std::shared_ptr source, const std::string& key,
- EntryValue value, bool isNew) {
- Set(value.f);
+void Servo::ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) {
+ if (!value->IsDouble()) return;
+ Set(value->GetDouble());
}
void Servo::UpdateTable() {
diff --git a/wpilibc/wpilibC++Devices/src/Solenoid.cpp b/wpilibc/wpilibC++Devices/src/Solenoid.cpp
index fd9c6450e6..6cf32e12a8 100644
--- a/wpilibc/wpilibC++Devices/src/Solenoid.cpp
+++ b/wpilibc/wpilibC++Devices/src/Solenoid.cpp
@@ -61,6 +61,7 @@ Solenoid::~Solenoid() {
if (CheckSolenoidModule(m_moduleNumber)) {
m_allocated->Free(m_moduleNumber * kSolenoidChannels + m_channel);
}
+ if (m_table != nullptr) m_table->RemoveTableListener(this);
}
/**
@@ -99,9 +100,10 @@ bool Solenoid::IsBlackListed() const {
return (value != 0);
}
-void Solenoid::ValueChanged(std::shared_ptr source, const std::string& key,
- EntryValue value, bool isNew) {
- Set(value.b);
+void Solenoid::ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) {
+ if (!value->IsBoolean()) return;
+ Set(value->GetBoolean());
}
void Solenoid::UpdateTable() {
diff --git a/wpilibc/wpilibC++IntegrationTests/CMakeLists.txt b/wpilibc/wpilibC++IntegrationTests/CMakeLists.txt
index 31431fbb8f..88887b318e 100644
--- a/wpilibc/wpilibC++IntegrationTests/CMakeLists.txt
+++ b/wpilibc/wpilibC++IntegrationTests/CMakeLists.txt
@@ -7,4 +7,4 @@ file(GLOB_RECURSE SRC_FILES src/*.cpp src/gtest/src/gtest-all.cc src/gtest/src/g
include_directories(include/ src/gtest/ src/gtest/include/ ../wpilibC++Devices/include/ ${WPILIB_INCLUDES} ${HAL_API_INCLUDES} ${NWT_API_INCLUDES})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -Wno-unused-variable")
add_executable(FRCUserProgram ${SRC_FILES})
-target_link_libraries(FRCUserProgram wpilib_nonshared HALAthena NetworkTables ${NI_LIBS})
+target_link_libraries(FRCUserProgram wpilib_nonshared HALAthena ntcore ${NI_LIBS})
diff --git a/wpilibc/wpilibC++IntegrationTests/src/PreferencesTest.cpp b/wpilibc/wpilibC++IntegrationTests/src/PreferencesTest.cpp
index 925f333d4e..030d373c9b 100644
--- a/wpilibc/wpilibC++IntegrationTests/src/PreferencesTest.cpp
+++ b/wpilibc/wpilibC++IntegrationTests/src/PreferencesTest.cpp
@@ -11,25 +11,27 @@
#include
#include
-static const char *kFileName = "/home/lvuser/wpilib-preferences.ini";
-static const double kSaveTime = 0.2;
+static const char *kFileName = "networktables.ini";
+static const double kSaveTime = 1.2;
/**
- * If we write a new wpilib-preference.ini with some sample values, test that
+ * If we write a new networktables.ini with some sample values, test that
* we get those same values back using the Preference class.
*/
TEST(PreferencesTest, ReadPreferencesFromFile) {
+ NetworkTable::Shutdown();
std::remove(kFileName);
std::ofstream preferencesFile(kFileName);
- preferencesFile << "[Preferences]" << std::endl;
- preferencesFile << "testFileGetString=\"Hello, preferences file\""
+ preferencesFile << "[NetworkTables Storage 3.0]" << std::endl;
+ preferencesFile << "string \"/Preferences/testFileGetString\"=\"Hello, preferences file\""
<< std::endl;
- preferencesFile << "testFileGetInt=\"1\"" << std::endl;
- preferencesFile << "testFileGetDouble=\"0.5\"" << std::endl;
- preferencesFile << "testFileGetFloat=\"0.25\"" << std::endl;
- preferencesFile << "testFileGetBoolean=\"true\"" << std::endl;
- preferencesFile << "testFileGetLong=\"1000000000000000000\"" << std::endl;
+ preferencesFile << "double \"/Preferences/testFileGetInt\"=1" << std::endl;
+ preferencesFile << "double \"/Preferences/testFileGetDouble\"=0.5" << std::endl;
+ preferencesFile << "double \"/Preferences/testFileGetFloat\"=0.25" << std::endl;
+ preferencesFile << "boolean \"/Preferences/testFileGetBoolean\"=true" << std::endl;
+ preferencesFile << "double \"/Preferences/testFileGetLong\"=1000000000000000000" << std::endl;
preferencesFile.close();
+ NetworkTable::Initialize();
Preferences *preferences = Preferences::GetInstance();
EXPECT_EQ("Hello, preferences file",
@@ -43,9 +45,13 @@ TEST(PreferencesTest, ReadPreferencesFromFile) {
/**
* If we set some values using the Preferences class, test that they show up
- * in wpilib-preferences.ini
+ * in networktables.ini
*/
TEST(PreferencesTest, WritePreferencesToFile) {
+ NetworkTable::Shutdown();
+ NetworkTable::GlobalDeleteAll();
+ std::remove(kFileName);
+ NetworkTable::Initialize();
Preferences *preferences = Preferences::GetInstance();
preferences->PutString("testFilePutString", "Hello, preferences file");
preferences->PutInt("testFilePutInt", 1);
@@ -58,10 +64,13 @@ TEST(PreferencesTest, WritePreferencesToFile) {
Wait(kSaveTime);
static char const *kExpectedFileContents[] = {
- "[Preferences]", "testFileGetString=\"Hello, preferences file\"",
- "testFileGetInt=\"1\"", "testFileGetDouble=\"0.5\"",
- "testFileGetFloat=\"0.25\"", "testFileGetBoolean=\"true\"",
- "testFileGetLong=\"1000000000000000000\""};
+ "[NetworkTables Storage 3.0]",
+ "boolean \"/Preferences/testFilePutBoolean\"=true",
+ "double \"/Preferences/testFilePutDouble\"=0.5",
+ "double \"/Preferences/testFilePutFloat\"=0.25",
+ "double \"/Preferences/testFilePutInt\"=1",
+ "double \"/Preferences/testFilePutLong\"=1e+18",
+ "string \"/Preferences/testFilePutString\"=\"Hello, preferences file\""};
std::ifstream preferencesFile(kFileName);
for (auto& kExpectedFileContent : kExpectedFileContents) {
@@ -72,6 +81,6 @@ TEST(PreferencesTest, WritePreferencesToFile) {
std::getline(preferencesFile, line);
ASSERT_EQ(kExpectedFileContent, line)
- << "A line in wpilib-preferences.ini was not correct";
+ << "A line in networktables.ini was not correct";
}
}
diff --git a/wpilibc/wpilibC++Sim/CMakeLists.txt b/wpilibc/wpilibC++Sim/CMakeLists.txt
index 7be2cec34b..1241fd3a64 100644
--- a/wpilibc/wpilibC++Sim/CMakeLists.txt
+++ b/wpilibc/wpilibC++Sim/CMakeLists.txt
@@ -20,22 +20,12 @@ if (WIN32)
add_definitions(-Dsnprintf=sprintf_s)
endif()
-if (WIN32)
- file(GLOB_RECURSE SRC_FILES src/*.cpp
- ../../networktables/cpp/lib/share/*.cpp
- ../../networktables/cpp/lib/WIN32/*.cpp)
-else()
- file(GLOB_RECURSE SRC_FILES src/*.cpp
- ../../networktables/cpp/lib/share/*.cpp
- ../../networktables/cpp/lib/Athena/*.cpp)
-endif()
-
file(GLOB_RECURSE COM_SRC_FILES ../wpilibC++/src/*.cpp)
set (INCLUDE_FOLDERS include
../wpilibC++/include
- ../../networktables/cpp/include
+ ../../networktables/ntcore/include
../../hal/include
${GZ_MSGS_INCLUDE_DIR}
${Boost_INCLUDE_DIR}
@@ -61,7 +51,7 @@ else()
add_library(WPILibSim SHARED ${SRC_FILES} ${COM_SRC_FILES})
endif()
-target_link_libraries(WPILibSim gz_msgs ${PTHREAD_LIBRARY} ${Boost_LIBRARIES} ${GAZEBO_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} -fPIC) # NetworkTables
+target_link_libraries(WPILibSim gz_msgs ntcore ${PTHREAD_LIBRARY} ${Boost_LIBRARIES} ${GAZEBO_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} -fPIC) # NetworkTables
if (WIN32)
set_target_properties(${project} PROPERTIES LINK_FLAGS "/DEBUG")
diff --git a/wpilibc/wpilibC++Sim/include/DoubleSolenoid.h b/wpilibc/wpilibC++Sim/include/DoubleSolenoid.h
index 87858a845a..122a439627 100644
--- a/wpilibc/wpilibC++Sim/include/DoubleSolenoid.h
+++ b/wpilibc/wpilibC++Sim/include/DoubleSolenoid.h
@@ -30,11 +30,12 @@ public:
explicit DoubleSolenoid(uint32_t forwardChannel, uint32_t reverseChannel);
DoubleSolenoid(uint8_t moduleNumber, uint32_t forwardChannel, uint32_t reverseChannel);
- virtual ~DoubleSolenoid() = default;
+ virtual ~DoubleSolenoid();
virtual void Set(Value value);
virtual Value Get() const;
- void ValueChanged(std::shared_ptr source, const std::string& key, EntryValue value, bool isNew) override;
+ void ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) override;
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
diff --git a/wpilibc/wpilibC++Sim/include/PWM.h b/wpilibc/wpilibC++Sim/include/PWM.h
index aec0d77592..dd29a9376d 100644
--- a/wpilibc/wpilibC++Sim/include/PWM.h
+++ b/wpilibc/wpilibC++Sim/include/PWM.h
@@ -39,7 +39,7 @@ public:
};
explicit PWM(uint32_t channel);
- virtual ~PWM() = default;
+ virtual ~PWM();
virtual void SetRaw(unsigned short value);
void SetPeriodMultiplier(PeriodMultiplier mult);
void EnableDeadbandElimination(bool eliminateDeadband);
@@ -87,7 +87,8 @@ protected:
bool m_eliminateDeadband;
int32_t m_centerPwm;
- void ValueChanged(std::shared_ptr source, const std::string& key, EntryValue value, bool isNew) override;
+ void ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) override;
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
diff --git a/wpilibc/wpilibC++Sim/include/Relay.h b/wpilibc/wpilibC++Sim/include/Relay.h
index c8076ab1be..0f5d33c3ee 100644
--- a/wpilibc/wpilibC++Sim/include/Relay.h
+++ b/wpilibc/wpilibC++Sim/include/Relay.h
@@ -47,7 +47,8 @@ public:
void Set(Value value);
Value Get() const;
- void ValueChanged(std::shared_ptr source, const std::string& key, EntryValue value, bool isNew) override;
+ void ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) override;
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
diff --git a/wpilibc/wpilibC++Sim/include/Solenoid.h b/wpilibc/wpilibC++Sim/include/Solenoid.h
index eac30deb6f..b91da6e570 100644
--- a/wpilibc/wpilibC++Sim/include/Solenoid.h
+++ b/wpilibc/wpilibC++Sim/include/Solenoid.h
@@ -22,11 +22,12 @@ class Solenoid : public LiveWindowSendable, public ITableListener
public:
explicit Solenoid(uint32_t channel);
Solenoid(uint8_t moduleNumber, uint32_t channel);
- virtual ~Solenoid() = default;
+ virtual ~Solenoid();
virtual void Set(bool on);
virtual bool Get() const;
- void ValueChanged(std::shared_ptr source, const std::string& key, EntryValue value, bool isNew) override;
+ void ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) override;
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
diff --git a/wpilibc/wpilibC++Sim/src/DoubleSolenoid.cpp b/wpilibc/wpilibC++Sim/src/DoubleSolenoid.cpp
index b6e45278e4..d1d09176ca 100644
--- a/wpilibc/wpilibC++Sim/src/DoubleSolenoid.cpp
+++ b/wpilibc/wpilibC++Sim/src/DoubleSolenoid.cpp
@@ -43,6 +43,10 @@ DoubleSolenoid::DoubleSolenoid(uint8_t moduleNumber, uint32_t forwardChannel, ui
forwardChannel, this);
}
+DoubleSolenoid::~DoubleSolenoid() {
+ if (m_table != nullptr) m_table->RemoveTableListener(this);
+}
+
/**
* Set the value of a solenoid.
*
@@ -75,12 +79,14 @@ DoubleSolenoid::Value DoubleSolenoid::Get() const
return m_value;
}
-void DoubleSolenoid::ValueChanged(std::shared_ptr source, const std::string& key, EntryValue value, bool isNew) {
- Value lvalue = kOff;
- std::string *val = (std::string *)value.ptr;
- if (*val == "Forward")
+void DoubleSolenoid::ValueChanged(ITable *source, llvm::StringRef key,
+ std::shared_ptr value,
+ bool isNew) {
+ if (!value->IsString()) return;
+ Value lvalue = kOff;
+ if (value->GetString() == "Forward")
lvalue = kForward;
- else if (*val == "Reverse")
+ else if (value->GetString() == "Reverse")
lvalue = kReverse;
Set(lvalue);
}
diff --git a/wpilibc/wpilibC++Sim/src/PIDController.cpp b/wpilibc/wpilibC++Sim/src/PIDController.cpp
index c6abdcac60..cd2a5e4073 100644
--- a/wpilibc/wpilibC++Sim/src/PIDController.cpp
+++ b/wpilibc/wpilibC++Sim/src/PIDController.cpp
@@ -93,6 +93,10 @@ void PIDController::Initialize(float Kp, float Ki, float Kd, float Kf,
m_toleranceType = kNoTolerance;
}
+PIDController::~PIDController() {
+ if (m_table != nullptr) m_table->RemoveTableListener(this);
+}
+
/**
* Call the Calculate method as a non-static method. This avoids having to prepend
* all local variables in that method with the class pointer. This way the "this"
@@ -579,20 +583,27 @@ std::shared_ptr PIDController::GetTable() const {
return m_table;
}
-void PIDController::ValueChanged(std::shared_ptr source, const std::string& key, EntryValue value, bool isNew){
- if (key==kP || key==kI || key==kD || key==kF) {
- if (m_P != m_table->GetNumber(kP) || m_I != m_table->GetNumber(kI) || m_D != m_table->GetNumber(kD) || m_F != m_table->GetNumber(kF) ) {
- SetPID(m_table->GetNumber(kP, 0.0), m_table->GetNumber(kI, 0.0), m_table->GetNumber(kD, 0.0), m_table->GetNumber(kF, 0.0));
- }
- } else if (key==kSetpoint && m_setpoint != value.f) {
- SetSetpoint(value.f);
- } else if (key==kEnabled && m_enabled != value.b) {
- if (value.b) {
- Enable();
- } else {
- Disable();
- }
- }
+void PIDController::ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) {
+ if (key == kP || key == kI || key == kD || key == kF) {
+ if (m_P != m_table->GetNumber(kP, 0.0) ||
+ m_I != m_table->GetNumber(kI, 0.0) ||
+ m_D != m_table->GetNumber(kD, 0.0) ||
+ m_F != m_table->GetNumber(kF, 0.0)) {
+ SetPID(m_table->GetNumber(kP, 0.0), m_table->GetNumber(kI, 0.0),
+ m_table->GetNumber(kD, 0.0), m_table->GetNumber(kF, 0.0));
+ }
+ } else if (key == kSetpoint && value->IsDouble() &&
+ m_setpoint != value->GetDouble()) {
+ SetSetpoint(value->GetDouble());
+ } else if (key == kEnabled && value->IsBoolean() &&
+ m_enabled != value->GetBoolean()) {
+ if (value->GetBoolean()) {
+ Enable();
+ } else {
+ Disable();
+ }
+ }
}
void PIDController::UpdateTable() {
diff --git a/wpilibc/wpilibC++Sim/src/PWM.cpp b/wpilibc/wpilibC++Sim/src/PWM.cpp
index 1b1a6dfc6a..dfb8bd9d2a 100644
--- a/wpilibc/wpilibC++Sim/src/PWM.cpp
+++ b/wpilibc/wpilibC++Sim/src/PWM.cpp
@@ -43,6 +43,10 @@ PWM::PWM(uint32_t channel)
m_centerPwm = kPwmDisabled; // In simulation, the same thing.
}
+PWM::~PWM() {
+ if (m_table != nullptr) m_table->RemoveTableListener(this);
+}
+
/**
* Optionally eliminate the deadband from a speed controller.
* @param eliminateDeadband If true, set the motor curve on the Jaguar to eliminate
@@ -217,8 +221,10 @@ void PWM::SetPeriodMultiplier(PeriodMultiplier mult)
}
-void PWM::ValueChanged(std::shared_ptr source, const std::string& key, EntryValue value, bool isNew) {
- SetSpeed(value.f);
+void PWM::ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) {
+ if (!value->IsDouble()) return;
+ SetSpeed(value->GetDouble());
}
void PWM::UpdateTable() {
diff --git a/wpilibc/wpilibC++Sim/src/Relay.cpp b/wpilibc/wpilibC++Sim/src/Relay.cpp
index a86320af6d..971fe28698 100644
--- a/wpilibc/wpilibC++Sim/src/Relay.cpp
+++ b/wpilibc/wpilibC++Sim/src/Relay.cpp
@@ -43,6 +43,7 @@ Relay::Relay(uint32_t channel, Relay::Direction direction)
Relay::~Relay()
{
impl->Set(0);
+ if (m_table != nullptr) m_table->RemoveTableListener(this);
}
/**
@@ -140,11 +141,12 @@ Relay::Value Relay::Get() const {
}
}
-void Relay::ValueChanged(std::shared_ptr source, const std::string& key, EntryValue value, bool isNew) {
- std::string *val = (std::string *) value.ptr;
- if (*val == "Off") Set(kOff);
- else if (*val == "Forward") Set(kForward);
- else if (*val == "Reverse") Set(kReverse);
+void Relay::ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) {
+ if (!value->IsString()) return;
+ if (value->GetString() == "Off") Set(kOff);
+ else if (value->GetString() == "Forward") Set(kForward);
+ else if (value->GetString() == "Reverse") Set(kReverse);
}
void Relay::UpdateTable() {
diff --git a/wpilibc/wpilibC++Sim/src/Solenoid.cpp b/wpilibc/wpilibC++Sim/src/Solenoid.cpp
index 682995b497..387194db2a 100644
--- a/wpilibc/wpilibC++Sim/src/Solenoid.cpp
+++ b/wpilibc/wpilibC++Sim/src/Solenoid.cpp
@@ -32,6 +32,10 @@ Solenoid::Solenoid(uint8_t moduleNumber, uint32_t channel)
this);
}
+Solenoid::~Solenoid() {
+ if (m_table != nullptr) m_table->RemoveTableListener(this);
+}
+
/**
* Set the value of a solenoid.
*
@@ -54,8 +58,10 @@ bool Solenoid::Get() const
}
-void Solenoid::ValueChanged(std::shared_ptr source, const std::string& key, EntryValue value, bool isNew) {
- Set(value.b);
+void Solenoid::ValueChanged(ITable* source, llvm::StringRef key,
+ std::shared_ptr value, bool isNew) {
+ if (!value->IsBoolean()) return;
+ Set(value->GetBoolean());
}
void Solenoid::UpdateTable() {
diff --git a/wpilibj/build.gradle b/wpilibj/build.gradle
index bb027daca7..b0c78d1c6d 100644
--- a/wpilibj/build.gradle
+++ b/wpilibj/build.gradle
@@ -3,7 +3,7 @@ apply plugin: 'cpp'
apply plugin: 'maven-publish'
// We need this so we can get the networktables javadoc for the javadoc task
-evaluationDependsOn(':networktables:java')
+evaluationDependsOn(':networktables:ntcore')
def jdkDownloadSite = 'http://www.oracle.com/technetwork/java/javase/downloads/jdk8-arm-downloads-2187472.html'
def jdkFolder = 'jdk-linux-arm-vfp-sflt'
@@ -117,10 +117,10 @@ sourceSets {
dependencies {
compile sourceSets.shared.output
- compile project(':networktables:java')
+ compile project(':networktables:ntcore')
testCompile 'junit:junit:4.11'
- sharedCompile project(':networktables:java')
- integrationTestCompile project(':networktables:java')
+ sharedCompile project(':networktables:ntcore')
+ integrationTestCompile project(':networktables:ntcore')
integrationTestCompile 'junit:junit:4.11'
integrationTestCompile sourceSets.main.output
integrationTestCompile sourceSets.shared.output
@@ -130,7 +130,7 @@ dependencies {
simulationCompile sourceSets.main.output
simulationCompile sourceSets.shared.output
simulationCompile project(':simulation:JavaGazebo')
- simulationCompile project(':networktables:java')
+ simulationCompile project(':networktables:ntcore')
}
task wpilibjJar(type: Jar) {
@@ -156,7 +156,7 @@ task wpilibjSources(type: Jar, dependsOn: classes) {
}
task javadoc(type: Javadoc, overwrite: true) {
- def netTables = project(':networktables:java')
+ def netTables = project(':networktables:ntcore')
source sourceSets.main.allJava, sourceSets.shared.allJava, netTables.sourceSets.main.allJava
classpath = files([sourceSets.main.compileClasspath, sourceSets.shared.compileClasspath, netTables.sourceSets.main.compileClasspath])
}
diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/command/Scheduler.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/command/Scheduler.java
index e7ad4acb02..72ae524746 100644
--- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/command/Scheduler.java
+++ b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/command/Scheduler.java
@@ -13,8 +13,6 @@ import java.util.Vector;
import edu.wpi.first.wpilibj.HLUsageReporting;
import edu.wpi.first.wpilibj.NamedSendable;
import edu.wpi.first.wpilibj.buttons.Trigger.ButtonScheduler;
-import edu.wpi.first.wpilibj.networktables2.type.NumberArray;
-import edu.wpi.first.wpilibj.networktables2.type.StringArray;
import edu.wpi.first.wpilibj.tables.ITable;
/**
@@ -318,49 +316,48 @@ public class Scheduler implements NamedSendable {
return "Scheduler";
}
- private StringArray commands;
- private NumberArray ids, toCancel;
-
/**
* {@inheritDoc}
*/
public void initTable(ITable subtable) {
m_table = subtable;
- commands = new StringArray();
- ids = new NumberArray();
- toCancel = new NumberArray();
- m_table.putValue("Names", commands);
- m_table.putValue("Ids", ids);
- m_table.putValue("Cancel", toCancel);
+ m_table.putStringArray("Names", new String[0]);
+ m_table.putNumberArray("Ids", new double[0]);
+ m_table.putNumberArray("Cancel", new double[0]);
}
private void updateTable() {
if (m_table != null) {
// Get the commands to cancel
- m_table.retrieveValue("Cancel", toCancel);
- if (toCancel.size() > 0) {
+ double[] toCancel = m_table.getNumberArray("Cancel", new double[0]);
+ if (toCancel.length > 0) {
for (LinkedListElement e = firstCommand; e != null; e = e.getNext()) {
- for (int i = 0; i < toCancel.size(); i++) {
- if (e.getData().hashCode() == toCancel.get(i)) {
+ for (int i = 0; i < toCancel.length; i++) {
+ if (e.getData().hashCode() == toCancel[i]) {
e.getData().cancel();
}
}
}
- toCancel.setSize(0);
- m_table.putValue("Cancel", toCancel);
+ m_table.putNumberArray("Cancel", new double[0]);
}
if (m_runningCommandsChanged) {
- commands.setSize(0);
- ids.setSize(0);
// Set the the running commands
+ int n = 0;
for (LinkedListElement e = firstCommand; e != null; e = e.getNext()) {
- commands.add(e.getData().getName());
- ids.add(e.getData().hashCode());
+ n++;
}
- m_table.putValue("Names", commands);
- m_table.putValue("Ids", ids);
+ String[] commands = new String[n];
+ double[] ids = new double[n];
+ n = 0;
+ for (LinkedListElement e = firstCommand; e != null; e = e.getNext()) {
+ commands[n] = e.getData().getName();
+ ids[n] = e.getData().hashCode();
+ n++;
+ }
+ m_table.putStringArray("Names", commands);
+ m_table.putNumberArray("Ids", ids);
}
}
}
diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooser.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooser.java
index 8111bd1fc8..c20a5aaa73 100644
--- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooser.java
+++ b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooser.java
@@ -8,10 +8,10 @@ package edu.wpi.first.wpilibj.smartdashboard;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.command.Command;
-import edu.wpi.first.wpilibj.networktables2.type.StringArray;
-import edu.wpi.first.wpilibj.networktables2.util.List;
import edu.wpi.first.wpilibj.tables.ITable;
+import java.util.ArrayList;
+
/**
* The {@link SendableChooser} class is a useful tool for presenting a selection
* of options to the {@link SmartDashboard}.
@@ -44,8 +44,8 @@ public class SendableChooser implements Sendable {
/**
* A table linking strings to the objects the represent
*/
- private StringArray choices = new StringArray();
- private List values = new List();
+ private ArrayList choices = new ArrayList();
+ private ArrayList