// 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/smartdashboard/SmartDashboard.h" #include #include #include #include #include #include "frc/Errors.h" #include "frc/smartdashboard/SendableRegistry.h" using namespace frc; namespace { class Singleton { public: static Singleton& GetInstance(); std::shared_ptr table; wpi::StringMap tablesToData; wpi::mutex tablesToDataMutex; private: Singleton() { table = nt::NetworkTableInstance::GetDefault().GetTable("SmartDashboard"); HAL_Report(HALUsageReporting::kResourceType_SmartDashboard, 0); } Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete; }; } // namespace Singleton& Singleton::GetInstance() { static Singleton instance; return instance; } void SmartDashboard::init() { Singleton::GetInstance(); } bool SmartDashboard::ContainsKey(wpi::StringRef key) { return Singleton::GetInstance().table->ContainsKey(key); } std::vector SmartDashboard::GetKeys(int types) { return Singleton::GetInstance().table->GetKeys(types); } void SmartDashboard::SetPersistent(wpi::StringRef key) { Singleton::GetInstance().table->GetEntry(key).SetPersistent(); } void SmartDashboard::ClearPersistent(wpi::StringRef key) { Singleton::GetInstance().table->GetEntry(key).ClearPersistent(); } bool SmartDashboard::IsPersistent(wpi::StringRef key) { return Singleton::GetInstance().table->GetEntry(key).IsPersistent(); } void SmartDashboard::SetFlags(wpi::StringRef key, unsigned int flags) { Singleton::GetInstance().table->GetEntry(key).SetFlags(flags); } void SmartDashboard::ClearFlags(wpi::StringRef key, unsigned int flags) { Singleton::GetInstance().table->GetEntry(key).ClearFlags(flags); } unsigned int SmartDashboard::GetFlags(wpi::StringRef key) { return Singleton::GetInstance().table->GetEntry(key).GetFlags(); } void SmartDashboard::Delete(wpi::StringRef key) { Singleton::GetInstance().table->Delete(key); } nt::NetworkTableEntry SmartDashboard::GetEntry(wpi::StringRef key) { return Singleton::GetInstance().table->GetEntry(key); } void SmartDashboard::PutData(wpi::StringRef key, Sendable* data) { if (!data) { throw FRC_MakeError(err::NullParameter, "value"); } auto& inst = Singleton::GetInstance(); std::scoped_lock lock(inst.tablesToDataMutex); auto& uid = inst.tablesToData[key]; auto& registry = SendableRegistry::GetInstance(); Sendable* sddata = registry.GetSendable(uid); if (sddata != data) { uid = registry.GetUniqueId(data); auto dataTable = inst.table->GetSubTable(key); registry.Publish(uid, dataTable); dataTable->GetEntry(".name").SetString(key); } } void SmartDashboard::PutData(Sendable* value) { if (!value) { throw FRC_MakeError(err::NullParameter, "value"); } auto name = SendableRegistry::GetInstance().GetName(value); if (!name.empty()) { PutData(name, value); } } Sendable* SmartDashboard::GetData(wpi::StringRef key) { auto& inst = Singleton::GetInstance(); std::scoped_lock lock(inst.tablesToDataMutex); auto it = inst.tablesToData.find(key); if (it == inst.tablesToData.end()) { throw FRC_MakeError(err::SmartDashboardMissingKey, key); } return SendableRegistry::GetInstance().GetSendable(it->getValue()); } bool SmartDashboard::PutBoolean(wpi::StringRef keyName, bool value) { return Singleton::GetInstance().table->GetEntry(keyName).SetBoolean(value); } bool SmartDashboard::SetDefaultBoolean(wpi::StringRef key, bool defaultValue) { return Singleton::GetInstance().table->GetEntry(key).SetDefaultBoolean( defaultValue); } bool SmartDashboard::GetBoolean(wpi::StringRef keyName, bool defaultValue) { return Singleton::GetInstance().table->GetEntry(keyName).GetBoolean( defaultValue); } bool SmartDashboard::PutNumber(wpi::StringRef keyName, double value) { return Singleton::GetInstance().table->GetEntry(keyName).SetDouble(value); } bool SmartDashboard::SetDefaultNumber(wpi::StringRef key, double defaultValue) { return Singleton::GetInstance().table->GetEntry(key).SetDefaultDouble( defaultValue); } double SmartDashboard::GetNumber(wpi::StringRef keyName, double defaultValue) { return Singleton::GetInstance().table->GetEntry(keyName).GetDouble( defaultValue); } bool SmartDashboard::PutString(wpi::StringRef keyName, wpi::StringRef value) { return Singleton::GetInstance().table->GetEntry(keyName).SetString(value); } bool SmartDashboard::SetDefaultString(wpi::StringRef key, wpi::StringRef defaultValue) { return Singleton::GetInstance().table->GetEntry(key).SetDefaultString( defaultValue); } std::string SmartDashboard::GetString(wpi::StringRef keyName, wpi::StringRef defaultValue) { return Singleton::GetInstance().table->GetEntry(keyName).GetString( defaultValue); } bool SmartDashboard::PutBooleanArray(wpi::StringRef key, wpi::ArrayRef value) { return Singleton::GetInstance().table->GetEntry(key).SetBooleanArray(value); } bool SmartDashboard::SetDefaultBooleanArray(wpi::StringRef key, wpi::ArrayRef defaultValue) { return Singleton::GetInstance().table->GetEntry(key).SetDefaultBooleanArray( defaultValue); } std::vector SmartDashboard::GetBooleanArray( wpi::StringRef key, wpi::ArrayRef defaultValue) { return Singleton::GetInstance().table->GetEntry(key).GetBooleanArray( defaultValue); } bool SmartDashboard::PutNumberArray(wpi::StringRef key, wpi::ArrayRef value) { return Singleton::GetInstance().table->GetEntry(key).SetDoubleArray(value); } bool SmartDashboard::SetDefaultNumberArray(wpi::StringRef key, wpi::ArrayRef defaultValue) { return Singleton::GetInstance().table->GetEntry(key).SetDefaultDoubleArray( defaultValue); } std::vector SmartDashboard::GetNumberArray( wpi::StringRef key, wpi::ArrayRef defaultValue) { return Singleton::GetInstance().table->GetEntry(key).GetDoubleArray( defaultValue); } bool SmartDashboard::PutStringArray(wpi::StringRef key, wpi::ArrayRef value) { return Singleton::GetInstance().table->GetEntry(key).SetStringArray(value); } bool SmartDashboard::SetDefaultStringArray( wpi::StringRef key, wpi::ArrayRef defaultValue) { return Singleton::GetInstance().table->GetEntry(key).SetDefaultStringArray( defaultValue); } std::vector SmartDashboard::GetStringArray( wpi::StringRef key, wpi::ArrayRef defaultValue) { return Singleton::GetInstance().table->GetEntry(key).GetStringArray( defaultValue); } bool SmartDashboard::PutRaw(wpi::StringRef key, wpi::StringRef value) { return Singleton::GetInstance().table->GetEntry(key).SetRaw(value); } bool SmartDashboard::SetDefaultRaw(wpi::StringRef key, wpi::StringRef defaultValue) { return Singleton::GetInstance().table->GetEntry(key).SetDefaultRaw( defaultValue); } std::string SmartDashboard::GetRaw(wpi::StringRef key, wpi::StringRef defaultValue) { return Singleton::GetInstance().table->GetEntry(key).GetRaw(defaultValue); } bool SmartDashboard::PutValue(wpi::StringRef keyName, std::shared_ptr value) { return Singleton::GetInstance().table->GetEntry(keyName).SetValue(value); } bool SmartDashboard::SetDefaultValue(wpi::StringRef key, std::shared_ptr defaultValue) { return Singleton::GetInstance().table->GetEntry(key).SetDefaultValue( defaultValue); } std::shared_ptr SmartDashboard::GetValue(wpi::StringRef keyName) { return Singleton::GetInstance().table->GetEntry(keyName).GetValue(); } detail::ListenerExecutor SmartDashboard::listenerExecutor; void SmartDashboard::PostListenerTask(std::function task) { listenerExecutor.Execute(task); } void SmartDashboard::UpdateValues() { auto& registry = SendableRegistry::GetInstance(); auto& inst = Singleton::GetInstance(); listenerExecutor.RunListenerTasks(); std::scoped_lock lock(inst.tablesToDataMutex); for (auto& i : inst.tablesToData) { registry.Update(i.getValue()); } }