Allow video sources to be added to Shuffleboard (#1453)

Add a Sendable wrapper for VideoSource objects.

Add convenience methods for adding video sources directly to containers
so users won't have to manually wrap video sources.
This commit is contained in:
Sam Carlberg
2018-12-30 14:45:41 -05:00
committed by Peter Johnson
parent a2368a6199
commit 80f87ff8ad
6 changed files with 219 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 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. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.shuffleboard;
import java.util.Map;
import java.util.WeakHashMap;
import edu.wpi.cscore.VideoSource;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.SendableBase;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
/**
* A wrapper to make video sources sendable and usable from Shuffleboard.
*/
public final class SendableCameraWrapper extends SendableBase {
private static final String kProtocol = "camera_server://";
private static Map<VideoSource, SendableCameraWrapper> m_wrappers = new WeakHashMap<>();
private final String m_uri;
/**
* Creates a new sendable wrapper. Private constructor to avoid direct instantiation with
* multiple wrappers floating around for the same camera.
*
* @param source the source to wrap
*/
private SendableCameraWrapper(VideoSource source) {
super(false);
String name = source.getName();
setName(name);
m_uri = kProtocol + name;
}
/**
* Gets a sendable wrapper object for the given video source, creating the wrapper if one does
* not already exist for the source.
*
* @param source the video source to wrap
* @return a sendable wrapper object for the video source, usable in Shuffleboard via
* {@link ShuffleboardTab#add(Sendable)} and {@link ShuffleboardLayout#add(Sendable)}
*/
public static SendableCameraWrapper wrap(VideoSource source) {
return m_wrappers.computeIfAbsent(source, SendableCameraWrapper::new);
}
@Override
public void initSendable(SendableBuilder builder) {
builder.addStringProperty(".ShuffleboardURI", () -> m_uri, null);
}
}

View File

@@ -10,6 +10,7 @@ package edu.wpi.first.wpilibj.shuffleboard;
import java.util.List;
import java.util.NoSuchElementException;
import edu.wpi.cscore.VideoSource;
import edu.wpi.first.wpilibj.Sendable;
/**
@@ -76,6 +77,19 @@ public interface ShuffleboardContainer extends ShuffleboardValue {
*/
ComplexWidget add(String title, Sendable sendable) throws IllegalArgumentException;
/**
* Adds a widget to this container to display the given video stream.
*
* @param title the title of the widget
* @param video the video stream to display
* @return a widget to display the sendable data
* @throws IllegalArgumentException if a widget already exists in this container with the given
* title
*/
default ComplexWidget add(String title, VideoSource video) throws IllegalArgumentException {
return add(title, SendableCameraWrapper.wrap(video));
}
/**
* Adds a widget to this container to display the given sendable.
*
@@ -86,6 +100,18 @@ public interface ShuffleboardContainer extends ShuffleboardValue {
*/
ComplexWidget add(Sendable sendable);
/**
* Adds a widget to this container to display the given video stream.
*
* @param video the video to display
* @return a widget to display the sendable data
* @throws IllegalArgumentException if a widget already exists in this container with the same
* title as the video source
*/
default ComplexWidget add(VideoSource video) {
return add(SendableCameraWrapper.wrap(video));
}
/**
* Adds a widget to this container to display the given data.
*