This is the latest WPILib src, VisionSample2013, cRIO image, ... pulled down from firstforge.wpi.edu.
There might be risks in using the top of tree rather than an official release, but the commit messages do mention fixes for some deadlocks and race conditions.
git-svn-id: https://robotics.mvla.net/svn/frc971/2013/trunk/src@4066 f308d9b7-e957-4cde-b6ac-9a88185e7312
diff --git a/azaleasource/WPILibCProgramming/trunk/WPILib/LiveWindow/LiveWindow.cpp b/azaleasource/WPILibCProgramming/trunk/WPILib/LiveWindow/LiveWindow.cpp
new file mode 100644
index 0000000..2202a10
--- /dev/null
+++ b/azaleasource/WPILibCProgramming/trunk/WPILib/LiveWindow/LiveWindow.cpp
@@ -0,0 +1,189 @@
+#include "LiveWindow/LiveWindow.h"
+#include "networktables/NetworkTable.h"
+#include <algorithm>
+#include <sstream>
+
+LiveWindow* LiveWindow::m_instance = NULL;
+
+/**
+ * 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()
+{
+ if (m_instance == NULL)
+ {
+ m_instance = new LiveWindow();
+ }
+ return m_instance;
+}
+
+/**
+ * LiveWindow constructor.
+ * Allocate the necessary tables.
+ */
+LiveWindow::LiveWindow()
+{
+ m_enabled = false;
+ m_liveWindowTable = NetworkTable::GetTable("LiveWindow");
+ m_statusTable = m_liveWindowTable->GetSubTable("~STATUS~");
+ m_scheduler = Scheduler::GetInstance();
+}
+
+/**
+ * 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)
+ {
+ printf("Starting live window mode\n");
+ if (m_firstTime)
+ {
+ InitializeLiveWindowComponents();
+ m_firstTime = false;
+ }
+ m_scheduler->SetEnabled(false);
+ m_scheduler->RemoveAll();
+ for (std::map<LiveWindowSendable *, LiveWindowComponent>::iterator it =
+ m_components.begin(); it != m_components.end(); ++it)
+ {
+ it->first->StartLiveWindowMode();
+ }
+ }
+ else
+ {
+ printf("Ending LiveWindow mode\n");
+ for (std::map<LiveWindowSendable *, LiveWindowComponent>::iterator it =
+ m_components.begin(); it != m_components.end(); ++it)
+ {
+ it->first->StopLiveWindowMode();
+ }
+ m_scheduler->SetEnabled(true);
+ }
+ m_enabled = enabled;
+ m_statusTable->PutBoolean("LW Enabled", m_enabled);
+}
+
+LiveWindow::~LiveWindow()
+{
+}
+
+/**
+ * Add a Sensor associated with the subsystem and with 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.
+ */
+void LiveWindow::AddSensor(char *subsystem, char *name,
+ LiveWindowSendable *component)
+{
+ m_components[component].subsystem = subsystem;
+ m_components[component].name = name;
+ m_components[component].isSensor = true;
+}
+
+/**
+ * Add an Actuator associated with the subsystem and with 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.
+ */
+void LiveWindow::AddActuator(char *subsystem, char *name,
+ LiveWindowSendable *component)
+{
+ m_components[component].subsystem = subsystem;
+ m_components[component].name = name;
+ m_components[component].isSensor = false;
+}
+
+/**
+ * INTERNAL
+ */
+void LiveWindow::AddSensor(std::string type, int module, int channel, LiveWindowSendable *component)
+{
+ std::ostringstream oss;
+ oss << type << "[" << module << "," << channel << "]";
+ std::string types(oss.str());
+ char* cc = new char[types.size() + 1];
+ types.copy(cc, types.size());
+ cc[types.size()]='\0';
+ AddSensor("Ungrouped", cc, component);
+ if (std::find(m_sensors.begin(), m_sensors.end(), component) == m_sensors.end())
+ m_sensors.push_back(component);
+}
+
+/**
+ * INTERNAL
+ */
+void LiveWindow::AddActuator(std::string type, int module, int channel, LiveWindowSendable *component)
+{
+ std::ostringstream oss;
+ oss << type << "[" << module << "," << channel << "]";
+ std::string types(oss.str());
+ char* cc = new char[types.size() + 1];
+ types.copy(cc, types.size());
+ cc[types.size()]='\0';
+ AddActuator("Ungrouped", cc, component);
+}
+
+/**
+ * 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 (unsigned int i = 0; i < m_sensors.size(); i++)
+ {
+ m_sensors[i]->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 (std::map<LiveWindowSendable *, LiveWindowComponent>::iterator it =
+ m_components.begin(); it != m_components.end(); ++it)
+ {
+ LiveWindowSendable *component = it->first;
+ LiveWindowComponent c = it->second;
+ std::string subsystem = c.subsystem;
+ std::string name = c.name;
+ m_liveWindowTable->GetSubTable(subsystem)->PutString("~TYPE~",
+ "LW Subsystem");
+ 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);
+ }
+ }
+}
+