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 java.util.function.Consumer;
010
011/**
012 * A command that runs a given runnable when it is initialized, and another runnable when it ends.
013 * Useful for running and then stopping a motor, or extending and then retracting a solenoid. Has no
014 * end condition as-is; either subclass it or use {@link Command#withTimeout(double)} or {@link
015 * Command#until(java.util.function.BooleanSupplier)} to give it one.
016 *
017 * <p>This class is provided by the NewCommands VendorDep
018 */
019public class StartEndCommand extends FunctionalCommand {
020  /**
021   * Creates a new StartEndCommand. Will run the given runnables when the command starts and when it
022   * ends.
023   *
024   * @param onInit the Runnable to run on command init
025   * @param onEnd the Runnable to run on command end
026   * @param requirements the subsystems required by this command
027   */
028  public StartEndCommand(Runnable onInit, Runnable onEnd, Subsystem... requirements) {
029    super(
030        onInit,
031        () -> {},
032        // we need to do some magic here to null-check `onEnd` before it's captured
033        droppingParameter(requireNonNullParam(onEnd, "onEnd", "StartEndCommand")),
034        () -> false,
035        requirements);
036  }
037
038  private static Consumer<Boolean> droppingParameter(Runnable run) {
039    return bool -> run.run();
040  }
041}