Squashed 'third_party/allwpilib_2019/' content from commit bd05dfa1c

Change-Id: I2b1c2250cdb9b055133780c33593292098c375b7
git-subtree-dir: third_party/allwpilib_2019
git-subtree-split: bd05dfa1c7cca74c4fac451e7b9d6a37e7b53447
diff --git a/wpilibc/src/main/native/cpp/DoubleSolenoid.cpp b/wpilibc/src/main/native/cpp/DoubleSolenoid.cpp
new file mode 100644
index 0000000..86678aa
--- /dev/null
+++ b/wpilibc/src/main/native/cpp/DoubleSolenoid.cpp
@@ -0,0 +1,186 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2008-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 "frc/DoubleSolenoid.h"
+
+#include <utility>
+
+#include <hal/HAL.h>
+#include <hal/Ports.h>
+#include <hal/Solenoid.h>
+
+#include "frc/SensorUtil.h"
+#include "frc/WPIErrors.h"
+#include "frc/smartdashboard/SendableBuilder.h"
+
+using namespace frc;
+
+DoubleSolenoid::DoubleSolenoid(int forwardChannel, int reverseChannel)
+    : DoubleSolenoid(SensorUtil::GetDefaultSolenoidModule(), forwardChannel,
+                     reverseChannel) {}
+
+DoubleSolenoid::DoubleSolenoid(int moduleNumber, int forwardChannel,
+                               int reverseChannel)
+    : SolenoidBase(moduleNumber),
+      m_forwardChannel(forwardChannel),
+      m_reverseChannel(reverseChannel) {
+  if (!SensorUtil::CheckSolenoidModule(m_moduleNumber)) {
+    wpi_setWPIErrorWithContext(ModuleIndexOutOfRange,
+                               "Solenoid Module " + wpi::Twine(m_moduleNumber));
+    return;
+  }
+  if (!SensorUtil::CheckSolenoidChannel(m_forwardChannel)) {
+    wpi_setWPIErrorWithContext(
+        ChannelIndexOutOfRange,
+        "Solenoid Channel " + wpi::Twine(m_forwardChannel));
+    return;
+  }
+  if (!SensorUtil::CheckSolenoidChannel(m_reverseChannel)) {
+    wpi_setWPIErrorWithContext(
+        ChannelIndexOutOfRange,
+        "Solenoid Channel " + wpi::Twine(m_reverseChannel));
+    return;
+  }
+  int32_t status = 0;
+  m_forwardHandle = HAL_InitializeSolenoidPort(
+      HAL_GetPortWithModule(moduleNumber, m_forwardChannel), &status);
+  if (status != 0) {
+    wpi_setErrorWithContextRange(status, 0, HAL_GetNumSolenoidChannels(),
+                                 forwardChannel, HAL_GetErrorMessage(status));
+    m_forwardHandle = HAL_kInvalidHandle;
+    m_reverseHandle = HAL_kInvalidHandle;
+    return;
+  }
+
+  m_reverseHandle = HAL_InitializeSolenoidPort(
+      HAL_GetPortWithModule(moduleNumber, m_reverseChannel), &status);
+  if (status != 0) {
+    wpi_setErrorWithContextRange(status, 0, HAL_GetNumSolenoidChannels(),
+                                 reverseChannel, HAL_GetErrorMessage(status));
+    // free forward solenoid
+    HAL_FreeSolenoidPort(m_forwardHandle);
+    m_forwardHandle = HAL_kInvalidHandle;
+    m_reverseHandle = HAL_kInvalidHandle;
+    return;
+  }
+
+  m_forwardMask = 1 << m_forwardChannel;
+  m_reverseMask = 1 << m_reverseChannel;
+
+  HAL_Report(HALUsageReporting::kResourceType_Solenoid, m_forwardChannel,
+             m_moduleNumber);
+  HAL_Report(HALUsageReporting::kResourceType_Solenoid, m_reverseChannel,
+             m_moduleNumber);
+  SetName("DoubleSolenoid", m_moduleNumber, m_forwardChannel);
+}
+
+DoubleSolenoid::~DoubleSolenoid() {
+  HAL_FreeSolenoidPort(m_forwardHandle);
+  HAL_FreeSolenoidPort(m_reverseHandle);
+}
+
+DoubleSolenoid::DoubleSolenoid(DoubleSolenoid&& rhs)
+    : SolenoidBase(std::move(rhs)),
+      m_forwardChannel(std::move(rhs.m_forwardChannel)),
+      m_reverseChannel(std::move(rhs.m_reverseChannel)),
+      m_forwardMask(std::move(rhs.m_forwardMask)),
+      m_reverseMask(std::move(rhs.m_reverseMask)) {
+  std::swap(m_forwardHandle, rhs.m_forwardHandle);
+  std::swap(m_reverseHandle, rhs.m_reverseHandle);
+}
+
+DoubleSolenoid& DoubleSolenoid::operator=(DoubleSolenoid&& rhs) {
+  SolenoidBase::operator=(std::move(rhs));
+
+  m_forwardChannel = std::move(rhs.m_forwardChannel);
+  m_reverseChannel = std::move(rhs.m_reverseChannel);
+  m_forwardMask = std::move(rhs.m_forwardMask);
+  m_reverseMask = std::move(rhs.m_reverseMask);
+  std::swap(m_forwardHandle, rhs.m_forwardHandle);
+  std::swap(m_reverseHandle, rhs.m_reverseHandle);
+
+  return *this;
+}
+
+void DoubleSolenoid::Set(Value value) {
+  if (StatusIsFatal()) return;
+
+  bool forward = false;
+  bool reverse = false;
+  switch (value) {
+    case kOff:
+      forward = false;
+      reverse = false;
+      break;
+    case kForward:
+      forward = true;
+      reverse = false;
+      break;
+    case kReverse:
+      forward = false;
+      reverse = true;
+      break;
+  }
+  int fstatus = 0;
+  HAL_SetSolenoid(m_forwardHandle, forward, &fstatus);
+  int rstatus = 0;
+  HAL_SetSolenoid(m_reverseHandle, reverse, &rstatus);
+
+  wpi_setErrorWithContext(fstatus, HAL_GetErrorMessage(fstatus));
+  wpi_setErrorWithContext(rstatus, HAL_GetErrorMessage(rstatus));
+}
+
+DoubleSolenoid::Value DoubleSolenoid::Get() const {
+  if (StatusIsFatal()) return kOff;
+  int fstatus = 0;
+  int rstatus = 0;
+  bool valueForward = HAL_GetSolenoid(m_forwardHandle, &fstatus);
+  bool valueReverse = HAL_GetSolenoid(m_reverseHandle, &rstatus);
+
+  wpi_setErrorWithContext(fstatus, HAL_GetErrorMessage(fstatus));
+  wpi_setErrorWithContext(rstatus, HAL_GetErrorMessage(rstatus));
+
+  if (valueForward) return kForward;
+  if (valueReverse) return kReverse;
+  return kOff;
+}
+
+bool DoubleSolenoid::IsFwdSolenoidBlackListed() const {
+  int blackList = GetPCMSolenoidBlackList(m_moduleNumber);
+  return (blackList & m_forwardMask) != 0;
+}
+
+bool DoubleSolenoid::IsRevSolenoidBlackListed() const {
+  int blackList = GetPCMSolenoidBlackList(m_moduleNumber);
+  return (blackList & m_reverseMask) != 0;
+}
+
+void DoubleSolenoid::InitSendable(SendableBuilder& builder) {
+  builder.SetSmartDashboardType("Double Solenoid");
+  builder.SetActuator(true);
+  builder.SetSafeState([=]() { Set(kOff); });
+  builder.AddSmallStringProperty(
+      "Value",
+      [=](wpi::SmallVectorImpl<char>& buf) -> wpi::StringRef {
+        switch (Get()) {
+          case kForward:
+            return "Forward";
+          case kReverse:
+            return "Reverse";
+          default:
+            return "Off";
+        }
+      },
+      [=](wpi::StringRef value) {
+        Value lvalue = kOff;
+        if (value == "Forward")
+          lvalue = kForward;
+        else if (value == "Reverse")
+          lvalue = kReverse;
+        Set(lvalue);
+      });
+}