mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-21 01:01:43 +00:00
[hal, wpilib] Switch PCM to be a single object that is allowed to be duplicated (#3475)
Having PCM as a singleton is a problem, as multiple things need to use it, and that gets really ugly. This changes PCM's to be a reference counted object, that can be passed around and constructed from multiple places. In Java, this is using a map to hold a data store with a ref count, and allocating new objects any time a duplicate is requested. In C++, this uses a trick constructor to store a PCM instance in the data store itself. This instance can then be passed to base objects using std::shared_ptr's aliasing constructor, which means constructing a solenoid from a PCM is not allocating after the 1st one. This did require removing sendable from PCM. A compressor class was added back in to act as sendable for the PCM. After this change is finished, the only change RobotBuilder and Team Code would require is passing a module type to solenoid constructors. Co-authored-by: sciencewhiz <sciencewhiz@users.noreply.github.com>
This commit is contained in:
@@ -13,8 +13,7 @@ import org.junit.jupiter.api.Test;
|
||||
public class DoubleSolenoidTest {
|
||||
@Test
|
||||
void testValidInitialization() {
|
||||
try (PneumaticsControlModule pcm = new PneumaticsControlModule(3);
|
||||
DoubleSolenoid solenoid = new DoubleSolenoid(pcm, 2, 3)) {
|
||||
try (DoubleSolenoid solenoid = new DoubleSolenoid(3, PneumaticsModuleType.CTREPCM, 2, 3)) {
|
||||
solenoid.set(DoubleSolenoid.Value.kReverse);
|
||||
assertEquals(DoubleSolenoid.Value.kReverse, solenoid.get());
|
||||
|
||||
@@ -28,36 +27,41 @@ public class DoubleSolenoidTest {
|
||||
|
||||
@Test
|
||||
void testThrowForwardPortAlreadyInitialized() {
|
||||
try (PneumaticsControlModule pcm = new PneumaticsControlModule(5);
|
||||
// Single solenoid that is reused for forward port
|
||||
Solenoid solenoid = new Solenoid(pcm, 2)) {
|
||||
assertThrows(AllocationException.class, () -> new DoubleSolenoid(pcm, 2, 3));
|
||||
try (
|
||||
// Single solenoid that is reused for forward port
|
||||
Solenoid solenoid = new Solenoid(5, PneumaticsModuleType.CTREPCM, 2)) {
|
||||
assertThrows(
|
||||
AllocationException.class,
|
||||
() -> new DoubleSolenoid(5, PneumaticsModuleType.CTREPCM, 2, 3));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testThrowReversePortAlreadyInitialized() {
|
||||
try (PneumaticsControlModule pcm = new PneumaticsControlModule(6);
|
||||
// Single solenoid that is reused for forward port
|
||||
Solenoid solenoid = new Solenoid(pcm, 3)) {
|
||||
assertThrows(AllocationException.class, () -> new DoubleSolenoid(pcm, 2, 3));
|
||||
try (
|
||||
// Single solenoid that is reused for forward port
|
||||
Solenoid solenoid = new Solenoid(6, PneumaticsModuleType.CTREPCM, 3)) {
|
||||
assertThrows(
|
||||
AllocationException.class,
|
||||
() -> new DoubleSolenoid(6, PneumaticsModuleType.CTREPCM, 2, 3));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testThrowBothPortsAlreadyInitialized() {
|
||||
try (PneumaticsControlModule pcm = new PneumaticsControlModule(6);
|
||||
// Single solenoid that is reused for forward port
|
||||
Solenoid solenoid0 = new Solenoid(pcm, 2);
|
||||
Solenoid solenoid1 = new Solenoid(pcm, 3)) {
|
||||
assertThrows(AllocationException.class, () -> new DoubleSolenoid(pcm, 2, 3));
|
||||
try (
|
||||
// Single solenoid that is reused for forward port
|
||||
Solenoid solenoid0 = new Solenoid(6, PneumaticsModuleType.CTREPCM, 2);
|
||||
Solenoid solenoid1 = new Solenoid(6, PneumaticsModuleType.CTREPCM, 3)) {
|
||||
assertThrows(
|
||||
AllocationException.class,
|
||||
() -> new DoubleSolenoid(6, PneumaticsModuleType.CTREPCM, 2, 3));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToggle() {
|
||||
try (PneumaticsControlModule pcm = new PneumaticsControlModule(4);
|
||||
DoubleSolenoid solenoid = new DoubleSolenoid(pcm, 2, 3)) {
|
||||
try (DoubleSolenoid solenoid = new DoubleSolenoid(4, PneumaticsModuleType.CTREPCM, 2, 3)) {
|
||||
// Bootstrap it into reverse
|
||||
solenoid.set(DoubleSolenoid.Value.kReverse);
|
||||
|
||||
@@ -76,15 +80,15 @@ public class DoubleSolenoidTest {
|
||||
|
||||
@Test
|
||||
void testInvalidForwardPort() {
|
||||
try (PneumaticsControlModule pcm = new PneumaticsControlModule(0)) {
|
||||
assertThrows(IllegalArgumentException.class, () -> new DoubleSolenoid(pcm, 100, 1));
|
||||
}
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> new DoubleSolenoid(0, PneumaticsModuleType.CTREPCM, 100, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInvalidReversePort() {
|
||||
try (PneumaticsControlModule pcm = new PneumaticsControlModule(0)) {
|
||||
assertThrows(IllegalArgumentException.class, () -> new DoubleSolenoid(pcm, 0, 100));
|
||||
}
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> new DoubleSolenoid(0, PneumaticsModuleType.CTREPCM, 0, 100));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,7 @@ import org.junit.jupiter.api.Test;
|
||||
public class SolenoidTest {
|
||||
@Test
|
||||
void testValidInitialization() {
|
||||
try (PneumaticsControlModule pcm = new PneumaticsControlModule(3);
|
||||
Solenoid solenoid = new Solenoid(pcm, 2)) {
|
||||
try (Solenoid solenoid = new Solenoid(3, PneumaticsModuleType.CTREPCM, 2)) {
|
||||
assertEquals(2, solenoid.getChannel());
|
||||
|
||||
solenoid.set(true);
|
||||
@@ -29,31 +28,29 @@ public class SolenoidTest {
|
||||
|
||||
@Test
|
||||
void testDoubleInitialization() {
|
||||
try (PneumaticsControlModule pcm = new PneumaticsControlModule(3);
|
||||
Solenoid solenoid = new Solenoid(pcm, 2)) {
|
||||
assertThrows(AllocationException.class, () -> new Solenoid(pcm, 2));
|
||||
try (Solenoid solenoid = new Solenoid(3, PneumaticsModuleType.CTREPCM, 2)) {
|
||||
assertThrows(
|
||||
AllocationException.class, () -> new Solenoid(3, PneumaticsModuleType.CTREPCM, 2));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDoubleInitializationFromDoubleSolenoid() {
|
||||
try (PneumaticsControlModule pcm = new PneumaticsControlModule(3);
|
||||
DoubleSolenoid solenoid = new DoubleSolenoid(pcm, 2, 3)) {
|
||||
assertThrows(AllocationException.class, () -> new Solenoid(pcm, 2));
|
||||
try (DoubleSolenoid solenoid = new DoubleSolenoid(3, PneumaticsModuleType.CTREPCM, 2, 3)) {
|
||||
assertThrows(
|
||||
AllocationException.class, () -> new Solenoid(3, PneumaticsModuleType.CTREPCM, 2));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInvalidChannel() {
|
||||
try (PneumaticsControlModule pcm = new PneumaticsControlModule(3)) {
|
||||
assertThrows(IllegalArgumentException.class, () -> new Solenoid(pcm, 100));
|
||||
}
|
||||
assertThrows(
|
||||
IllegalArgumentException.class, () -> new Solenoid(3, PneumaticsModuleType.CTREPCM, 100));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToggle() {
|
||||
try (PneumaticsControlModule pcm = new PneumaticsControlModule(3);
|
||||
Solenoid solenoid = new Solenoid(pcm, 2)) {
|
||||
try (Solenoid solenoid = new Solenoid(3, PneumaticsModuleType.CTREPCM, 2)) {
|
||||
solenoid.set(true);
|
||||
assertTrue(solenoid.get());
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import edu.wpi.first.hal.HAL;
|
||||
import edu.wpi.first.wpilibj.DoubleSolenoid;
|
||||
import edu.wpi.first.wpilibj.PneumaticsControlModule;
|
||||
import edu.wpi.first.wpilibj.PneumaticsModuleType;
|
||||
import edu.wpi.first.wpilibj.simulation.testutils.BooleanCallback;
|
||||
import edu.wpi.first.wpilibj.simulation.testutils.DoubleCallback;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -32,6 +33,7 @@ class CTREPCMSimTest {
|
||||
PneumaticsControlModule pcm = new PneumaticsControlModule(0)) {
|
||||
assertTrue(sim.getInitialized());
|
||||
}
|
||||
assertFalse(sim.getInitialized());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -39,8 +41,8 @@ class CTREPCMSimTest {
|
||||
HAL.initialize(500, 0);
|
||||
|
||||
try (PneumaticsControlModule pcm = new PneumaticsControlModule(0);
|
||||
DoubleSolenoid doubleSolenoid = new DoubleSolenoid(pcm, 3, 4)) {
|
||||
CTREPCMSim sim = new CTREPCMSim(pcm);
|
||||
DoubleSolenoid doubleSolenoid = new DoubleSolenoid(0, PneumaticsModuleType.CTREPCM, 3, 4)) {
|
||||
CTREPCMSim sim = new CTREPCMSim(0);
|
||||
sim.resetData();
|
||||
|
||||
BooleanCallback callback3 = new BooleanCallback();
|
||||
@@ -75,11 +77,14 @@ class CTREPCMSimTest {
|
||||
// Off
|
||||
callback3.reset();
|
||||
callback4.reset();
|
||||
doubleSolenoid.set(DoubleSolenoid.Value.kForward);
|
||||
assertFalse(callback3.wasTriggered());
|
||||
assertNull(callback3.getSetValue());
|
||||
doubleSolenoid.set(DoubleSolenoid.Value.kOff);
|
||||
assertTrue(callback3.wasTriggered());
|
||||
assertFalse(callback3.getSetValue());
|
||||
assertFalse(callback4.wasTriggered());
|
||||
assertNull(callback4.getSetValue());
|
||||
assertFalse(sim.getSolenoidOutput(3));
|
||||
assertFalse(sim.getSolenoidOutput(4));
|
||||
assertEquals(0x0, pcm.getSolenoids());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user