From 951c81f5b7381b329a7b4395d56d217a0be32531 Mon Sep 17 00:00:00 2001 From: Thad House Date: Thu, 24 Dec 2015 21:10:47 -0800 Subject: [PATCH] Adds WaitResult to Java waitForInterrupt WaitResult gets returned from C++ and the JNI, so should probably be returned in Java as well. Adds WaitResult tests to Java AbstractInterruptTest Change-Id: Ic3cb2919652696c458c39006b2f716301c0736f4 --- .../wpilibj/InterruptableSensorBase.java | 33 +++++++++-- .../first/wpilibj/AbstractInterruptTest.java | 56 +++++++++++++++++++ 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/InterruptableSensorBase.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/InterruptableSensorBase.java index 744e59f1f0..d7a5012df2 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/InterruptableSensorBase.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/InterruptableSensorBase.java @@ -15,6 +15,27 @@ import edu.wpi.first.wpilibj.util.CheckedAllocationException; * Base for sensors to be used with interrupts */ public abstract class InterruptableSensorBase extends SensorBase { + + public static enum WaitResult { + kTimeout(0x0), kRisingEdge(0x1), kFallingEdge(0x100), kBoth(0x101); + + public final int value; + + public static WaitResult valueOf(int value) { + for (WaitResult mode : values()) { + if (mode.value == value) { + return mode; + } + } + return null; + } + + + private WaitResult(int value) { + this.value = value; + } + } + /** * The interrupt resource */ @@ -141,21 +162,25 @@ public abstract class InterruptableSensorBase extends SensorBase { * @param timeout Timeout in seconds * @param ignorePrevious If true, ignore interrupts that happened before * waitForInterrupt was called. + * @return Result of the wait. */ - public void waitForInterrupt(double timeout, boolean ignorePrevious) { + public WaitResult waitForInterrupt(double timeout, boolean ignorePrevious) { if (m_interrupt == 0) { throw new IllegalStateException("The interrupt is not allocated."); } - InterruptJNI.waitForInterrupt(m_interrupt, timeout, ignorePrevious); + int result = InterruptJNI.waitForInterrupt(m_interrupt, timeout, ignorePrevious); + + return WaitResult.valueOf(result); } /** * In synchronous mode, wait for the defined interrupt to occur. * * @param timeout Timeout in seconds + * @return Result of the wait. */ - public void waitForInterrupt(double timeout) { - waitForInterrupt(timeout, true); + public WaitResult waitForInterrupt(double timeout) { + return waitForInterrupt(timeout, true); } /** diff --git a/wpilibjIntegrationTests/src/main/java/edu/wpi/first/wpilibj/AbstractInterruptTest.java b/wpilibjIntegrationTests/src/main/java/edu/wpi/first/wpilibj/AbstractInterruptTest.java index 2ca2931767..4115d705ed 100644 --- a/wpilibjIntegrationTests/src/main/java/edu/wpi/first/wpilibj/AbstractInterruptTest.java +++ b/wpilibjIntegrationTests/src/main/java/edu/wpi/first/wpilibj/AbstractInterruptTest.java @@ -218,6 +218,62 @@ public abstract class AbstractInterruptTest extends AbstractComsSetup { synchronousDelay, interruptRunTime, .1); } + @Test(timeout = (long) (synchronousTimeout * 1e3)) + public void testSynchronousInterruptsWaitResultTimeout() { + // Given + getInterruptable().requestInterrupts(); + + //Don't fire interrupt. Expect it to timeout. + InterruptableSensorBase.WaitResult result = getInterruptable().waitForInterrupt(synchronousTimeout / 2); + + assertEquals("The interrupt did not time out correctly.", result, InterruptableSensorBase.WaitResult.kTimeout); + } + + @Test(timeout = (long) (synchronousTimeout * 1e3)) + public void testSynchronousInterruptsWaitResultRisingEdge() { + // Given + getInterruptable().requestInterrupts(); + + final double synchronousDelay = synchronousTimeout / 2.; + Runnable r = new Runnable() { + @Override + public void run() { + Timer.delay(synchronousDelay); + setInterruptLow(); + setInterruptHigh(); + } + }; + + new Thread(r).start(); + // Delay for twice as long as the timeout so the test should fail first + InterruptableSensorBase.WaitResult result = getInterruptable().waitForInterrupt(synchronousTimeout * 2); + + assertEquals("The interrupt did not fire on the rising edge.", result, InterruptableSensorBase.WaitResult.kRisingEdge); + } + + @Test(timeout = (long) (synchronousTimeout * 1e3)) + public void testSynchronousInterruptsWaitResultFallingEdge() { + // Given + getInterruptable().requestInterrupts(); + getInterruptable().setUpSourceEdge(false, true); + + final double synchronousDelay = synchronousTimeout / 2.; + Runnable r = new Runnable() { + @Override + public void run() { + Timer.delay(synchronousDelay); + setInterruptHigh(); + setInterruptLow(); + } + }; + + new Thread(r).start(); + // Delay for twice as long as the timeout so the test should fail first + InterruptableSensorBase.WaitResult result = getInterruptable().waitForInterrupt(synchronousTimeout * 2); + + assertEquals("The interrupt did not fire on the falling edge.", result, InterruptableSensorBase.WaitResult.kFallingEdge); + } + @Test(timeout = 4000) public void testDisableStopsInterruptFiring() {