// Copyright (c) FIRST and other WPILib contributors. // Open Source Software; you can modify and/or share it under the terms of // the WPILib BSD license file in the root directory of this project. #include "frc/shuffleboard/ShuffleboardContainer.h" #include #include "frc/Errors.h" #include "frc/shuffleboard/ComplexWidget.h" #include "frc/shuffleboard/ShuffleboardComponent.h" #include "frc/shuffleboard/ShuffleboardLayout.h" #include "frc/shuffleboard/SimpleWidget.h" #include "frc/smartdashboard/SendableRegistry.h" using namespace frc; static constexpr const char* layoutStrings[] = {"List Layout", "Grid Layout"}; static constexpr const char* GetStringFromBuiltInLayout(BuiltInLayouts layout) { return layoutStrings[static_cast(layout)]; } ShuffleboardContainer::ShuffleboardContainer(std::string_view title) : ShuffleboardValue(title) {} const std::vector>& ShuffleboardContainer::GetComponents() const { return m_components; } ShuffleboardLayout& ShuffleboardContainer::GetLayout(std::string_view title, BuiltInLayouts type) { return GetLayout(title, GetStringFromBuiltInLayout(type)); } ShuffleboardLayout& ShuffleboardContainer::GetLayout(std::string_view title, const LayoutType& type) { return GetLayout(title, type.GetLayoutName()); } ShuffleboardLayout& ShuffleboardContainer::GetLayout(std::string_view title, std::string_view type) { if (m_layouts.count(title) == 0) { auto layout = std::make_unique(*this, title, type); auto ptr = layout.get(); m_components.emplace_back(std::move(layout)); m_layouts.insert(std::make_pair(title, ptr)); } return *m_layouts[title]; } ShuffleboardLayout& ShuffleboardContainer::GetLayout(std::string_view title) { if (m_layouts.count(title) == 0) { throw FRC_MakeError(err::InvalidParameter, "No layout with title {} has been defined", title); } return *m_layouts[title]; } ComplexWidget& ShuffleboardContainer::Add(std::string_view title, Sendable& sendable) { CheckTitle(title); auto widget = std::make_unique(*this, title, sendable); auto ptr = widget.get(); m_components.emplace_back(std::move(widget)); return *ptr; } ComplexWidget& ShuffleboardContainer::Add(Sendable& sendable) { auto name = SendableRegistry::GetInstance().GetName(&sendable); if (name.empty()) { wpi::outs() << "Sendable must have a name\n"; } return Add(name, sendable); } SimpleWidget& ShuffleboardContainer::Add( std::string_view title, std::shared_ptr defaultValue) { CheckTitle(title); auto widget = std::make_unique(*this, title); auto ptr = widget.get(); m_components.emplace_back(std::move(widget)); ptr->GetEntry().SetDefaultValue(defaultValue); return *ptr; } SimpleWidget& ShuffleboardContainer::Add(std::string_view title, bool defaultValue) { return Add(title, nt::Value::MakeBoolean(defaultValue)); } SimpleWidget& ShuffleboardContainer::Add(std::string_view title, double defaultValue) { return Add(title, nt::Value::MakeDouble(defaultValue)); } SimpleWidget& ShuffleboardContainer::Add(std::string_view title, int defaultValue) { return Add(title, nt::Value::MakeDouble(defaultValue)); } SimpleWidget& ShuffleboardContainer::Add(std::string_view title, std::string_view defaultValue) { return Add(title, nt::Value::MakeString(defaultValue)); } SimpleWidget& ShuffleboardContainer::Add(std::string_view title, const char* defaultValue) { return Add(title, nt::Value::MakeString(defaultValue)); } SimpleWidget& ShuffleboardContainer::Add(std::string_view title, wpi::ArrayRef defaultValue) { return Add(title, nt::Value::MakeBooleanArray(defaultValue)); } SimpleWidget& ShuffleboardContainer::Add(std::string_view title, wpi::ArrayRef defaultValue) { return Add(title, nt::Value::MakeDoubleArray(defaultValue)); } SimpleWidget& ShuffleboardContainer::Add( std::string_view title, wpi::ArrayRef defaultValue) { return Add(title, nt::Value::MakeStringArray(defaultValue)); } SuppliedValueWidget& ShuffleboardContainer::AddString( std::string_view title, std::function supplier) { static auto setter = [](nt::NetworkTableEntry entry, std::string value) { entry.SetString(value); }; CheckTitle(title); auto widget = std::make_unique>( *this, title, supplier, setter); auto ptr = widget.get(); m_components.emplace_back(std::move(widget)); return *ptr; } SuppliedValueWidget& ShuffleboardContainer::AddNumber( std::string_view title, std::function supplier) { static auto setter = [](nt::NetworkTableEntry entry, double value) { entry.SetDouble(value); }; CheckTitle(title); auto widget = std::make_unique>(*this, title, supplier, setter); auto ptr = widget.get(); m_components.emplace_back(std::move(widget)); return *ptr; } SuppliedValueWidget& ShuffleboardContainer::AddBoolean( std::string_view title, std::function supplier) { static auto setter = [](nt::NetworkTableEntry entry, bool value) { entry.SetBoolean(value); }; CheckTitle(title); auto widget = std::make_unique>(*this, title, supplier, setter); auto ptr = widget.get(); m_components.emplace_back(std::move(widget)); return *ptr; } SuppliedValueWidget>& ShuffleboardContainer::AddStringArray( std::string_view title, std::function()> supplier) { static auto setter = [](nt::NetworkTableEntry entry, std::vector value) { entry.SetStringArray(value); }; CheckTitle(title); auto widget = std::make_unique>>( *this, title, supplier, setter); auto ptr = widget.get(); m_components.emplace_back(std::move(widget)); return *ptr; } SuppliedValueWidget>& ShuffleboardContainer::AddNumberArray( std::string_view title, std::function()> supplier) { static auto setter = [](nt::NetworkTableEntry entry, std::vector value) { entry.SetDoubleArray(value); }; CheckTitle(title); auto widget = std::make_unique>>( *this, title, supplier, setter); auto ptr = widget.get(); m_components.emplace_back(std::move(widget)); return *ptr; } SuppliedValueWidget>& ShuffleboardContainer::AddBooleanArray( std::string_view title, std::function()> supplier) { static auto setter = [](nt::NetworkTableEntry entry, std::vector value) { entry.SetBooleanArray(value); }; CheckTitle(title); auto widget = std::make_unique>>( *this, title, supplier, setter); auto ptr = widget.get(); m_components.emplace_back(std::move(widget)); return *ptr; } SuppliedValueWidget& ShuffleboardContainer::AddRaw( std::string_view title, std::function supplier) { static auto setter = [](nt::NetworkTableEntry entry, std::string_view value) { entry.SetRaw(value); }; CheckTitle(title); auto widget = std::make_unique>( *this, title, supplier, setter); auto ptr = widget.get(); m_components.emplace_back(std::move(widget)); return *ptr; } SimpleWidget& ShuffleboardContainer::AddPersistent( std::string_view title, std::shared_ptr defaultValue) { auto& widget = Add(title, defaultValue); widget.GetEntry().SetPersistent(); return widget; } SimpleWidget& ShuffleboardContainer::AddPersistent(std::string_view title, bool defaultValue) { return AddPersistent(title, nt::Value::MakeBoolean(defaultValue)); } SimpleWidget& ShuffleboardContainer::AddPersistent(std::string_view title, double defaultValue) { return AddPersistent(title, nt::Value::MakeDouble(defaultValue)); } SimpleWidget& ShuffleboardContainer::AddPersistent(std::string_view title, int defaultValue) { return AddPersistent(title, nt::Value::MakeDouble(defaultValue)); } SimpleWidget& ShuffleboardContainer::AddPersistent( std::string_view title, std::string_view defaultValue) { return AddPersistent(title, nt::Value::MakeString(defaultValue)); } SimpleWidget& ShuffleboardContainer::AddPersistent( std::string_view title, wpi::ArrayRef defaultValue) { return AddPersistent(title, nt::Value::MakeBooleanArray(defaultValue)); } SimpleWidget& ShuffleboardContainer::AddPersistent( std::string_view title, wpi::ArrayRef defaultValue) { return AddPersistent(title, nt::Value::MakeDoubleArray(defaultValue)); } SimpleWidget& ShuffleboardContainer::AddPersistent( std::string_view title, wpi::ArrayRef defaultValue) { return AddPersistent(title, nt::Value::MakeStringArray(defaultValue)); } void ShuffleboardContainer::EnableIfActuator() { for (auto& component : GetComponents()) { component->EnableIfActuator(); } } void ShuffleboardContainer::DisableIfActuator() { for (auto& component : GetComponents()) { component->DisableIfActuator(); } } void ShuffleboardContainer::CheckTitle(std::string_view title) { std::string titleStr{title}; if (m_usedTitles.count(titleStr) > 0) { wpi::errs() << "Title is already in use: " << title << "\n"; return; } m_usedTitles.insert(titleStr); }