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.wpilibj.simulation;
006
007import edu.wpi.first.hal.simulation.AnalogTriggerDataJNI;
008import edu.wpi.first.hal.simulation.NotifyCallback;
009import edu.wpi.first.wpilibj.AnalogTrigger;
010import java.util.NoSuchElementException;
011
012/** Class to control a simulated analog trigger. */
013public class AnalogTriggerSim {
014  private final int m_index;
015
016  /**
017   * Constructs from an AnalogTrigger object.
018   *
019   * @param analogTrigger AnalogTrigger to simulate
020   */
021  public AnalogTriggerSim(AnalogTrigger analogTrigger) {
022    m_index = analogTrigger.getIndex();
023  }
024
025  private AnalogTriggerSim(int index) {
026    m_index = index;
027  }
028
029  /**
030   * Creates an AnalogTriggerSim for an analog input channel.
031   *
032   * @param channel analog input channel
033   * @return Simulated object
034   * @throws NoSuchElementException if no AnalogTrigger is configured for that channel
035   */
036  public static AnalogTriggerSim createForChannel(int channel) {
037    int index = AnalogTriggerDataJNI.findForChannel(channel);
038    if (index < 0) {
039      throw new NoSuchElementException("no analog trigger found for channel " + channel);
040    }
041    return new AnalogTriggerSim(index);
042  }
043
044  /**
045   * Creates an AnalogTriggerSim for a simulated index. The index is incremented for each simulated
046   * AnalogTrigger.
047   *
048   * @param index simulator index
049   * @return Simulated object
050   */
051  public static AnalogTriggerSim createForIndex(int index) {
052    return new AnalogTriggerSim(index);
053  }
054
055  /**
056   * Register a callback on whether the analog trigger is initialized.
057   *
058   * @param callback the callback that will be called whenever the analog trigger is initialized
059   * @param initialNotify if true, the callback will be run on the initial value
060   * @return the {@link CallbackStore} object associated with this callback. Save a reference to
061   *     this object so GC doesn't cancel the callback.
062   */
063  public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) {
064    int uid = AnalogTriggerDataJNI.registerInitializedCallback(m_index, callback, initialNotify);
065    return new CallbackStore(m_index, uid, AnalogTriggerDataJNI::cancelInitializedCallback);
066  }
067
068  /**
069   * Check if this analog trigger has been initialized.
070   *
071   * @return true if initialized
072   */
073  public boolean getInitialized() {
074    return AnalogTriggerDataJNI.getInitialized(m_index);
075  }
076
077  /**
078   * Change whether this analog trigger has been initialized.
079   *
080   * @param initialized the new value
081   */
082  public void setInitialized(boolean initialized) {
083    AnalogTriggerDataJNI.setInitialized(m_index, initialized);
084  }
085
086  /**
087   * Register a callback on the lower bound.
088   *
089   * @param callback the callback that will be called whenever the lower bound is changed
090   * @param initialNotify if true, the callback will be run on the initial value
091   * @return the {@link CallbackStore} object associated with this callback. Save a reference to
092   *     this object so GC doesn't cancel the callback.
093   */
094  public CallbackStore registerTriggerLowerBoundCallback(
095      NotifyCallback callback, boolean initialNotify) {
096    int uid =
097        AnalogTriggerDataJNI.registerTriggerLowerBoundCallback(m_index, callback, initialNotify);
098    return new CallbackStore(m_index, uid, AnalogTriggerDataJNI::cancelTriggerLowerBoundCallback);
099  }
100
101  /**
102   * Get the lower bound.
103   *
104   * @return the lower bound
105   */
106  public double getTriggerLowerBound() {
107    return AnalogTriggerDataJNI.getTriggerLowerBound(m_index);
108  }
109
110  /**
111   * Change the lower bound.
112   *
113   * @param triggerLowerBound the new lower bound
114   */
115  public void setTriggerLowerBound(double triggerLowerBound) {
116    AnalogTriggerDataJNI.setTriggerLowerBound(m_index, triggerLowerBound);
117  }
118
119  /**
120   * Register a callback on the upper bound.
121   *
122   * @param callback the callback that will be called whenever the upper bound is changed
123   * @param initialNotify if true, the callback will be run on the initial value
124   * @return the {@link CallbackStore} object associated with this callback. Save a reference to
125   *     this object so GC doesn't cancel the callback.
126   */
127  public CallbackStore registerTriggerUpperBoundCallback(
128      NotifyCallback callback, boolean initialNotify) {
129    int uid =
130        AnalogTriggerDataJNI.registerTriggerUpperBoundCallback(m_index, callback, initialNotify);
131    return new CallbackStore(m_index, uid, AnalogTriggerDataJNI::cancelTriggerUpperBoundCallback);
132  }
133
134  /**
135   * Get the upper bound.
136   *
137   * @return the upper bound
138   */
139  public double getTriggerUpperBound() {
140    return AnalogTriggerDataJNI.getTriggerUpperBound(m_index);
141  }
142
143  /**
144   * Change the upper bound.
145   *
146   * @param triggerUpperBound the new upper bound
147   */
148  public void setTriggerUpperBound(double triggerUpperBound) {
149    AnalogTriggerDataJNI.setTriggerUpperBound(m_index, triggerUpperBound);
150  }
151
152  /** Reset all simulation data for this object. */
153  public void resetData() {
154    AnalogTriggerDataJNI.resetData(m_index);
155  }
156}