Rename our allwpilib (which is now 2020) to not have 2019 in the name

Change-Id: I3c07f85ed32ab8b97db765a9b43f2a6ce7da964a
diff --git a/simulation/halsim_ds_nt/CMakeLists.txt b/simulation/halsim_ds_nt/CMakeLists.txt
new file mode 100644
index 0000000..bfed6ff
--- /dev/null
+++ b/simulation/halsim_ds_nt/CMakeLists.txt
@@ -0,0 +1,16 @@
+project(halsim_ds_nt)
+
+include(CompileWarnings)
+
+file(GLOB halsim_ds_nt_src src/main/native/cpp/*.cpp)
+
+add_library(halsim_ds_nt MODULE ${halsim_ds_nt_src})
+wpilib_target_warnings(halsim_ds_nt)
+set_target_properties(halsim_ds_nt PROPERTIES DEBUG_POSTFIX "d")
+target_link_libraries(halsim_ds_nt PUBLIC hal ntcore)
+
+target_include_directories(halsim_ds_nt PRIVATE src/main/native/include)
+
+set_property(TARGET halsim_ds_nt PROPERTY FOLDER "libraries")
+
+install(TARGETS halsim_ds_nt EXPORT halsim_ds_nt DESTINATION "${main_lib_dest}")
diff --git a/simulation/halsim_ds_nt/build.gradle b/simulation/halsim_ds_nt/build.gradle
new file mode 100644
index 0000000..fa02630
--- /dev/null
+++ b/simulation/halsim_ds_nt/build.gradle
@@ -0,0 +1,9 @@
+description = "A simulation shared object that uses NetworkTables to act as a stand-in for the FRC Driver Station"
+
+ext {
+    includeNtCore = true
+    includeWpiutil = true
+    pluginName = 'halsim_ds_nt'
+}
+
+apply from: "${rootDir}/shared/plugins/setupBuild.gradle"
diff --git a/simulation/halsim_ds_nt/src/dev/native/cpp/main.cpp b/simulation/halsim_ds_nt/src/dev/native/cpp/main.cpp
new file mode 100644
index 0000000..e324b44
--- /dev/null
+++ b/simulation/halsim_ds_nt/src/dev/native/cpp/main.cpp
@@ -0,0 +1,8 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 FIRST. 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.                                                               */
+/*----------------------------------------------------------------------------*/
+
+int main() {}
diff --git a/simulation/halsim_ds_nt/src/main/native/cpp/HALSimDsNt.cpp b/simulation/halsim_ds_nt/src/main/native/cpp/HALSimDsNt.cpp
new file mode 100644
index 0000000..d694530
--- /dev/null
+++ b/simulation/halsim_ds_nt/src/main/native/cpp/HALSimDsNt.cpp
@@ -0,0 +1,194 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. 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 "HALSimDsNt.h"
+
+void HALSimDSNT::Initialize() {
+  rootTable =
+      nt::NetworkTableInstance::GetDefault().GetTable("sim")->GetSubTable(
+          "DS_CONTROL");  // Not to be confused with sim::DriverStation from
+                          // HALSim LowFi
+
+  // LOOP TIMING //
+
+  auto timinghz = rootTable->GetEntry("timing_hz");
+  timinghz.ForceSetDouble(50);
+  timinghz.AddListener(
+      [this](const nt::EntryNotification& ev) -> void {
+        double valIn = ev.value->GetDouble();
+        double val = 0;
+        val = (valIn < 1 ? 1 : valIn > 100 ? 100 : valIn);
+
+        if (val != valIn) {
+          this->rootTable->GetEntry("timing_hz").ForceSetDouble(val);
+          Flush();
+        }
+
+        this->timingHz = val;
+      },
+      NT_NotifyKind::NT_NOTIFY_UPDATE);
+
+  // MODES //
+
+  modeTable = rootTable->GetSubTable("mode");
+  auto mtele = modeTable->GetEntry("teleop?");
+  auto mauto = modeTable->GetEntry("auto?");
+  auto mtest = modeTable->GetEntry("test?");
+  auto enabled = modeTable->GetEntry("enabled?");
+  auto estop = modeTable->GetEntry("estop?");
+
+  mtele.ForceSetBoolean(true);
+  mauto.ForceSetBoolean(false);
+  mtest.ForceSetBoolean(false);
+  enabled.ForceSetBoolean(false);
+  estop.ForceSetBoolean(false);
+
+  mtele.AddListener(
+      [this](const nt::EntryNotification& ev) -> void {
+        this->HandleModePress(HALSimDSNT_Mode::teleop, ev.value->GetBoolean());
+      },
+      NT_NotifyKind::NT_NOTIFY_UPDATE);
+
+  mauto.AddListener(
+      [this](const nt::EntryNotification& ev) -> void {
+        this->HandleModePress(HALSimDSNT_Mode::auton, ev.value->GetBoolean());
+      },
+      NT_NotifyKind::NT_NOTIFY_UPDATE);
+
+  mtest.AddListener(
+      [this](const nt::EntryNotification& ev) -> void {
+        this->HandleModePress(HALSimDSNT_Mode::test, ev.value->GetBoolean());
+      },
+      NT_NotifyKind::NT_NOTIFY_UPDATE);
+
+  enabled.AddListener(
+      [this](const nt::EntryNotification& ev) -> void {
+        std::scoped_lock lock(modeMutex);
+        if (!this->isEstop) {
+          this->isEnabled = ev.value->GetBoolean();
+        } else {
+          this->isEnabled = false;
+        }
+        this->DoModeUpdate();
+        this->UpdateModeButtons();
+      },
+      NT_NotifyKind::NT_NOTIFY_UPDATE);
+
+  estop.AddListener(
+      [this](const nt::EntryNotification& ev) -> void {
+        std::scoped_lock lock(modeMutex);
+        this->isEstop = ev.value->GetBoolean();
+        if (this->isEstop) {
+          this->isEnabled = false;
+        }
+        this->DoModeUpdate();
+        this->UpdateModeButtons();
+      },
+      NT_NotifyKind::NT_NOTIFY_UPDATE);
+
+  // ALLIANCES //
+
+  allianceTable = rootTable->GetSubTable("alliance");
+  auto allianceStation = allianceTable->GetEntry("station");
+  auto allianceColorRed = allianceTable->GetEntry("red?");
+
+  allianceStation.ForceSetDouble(1);
+  allianceColorRed.ForceSetBoolean(true);
+
+  allianceStation.AddListener(
+      [this](const nt::EntryNotification& ev) -> void {
+        double stnIn = ev.value->GetDouble();
+        double stn = 0;
+        stn = (stnIn > 3 ? 3 : stnIn < 1 ? 1 : stnIn);
+
+        if (stn != stnIn) {
+          this->allianceTable->GetEntry("station").ForceSetDouble(stn);
+          Flush();
+        }
+
+        this->allianceStation = stn;
+        this->DoAllianceUpdate();
+      },
+      NT_NotifyKind::NT_NOTIFY_UPDATE);
+
+  allianceColorRed.AddListener(
+      [this](const nt::EntryNotification& ev) -> void {
+        this->isAllianceRed = ev.value->GetBoolean();
+        this->DoAllianceUpdate();
+      },
+      NT_NotifyKind::NT_NOTIFY_UPDATE);
+
+  // FINAL LOGIC //
+
+  Flush();
+
+  loopThread = std::thread([this]() -> void {
+    this->running = true;
+    this->LoopFunc();
+  });
+  loopThread.detach();
+}
+
+void HALSimDSNT::HandleModePress(enum HALSimDSNT_Mode mode, bool isPressed) {
+  if (isPressed) {
+    if (mode != currentMode) {
+      std::scoped_lock lock(modeMutex);
+      currentMode = mode;
+      isEnabled = false;
+      this->DoModeUpdate();
+    }
+  }
+
+  this->UpdateModeButtons();
+}
+
+void HALSimDSNT::UpdateModeButtons() {
+  modeTable->GetEntry("teleop?").ForceSetBoolean(currentMode ==
+                                                 HALSimDSNT_Mode::teleop);
+  modeTable->GetEntry("auto?").ForceSetBoolean(currentMode ==
+                                               HALSimDSNT_Mode::auton);
+  modeTable->GetEntry("test?").ForceSetBoolean(currentMode ==
+                                               HALSimDSNT_Mode::test);
+  modeTable->GetEntry("enabled?").ForceSetBoolean(isEnabled);
+  Flush();
+}
+
+void HALSimDSNT::DoModeUpdate() {
+  HALSIM_SetDriverStationAutonomous(currentMode == HALSimDSNT_Mode::auton);
+  HALSIM_SetDriverStationTest(currentMode == HALSimDSNT_Mode::test);
+  HALSIM_SetDriverStationEnabled(isEnabled);
+  if (isEnabled && !lastIsEnabled) {
+    currentMatchTime = 0;
+  }
+  lastIsEnabled = isEnabled;
+  HALSIM_SetDriverStationEStop(isEstop);
+  HALSIM_SetDriverStationFmsAttached(false);
+  HALSIM_SetDriverStationDsAttached(true);
+  HALSIM_NotifyDriverStationNewData();
+}
+
+void HALSimDSNT::DoAllianceUpdate() {
+  HALSIM_SetDriverStationAllianceStationId(static_cast<HAL_AllianceStationID>(
+      (isAllianceRed ? HAL_AllianceStationID_kRed1
+                     : HAL_AllianceStationID_kBlue1) +
+      (static_cast<int32_t>(allianceStation) - 1)));
+}
+
+void HALSimDSNT::LoopFunc() {
+  while (running) {
+    double dt = 1000 / timingHz;
+    std::this_thread::sleep_for(
+        std::chrono::milliseconds(static_cast<int64_t>(dt)));
+    if (isEnabled) {
+      currentMatchTime = currentMatchTime + dt;
+      HALSIM_SetDriverStationMatchTime(currentMatchTime);
+    }
+    HALSIM_NotifyDriverStationNewData();
+  }
+}
+
+void HALSimDSNT::Flush() { rootTable->GetInstance().Flush(); }
diff --git a/simulation/halsim_ds_nt/src/main/native/cpp/main.cpp b/simulation/halsim_ds_nt/src/main/native/cpp/main.cpp
new file mode 100644
index 0000000..7090de9
--- /dev/null
+++ b/simulation/halsim_ds_nt/src/main/native/cpp/main.cpp
@@ -0,0 +1,26 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. 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 <iostream>
+
+#include <HALSimDsNt.h>
+
+static HALSimDSNT dsnt;
+
+extern "C" {
+#if defined(WIN32) || defined(_WIN32)
+__declspec(dllexport)
+#endif
+    int HALSIM_InitExtension(void) {
+  std::cout << "DriverStationNT Initializing." << std::endl;
+
+  dsnt.Initialize();
+
+  std::cout << "DriverStationNT Initialized!" << std::endl;
+  return 0;
+}
+}  // extern "C"
diff --git a/simulation/halsim_ds_nt/src/main/native/include/HALSimDsNt.h b/simulation/halsim_ds_nt/src/main/native/include/HALSimDsNt.h
new file mode 100644
index 0000000..21d19ee
--- /dev/null
+++ b/simulation/halsim_ds_nt/src/main/native/include/HALSimDsNt.h
@@ -0,0 +1,37 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. 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.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <atomic>
+#include <memory>
+#include <thread>
+
+#include <mockdata/DriverStationData.h>
+#include <networktables/NetworkTableInstance.h>
+#include <wpi/mutex.h>
+
+enum HALSimDSNT_Mode { teleop, auton, test };
+
+class HALSimDSNT {
+ public:
+  std::shared_ptr<nt::NetworkTable> rootTable, modeTable, allianceTable;
+  enum HALSimDSNT_Mode currentMode;
+  bool isEnabled, lastIsEnabled, isEstop;
+  std::atomic<bool> isAllianceRed, running;
+  std::atomic<double> currentMatchTime, timingHz, allianceStation;
+  std::thread loopThread;
+  wpi::mutex modeMutex;
+
+  void Initialize();
+  void HandleModePress(enum HALSimDSNT_Mode mode, bool isPressed);
+  void UpdateModeButtons();
+  void DoModeUpdate();
+  void DoAllianceUpdate();
+  void LoopFunc();
+  void Flush();
+};