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 edu.wpi.first.util.sendable.Sendable; 008import edu.wpi.first.util.sendable.SendableBuilder; 009import edu.wpi.first.util.sendable.SendableRegistry; 010import java.util.HashSet; 011import java.util.Set; 012 013/** A {@link Sendable} base class for {@link Command}s. */ 014public abstract class CommandBase implements Sendable, Command { 015 protected Set<Subsystem> m_requirements = new HashSet<>(); 016 017 protected CommandBase() { 018 String name = getClass().getName(); 019 SendableRegistry.add(this, name.substring(name.lastIndexOf('.') + 1)); 020 } 021 022 /** 023 * Adds the specified requirements to the command. 024 * 025 * @param requirements the requirements to add 026 */ 027 public final void addRequirements(Subsystem... requirements) { 028 m_requirements.addAll(Set.of(requirements)); 029 } 030 031 @Override 032 public Set<Subsystem> getRequirements() { 033 return m_requirements; 034 } 035 036 @Override 037 public String getName() { 038 return SendableRegistry.getName(this); 039 } 040 041 /** 042 * Sets the name of this Command. 043 * 044 * @param name name 045 */ 046 public void setName(String name) { 047 SendableRegistry.setName(this, name); 048 } 049 050 /** 051 * Decorates this Command with a name. Is an inline function for #setName(String); 052 * 053 * @param name name 054 * @return the decorated Command 055 */ 056 public CommandBase withName(String name) { 057 this.setName(name); 058 return this; 059 } 060 061 /** 062 * Gets the subsystem name of this Command. 063 * 064 * @return Subsystem name 065 */ 066 public String getSubsystem() { 067 return SendableRegistry.getSubsystem(this); 068 } 069 070 /** 071 * Sets the subsystem name of this Command. 072 * 073 * @param subsystem subsystem name 074 */ 075 public void setSubsystem(String subsystem) { 076 SendableRegistry.setSubsystem(this, subsystem); 077 } 078 079 /** 080 * Initializes this sendable. Useful for allowing implementations to easily extend SendableBase. 081 * 082 * @param builder the builder used to construct this sendable 083 */ 084 @Override 085 public void initSendable(SendableBuilder builder) { 086 builder.setSmartDashboardType("Command"); 087 builder.addStringProperty(".name", this::getName, null); 088 builder.addBooleanProperty( 089 "running", 090 this::isScheduled, 091 value -> { 092 if (value) { 093 if (!isScheduled()) { 094 schedule(); 095 } 096 } else { 097 if (isScheduled()) { 098 cancel(); 099 } 100 } 101 }); 102 builder.addBooleanProperty( 103 ".isParented", () -> CommandGroupBase.getGroupedCommands().contains(this), null); 104 } 105}