001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package edu.wpi.first.wpilibj2.command; 006 007import static edu.wpi.first.util.ErrorMessages.requireNonNullParam; 008 009import edu.wpi.first.util.sendable.Sendable; 010import edu.wpi.first.util.sendable.SendableBuilder; 011import edu.wpi.first.util.sendable.SendableRegistry; 012import java.util.HashSet; 013import java.util.Set; 014 015/** 016 * A {@link Sendable} base class for {@link Command}s. 017 * 018 * <p>This class is provided by the NewCommands VendorDep 019 */ 020public abstract class CommandBase implements Sendable, Command { 021 protected Set<Subsystem> m_requirements = new HashSet<>(); 022 023 protected CommandBase() { 024 String name = getClass().getName(); 025 SendableRegistry.add(this, name.substring(name.lastIndexOf('.') + 1)); 026 } 027 028 /** 029 * Adds the specified requirements to the command. 030 * 031 * @param requirements the requirements to add 032 */ 033 public final void addRequirements(Subsystem... requirements) { 034 for (Subsystem requirement : requirements) { 035 m_requirements.add(requireNonNullParam(requirement, "requirement", "addRequirements")); 036 } 037 } 038 039 @Override 040 public Set<Subsystem> getRequirements() { 041 return m_requirements; 042 } 043 044 @Override 045 public String getName() { 046 return SendableRegistry.getName(this); 047 } 048 049 /** 050 * Sets the name of this Command. 051 * 052 * @param name name 053 */ 054 @Override 055 public void setName(String name) { 056 SendableRegistry.setName(this, name); 057 } 058 059 /** 060 * Gets the subsystem name of this Command. 061 * 062 * @return Subsystem name 063 */ 064 public String getSubsystem() { 065 return SendableRegistry.getSubsystem(this); 066 } 067 068 /** 069 * Sets the subsystem name of this Command. 070 * 071 * @param subsystem subsystem name 072 */ 073 public void setSubsystem(String subsystem) { 074 SendableRegistry.setSubsystem(this, subsystem); 075 } 076 077 /** 078 * Initializes this sendable. Useful for allowing implementations to easily extend SendableBase. 079 * 080 * @param builder the builder used to construct this sendable 081 */ 082 @Override 083 public void initSendable(SendableBuilder builder) { 084 builder.setSmartDashboardType("Command"); 085 builder.addStringProperty(".name", this::getName, null); 086 builder.addBooleanProperty( 087 "running", 088 this::isScheduled, 089 value -> { 090 if (value) { 091 if (!isScheduled()) { 092 schedule(); 093 } 094 } else { 095 if (isScheduled()) { 096 cancel(); 097 } 098 } 099 }); 100 builder.addBooleanProperty( 101 ".isParented", () -> CommandScheduler.getInstance().isComposed(this), null); 102 builder.addStringProperty( 103 "interruptBehavior", () -> getInterruptionBehavior().toString(), null); 104 builder.addBooleanProperty("runsWhenDisabled", this::runsWhenDisabled, null); 105 } 106}