Squashed 'third_party/allwpilib_2017/' content from commit 35ac87d
Change-Id: I7bb6f5556c30d3f5a092e68de0be9c710c60c9f4
git-subtree-dir: third_party/allwpilib_2017
git-subtree-split: 35ac87d6ff8b7f061c4f18c9ea316e5dccd4888a
diff --git a/wpilibc/shared/src/LiveWindow/LiveWindow.cpp b/wpilibc/shared/src/LiveWindow/LiveWindow.cpp
new file mode 100644
index 0000000..1328545
--- /dev/null
+++ b/wpilibc/shared/src/LiveWindow/LiveWindow.cpp
@@ -0,0 +1,238 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2012-2017. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "LiveWindow/LiveWindow.h"
+
+#include <algorithm>
+#include <sstream>
+
+#include "networktables/NetworkTable.h"
+
+using namespace frc;
+
+/**
+ * Get an instance of the LiveWindow main class.
+ *
+ * This is a singleton to guarantee that there is only a single instance
+ * regardless of how many times GetInstance is called.
+ */
+LiveWindow* LiveWindow::GetInstance() {
+ static LiveWindow instance;
+ return &instance;
+}
+
+/**
+ * LiveWindow constructor.
+ *
+ * Allocate the necessary tables.
+ */
+LiveWindow::LiveWindow() : m_scheduler(Scheduler::GetInstance()) {
+ m_liveWindowTable = NetworkTable::GetTable("LiveWindow");
+ m_statusTable = m_liveWindowTable->GetSubTable("~STATUS~");
+}
+
+/**
+ * Change the enabled status of LiveWindow.
+ *
+ * If it changes to enabled, start livewindow running otherwise stop it
+ */
+void LiveWindow::SetEnabled(bool enabled) {
+ if (m_enabled == enabled) return;
+ if (enabled) {
+ if (m_firstTime) {
+ InitializeLiveWindowComponents();
+ m_firstTime = false;
+ }
+ m_scheduler->SetEnabled(false);
+ m_scheduler->RemoveAll();
+ for (auto& elem : m_components) {
+ elem.first->StartLiveWindowMode();
+ }
+ } else {
+ for (auto& elem : m_components) {
+ elem.first->StopLiveWindowMode();
+ }
+ m_scheduler->SetEnabled(true);
+ }
+ m_enabled = enabled;
+ m_statusTable->PutBoolean("LW Enabled", m_enabled);
+}
+
+/**
+ * @name AddSensor(subsystem, name, component)
+ *
+ * Add a Sensor associated with the subsystem and call it by the given name.
+ *
+ * @param subsystem The subsystem this component is part of.
+ * @param name The name of this component.
+ * @param component A LiveWindowSendable component that represents a sensor.
+ */
+//@{
+/**
+ * @brief Use a STL smart pointer to share ownership of component.
+ */
+void LiveWindow::AddSensor(const std::string& subsystem,
+ const std::string& name,
+ std::shared_ptr<LiveWindowSendable> component) {
+ m_components[component].subsystem = subsystem;
+ m_components[component].name = name;
+ m_components[component].isSensor = true;
+}
+
+/**
+ * @brief Pass a reference to LiveWindow and retain ownership of the component.
+ */
+void LiveWindow::AddSensor(const std::string& subsystem,
+ const std::string& name,
+ LiveWindowSendable& component) {
+ AddSensor(subsystem, name, std::shared_ptr<LiveWindowSendable>(
+ &component, [](LiveWindowSendable*) {}));
+}
+
+/**
+ * @brief Use a raw pointer to the LiveWindow.
+ * @deprecated Prefer smart pointers or references.
+ */
+void LiveWindow::AddSensor(const std::string& subsystem,
+ const std::string& name,
+ LiveWindowSendable* component) {
+ AddSensor(subsystem, name, std::shared_ptr<LiveWindowSendable>(
+ component, NullDeleter<LiveWindowSendable>()));
+}
+//@}
+
+/**
+ * @name AddActuator(subsystem, name, component)
+ *
+ * Add an Actuator associated with the subsystem and call it by the given name.
+ *
+ * @param subsystem The subsystem this component is part of.
+ * @param name The name of this component.
+ * @param component A LiveWindowSendable component that represents a actuator.
+ */
+//@{
+/**
+ * @brief Use a STL smart pointer to share ownership of component.
+ */
+void LiveWindow::AddActuator(const std::string& subsystem,
+ const std::string& name,
+ std::shared_ptr<LiveWindowSendable> component) {
+ m_components[component].subsystem = subsystem;
+ m_components[component].name = name;
+ m_components[component].isSensor = false;
+}
+
+/**
+ * @brief Pass a reference to LiveWindow and retain ownership of the component.
+ */
+void LiveWindow::AddActuator(const std::string& subsystem,
+ const std::string& name,
+ LiveWindowSendable& component) {
+ AddActuator(subsystem, name, std::shared_ptr<LiveWindowSendable>(
+ &component, [](LiveWindowSendable*) {}));
+}
+
+/**
+ * @brief Use a raw pointer to the LiveWindow.
+ * @deprecated Prefer smart pointers or references.
+ */
+void LiveWindow::AddActuator(const std::string& subsystem,
+ const std::string& name,
+ LiveWindowSendable* component) {
+ AddActuator(subsystem, name,
+ std::shared_ptr<LiveWindowSendable>(
+ component, NullDeleter<LiveWindowSendable>()));
+}
+//@}
+
+/**
+ * Meant for internal use in other WPILib classes.
+ */
+void LiveWindow::AddSensor(std::string type, int channel,
+ LiveWindowSendable* component) {
+ std::ostringstream oss;
+ oss << type << "[" << channel << "]";
+ AddSensor("Ungrouped", oss.str(), component);
+ std::shared_ptr<LiveWindowSendable> component_stl(
+ component, NullDeleter<LiveWindowSendable>());
+ if (std::find(m_sensors.begin(), m_sensors.end(), component_stl) ==
+ m_sensors.end())
+ m_sensors.push_back(component_stl);
+}
+
+/**
+ * Meant for internal use in other WPILib classes.
+ */
+void LiveWindow::AddActuator(std::string type, int channel,
+ LiveWindowSendable* component) {
+ std::ostringstream oss;
+ oss << type << "[" << channel << "]";
+ AddActuator("Ungrouped", oss.str(),
+ std::shared_ptr<LiveWindowSendable>(component,
+ [](LiveWindowSendable*) {}));
+}
+
+/**
+ * Meant for internal use in other WPILib classes.
+ */
+void LiveWindow::AddActuator(std::string type, int module, int channel,
+ LiveWindowSendable* component) {
+ std::ostringstream oss;
+ oss << type << "[" << module << "," << channel << "]";
+ AddActuator("Ungrouped", oss.str(),
+ std::shared_ptr<LiveWindowSendable>(component,
+ [](LiveWindowSendable*) {}));
+}
+
+/**
+ * Tell all the sensors to update (send) their values.
+ *
+ * Actuators are handled through callbacks on their value changing from the
+ * SmartDashboard widgets.
+ */
+void LiveWindow::UpdateValues() {
+ for (auto& elem : m_sensors) {
+ elem->UpdateTable();
+ }
+}
+
+/**
+ * This method is called periodically to cause the sensors to send new values
+ * to the SmartDashboard.
+ */
+void LiveWindow::Run() {
+ if (m_enabled) {
+ UpdateValues();
+ }
+}
+
+/**
+ * Initialize all the LiveWindow elements the first time we enter LiveWindow
+ * mode. By holding off creating the NetworkTable entries, it allows them to be
+ * redefined before the first time in LiveWindow mode. This allows default
+ * sensor and actuator values to be created that are replaced with the custom
+ * names from users calling addActuator and addSensor.
+ */
+void LiveWindow::InitializeLiveWindowComponents() {
+ for (auto& elem : m_components) {
+ std::shared_ptr<LiveWindowSendable> component = elem.first;
+ LiveWindowComponent c = elem.second;
+ std::string subsystem = c.subsystem;
+ std::string name = c.name;
+ m_liveWindowTable->GetSubTable(subsystem)->PutString("~TYPE~",
+ "LW Subsystem");
+ std::shared_ptr<ITable> table(
+ m_liveWindowTable->GetSubTable(subsystem)->GetSubTable(name));
+ table->PutString("~TYPE~", component->GetSmartDashboardType());
+ table->PutString("Name", name);
+ table->PutString("Subsystem", subsystem);
+ component->InitTable(table);
+ if (c.isSensor) {
+ m_sensors.push_back(component);
+ }
+ }
+}