mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-24 01:31:46 +00:00
[wpilib] Add EventLoop (#4104)
This is a generic expansion of the command-based Trigger framework.
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.wpilibj.event;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class BooleanEventTest {
|
||||
@Test
|
||||
void testBinaryCompositions() {
|
||||
var loop = new EventLoop();
|
||||
|
||||
var andCounter = new AtomicInteger(0);
|
||||
var orCounter = new AtomicInteger(0);
|
||||
|
||||
assertEquals(0, andCounter.get());
|
||||
assertEquals(0, orCounter.get());
|
||||
|
||||
new BooleanEvent(loop, () -> true).and(() -> false).ifHigh(andCounter::incrementAndGet);
|
||||
new BooleanEvent(loop, () -> true).or(() -> false).ifHigh(orCounter::incrementAndGet);
|
||||
|
||||
loop.poll();
|
||||
|
||||
assertEquals(0, andCounter.get());
|
||||
assertEquals(1, orCounter.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBinaryCompositionLoopSemantics() {
|
||||
var loop1 = new EventLoop();
|
||||
var loop2 = new EventLoop();
|
||||
|
||||
var counter1 = new AtomicInteger(0);
|
||||
var counter2 = new AtomicInteger(0);
|
||||
|
||||
new BooleanEvent(loop1, () -> true)
|
||||
.and(new BooleanEvent(loop2, () -> true))
|
||||
.ifHigh(counter1::incrementAndGet);
|
||||
|
||||
new BooleanEvent(loop2, () -> true)
|
||||
.and(new BooleanEvent(loop1, () -> true))
|
||||
.ifHigh(counter2::incrementAndGet);
|
||||
|
||||
assertEquals(0, counter1.get());
|
||||
assertEquals(0, counter2.get());
|
||||
|
||||
loop1.poll();
|
||||
|
||||
assertEquals(1, counter1.get());
|
||||
assertEquals(0, counter2.get());
|
||||
|
||||
loop2.poll();
|
||||
|
||||
assertEquals(1, counter1.get());
|
||||
assertEquals(1, counter2.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEdgeDecorators() {
|
||||
var bool = new AtomicBoolean(false);
|
||||
var counter = new AtomicInteger(0);
|
||||
|
||||
var loop = new EventLoop();
|
||||
|
||||
new BooleanEvent(loop, bool::get).falling().ifHigh(counter::decrementAndGet);
|
||||
new BooleanEvent(loop, bool::get).rising().ifHigh(counter::incrementAndGet);
|
||||
|
||||
assertEquals(0, counter.get());
|
||||
|
||||
bool.set(false);
|
||||
loop.poll();
|
||||
|
||||
assertEquals(0, counter.get());
|
||||
|
||||
bool.set(true);
|
||||
loop.poll();
|
||||
|
||||
assertEquals(1, counter.get());
|
||||
|
||||
bool.set(true);
|
||||
loop.poll();
|
||||
|
||||
assertEquals(1, counter.get());
|
||||
|
||||
bool.set(false);
|
||||
loop.poll();
|
||||
|
||||
assertEquals(0, counter.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEdgeReuse() {
|
||||
var loop = new EventLoop();
|
||||
var bool = new AtomicBoolean(false);
|
||||
var counter = new AtomicInteger(0);
|
||||
|
||||
var event = new BooleanEvent(loop, bool::get).rising();
|
||||
event.ifHigh(counter::incrementAndGet);
|
||||
event.ifHigh(counter::incrementAndGet);
|
||||
|
||||
assertEquals(0, counter.get());
|
||||
|
||||
loop.poll();
|
||||
|
||||
assertEquals(0, counter.get());
|
||||
|
||||
bool.set(true);
|
||||
loop.poll();
|
||||
|
||||
assertEquals(1, counter.get()); // FIXME?: natural sense dictates counter == 2!!
|
||||
|
||||
loop.poll();
|
||||
|
||||
assertEquals(1, counter.get());
|
||||
|
||||
bool.set(false);
|
||||
loop.poll();
|
||||
|
||||
assertEquals(1, counter.get());
|
||||
|
||||
bool.set(true);
|
||||
loop.poll();
|
||||
|
||||
assertEquals(2, counter.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEdgeReconstruct() {
|
||||
var loop = new EventLoop();
|
||||
var bool = new AtomicBoolean(false);
|
||||
var counter = new AtomicInteger(0);
|
||||
|
||||
var event = new BooleanEvent(loop, bool::get);
|
||||
event.rising().ifHigh(counter::incrementAndGet);
|
||||
event.rising().ifHigh(counter::incrementAndGet);
|
||||
|
||||
assertEquals(0, counter.get());
|
||||
|
||||
loop.poll();
|
||||
|
||||
assertEquals(0, counter.get());
|
||||
|
||||
bool.set(true);
|
||||
loop.poll();
|
||||
|
||||
// unlike the previous test ...
|
||||
assertEquals(2, counter.get()); // as natural sense dictates, counter == 2
|
||||
|
||||
loop.poll();
|
||||
|
||||
assertEquals(2, counter.get());
|
||||
|
||||
bool.set(false);
|
||||
loop.poll();
|
||||
|
||||
assertEquals(2, counter.get());
|
||||
|
||||
bool.set(true);
|
||||
loop.poll();
|
||||
|
||||
assertEquals(4, counter.get());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.wpilibj.event;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class EventLoopTest {
|
||||
@Test
|
||||
void testConditions() {
|
||||
var counterTrue = new AtomicInteger(0);
|
||||
var counterFalse = new AtomicInteger(0);
|
||||
var loop = new EventLoop();
|
||||
loop.bind(() -> true, counterTrue::incrementAndGet);
|
||||
loop.bind(() -> false, counterFalse::incrementAndGet);
|
||||
|
||||
assertEquals(0, counterTrue.get());
|
||||
assertEquals(0, counterFalse.get());
|
||||
|
||||
loop.poll();
|
||||
|
||||
assertEquals(1, counterTrue.get());
|
||||
assertEquals(0, counterFalse.get());
|
||||
|
||||
loop.poll();
|
||||
|
||||
assertEquals(2, counterTrue.get());
|
||||
assertEquals(0, counterFalse.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testClear() {
|
||||
var condition = new AtomicBoolean(false);
|
||||
var counter = new AtomicInteger(0);
|
||||
var loop = new EventLoop();
|
||||
|
||||
// first ensure binding works
|
||||
loop.bind(condition::get, counter::incrementAndGet);
|
||||
|
||||
condition.set(false);
|
||||
loop.poll();
|
||||
assertEquals(0, counter.get());
|
||||
|
||||
condition.set(true);
|
||||
loop.poll();
|
||||
assertEquals(1, counter.get());
|
||||
|
||||
// clear bindings
|
||||
loop.clear();
|
||||
|
||||
condition.set(true);
|
||||
loop.poll();
|
||||
// shouldn't change
|
||||
assertEquals(1, counter.get());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user