mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-29 02:21:44 +00:00
[wpilib] Remove LiveWindow (#7733)
This will be replaced by a different mechanism, but removing it eases the initial implementation burden of a new Telemetry/Sendable framework.
This commit is contained in:
@@ -42,14 +42,6 @@ public interface SendableBuilder extends AutoCloseable {
|
||||
*/
|
||||
void setActuator(boolean value);
|
||||
|
||||
/**
|
||||
* Set the function that should be called to set the Sendable into a safe state. This is called
|
||||
* when entering and exiting Live Window mode.
|
||||
*
|
||||
* @param func function
|
||||
*/
|
||||
void setSafeState(Runnable func);
|
||||
|
||||
/**
|
||||
* Add a boolean property.
|
||||
*
|
||||
|
||||
@@ -5,17 +5,13 @@
|
||||
package edu.wpi.first.util.sendable;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* The SendableRegistry class is the public interface for registering sensors and actuators for use
|
||||
* on dashboards and LiveWindow.
|
||||
* on dashboards.
|
||||
*/
|
||||
@SuppressWarnings("PMD.AvoidCatchingGenericException")
|
||||
public final class SendableRegistry {
|
||||
@@ -40,8 +36,6 @@ public final class SendableRegistry {
|
||||
SendableBuilder m_builder;
|
||||
String m_name;
|
||||
String m_subsystem = "Ungrouped";
|
||||
WeakReference<Sendable> m_parent;
|
||||
boolean m_liveWindow;
|
||||
AutoCloseable[] m_data;
|
||||
|
||||
void setName(String moduleType, int channel) {
|
||||
@@ -53,7 +47,6 @@ public final class SendableRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
private static Supplier<SendableBuilder> liveWindowFactory;
|
||||
private static final Map<Object, Component> components = new WeakHashMap<>();
|
||||
private static int nextDataHandle;
|
||||
|
||||
@@ -74,15 +67,6 @@ public final class SendableRegistry {
|
||||
throw new UnsupportedOperationException("This is a utility class!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the factory for LiveWindow builders.
|
||||
*
|
||||
* @param factory factory function
|
||||
*/
|
||||
public static synchronized void setLiveWindowBuilderFactory(Supplier<SendableBuilder> factory) {
|
||||
liveWindowFactory = factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an object to the registry.
|
||||
*
|
||||
@@ -133,100 +117,6 @@ public final class SendableRegistry {
|
||||
comp.m_subsystem = subsystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an object to the registry and LiveWindow.
|
||||
*
|
||||
* @param sendable object to add
|
||||
* @param name component name
|
||||
*/
|
||||
public static synchronized void addLW(Sendable sendable, String name) {
|
||||
Component comp = getOrAdd(sendable);
|
||||
if (liveWindowFactory != null) {
|
||||
if (comp.m_builder != null) {
|
||||
try {
|
||||
comp.m_builder.close();
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
comp.m_builder = liveWindowFactory.get();
|
||||
}
|
||||
comp.m_liveWindow = true;
|
||||
comp.m_name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an object to the registry and LiveWindow.
|
||||
*
|
||||
* @param sendable object to add
|
||||
* @param moduleType A string that defines the module name in the label for the value
|
||||
* @param channel The channel number the device is plugged into
|
||||
*/
|
||||
public static synchronized void addLW(Sendable sendable, String moduleType, int channel) {
|
||||
Component comp = getOrAdd(sendable);
|
||||
if (liveWindowFactory != null) {
|
||||
if (comp.m_builder != null) {
|
||||
try {
|
||||
comp.m_builder.close();
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
comp.m_builder = liveWindowFactory.get();
|
||||
}
|
||||
comp.m_liveWindow = true;
|
||||
comp.setName(moduleType, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an object to the registry and LiveWindow.
|
||||
*
|
||||
* @param sendable object to add
|
||||
* @param moduleType A string that defines the module name in the label for the value
|
||||
* @param moduleNumber The number of the particular module type
|
||||
* @param channel The channel number the device is plugged into
|
||||
*/
|
||||
public static synchronized void addLW(
|
||||
Sendable sendable, String moduleType, int moduleNumber, int channel) {
|
||||
Component comp = getOrAdd(sendable);
|
||||
if (liveWindowFactory != null) {
|
||||
if (comp.m_builder != null) {
|
||||
try {
|
||||
comp.m_builder.close();
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
comp.m_builder = liveWindowFactory.get();
|
||||
}
|
||||
comp.m_liveWindow = true;
|
||||
comp.setName(moduleType, moduleNumber, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an object to the registry and LiveWindow.
|
||||
*
|
||||
* @param sendable object to add
|
||||
* @param subsystem subsystem name
|
||||
* @param name component name
|
||||
*/
|
||||
public static synchronized void addLW(Sendable sendable, String subsystem, String name) {
|
||||
Component comp = getOrAdd(sendable);
|
||||
if (liveWindowFactory != null) {
|
||||
if (comp.m_builder != null) {
|
||||
try {
|
||||
comp.m_builder.close();
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
comp.m_builder = liveWindowFactory.get();
|
||||
}
|
||||
comp.m_liveWindow = true;
|
||||
comp.m_name = name;
|
||||
comp.m_subsystem = subsystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a child object to an object. Adds the child object to the registry if it's not already
|
||||
* present.
|
||||
@@ -240,7 +130,7 @@ public final class SendableRegistry {
|
||||
comp = new Component();
|
||||
components.put(child, comp);
|
||||
}
|
||||
comp.m_parent = new WeakReference<>(parent);
|
||||
// comp.m_parent = new WeakReference<>(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -430,30 +320,6 @@ public final class SendableRegistry {
|
||||
return comp.m_data[handle];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables LiveWindow for an object.
|
||||
*
|
||||
* @param sendable object
|
||||
*/
|
||||
public static synchronized void enableLiveWindow(Sendable sendable) {
|
||||
Component comp = components.get(sendable);
|
||||
if (comp != null) {
|
||||
comp.m_liveWindow = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables LiveWindow for an object.
|
||||
*
|
||||
* @param sendable object
|
||||
*/
|
||||
public static synchronized void disableLiveWindow(Sendable sendable) {
|
||||
Component comp = components.get(sendable);
|
||||
if (comp != null) {
|
||||
comp.m_liveWindow = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes an object in the registry to a builder.
|
||||
*
|
||||
@@ -485,98 +351,4 @@ public final class SendableRegistry {
|
||||
comp.m_builder.update();
|
||||
}
|
||||
}
|
||||
|
||||
/** Data passed to foreachLiveWindow() callback function. */
|
||||
@SuppressWarnings("MemberName")
|
||||
public static class CallbackData {
|
||||
/** Sendable object. */
|
||||
public Sendable sendable;
|
||||
|
||||
/** Name. */
|
||||
public String name;
|
||||
|
||||
/** Subsystem. */
|
||||
public String subsystem;
|
||||
|
||||
/** Parent sendable object. */
|
||||
public Sendable parent;
|
||||
|
||||
/** Data stored in object with setData(). Update this to change the data. */
|
||||
public AutoCloseable data;
|
||||
|
||||
/** Sendable builder for the sendable. */
|
||||
public SendableBuilder builder;
|
||||
|
||||
/** Default constructor. */
|
||||
public CallbackData() {}
|
||||
}
|
||||
|
||||
// As foreachLiveWindow is single threaded, cache the components it
|
||||
// iterates over to avoid risk of ConcurrentModificationException
|
||||
private static List<Component> foreachComponents = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Iterates over LiveWindow-enabled objects in the registry. It is *not* safe to call other
|
||||
* SendableRegistry functions from the callback.
|
||||
*
|
||||
* @param dataHandle data handle to get data object passed to callback
|
||||
* @param callback function to call for each object
|
||||
*/
|
||||
@SuppressWarnings("PMD.CompareObjectsWithEquals")
|
||||
public static synchronized void foreachLiveWindow(
|
||||
int dataHandle, Consumer<CallbackData> callback) {
|
||||
CallbackData cbdata = new CallbackData();
|
||||
foreachComponents.clear();
|
||||
foreachComponents.addAll(components.values());
|
||||
for (Component comp : foreachComponents) {
|
||||
if (comp.m_builder == null || comp.m_sendable == null) {
|
||||
continue;
|
||||
}
|
||||
cbdata.sendable = comp.m_sendable.get();
|
||||
if (cbdata.sendable != null && comp.m_liveWindow) {
|
||||
cbdata.name = comp.m_name;
|
||||
cbdata.subsystem = comp.m_subsystem;
|
||||
if (comp.m_parent != null) {
|
||||
cbdata.parent = comp.m_parent.get();
|
||||
} else {
|
||||
cbdata.parent = null;
|
||||
}
|
||||
if (comp.m_data != null && dataHandle < comp.m_data.length) {
|
||||
cbdata.data = comp.m_data[dataHandle];
|
||||
} else {
|
||||
cbdata.data = null;
|
||||
}
|
||||
cbdata.builder = comp.m_builder;
|
||||
try {
|
||||
callback.accept(cbdata);
|
||||
} catch (Throwable throwable) {
|
||||
Throwable cause = throwable.getCause();
|
||||
if (cause != null) {
|
||||
throwable = cause;
|
||||
}
|
||||
System.err.println("Unhandled exception calling LiveWindow for " + comp.m_name + ": ");
|
||||
throwable.printStackTrace();
|
||||
comp.m_liveWindow = false;
|
||||
}
|
||||
if (cbdata.data != null) {
|
||||
if (comp.m_data == null) {
|
||||
comp.m_data = new AutoCloseable[dataHandle + 1];
|
||||
} else if (dataHandle >= comp.m_data.length) {
|
||||
comp.m_data = Arrays.copyOf(comp.m_data, dataHandle + 1);
|
||||
}
|
||||
if (comp.m_data[dataHandle] != cbdata.data) {
|
||||
if (comp.m_data[dataHandle] != null) {
|
||||
try {
|
||||
comp.m_data[dataHandle].close();
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
comp.m_data[dataHandle] = cbdata.data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreachComponents.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ struct Component {
|
||||
std::string name;
|
||||
std::string subsystem = "Ungrouped";
|
||||
Sendable* parent = nullptr;
|
||||
bool liveWindow = false;
|
||||
wpi::SmallVector<std::shared_ptr<void>, 2> data;
|
||||
|
||||
void SetName(std::string_view moduleType, int channel) {
|
||||
@@ -41,7 +40,6 @@ struct Component {
|
||||
struct SendableRegistryInst {
|
||||
wpi::recursive_mutex mutex;
|
||||
|
||||
std::function<std::unique_ptr<SendableBuilder>()> liveWindowFactory;
|
||||
wpi::UidVector<std::unique_ptr<Component>, 32> components;
|
||||
wpi::DenseMap<void*, SendableRegistry::UID> componentMap;
|
||||
int nextDataHandle = 0;
|
||||
@@ -85,11 +83,6 @@ void SendableRegistry::EnsureInitialized() {
|
||||
GetInstance();
|
||||
}
|
||||
|
||||
void SendableRegistry::SetLiveWindowBuilderFactory(
|
||||
std::function<std::unique_ptr<SendableBuilder>()> factory) {
|
||||
GetInstance().liveWindowFactory = std::move(factory);
|
||||
}
|
||||
|
||||
void SendableRegistry::Add(Sendable* sendable, std::string_view name) {
|
||||
auto& inst = GetInstance();
|
||||
std::scoped_lock lock(inst.mutex);
|
||||
@@ -126,58 +119,6 @@ void SendableRegistry::Add(Sendable* sendable, std::string_view subsystem,
|
||||
comp.subsystem = subsystem;
|
||||
}
|
||||
|
||||
void SendableRegistry::AddLW(Sendable* sendable, std::string_view name) {
|
||||
auto& inst = GetInstance();
|
||||
std::scoped_lock lock(inst.mutex);
|
||||
auto& comp = inst.GetOrAdd(sendable);
|
||||
comp.sendable = sendable;
|
||||
if (inst.liveWindowFactory) {
|
||||
comp.builder = inst.liveWindowFactory();
|
||||
}
|
||||
comp.liveWindow = true;
|
||||
comp.name = name;
|
||||
}
|
||||
|
||||
void SendableRegistry::AddLW(Sendable* sendable, std::string_view moduleType,
|
||||
int channel) {
|
||||
auto& inst = GetInstance();
|
||||
std::scoped_lock lock(inst.mutex);
|
||||
auto& comp = inst.GetOrAdd(sendable);
|
||||
comp.sendable = sendable;
|
||||
if (inst.liveWindowFactory) {
|
||||
comp.builder = inst.liveWindowFactory();
|
||||
}
|
||||
comp.liveWindow = true;
|
||||
comp.SetName(moduleType, channel);
|
||||
}
|
||||
|
||||
void SendableRegistry::AddLW(Sendable* sendable, std::string_view moduleType,
|
||||
int moduleNumber, int channel) {
|
||||
auto& inst = GetInstance();
|
||||
std::scoped_lock lock(inst.mutex);
|
||||
auto& comp = inst.GetOrAdd(sendable);
|
||||
comp.sendable = sendable;
|
||||
if (inst.liveWindowFactory) {
|
||||
comp.builder = inst.liveWindowFactory();
|
||||
}
|
||||
comp.liveWindow = true;
|
||||
comp.SetName(moduleType, moduleNumber, channel);
|
||||
}
|
||||
|
||||
void SendableRegistry::AddLW(Sendable* sendable, std::string_view subsystem,
|
||||
std::string_view name) {
|
||||
auto& inst = GetInstance();
|
||||
std::scoped_lock lock(inst.mutex);
|
||||
auto& comp = inst.GetOrAdd(sendable);
|
||||
comp.sendable = sendable;
|
||||
if (inst.liveWindowFactory) {
|
||||
comp.builder = inst.liveWindowFactory();
|
||||
}
|
||||
comp.liveWindow = true;
|
||||
comp.name = name;
|
||||
comp.subsystem = subsystem;
|
||||
}
|
||||
|
||||
void SendableRegistry::AddChild(Sendable* parent, Sendable* child) {
|
||||
auto& inst = GetInstance();
|
||||
std::scoped_lock lock(inst.mutex);
|
||||
@@ -361,26 +302,6 @@ std::shared_ptr<void> SendableRegistry::GetData(Sendable* sendable,
|
||||
return comp.data[handle];
|
||||
}
|
||||
|
||||
void SendableRegistry::EnableLiveWindow(Sendable* sendable) {
|
||||
auto& inst = GetInstance();
|
||||
std::scoped_lock lock(inst.mutex);
|
||||
auto it = inst.componentMap.find(sendable);
|
||||
if (it == inst.componentMap.end() || !inst.components[it->getSecond() - 1]) {
|
||||
return;
|
||||
}
|
||||
inst.components[it->getSecond() - 1]->liveWindow = true;
|
||||
}
|
||||
|
||||
void SendableRegistry::DisableLiveWindow(Sendable* sendable) {
|
||||
auto& inst = GetInstance();
|
||||
std::scoped_lock lock(inst.mutex);
|
||||
auto it = inst.componentMap.find(sendable);
|
||||
if (it == inst.componentMap.end() || !inst.components[it->getSecond() - 1]) {
|
||||
return;
|
||||
}
|
||||
inst.components[it->getSecond() - 1]->liveWindow = false;
|
||||
}
|
||||
|
||||
SendableRegistry::UID SendableRegistry::GetUniqueId(Sendable* sendable) {
|
||||
auto& inst = GetInstance();
|
||||
std::scoped_lock lock(inst.mutex);
|
||||
@@ -430,25 +351,3 @@ void SendableRegistry::Update(UID sendableUid) {
|
||||
inst.components[sendableUid - 1]->builder->Update();
|
||||
}
|
||||
}
|
||||
|
||||
void SendableRegistry::ForeachLiveWindow(
|
||||
int dataHandle, wpi::function_ref<void(CallbackData& data)> callback) {
|
||||
auto& inst = GetInstance();
|
||||
assert(dataHandle >= 0);
|
||||
std::scoped_lock lock(inst.mutex);
|
||||
wpi::SmallVector<Component*, 128> components;
|
||||
for (auto&& comp : inst.components) {
|
||||
components.emplace_back(comp.get());
|
||||
}
|
||||
for (auto comp : components) {
|
||||
if (comp && comp->builder && comp->sendable && comp->liveWindow) {
|
||||
if (static_cast<size_t>(dataHandle) >= comp->data.size()) {
|
||||
comp->data.resize(dataHandle + 1);
|
||||
}
|
||||
CallbackData cbdata{comp->sendable, comp->name,
|
||||
comp->subsystem, comp->parent,
|
||||
comp->data[dataHandle], *comp->builder};
|
||||
callback(cbdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,14 +48,6 @@ class SendableBuilder {
|
||||
*/
|
||||
virtual void SetActuator(bool value) = 0;
|
||||
|
||||
/**
|
||||
* Set the function that should be called to set the Sendable into a safe
|
||||
* state. This is called when entering and exiting Live Window mode.
|
||||
*
|
||||
* @param func function
|
||||
*/
|
||||
virtual void SetSafeState(std::function<void()> func) = 0;
|
||||
|
||||
/**
|
||||
* Add a boolean property.
|
||||
*
|
||||
|
||||
@@ -4,13 +4,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "wpi/function_ref.h"
|
||||
|
||||
namespace wpi {
|
||||
|
||||
class Sendable;
|
||||
@@ -18,7 +15,7 @@ class SendableBuilder;
|
||||
|
||||
/**
|
||||
* The SendableRegistry class is the public interface for registering sensors
|
||||
* and actuators for use on dashboards and LiveWindow.
|
||||
* and actuators for use on dashboards.
|
||||
*/
|
||||
class SendableRegistry final {
|
||||
public:
|
||||
@@ -32,14 +29,6 @@ class SendableRegistry final {
|
||||
*/
|
||||
static void EnsureInitialized();
|
||||
|
||||
/**
|
||||
* Sets the factory for LiveWindow builders.
|
||||
*
|
||||
* @param factory factory function
|
||||
*/
|
||||
static void SetLiveWindowBuilderFactory(
|
||||
std::function<std::unique_ptr<SendableBuilder>()> factory);
|
||||
|
||||
/**
|
||||
* Adds an object to the registry.
|
||||
*
|
||||
@@ -80,47 +69,6 @@ class SendableRegistry final {
|
||||
static void Add(Sendable* sendable, std::string_view subsystem,
|
||||
std::string_view name);
|
||||
|
||||
/**
|
||||
* Adds an object to the registry and LiveWindow.
|
||||
*
|
||||
* @param sendable object to add
|
||||
* @param name component name
|
||||
*/
|
||||
static void AddLW(Sendable* sendable, std::string_view name);
|
||||
|
||||
/**
|
||||
* Adds an object to the registry and LiveWindow.
|
||||
*
|
||||
* @param sendable object to add
|
||||
* @param moduleType A string that defines the module name in the label for
|
||||
* the value
|
||||
* @param channel The channel number the device is plugged into
|
||||
*/
|
||||
static void AddLW(Sendable* sendable, std::string_view moduleType,
|
||||
int channel);
|
||||
|
||||
/**
|
||||
* Adds an object to the registry and LiveWindow.
|
||||
*
|
||||
* @param sendable object to add
|
||||
* @param moduleType A string that defines the module name in the label for
|
||||
* the value
|
||||
* @param moduleNumber The number of the particular module type
|
||||
* @param channel The channel number the device is plugged into
|
||||
*/
|
||||
static void AddLW(Sendable* sendable, std::string_view moduleType,
|
||||
int moduleNumber, int channel);
|
||||
|
||||
/**
|
||||
* Adds an object to the registry and LiveWindow.
|
||||
*
|
||||
* @param sendable object to add
|
||||
* @param subsystem subsystem name
|
||||
* @param name component name
|
||||
*/
|
||||
static void AddLW(Sendable* sendable, std::string_view subsystem,
|
||||
std::string_view name);
|
||||
|
||||
/**
|
||||
* Adds a child object to an object. Adds the child object to the registry
|
||||
* if it's not already present.
|
||||
@@ -255,20 +203,6 @@ class SendableRegistry final {
|
||||
*/
|
||||
static std::shared_ptr<void> GetData(Sendable* sendable, int handle);
|
||||
|
||||
/**
|
||||
* Enables LiveWindow for an object.
|
||||
*
|
||||
* @param sendable object
|
||||
*/
|
||||
static void EnableLiveWindow(Sendable* sendable);
|
||||
|
||||
/**
|
||||
* Disables LiveWindow for an object.
|
||||
*
|
||||
* @param sendable object
|
||||
*/
|
||||
static void DisableLiveWindow(Sendable* sendable);
|
||||
|
||||
/**
|
||||
* Get unique id for an object. Since objects can move, use this instead
|
||||
* of storing Sendable* directly if ownership is in question.
|
||||
@@ -301,39 +235,6 @@ class SendableRegistry final {
|
||||
* @param sendableUid sendable unique id
|
||||
*/
|
||||
static void Update(UID sendableUid);
|
||||
|
||||
/**
|
||||
* Data passed to ForeachLiveWindow() callback function
|
||||
*/
|
||||
struct CallbackData {
|
||||
CallbackData(Sendable* sendable_, std::string_view name_,
|
||||
std::string_view subsystem_, wpi::Sendable* parent_,
|
||||
std::shared_ptr<void>& data_, SendableBuilder& builder_)
|
||||
: sendable(sendable_),
|
||||
name(name_),
|
||||
subsystem(subsystem_),
|
||||
parent(parent_),
|
||||
data(data_),
|
||||
builder(builder_) {}
|
||||
|
||||
Sendable* sendable;
|
||||
std::string_view name;
|
||||
std::string_view subsystem;
|
||||
Sendable* parent;
|
||||
std::shared_ptr<void>& data;
|
||||
SendableBuilder& builder;
|
||||
};
|
||||
|
||||
/**
|
||||
* Iterates over LiveWindow-enabled objects in the registry.
|
||||
* It is *not* safe to call other SendableRegistry functions from the
|
||||
* callback (this will likely deadlock).
|
||||
*
|
||||
* @param dataHandle data handle to get data pointer passed to callback
|
||||
* @param callback function to call for each object
|
||||
*/
|
||||
static void ForeachLiveWindow(
|
||||
int dataHandle, wpi::function_ref<void(CallbackData& cbdata)> callback);
|
||||
};
|
||||
|
||||
} // namespace wpi
|
||||
|
||||
Reference in New Issue
Block a user