001package com.stuypulse.robot.commands.compound;
002
003import java.util.UUID;
004
005import org.jspecify.annotations.NonNull;
006
007import dev.doglog.DogLog;
008import edu.wpi.first.networktables.DoubleSubscriber;
009import edu.wpi.first.wpilibj2.command.WaitCommand;
010
011import edu.wpi.first.util.sendable.SendableBuilder;
012import edu.wpi.first.util.sendable.SendableRegistry;
013
014/**
015 * A command that does nothing but takes a specified amount of time to finish
016 * based on a tunable value.
017 */
018public class TunableWaitCommand extends WaitCommand {
019    private static final double tunableDefaultValue = 0.0;
020    private final DoubleSubscriber tunable;
021
022    @NonNull
023    private static String makeTunableName(String rawName) {
024        return rawName == null ? "Tunable_Wait_" + UUID.randomUUID().toString() : rawName;
025    }
026
027    /**
028     * Creates a tunable wait command based on a DogLog tunable's DoubleSubscriber
029     * @param tunable The DoubleSubscriber instance returned by creation of a {@link DogLog#tunable(String, double)}
030     */
031    public TunableWaitCommand(DoubleSubscriber tunable) {
032        super(tunableDefaultValue);
033        this.tunable = tunable;
034        SendableRegistry.setName(this, getName() + ": " + tunable.get() + " seconds");
035    }
036
037    /**
038     * Creates a tunable wait command by <strong>creating</strong> a tunable at the path specified
039     * 
040     * Initializes the tunable to a default value of 0.0
041     * @param tunableName path and name of the {@link DogLog#tunable(String, double)} created
042     */
043    public TunableWaitCommand(String tunableName) {
044        this(DogLog.tunable(makeTunableName(tunableName),
045                tunableDefaultValue));
046    }
047
048    /**
049     * Creates a tunable wait command by <strong>creating</strong> a tunable at the path specified
050     * @param tunableName path and name of the {@link DogLog#tunable(String, double)} created
051     * @param defaultValue value the tunable will be initialized to
052     */
053    public TunableWaitCommand(String tunableName, double defaultValue) {
054        this(DogLog.tunable(makeTunableName(tunableName),
055                defaultValue));
056    }
057
058    @Override
059    public boolean isFinished() {
060        return m_timer.hasElapsed(tunable.get());
061    }
062
063    @Override
064    public void initSendable(SendableBuilder builder) {
065        super.initSendable(builder);
066        builder.addDoubleProperty("duration", tunable, null);
067    }
068}