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.AddressableLEDDataJNI; 008import edu.wpi.first.hal.simulation.ConstBufferCallback; 009import edu.wpi.first.hal.simulation.NotifyCallback; 010import edu.wpi.first.wpilibj.AddressableLED; 011import java.util.NoSuchElementException; 012 013/** Class to control a simulated addressable LED. */ 014public class AddressableLEDSim { 015 private final int m_index; 016 017 /** Constructs for the first addressable LED. */ 018 public AddressableLEDSim() { 019 m_index = 0; 020 } 021 022 /** 023 * Constructs from an AddressableLED object. 024 * 025 * @param addressableLED AddressableLED to simulate 026 */ 027 @SuppressWarnings("PMD.UnusedFormalParameter") 028 public AddressableLEDSim(AddressableLED addressableLED) { 029 // there is only support for a single AddressableLED, so no lookup 030 m_index = 0; 031 } 032 033 private AddressableLEDSim(int index) { 034 m_index = index; 035 } 036 037 /** 038 * Creates an AddressableLEDSim for a PWM channel. 039 * 040 * @param pwmChannel PWM channel 041 * @return Simulated object 042 * @throws NoSuchElementException if no AddressableLED is configured for that channel 043 */ 044 public static AddressableLEDSim createForChannel(int pwmChannel) { 045 int index = AddressableLEDDataJNI.findForChannel(pwmChannel); 046 if (index < 0) { 047 throw new NoSuchElementException("no addressable LED found for PWM channel " + pwmChannel); 048 } 049 return new AddressableLEDSim(index); 050 } 051 052 /** 053 * Creates an AddressableLEDSim for a simulated index. The index is incremented for each simulated 054 * AddressableLED. 055 * 056 * @param index simulator index 057 * @return Simulated object 058 */ 059 public static AddressableLEDSim createForIndex(int index) { 060 return new AddressableLEDSim(index); 061 } 062 063 /** 064 * Register a callback on the Initialized property. 065 * 066 * @param callback the callback that will be called whenever the Initialized property is changed 067 * @param initialNotify if true, the callback will be run on the initial value 068 * @return the {@link CallbackStore} object associated with this callback. Save a reference to 069 * this object so GC doesn't cancel the callback. 070 */ 071 public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) { 072 int uid = AddressableLEDDataJNI.registerInitializedCallback(m_index, callback, initialNotify); 073 return new CallbackStore(m_index, uid, AddressableLEDDataJNI::cancelInitializedCallback); 074 } 075 076 /** 077 * Check if initialized. 078 * 079 * @return true if initialized 080 */ 081 public boolean getInitialized() { 082 return AddressableLEDDataJNI.getInitialized(m_index); 083 } 084 085 /** 086 * Change the Initialized value of the LED strip. 087 * 088 * @param initialized the new value 089 */ 090 public void setInitialized(boolean initialized) { 091 AddressableLEDDataJNI.setInitialized(m_index, initialized); 092 } 093 094 /** 095 * Register a callback on the output port. 096 * 097 * @param callback the callback that will be called whenever the output port is changed 098 * @param initialNotify if true, the callback will be run on the initial value 099 * @return the {@link CallbackStore} object associated with this callback. Save a reference to 100 * this object so GC doesn't cancel the callback. 101 */ 102 public CallbackStore registerOutputPortCallback(NotifyCallback callback, boolean initialNotify) { 103 int uid = AddressableLEDDataJNI.registerOutputPortCallback(m_index, callback, initialNotify); 104 return new CallbackStore(m_index, uid, AddressableLEDDataJNI::cancelOutputPortCallback); 105 } 106 107 /** 108 * Get the output port. 109 * 110 * @return the output port 111 */ 112 public int getOutputPort() { 113 return AddressableLEDDataJNI.getOutputPort(m_index); 114 } 115 116 /** 117 * Change the output port. 118 * 119 * @param outputPort the new output port 120 */ 121 public void setOutputPort(int outputPort) { 122 AddressableLEDDataJNI.setOutputPort(m_index, outputPort); 123 } 124 125 /** 126 * Register a callback on the length. 127 * 128 * @param callback the callback that will be called whenever the length is changed 129 * @param initialNotify if true, the callback will be run on the initial value 130 * @return the {@link CallbackStore} object associated with this callback. Save a reference to 131 * this object so GC doesn't cancel the callback. 132 */ 133 public CallbackStore registerLengthCallback(NotifyCallback callback, boolean initialNotify) { 134 int uid = AddressableLEDDataJNI.registerLengthCallback(m_index, callback, initialNotify); 135 return new CallbackStore(m_index, uid, AddressableLEDDataJNI::cancelLengthCallback); 136 } 137 138 /** 139 * Get the length of the LED strip. 140 * 141 * @return the length 142 */ 143 public int getLength() { 144 return AddressableLEDDataJNI.getLength(m_index); 145 } 146 147 /** 148 * Change the length of the LED strip. 149 * 150 * @param length the new value 151 */ 152 public void setLength(int length) { 153 AddressableLEDDataJNI.setLength(m_index, length); 154 } 155 156 /** 157 * Register a callback on whether the LEDs are running. 158 * 159 * @param callback the callback that will be called whenever the LED state is changed 160 * @param initialNotify if true, the callback will be run on the initial value 161 * @return the {@link CallbackStore} object associated with this callback. Save a reference to 162 * this object so GC doesn't cancel the callback. 163 */ 164 public CallbackStore registerRunningCallback(NotifyCallback callback, boolean initialNotify) { 165 int uid = AddressableLEDDataJNI.registerRunningCallback(m_index, callback, initialNotify); 166 return new CallbackStore(m_index, uid, AddressableLEDDataJNI::cancelRunningCallback); 167 } 168 169 /** 170 * Check if the LEDs are running. 171 * 172 * @return true if they are 173 */ 174 public boolean getRunning() { 175 return AddressableLEDDataJNI.getRunning(m_index); 176 } 177 178 /** 179 * Change whether the LEDs are active. 180 * 181 * @param running the new value 182 */ 183 public void setRunning(boolean running) { 184 AddressableLEDDataJNI.setRunning(m_index, running); 185 } 186 187 /** 188 * Register a callback on the LED data. 189 * 190 * @param callback the callback that will be called whenever the LED data is changed 191 * @return the {@link CallbackStore} object associated with this callback. Save a reference to 192 * this object so GC doesn't cancel the callback. 193 */ 194 public CallbackStore registerDataCallback(ConstBufferCallback callback) { 195 int uid = AddressableLEDDataJNI.registerDataCallback(m_index, callback); 196 return new CallbackStore(m_index, uid, AddressableLEDDataJNI::cancelDataCallback); 197 } 198 199 /** 200 * Get the LED data. 201 * 202 * @return the LED data 203 */ 204 public byte[] getData() { 205 return AddressableLEDDataJNI.getData(m_index); 206 } 207 208 /** 209 * Change the LED data. 210 * 211 * @param data the new data 212 */ 213 public void setData(byte[] data) { 214 AddressableLEDDataJNI.setData(m_index, data); 215 } 216 217 /** Reset all simulation data for this LED object. */ 218 public void resetData() { 219 AddressableLEDDataJNI.resetData(m_index); 220 } 221}