Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a whenHeld to a custom trigger class #162

Open
wants to merge 1 commit into
base: testing
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public boolean get() {
}
}

private class BionicJoystickPOVButton extends Trigger {
private class BionicJoystickPOVButton extends BionicTrigger {
private BionicJoystick inputJoystick;
private int povAngle;

Expand Down
207 changes: 207 additions & 0 deletions src/main/java/frc/team4909/robot/operator/generic/BionicTrigger.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/

package frc.team4909.robot.operator.generic;

import edu.wpi.first.wpilibj.SendableBase;
import edu.wpi.first.wpilibj.buttons.Trigger;
import edu.wpi.first.wpilibj.command.Command;
import edu.wpi.first.wpilibj.command.Scheduler;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;

/**
* This class provides an easy way to link commands to inputs.
*
* <p>
* It is very easy to link a button to a command. For instance, you could link
* the trigger button of a joystick to a "score" command.
*
* <p>
* It is encouraged that teams write a subclass of Trigger if they want to have
* something unusual (for instance, if they want to react to the user holding a
* button while the robot is reading a certain sensor input). For this, they
* only have to write the {@link Trigger#get()} method to get the full
* functionality of the Trigger class.
*/
public abstract class BionicTrigger extends SendableBase {
private volatile boolean m_sendablePressed;

/**
* Returns whether or not the trigger is active.
*
* <p>
* This method will be called repeatedly a command is linked to the Trigger.
*
* @return whether or not the trigger condition is active.
*/
public abstract boolean get();

/**
* Returns whether get() return true or the internal table for SmartDashboard
* use is pressed.
*
* @return whether get() return true or the internal table for SmartDashboard
* use is pressed.
*/
@SuppressWarnings("PMD.UselessParentheses")
private boolean grab() {
return get() || m_sendablePressed;
}

/**
* Starts the given command whenever the trigger just becomes active.
*
* @param command the command to start
*/
public void whenActive(final Command command) {
new Trigger.ButtonScheduler() {
private boolean m_pressedLast = grab();

@Override
public void execute() {
boolean pressed = grab();

if (!m_pressedLast && pressed) {
command.start();
}

m_pressedLast = pressed;
}
}.start();
}

/**
* Constantly starts the given command while the button is held.
*
* {@link Command#start()} will be called repeatedly while the trigger is
* active, and will be canceled when the trigger becomes inactive.
*
* @param command the command to start
*/
public void whileActive(final Command command) {
new Trigger.ButtonScheduler() {
private boolean m_pressedLast = grab();

@Override
public void execute() {
boolean pressed = grab();

if (pressed) {
command.start();
} else if (m_pressedLast && !pressed) {
command.cancel();
}

m_pressedLast = pressed;
}
}.start();
}

/**
* Starts the given command when the button is pressed, cancels when released.
*
* {@link Command#start()} will be called once when the trigger is
* active, and will be canceled when the trigger becomes inactive.
*
* @param command the command to start
*/
public void whenHeld(final Command command) {
new Trigger.ButtonScheduler() {
private boolean m_pressedLast = grab();

@Override
public void execute() {
boolean pressed = grab();

if (!m_pressedLast && pressed) {
command.start();
} else if (m_pressedLast && !pressed) {
command.cancel();
}

m_pressedLast = pressed;
}
}.start();
}

/**
* Starts the command when the trigger becomes inactive.
*
* @param command the command to start
*/
public void whenInactive(final Command command) {
new Trigger.ButtonScheduler() {
private boolean m_pressedLast = grab();

@Override
public void execute() {
boolean pressed = grab();

if (m_pressedLast && !pressed) {
command.start();
}

m_pressedLast = pressed;
}
}.start();
}

/**
* Toggles a command when the trigger becomes active.
*
* @param command the command to toggle
*/
public void toggleWhenActive(final Command command) {
new Trigger.ButtonScheduler() {
private boolean m_pressedLast = grab();

@Override
public void execute() {
boolean pressed = grab();

if (!m_pressedLast && pressed) {
if (command.isRunning()) {
command.cancel();
} else {
command.start();
}
}

m_pressedLast = pressed;
}
}.start();
}

/**
* Cancels a command when the trigger becomes active.
*
* @param command the command to cancel
*/
public void cancelWhenActive(final Command command) {
new Trigger.ButtonScheduler() {
private boolean m_pressedLast = grab();

@Override
public void execute() {
boolean pressed = grab();

if (!m_pressedLast && pressed) {
command.cancel();
}

m_pressedLast = pressed;
}
}.start();
}

@Override
public void initSendable(SendableBuilder builder) {
builder.setSmartDashboardType("Button");
builder.setSafeState(() -> m_sendablePressed = false);
builder.addBooleanProperty("pressed", this::grab, value -> m_sendablePressed = value);
}
}