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.wpilibj.util.ErrorMessages.requireNonNullParam;
008import static edu.wpi.first.wpilibj2.command.CommandGroupBase.requireUngrouped;
009
010import java.util.function.BooleanSupplier;
011
012/**
013 * Runs one of two commands, depending on the value of the given condition when this command is
014 * initialized. Does not actually schedule the selected command - rather, the command is run through
015 * this command; this ensures that the command will behave as expected if used as part of a
016 * CommandGroup. Requires the requirements of both commands, again to ensure proper functioning when
017 * used in a CommandGroup. If this is undesired, consider using {@link ScheduleCommand}.
018 *
019 * <p>As this command contains multiple component commands within it, it is technically a command
020 * group; the command instances that are passed to it cannot be added to any other groups, or
021 * scheduled individually.
022 *
023 * <p>As a rule, CommandGroups require the union of the requirements of their component commands.
024 */
025public class ConditionalCommand extends CommandBase {
026  private final Command m_onTrue;
027  private final Command m_onFalse;
028  private final BooleanSupplier m_condition;
029  private Command m_selectedCommand;
030
031  /**
032   * Creates a new ConditionalCommand.
033   *
034   * @param onTrue the command to run if the condition is true
035   * @param onFalse the command to run if the condition is false
036   * @param condition the condition to determine which command to run
037   */
038  public ConditionalCommand(Command onTrue, Command onFalse, BooleanSupplier condition) {
039    requireUngrouped(onTrue, onFalse);
040
041    CommandGroupBase.registerGroupedCommands(onTrue, onFalse);
042
043    m_onTrue = onTrue;
044    m_onFalse = onFalse;
045    m_condition = requireNonNullParam(condition, "condition", "ConditionalCommand");
046    m_requirements.addAll(m_onTrue.getRequirements());
047    m_requirements.addAll(m_onFalse.getRequirements());
048  }
049
050  @Override
051  public void initialize() {
052    if (m_condition.getAsBoolean()) {
053      m_selectedCommand = m_onTrue;
054    } else {
055      m_selectedCommand = m_onFalse;
056    }
057    m_selectedCommand.initialize();
058  }
059
060  @Override
061  public void execute() {
062    m_selectedCommand.execute();
063  }
064
065  @Override
066  public void end(boolean interrupted) {
067    m_selectedCommand.end(interrupted);
068  }
069
070  @Override
071  public boolean isFinished() {
072    return m_selectedCommand.isFinished();
073  }
074
075  @Override
076  public boolean runsWhenDisabled() {
077    return m_onTrue.runsWhenDisabled() && m_onFalse.runsWhenDisabled();
078  }
079}