mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[wpilib] Remove UserControls (#8973)
It was too complex, and we can solve it by figuring out how to make singleton GenericHID objects, implemented in #8970.
This commit is contained in:
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
package wpilib.robot;
|
package wpilib.robot;
|
||||||
|
|
||||||
import org.wpilib.driverstation.DefaultUserControls;
|
|
||||||
import org.wpilib.opmode.PeriodicOpMode;
|
import org.wpilib.opmode.PeriodicOpMode;
|
||||||
import org.wpilib.opmode.Teleop;
|
import org.wpilib.opmode.Teleop;
|
||||||
|
|
||||||
@@ -13,12 +12,8 @@ public class DefaultTeleMode extends PeriodicOpMode {
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private final OpRobot robot;
|
private final OpRobot robot;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
public DefaultTeleMode(OpRobot robot) {
|
||||||
private final DefaultUserControls userControls;
|
|
||||||
|
|
||||||
public DefaultTeleMode(OpRobot robot, DefaultUserControls userControls) {
|
|
||||||
this.robot = robot;
|
this.robot = robot;
|
||||||
this.userControls = userControls;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -4,12 +4,9 @@
|
|||||||
|
|
||||||
package wpilib.robot;
|
package wpilib.robot;
|
||||||
|
|
||||||
import org.wpilib.driverstation.DefaultUserControls;
|
|
||||||
import org.wpilib.driverstation.UserControlsInstance;
|
|
||||||
import org.wpilib.framework.OpModeRobot;
|
import org.wpilib.framework.OpModeRobot;
|
||||||
|
|
||||||
/** This is a dev program for testing OpModeRobot. */
|
/** This is a dev program for testing OpModeRobot. */
|
||||||
@UserControlsInstance(DefaultUserControls.class)
|
|
||||||
public class OpRobot extends OpModeRobot {
|
public class OpRobot extends OpModeRobot {
|
||||||
/** Called once at the beginning of the robot program. */
|
/** Called once at the beginning of the robot program. */
|
||||||
public OpRobot() {}
|
public OpRobot() {}
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
// 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 org.wpilib.driverstation;
|
|
||||||
|
|
||||||
import org.wpilib.driverstation.internal.DriverStationBackend;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A default implementation of UserControls that provides Gamepad instances for each of the 6
|
|
||||||
* joystick ports provided by the DS.
|
|
||||||
*/
|
|
||||||
public class DefaultUserControls implements UserControls {
|
|
||||||
private final Gamepad[] m_gamepads;
|
|
||||||
|
|
||||||
/** Constructs a DefaultUserControls instance with Gamepads for each port. */
|
|
||||||
public DefaultUserControls() {
|
|
||||||
m_gamepads = new Gamepad[DriverStationBackend.JOYSTICK_PORTS];
|
|
||||||
for (int i = 0; i < m_gamepads.length; i++) {
|
|
||||||
m_gamepads[i] = new Gamepad(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the Gamepad instance for the specified port.
|
|
||||||
*
|
|
||||||
* @param port The joystick port number.
|
|
||||||
* @return The Gamepad instance for the given port.
|
|
||||||
*/
|
|
||||||
public Gamepad getGamepad(int port) {
|
|
||||||
return m_gamepads[port];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
// 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 org.wpilib.driverstation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An interface representing user controls such as gamepads or joysticks. If your main robot class
|
|
||||||
* has a UserControlsInstance attribute with a class implementing this interface, the constructor is
|
|
||||||
* able to receive an instance of that class. Additionally, any OpModes can also receive that same
|
|
||||||
* instance.
|
|
||||||
*
|
|
||||||
* <p>The implementation of this class must have a default constructor
|
|
||||||
*/
|
|
||||||
public interface UserControls {}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
// 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 org.wpilib.driverstation;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An annotation to specify the UserControls implementation class to be used for a robot. Apply this
|
|
||||||
* annotation to your main robot class, providing a class that implements the UserControls
|
|
||||||
* interface.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
public @interface UserControlsInstance {
|
|
||||||
/**
|
|
||||||
* The UserControls implementation class to be used.
|
|
||||||
*
|
|
||||||
* @return The class that implements UserControls.
|
|
||||||
*/
|
|
||||||
Class<? extends UserControls> value();
|
|
||||||
}
|
|
||||||
@@ -24,8 +24,6 @@ import java.util.jar.JarFile;
|
|||||||
import org.wpilib.driverstation.Alert;
|
import org.wpilib.driverstation.Alert;
|
||||||
import org.wpilib.driverstation.DriverStationErrors;
|
import org.wpilib.driverstation.DriverStationErrors;
|
||||||
import org.wpilib.driverstation.RobotState;
|
import org.wpilib.driverstation.RobotState;
|
||||||
import org.wpilib.driverstation.UserControls;
|
|
||||||
import org.wpilib.driverstation.UserControlsInstance;
|
|
||||||
import org.wpilib.driverstation.internal.DriverStationBackend;
|
import org.wpilib.driverstation.internal.DriverStationBackend;
|
||||||
import org.wpilib.hardware.hal.ControlWord;
|
import org.wpilib.hardware.hal.ControlWord;
|
||||||
import org.wpilib.hardware.hal.DriverStationJNI;
|
import org.wpilib.hardware.hal.DriverStationJNI;
|
||||||
@@ -90,23 +88,6 @@ public abstract class OpModeRobot extends RobotBase {
|
|||||||
"Error adding OpMode " + cls.getSimpleName() + ": " + message, false);
|
"Error adding OpMode " + cls.getSimpleName() + ": " + message, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Optional<Class<? extends UserControls>> m_userControlsBaseClass;
|
|
||||||
private UserControls m_userControlsInstance;
|
|
||||||
|
|
||||||
void setUserControlsInstance(UserControls userControlsInstance) {
|
|
||||||
if (m_userControlsBaseClass.isEmpty()) {
|
|
||||||
throw new IllegalStateException("No UserControls class specified");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_userControlsBaseClass.get().isAssignableFrom(userControlsInstance.getClass())) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
userControlsInstance.getClass().getSimpleName()
|
|
||||||
+ " is not assignable to "
|
|
||||||
+ m_userControlsBaseClass.get().getSimpleName());
|
|
||||||
}
|
|
||||||
m_userControlsInstance = userControlsInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a public constructor to instantiate the opmode. This constructor can have up to 2
|
* Find a public constructor to instantiate the opmode. This constructor can have up to 2
|
||||||
* parameters. The first parameter (if present) must be assignable from this.getClass(). The
|
* parameters. The first parameter (if present) must be assignable from this.getClass(). The
|
||||||
@@ -116,28 +97,12 @@ public abstract class OpModeRobot extends RobotBase {
|
|||||||
private <T> Optional<ConstructorMatch<T>> findOpModeConstructor(Class<T> cls) {
|
private <T> Optional<ConstructorMatch<T>> findOpModeConstructor(Class<T> cls) {
|
||||||
Optional<ConstructorMatch<T>> ctor;
|
Optional<ConstructorMatch<T>> ctor;
|
||||||
|
|
||||||
// try 2-parameter constructor
|
|
||||||
if (m_userControlsBaseClass.isPresent()) {
|
|
||||||
ctor = ConstructorMatch.findBestConstructor(cls, getClass(), m_userControlsBaseClass.get());
|
|
||||||
if (ctor.isPresent()) {
|
|
||||||
return ctor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// try 1-parameter constructor with RobotBase parameter
|
// try 1-parameter constructor with RobotBase parameter
|
||||||
ctor = ConstructorMatch.findBestConstructor(cls, getClass());
|
ctor = ConstructorMatch.findBestConstructor(cls, getClass());
|
||||||
if (ctor.isPresent()) {
|
if (ctor.isPresent()) {
|
||||||
return ctor;
|
return ctor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// try 1-parameter constructor with UserControls parameter
|
|
||||||
if (m_userControlsBaseClass.isPresent()) {
|
|
||||||
ctor = ConstructorMatch.findBestConstructor(cls, m_userControlsBaseClass.get());
|
|
||||||
if (ctor.isPresent()) {
|
|
||||||
return ctor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// try no-parameter constructor
|
// try no-parameter constructor
|
||||||
ctor = ConstructorMatch.findBestConstructor(cls);
|
ctor = ConstructorMatch.findBestConstructor(cls);
|
||||||
return ctor;
|
return ctor;
|
||||||
@@ -151,11 +116,7 @@ public abstract class OpModeRobot extends RobotBase {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (m_userControlsInstance != null) {
|
return constructor.get().newInstance(this);
|
||||||
return constructor.get().newInstance(this, m_userControlsInstance);
|
|
||||||
} else {
|
|
||||||
return constructor.get().newInstance(this);
|
|
||||||
}
|
|
||||||
} catch (ReflectiveOperationException e) {
|
} catch (ReflectiveOperationException e) {
|
||||||
DriverStationErrors.reportError(
|
DriverStationErrors.reportError(
|
||||||
"Could not instantiate OpMode " + cls.getSimpleName(), e.getStackTrace());
|
"Could not instantiate OpMode " + cls.getSimpleName(), e.getStackTrace());
|
||||||
@@ -564,14 +525,6 @@ public abstract class OpModeRobot extends RobotBase {
|
|||||||
// Add LoopFunc as periodic callback (match C++)
|
// Add LoopFunc as periodic callback (match C++)
|
||||||
addPeriodic(this::loopFunc, period);
|
addPeriodic(this::loopFunc, period);
|
||||||
|
|
||||||
// Check to see if we have a DS annotation
|
|
||||||
UserControlsInstance userControlsAnnotation =
|
|
||||||
getClass().getAnnotation(UserControlsInstance.class);
|
|
||||||
if (userControlsAnnotation != null) {
|
|
||||||
m_userControlsBaseClass = Optional.of(userControlsAnnotation.value());
|
|
||||||
} else {
|
|
||||||
m_userControlsBaseClass = Optional.empty();
|
|
||||||
}
|
|
||||||
// Scan for annotated opmode classes within the derived class's package and subpackages
|
// Scan for annotated opmode classes within the derived class's package and subpackages
|
||||||
addAnnotatedOpModeClasses(getClass().getPackage());
|
addAnnotatedOpModeClasses(getClass().getPackage());
|
||||||
RobotState.publishOpModes();
|
RobotState.publishOpModes();
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ import java.util.Optional;
|
|||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import org.wpilib.driverstation.DriverStationErrors;
|
import org.wpilib.driverstation.DriverStationErrors;
|
||||||
import org.wpilib.driverstation.RobotState;
|
import org.wpilib.driverstation.RobotState;
|
||||||
import org.wpilib.driverstation.UserControls;
|
|
||||||
import org.wpilib.driverstation.UserControlsInstance;
|
|
||||||
import org.wpilib.driverstation.internal.DriverStationBackend;
|
import org.wpilib.driverstation.internal.DriverStationBackend;
|
||||||
import org.wpilib.hardware.hal.HAL;
|
import org.wpilib.hardware.hal.HAL;
|
||||||
import org.wpilib.hardware.hal.HALUtil;
|
import org.wpilib.hardware.hal.HALUtil;
|
||||||
@@ -291,32 +289,16 @@ public abstract class RobotBase implements AutoCloseable {
|
|||||||
private static boolean m_suppressExitWarning;
|
private static boolean m_suppressExitWarning;
|
||||||
|
|
||||||
private static <T extends RobotBase> T constructRobot(Class<T> robotClass) throws Throwable {
|
private static <T extends RobotBase> T constructRobot(Class<T> robotClass) throws Throwable {
|
||||||
UserControlsInstance userControlsAttribute =
|
Optional<ConstructorMatch<T>> constructorMatch =
|
||||||
robotClass.getDeclaredAnnotation(UserControlsInstance.class);
|
ConstructorMatch.findBestConstructor(robotClass);
|
||||||
UserControls userControlsInstance = null;
|
|
||||||
Optional<ConstructorMatch<T>> constructorMatch = Optional.empty();
|
|
||||||
if (userControlsAttribute != null) {
|
|
||||||
var userControlsClass = userControlsAttribute.value();
|
|
||||||
userControlsInstance = userControlsClass.getDeclaredConstructor().newInstance();
|
|
||||||
constructorMatch = ConstructorMatch.findBestConstructor(robotClass, userControlsClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (constructorMatch.isEmpty()) {
|
|
||||||
// Try to find a constructor with no parameters if there is no UserControls constructor
|
|
||||||
constructorMatch = ConstructorMatch.findBestConstructor(robotClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (constructorMatch.isEmpty()) {
|
if (constructorMatch.isEmpty()) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"No valid constructor found in robot class " + robotClass.getName());
|
"No valid constructor found in robot class " + robotClass.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
T robot = constructorMatch.get().newInstance(userControlsInstance);
|
T robot = constructorMatch.get().newInstance();
|
||||||
|
|
||||||
if (userControlsInstance != null && robot instanceof OpModeRobot opModeRobot) {
|
|
||||||
// Insert the UserControls instance into the opModeRobot for use when constructing opmodes
|
|
||||||
opModeRobot.setUserControlsInstance(userControlsInstance);
|
|
||||||
}
|
|
||||||
return robot;
|
return robot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,27 +4,28 @@
|
|||||||
|
|
||||||
package org.wpilib.examples.expansionhubsample;
|
package org.wpilib.examples.expansionhubsample;
|
||||||
|
|
||||||
import org.wpilib.driverstation.DefaultUserControls;
|
import org.wpilib.driverstation.DriverStation;
|
||||||
|
import org.wpilib.driverstation.Gamepad;
|
||||||
import org.wpilib.opmode.PeriodicOpMode;
|
import org.wpilib.opmode.PeriodicOpMode;
|
||||||
import org.wpilib.opmode.Teleop;
|
import org.wpilib.opmode.Teleop;
|
||||||
|
|
||||||
@Teleop
|
@Teleop
|
||||||
public class DefaultTeleMode extends PeriodicOpMode {
|
public class DefaultTeleMode extends PeriodicOpMode {
|
||||||
private final Robot robot;
|
private final Robot robot;
|
||||||
private final DefaultUserControls userControls;
|
private final Gamepad gamepad;
|
||||||
|
|
||||||
public DefaultTeleMode(Robot robot, DefaultUserControls userControls) {
|
public DefaultTeleMode(Robot robot) {
|
||||||
this.robot = robot;
|
this.robot = robot;
|
||||||
this.userControls = userControls;
|
this.gamepad = DriverStation.getGamepad(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void periodic() {
|
public void periodic() {
|
||||||
robot.motor0.setThrottle(-userControls.getGamepad(0).getLeftY());
|
robot.motor0.setThrottle(-gamepad.getLeftY());
|
||||||
robot.motor1.setThrottle(-userControls.getGamepad(0).getRightY());
|
robot.motor1.setThrottle(-gamepad.getRightY());
|
||||||
robot.motor2.setThrottle(-userControls.getGamepad(0).getLeftX());
|
robot.motor2.setThrottle(-gamepad.getLeftX());
|
||||||
robot.motor3.setThrottle(-userControls.getGamepad(0).getRightX());
|
robot.motor3.setThrottle(-gamepad.getRightX());
|
||||||
robot.servo0.setPosition(userControls.getGamepad(0).getLeftTriggerAxis());
|
robot.servo0.setPosition(gamepad.getLeftTriggerAxis());
|
||||||
robot.servo1.setPosition(userControls.getGamepad(0).getRightTriggerAxis());
|
robot.servo1.setPosition(gamepad.getRightTriggerAxis());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
package org.wpilib.examples.expansionhubsample;
|
package org.wpilib.examples.expansionhubsample;
|
||||||
|
|
||||||
import org.wpilib.driverstation.DefaultUserControls;
|
|
||||||
import org.wpilib.driverstation.UserControlsInstance;
|
|
||||||
import org.wpilib.framework.OpModeRobot;
|
import org.wpilib.framework.OpModeRobot;
|
||||||
import org.wpilib.hardware.expansionhub.ExpansionHubMotor;
|
import org.wpilib.hardware.expansionhub.ExpansionHubMotor;
|
||||||
import org.wpilib.hardware.expansionhub.ExpansionHubServo;
|
import org.wpilib.hardware.expansionhub.ExpansionHubServo;
|
||||||
@@ -14,7 +12,6 @@ import org.wpilib.hardware.expansionhub.ExpansionHubServo;
|
|||||||
* This is a demo program showing the use of the Expansion Hub motors and servos. The motors and
|
* This is a demo program showing the use of the Expansion Hub motors and servos. The motors and
|
||||||
* servos are driven using the controllers in the telop opmode, and timed in the auto op mode.
|
* servos are driven using the controllers in the telop opmode, and timed in the auto op mode.
|
||||||
*/
|
*/
|
||||||
@UserControlsInstance(DefaultUserControls.class)
|
|
||||||
public class Robot extends OpModeRobot {
|
public class Robot extends OpModeRobot {
|
||||||
public final ExpansionHubMotor motor0 = new ExpansionHubMotor(0, 0);
|
public final ExpansionHubMotor motor0 = new ExpansionHubMotor(0, 0);
|
||||||
public final ExpansionHubMotor motor1 = new ExpansionHubMotor(0, 1);
|
public final ExpansionHubMotor motor1 = new ExpansionHubMotor(0, 1);
|
||||||
|
|||||||
@@ -106,57 +106,17 @@ class ConstructorMatchTest {
|
|||||||
// Since this is built for opmodes, we're going to write tests that assume that
|
// Since this is built for opmodes, we're going to write tests that assume that
|
||||||
// scenario.
|
// scenario.
|
||||||
|
|
||||||
public interface UserControls {}
|
|
||||||
|
|
||||||
public static class DefaultUserControls implements UserControls {}
|
|
||||||
|
|
||||||
public static class CustomUserControls implements UserControls {}
|
|
||||||
|
|
||||||
public static class RobotBase {}
|
public static class RobotBase {}
|
||||||
|
|
||||||
public static class RobotWithNoUserControls extends RobotBase {}
|
public static class BasicRobot extends RobotBase {}
|
||||||
|
|
||||||
public static class RobotWithDefaultUserControls extends RobotBase {
|
public static class CustomRobot extends RobotBase {}
|
||||||
public RobotWithDefaultUserControls(DefaultUserControls controls) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testRobotWithDefaultUserControls() throws ReflectiveOperationException {
|
void testRobotNoArgs() throws ReflectiveOperationException {
|
||||||
var ctor =
|
var ctor = ConstructorMatch.findBestConstructor(BasicRobot.class);
|
||||||
ConstructorMatch.findBestConstructor(
|
|
||||||
RobotWithDefaultUserControls.class, DefaultUserControls.class);
|
|
||||||
assertTrue(ctor.isPresent());
|
assertTrue(ctor.isPresent());
|
||||||
ctor.get().newInstance(new DefaultUserControls());
|
ctor.get().newInstance();
|
||||||
assertThrows(
|
|
||||||
IllegalArgumentException.class, () -> ctor.get().newInstance(new CustomUserControls()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class RobotWithCustomUserControls extends RobotBase {
|
|
||||||
public RobotWithCustomUserControls(CustomUserControls controls) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRobotWithCustomUserControls() throws ReflectiveOperationException {
|
|
||||||
var ctor =
|
|
||||||
ConstructorMatch.findBestConstructor(
|
|
||||||
RobotWithCustomUserControls.class, CustomUserControls.class);
|
|
||||||
assertTrue(ctor.isPresent());
|
|
||||||
ctor.get().newInstance(new CustomUserControls());
|
|
||||||
assertThrows(
|
|
||||||
IllegalArgumentException.class, () -> ctor.get().newInstance(new DefaultUserControls()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class RobotWithUserControls extends RobotBase {
|
|
||||||
public RobotWithUserControls(UserControls controls) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRobotWithUserControls() throws ReflectiveOperationException {
|
|
||||||
var ctor =
|
|
||||||
ConstructorMatch.findBestConstructor(RobotWithUserControls.class, UserControls.class);
|
|
||||||
assertTrue(ctor.isPresent());
|
|
||||||
ctor.get().newInstance(new DefaultUserControls());
|
|
||||||
ctor.get().newInstance(new CustomUserControls());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class OpModeWithRobotBase {
|
public static class OpModeWithRobotBase {
|
||||||
@@ -167,108 +127,85 @@ class ConstructorMatchTest {
|
|||||||
void testOpModeWithRobotBase() throws ReflectiveOperationException {
|
void testOpModeWithRobotBase() throws ReflectiveOperationException {
|
||||||
var ctor = ConstructorMatch.findBestConstructor(OpModeWithRobotBase.class, RobotBase.class);
|
var ctor = ConstructorMatch.findBestConstructor(OpModeWithRobotBase.class, RobotBase.class);
|
||||||
assertTrue(ctor.isPresent());
|
assertTrue(ctor.isPresent());
|
||||||
var defaultUserControls = new DefaultUserControls();
|
ctor.get().newInstance(new RobotBase());
|
||||||
var customUserControls = new CustomUserControls();
|
ctor.get().newInstance(new BasicRobot());
|
||||||
ctor.get().newInstance(new RobotWithNoUserControls(), defaultUserControls);
|
ctor.get().newInstance(new CustomRobot());
|
||||||
ctor.get()
|
|
||||||
.newInstance(new RobotWithDefaultUserControls(defaultUserControls), defaultUserControls);
|
|
||||||
ctor.get().newInstance(new RobotWithCustomUserControls(customUserControls), customUserControls);
|
|
||||||
ctor.get().newInstance(new RobotWithUserControls(defaultUserControls), defaultUserControls);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class OpModeWithRobotWithNoUserControls {
|
public static class OpModeWithBasicRobot {
|
||||||
public OpModeWithRobotWithNoUserControls(RobotWithNoUserControls robot) {}
|
public OpModeWithBasicRobot(BasicRobot robot) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testOpModeWithRobotWithNoUserControls() throws ReflectiveOperationException {
|
void testOpModeWithBasicRobot() throws ReflectiveOperationException {
|
||||||
var ctor =
|
var ctor = ConstructorMatch.findBestConstructor(OpModeWithBasicRobot.class, BasicRobot.class);
|
||||||
ConstructorMatch.findBestConstructor(
|
|
||||||
OpModeWithRobotWithNoUserControls.class, RobotWithNoUserControls.class);
|
|
||||||
assertTrue(ctor.isPresent());
|
assertTrue(ctor.isPresent());
|
||||||
var defaultUserControls = new DefaultUserControls();
|
ctor.get().newInstance(new BasicRobot());
|
||||||
ctor.get().newInstance(new RobotWithNoUserControls(), defaultUserControls);
|
assertThrows(IllegalArgumentException.class, () -> ctor.get().newInstance(new RobotBase()));
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> ctor.get().newInstance(new CustomRobot()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class OpModeWithRobotWithDefaultUserControls {
|
public static class OpModeWithMultipleRobotConstructors {
|
||||||
public OpModeWithRobotWithDefaultUserControls(RobotWithDefaultUserControls robot) {}
|
public OpModeWithMultipleRobotConstructors(RobotBase robot) {}
|
||||||
|
|
||||||
public OpModeWithRobotWithDefaultUserControls(
|
public OpModeWithMultipleRobotConstructors(BasicRobot robot) {}
|
||||||
RobotWithDefaultUserControls robot, DefaultUserControls controls) {}
|
|
||||||
|
|
||||||
public OpModeWithRobotWithDefaultUserControls(DefaultUserControls controls) {}
|
public OpModeWithMultipleRobotConstructors() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testOpModeWithRobotWithDefaultUserControlsRobotArg() throws ReflectiveOperationException {
|
void testOpModeWithMultipleRobotConstructorsRobotArg() throws ReflectiveOperationException {
|
||||||
var ctor =
|
var ctor =
|
||||||
ConstructorMatch.findBestConstructor(
|
ConstructorMatch.findBestConstructor(
|
||||||
OpModeWithRobotWithDefaultUserControls.class, RobotWithDefaultUserControls.class);
|
OpModeWithMultipleRobotConstructors.class, BasicRobot.class);
|
||||||
assertTrue(ctor.isPresent());
|
assertTrue(ctor.isPresent());
|
||||||
var defaultUserControls = new DefaultUserControls();
|
var parameterTypes = ctor.get().getParameterTypes();
|
||||||
ctor.get()
|
assertEquals(BasicRobot.class, parameterTypes.get(0));
|
||||||
.newInstance(new RobotWithDefaultUserControls(defaultUserControls), defaultUserControls);
|
ctor.get().newInstance(new BasicRobot());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testOpModeWithRobotWithDefaultUserControlsControlsArg() throws ReflectiveOperationException {
|
void testOpModeWithMultipleRobotConstructorsNoArgs() throws ReflectiveOperationException {
|
||||||
var ctor =
|
var ctor = ConstructorMatch.findBestConstructor(OpModeWithMultipleRobotConstructors.class);
|
||||||
ConstructorMatch.findBestConstructor(
|
|
||||||
OpModeWithRobotWithDefaultUserControls.class, DefaultUserControls.class);
|
|
||||||
assertTrue(ctor.isPresent());
|
assertTrue(ctor.isPresent());
|
||||||
var defaultUserControls = new DefaultUserControls();
|
ctor.get().newInstance();
|
||||||
ctor.get()
|
|
||||||
.newInstance(new RobotWithDefaultUserControls(defaultUserControls), defaultUserControls);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
public static class ModeBase {}
|
||||||
void testOpModeWithRobotWithDefaultUserControlsNoArgs() throws ReflectiveOperationException {
|
|
||||||
var ctor =
|
public static class DefaultMode extends ModeBase {}
|
||||||
ConstructorMatch.findBestConstructor(
|
|
||||||
OpModeWithRobotWithDefaultUserControls.class,
|
|
||||||
RobotWithDefaultUserControls.class,
|
|
||||||
DefaultUserControls.class);
|
|
||||||
assertTrue(ctor.isPresent());
|
|
||||||
var defaultUserControls = new DefaultUserControls();
|
|
||||||
ctor.get()
|
|
||||||
.newInstance(new RobotWithDefaultUserControls(defaultUserControls), defaultUserControls);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class MostSpecificFirstArg {
|
public static class MostSpecificFirstArg {
|
||||||
public MostSpecificFirstArg(RobotBase robot, DefaultUserControls controls) {}
|
public MostSpecificFirstArg(RobotBase robot, DefaultMode mode) {}
|
||||||
|
|
||||||
public MostSpecificFirstArg(RobotWithDefaultUserControls robot, UserControls controls) {}
|
public MostSpecificFirstArg(BasicRobot robot, ModeBase mode) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testMostSpecificFirstArg() throws ReflectiveOperationException {
|
void testMostSpecificFirstArg() throws ReflectiveOperationException {
|
||||||
var ctor =
|
var ctor =
|
||||||
ConstructorMatch.findBestConstructor(
|
ConstructorMatch.findBestConstructor(
|
||||||
MostSpecificFirstArg.class,
|
MostSpecificFirstArg.class, BasicRobot.class, DefaultMode.class);
|
||||||
RobotWithDefaultUserControls.class,
|
|
||||||
DefaultUserControls.class);
|
|
||||||
assertTrue(ctor.isPresent());
|
assertTrue(ctor.isPresent());
|
||||||
var parameterTypes = ctor.get().getParameterTypes();
|
var parameterTypes = ctor.get().getParameterTypes();
|
||||||
assertEquals(RobotWithDefaultUserControls.class, parameterTypes.get(0));
|
assertEquals(BasicRobot.class, parameterTypes.get(0));
|
||||||
assertEquals(UserControls.class, parameterTypes.get(1));
|
assertEquals(ModeBase.class, parameterTypes.get(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MostSpecificSecondArg {
|
public static class MostSpecificSecondArg {
|
||||||
public MostSpecificSecondArg(RobotBase robot, DefaultUserControls controls) {}
|
public MostSpecificSecondArg(RobotBase robot, DefaultMode mode) {}
|
||||||
|
|
||||||
public MostSpecificSecondArg(RobotBase robot, UserControls controls) {}
|
public MostSpecificSecondArg(RobotBase robot, ModeBase mode) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testMostSpecificSecondArg() throws ReflectiveOperationException {
|
void testMostSpecificSecondArg() throws ReflectiveOperationException {
|
||||||
var ctor =
|
var ctor =
|
||||||
ConstructorMatch.findBestConstructor(
|
ConstructorMatch.findBestConstructor(
|
||||||
MostSpecificSecondArg.class,
|
MostSpecificSecondArg.class, BasicRobot.class, DefaultMode.class);
|
||||||
RobotWithDefaultUserControls.class,
|
|
||||||
DefaultUserControls.class);
|
|
||||||
assertTrue(ctor.isPresent());
|
assertTrue(ctor.isPresent());
|
||||||
var parameterTypes = ctor.get().getParameterTypes();
|
var parameterTypes = ctor.get().getParameterTypes();
|
||||||
assertEquals(RobotBase.class, parameterTypes.get(0));
|
assertEquals(RobotBase.class, parameterTypes.get(0));
|
||||||
assertEquals(DefaultUserControls.class, parameterTypes.get(1));
|
assertEquals(DefaultMode.class, parameterTypes.get(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user