Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
tomtzook committed Feb 1, 2024
2 parents 35c64bd + 0ec9032 commit 40ffa4f
Show file tree
Hide file tree
Showing 8 changed files with 242 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,8 @@ protected void registerDevice(int id, Class<?> type) {
LOGGER.warn("Device of id {} override", id);
}
}

protected <T, T2 extends T> void registerDevice(DeviceId<T> id, Class<T2> type) {
registerDevice(id.id(), type);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.flash3388.flashlib.io.devices;

public interface DeviceId<T> {

int id();
Class<T> baseType();

static <T> DeviceId<T> of(int id, Class<T> baseType) {
return new Impl<>(id, baseType);
}

class Impl<T> implements DeviceId<T> {

private final int mId;
private final Class<T> mBaseType;

public Impl(int id, Class<T> baseType) {
mId = id;
mBaseType = baseType;
}

@Override
public int id() {
return mId;
}

@Override
public Class<T> baseType() {
return mBaseType;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,33 @@ public interface DeviceInterface {
@MainThreadOnly
<T> T newDevice(int id, Class<T> type, Map<String, Object> namedArgs);

/**
* Finds a registered implementation for the given ID which matches the wanted type.
* Once the implementation is found, a constructor is matched to the given arguments
* count and an instance is created.
*
* @param id implementation identifier
* @param namedArgs arguments to the constructor
* @return created instance
* @param <T> type which the implementation must support, defined by the ID
*/
@MainThreadOnly
<T> T newDevice(DeviceId<T> id, Map<String, Object> namedArgs);

/**
* Finds a registered implementation for the given ID which matches the wanted type.
* Once the implementation is found, a constructor is matched to the given arguments
* count and an instance is created.
*
* @param id implementation identifier
* @param type type which the implementation must support (usually interface)
* @param namedArgs arguments to the constructor
* @return created instance
* @param <T> type which the implementation must support, defined by the ID
*/
@MainThreadOnly
<T, T2 extends T> T2 newDevice(DeviceId<T> id, Class<T2> type, Map<String, Object> namedArgs);

/**
* Creates a new group of {@link SpeedController} devices, which is encapsulated under a single interface.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ public <T> T newDevice(int id, Class<T> type, Map<String, Object> namedArgs) {
return newInstance(foundType, namedArgs);
}

@Override
public <T> T newDevice(DeviceId<T> id, Map<String, Object> namedArgs) {
return newDevice(id.id(), id.baseType(), namedArgs);
}

@Override
public <T, T2 extends T> T2 newDevice(DeviceId<T> id, Class<T2> type, Map<String, Object> namedArgs) {
return newDevice(id.id(), type, namedArgs);
}

@Override
public GroupBuilder<SpeedController, SpeedControllerGroup> newSpeedControllerGroup() {
mMainThread.verifyCurrentThread();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,104 @@ public class FlashLibDevicesIds {

private FlashLibDevicesIds() {}

public static final int PwmSpeedController = 21;
public static final int PwmPositionController = 22;
public static final int TalonSrx = 23;
public static final int Talon = 24;

public static final int AnalogAccelerometer = 51;
public static final int AnalogRangeFinder = 52;
public static final int PulseWidthRangeFinder = 53;
public static final int Ultrasonic = 54;
/**
* Defines a basic PWM speed (motor) controller.
*
* <p>
* Params:
* <ul>
* <li><em>port</em> ({@link com.flash3388.flashlib.io.Pwm}): port the device is connected to.</li>
* <li><em>pulseBounds</em> ({@link com.flash3388.flashlib.io.devices.actuators.PwmBounds}): defines pwm bounds for controlling the device.</li>
* <li><em>pwmFrequency</em> (<em>double</em>): frequency to use for communicating with the device (in HZ).</li>
* </ul>
*/
public static final DeviceId<SpeedController> PwmSpeedController = DeviceId.of(21, SpeedController.class);

/**
* Defines a basic PWM position controller.
*
* <p>
* Params:
* <ul>
* <li><em>port</em> ({@link com.flash3388.flashlib.io.Pwm}): port the device is connected to.</li>
* <li><em>pulseBounds</em> ({@link com.flash3388.flashlib.io.devices.actuators.PwmBounds}): defines pwm bounds for controlling the device.</li>
* <li><em>pwmFrequency</em> (<em>double</em>): frequency to use for communicating with the device (in HZ).</li>
* </ul>
*/
public static final DeviceId<PositionController> PwmPositionController = DeviceId.of(22, PositionController.class);

/**
* Defines a TalonSRX speed (motor) controller connected via a PWM port.
*
* <p>
* Params:
* <ul>
* <li><em>port</em> ({@link com.flash3388.flashlib.io.Pwm}): port the device is connected to.</li>
* </ul>
*/
public static final DeviceId<SpeedController> TalonSrx = DeviceId.of(23, SpeedController.class);

/**
* Defines a Talon speed (motor) controller connected via a PWM port.
*
* <p>
* Params:
* <ul>
* <li><em>port</em> ({@link com.flash3388.flashlib.io.Pwm}): port the device is connected to.</li>
* </ul>
*/
public static final DeviceId<SpeedController> Talon = DeviceId.of(24, SpeedController.class);

/**
* Defines a basic accelerometer which is connected via an analog port.
*
* <p>
* Params:
* <ul>
* <li><em>input</em> ({@link com.flash3388.flashlib.io.AnalogInput}): port the device is connected to.</li>
* <li><em>zeroGVoltage</em> (<em>double</em>): voltage when acceleration is 0, as defined by the device.</li>
* <li><em>voltsPerG</em> (<em>double</em>): conversion factor from volts to G acceleration.</li>
* </ul>
*/
public static final DeviceId<Accelerometer> AnalogAccelerometer = DeviceId.of(51, Accelerometer.class);

/**
* Defines a basic range finder which is connected via an analog port.
*
* <p>
* Params:
* <ul>
* <li><em>input</em> ({@link com.flash3388.flashlib.io.AnalogInput}): port the device is connected to.</li>
* <li><em>sensitivity</em> (<em>double</em>): sensitivity of the device in volts/centimeter</li>
* </ul>
*/
public static final DeviceId<RangeFinder> AnalogRangeFinder = DeviceId.of(52, RangeFinder.class);

/**
* Defines a basic range finder which is connected via a digital port and uses pulses to report the range.
*
* <p>
* Params:
* <ul>
* <li><em>counter</em> ({@link com.flash3388.flashlib.io.PulseLengthCounter}): counter on the port the device is connected to.</li>
* <li><em>sensitivity</em> (<em>double</em>): sensitivity of the device in microseconds/centimeter</li>
* </ul>
*/
public static final DeviceId<RangeFinder> PulseWidthRangeFinder = DeviceId.of(53, RangeFinder.class);

/**
* Defines a basic ultrasonic range finder which is connected to a digital port. Works for devices
* which use two channels: trigger which forces the device to send a pulse, and echo which the device uses
* to reply with the distance.
*
* Based on <em>HC-SR04</em>.
*
* <p>
* Params:
* <ul>
* <li><em>pingChannel</em> ({@link com.flash3388.flashlib.io.DigitalOutput}): channel used to trigger pings (trigger).</li>
* <li><em>counter</em> ({@link com.flash3388.flashlib.io.PulseLengthCounter}): counter on the pulse used to report the range (echo).</li>
* </ul>
*/
public static final DeviceId<RangeFinder> Ultrasonic = DeviceId.of(54, RangeFinder.class);
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,21 @@ public GroupBuilder<E, T> addNewDevice(int id, Map<String, Object> namedArgs) {
return addNewDevice(id, mElementType, namedArgs);
}

/**
* Finds a registered implementation for the given ID which matches the wanted type.
* Once the implementation is found, a constructor is matched to the given arguments
* count and an instance is created.
*
* @param id implementation identifier
* @param namedArgs arguments to the constructor
* @return this
*
* @see DeviceInterface#newDevice(int, Class, Map)
*/
public <T2 extends T> GroupBuilder<E, T> addNewDevice(DeviceId<T2> id, Map<String, Object> namedArgs) {
return addNewDevice(id.id(), mElementType, namedArgs);
}

public T build() {
return mCreator.apply(mParts);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,24 @@ public boolean isRunning(Action action) {
public void cancelActionsIf(Predicate<? super Action> predicate) {
mMainThread.verifyCurrentThread();

if (!mCanModifyRunningActions) {
throw new IllegalStateException("cannot cancel actions in bulk while action modification is disabled");
}

mPendingActions.values().removeIf(context -> predicate.test(context.getAction()));

for (Iterator<RunningActionContext> iterator = mRunningActions.values().iterator(); iterator.hasNext();) {
RunningActionContext context = iterator.next();
mCanModifyRunningActions = false;
try {
for (Iterator<RunningActionContext> iterator = mRunningActions.values().iterator(); iterator.hasNext();) {
RunningActionContext context = iterator.next();

if (predicate.test(context.getAction())) {
cancelAndEnd(context);
iterator.remove();
if (predicate.test(context.getAction())) {
cancelAndEnd(context);
iterator.remove();
}
}
} finally {
mCanModifyRunningActions = true;
}
}

Expand All @@ -163,12 +172,21 @@ public void cancelActionsIfWithoutFlag(ActionFlag flag) {
public void cancelAllActions() {
mMainThread.verifyCurrentThread();

if (!mCanModifyRunningActions) {
throw new IllegalStateException("cannot cancel actions in bulk while action modification is disabled");
}

mPendingActions.clear();

for (Iterator<RunningActionContext> iterator = mRunningActions.values().iterator(); iterator.hasNext();) {
RunningActionContext context = iterator.next();
cancelAndEnd(context);
iterator.remove();
mCanModifyRunningActions = false;
try {
for (Iterator<RunningActionContext> iterator = mRunningActions.values().iterator(); iterator.hasNext();) {
RunningActionContext context = iterator.next();
cancelAndEnd(context);
iterator.remove();
}
} finally {
mCanModifyRunningActions = true;
}
}

Expand Down Expand Up @@ -264,29 +282,38 @@ public ActionGroup newActionGroup(ActionGroupType type) {
}

private void executeTriggers() {
TriggerActionControllerImpl controller = new TriggerActionControllerImpl();
for (GenericTrigger trigger : mTriggers) {
trigger.update(controller);
}
// while in this method, calls to start and cancel methods cannot occur due
// to modifications of the collections.
// since this implementation is meant for single-thread, then such calls
// can only occur from within other actions.
mCanModifyRunningActions = false;
try {
TriggerActionControllerImpl controller = new TriggerActionControllerImpl();
for (GenericTrigger trigger : mTriggers) {
trigger.update(controller);
}

for (Action action : controller.getActionsToStopIfRunning()) {
if (isRunning(action)) {
cancel(action);
for (Action action : controller.getActionsToStopIfRunning()) {
if (isRunning(action)) {
cancel(action);
}
}
}

for (Action action : controller.getActionsToToggle()) {
if (!isRunning(action)) {
start(action);
} else {
cancel(action);
for (Action action : controller.getActionsToToggle()) {
if (!isRunning(action)) {
start(action);
} else {
cancel(action);
}
}
}

for (Action action : controller.getActionsToStartIfRunning()) {
if (!isRunning(action)) {
start(action);
for (Action action : controller.getActionsToStartIfRunning()) {
if (!isRunning(action)) {
start(action);
}
}
} finally {
mCanModifyRunningActions = true;
}
}

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
GROUP = com.flash3388.flashlib
VERSION = 3.2.3
VERSION = 3.2.4

NEXUS_SNAPSHOT_REPOSITORY_URL = https\://oss.sonatype.org/content/repositories/snapshots
NEXUS_RELEASE_REPOSITORY_URL = https\://oss.sonatype.org/service/local/staging/deploy/maven2
Expand Down

0 comments on commit 40ffa4f

Please sign in to comment.