Files
allwpilib/wpilibc/src/main/native/include/frc/smartdashboard/SendableBuilderImpl.h
Peter Johnson 6666d3be42 SendableBuilder: Allow multiple updateTable functions
This fixes cases like CommandScheduler not working when added to both
LiveWindow and SmartDashboard.
2020-01-10 23:42:18 -08:00

212 lines
6.6 KiB
C++

/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017-2020 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 <functional>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include <networktables/NetworkTable.h>
#include <networktables/NetworkTableEntry.h>
#include <networktables/NetworkTableValue.h>
#include <wpi/ArrayRef.h>
#include <wpi/SmallVector.h>
#include <wpi/Twine.h>
#include "frc/smartdashboard/SendableBuilder.h"
namespace frc {
class SendableBuilderImpl : public SendableBuilder {
public:
SendableBuilderImpl() = default;
~SendableBuilderImpl() override = default;
SendableBuilderImpl(SendableBuilderImpl&&) = default;
SendableBuilderImpl& operator=(SendableBuilderImpl&&) = default;
/**
* Set the network table. Must be called prior to any Add* functions being
* called.
* @param table Network table
*/
void SetTable(std::shared_ptr<nt::NetworkTable> table);
/**
* Get the network table.
* @return The network table
*/
std::shared_ptr<nt::NetworkTable> GetTable();
/**
* Return whether this sendable has an associated table.
* @return True if it has a table, false if not.
*/
bool HasTable() const;
/**
* Return whether this sendable should be treated as an actuator.
* @return True if actuator, false if not.
*/
bool IsActuator() const;
/**
* Update the network table values by calling the getters for all properties.
*/
void UpdateTable();
/**
* Hook setters for all properties.
*/
void StartListeners();
/**
* Unhook setters for all properties.
*/
void StopListeners();
/**
* Start LiveWindow mode by hooking the setters for all properties. Also
* calls the SafeState function if one was provided.
*/
void StartLiveWindowMode();
/**
* Stop LiveWindow mode by unhooking the setters for all properties. Also
* calls the SafeState function if one was provided.
*/
void StopLiveWindowMode();
/**
* Clear properties.
*/
void ClearProperties();
void SetSmartDashboardType(const wpi::Twine& type) override;
void SetActuator(bool value) override;
void SetSafeState(std::function<void()> func) override;
void SetUpdateTable(std::function<void()> func) override;
nt::NetworkTableEntry GetEntry(const wpi::Twine& key) override;
void AddBooleanProperty(const wpi::Twine& key, std::function<bool()> getter,
std::function<void(bool)> setter) override;
void AddDoubleProperty(const wpi::Twine& key, std::function<double()> getter,
std::function<void(double)> setter) override;
void AddStringProperty(const wpi::Twine& key,
std::function<std::string()> getter,
std::function<void(wpi::StringRef)> setter) override;
void AddBooleanArrayProperty(
const wpi::Twine& key, std::function<std::vector<int>()> getter,
std::function<void(wpi::ArrayRef<int>)> setter) override;
void AddDoubleArrayProperty(
const wpi::Twine& key, std::function<std::vector<double>()> getter,
std::function<void(wpi::ArrayRef<double>)> setter) override;
void AddStringArrayProperty(
const wpi::Twine& key, std::function<std::vector<std::string>()> getter,
std::function<void(wpi::ArrayRef<std::string>)> setter) override;
void AddRawProperty(const wpi::Twine& key,
std::function<std::string()> getter,
std::function<void(wpi::StringRef)> setter) override;
void AddValueProperty(
const wpi::Twine& key, std::function<std::shared_ptr<nt::Value>()> getter,
std::function<void(std::shared_ptr<nt::Value>)> setter) override;
void AddSmallStringProperty(
const wpi::Twine& key,
std::function<wpi::StringRef(wpi::SmallVectorImpl<char>& buf)> getter,
std::function<void(wpi::StringRef)> setter) override;
void AddSmallBooleanArrayProperty(
const wpi::Twine& key,
std::function<wpi::ArrayRef<int>(wpi::SmallVectorImpl<int>& buf)> getter,
std::function<void(wpi::ArrayRef<int>)> setter) override;
void AddSmallDoubleArrayProperty(
const wpi::Twine& key,
std::function<wpi::ArrayRef<double>(wpi::SmallVectorImpl<double>& buf)>
getter,
std::function<void(wpi::ArrayRef<double>)> setter) override;
void AddSmallStringArrayProperty(
const wpi::Twine& key,
std::function<
wpi::ArrayRef<std::string>(wpi::SmallVectorImpl<std::string>& buf)>
getter,
std::function<void(wpi::ArrayRef<std::string>)> setter) override;
void AddSmallRawProperty(
const wpi::Twine& key,
std::function<wpi::StringRef(wpi::SmallVectorImpl<char>& buf)> getter,
std::function<void(wpi::StringRef)> setter) override;
private:
struct Property {
Property(nt::NetworkTable& table, const wpi::Twine& key)
: entry(table.GetEntry(key)) {}
Property(const Property&) = delete;
Property& operator=(const Property&) = delete;
Property(Property&& other) noexcept
: entry(other.entry),
listener(other.listener),
update(std::move(other.update)),
createListener(std::move(other.createListener)) {
other.entry = nt::NetworkTableEntry();
other.listener = 0;
}
Property& operator=(Property&& other) noexcept {
entry = other.entry;
listener = other.listener;
other.entry = nt::NetworkTableEntry();
other.listener = 0;
update = std::move(other.update);
createListener = std::move(other.createListener);
return *this;
}
~Property() { StopListener(); }
void StartListener() {
if (entry && listener == 0 && createListener)
listener = createListener(entry);
}
void StopListener() {
if (entry && listener != 0) {
entry.RemoveListener(listener);
listener = 0;
}
}
nt::NetworkTableEntry entry;
NT_EntryListener listener = 0;
std::function<void(nt::NetworkTableEntry entry, uint64_t time)> update;
std::function<NT_EntryListener(nt::NetworkTableEntry entry)> createListener;
};
std::vector<Property> m_properties;
std::function<void()> m_safeState;
std::vector<std::function<void()>> m_updateTables;
std::shared_ptr<nt::NetworkTable> m_table;
nt::NetworkTableEntry m_controllableEntry;
bool m_actuator = false;
};
} // namespace frc