mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[wpilib] Fix OpModeRobot initialization (#8834)
There were 3 cases failing before. 1. An OpModeRobot with no annotation. 2. An OpModeRobot with an annotation but a parameterless constructor. 3. An OpMode with a UserControls constructor This PR solves both of these issues. The first one is solved by adding the null check before setting the user controls instance. That one will never have an opmode instance. The second one is solved by falling back to a parameterless constructor if one with a parameter is not found. The 3rd one is solved by using the annotation type rather than the instance for constructor lookup. Also fixes ExpansionHubSample's missing annotations.
This commit is contained in:
@@ -115,9 +115,8 @@ public abstract class OpModeRobot extends RobotBase {
|
||||
Optional<ConstructorMatch<T>> ctor;
|
||||
|
||||
// try 2-parameter constructor
|
||||
if (m_userControlsInstance != null) {
|
||||
ctor =
|
||||
ConstructorMatch.findBestConstructor(cls, getClass(), m_userControlsInstance.getClass());
|
||||
if (m_userControlsBaseClass.isPresent()) {
|
||||
ctor = ConstructorMatch.findBestConstructor(cls, getClass(), m_userControlsBaseClass.get());
|
||||
if (ctor.isPresent()) {
|
||||
return ctor;
|
||||
}
|
||||
@@ -130,8 +129,8 @@ public abstract class OpModeRobot extends RobotBase {
|
||||
}
|
||||
|
||||
// try 1-parameter constructor with UserControls parameter
|
||||
if (m_userControlsInstance != null) {
|
||||
ctor = ConstructorMatch.findBestConstructor(cls, m_userControlsInstance.getClass());
|
||||
if (m_userControlsBaseClass.isPresent()) {
|
||||
ctor = ConstructorMatch.findBestConstructor(cls, m_userControlsBaseClass.get());
|
||||
if (ctor.isPresent()) {
|
||||
return ctor;
|
||||
}
|
||||
|
||||
@@ -294,12 +294,15 @@ public abstract class RobotBase implements AutoCloseable {
|
||||
UserControlsInstance userControlsAttribute =
|
||||
robotClass.getDeclaredAnnotation(UserControlsInstance.class);
|
||||
UserControls userControlsInstance = null;
|
||||
Optional<ConstructorMatch<T>> constructorMatch;
|
||||
Optional<ConstructorMatch<T>> constructorMatch = Optional.empty();
|
||||
if (userControlsAttribute != null) {
|
||||
var userControlsClass = userControlsAttribute.value();
|
||||
userControlsInstance = userControlsClass.getDeclaredConstructor().newInstance();
|
||||
constructorMatch = ConstructorMatch.findBestConstructor(robotClass, userControlsClass);
|
||||
} else {
|
||||
}
|
||||
|
||||
if (constructorMatch.isEmpty()) {
|
||||
// Try to find a constructor with no parameters if there is no UserControls constructor
|
||||
constructorMatch = ConstructorMatch.findBestConstructor(robotClass);
|
||||
}
|
||||
|
||||
@@ -310,7 +313,7 @@ public abstract class RobotBase implements AutoCloseable {
|
||||
|
||||
T robot = constructorMatch.get().newInstance(userControlsInstance);
|
||||
|
||||
if (robot instanceof OpModeRobot opModeRobot) {
|
||||
if (userControlsInstance != null && robot instanceof OpModeRobot opModeRobot) {
|
||||
// Insert the UserControls instance into the opModeRobot for use when constructing opmodes
|
||||
opModeRobot.setUserControlsInstance(userControlsInstance);
|
||||
}
|
||||
|
||||
@@ -47,6 +47,16 @@ eclipse {
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(JavaExec).configureEach {
|
||||
// Commands v3 needs reflective access to the continuation classes
|
||||
jvmArgs += [
|
||||
'--add-opens',
|
||||
'java.base/jdk.internal.vm=ALL-UNNAMED',
|
||||
'--add-opens',
|
||||
'java.base/java.lang=ALL-UNNAMED',
|
||||
]
|
||||
}
|
||||
|
||||
jacoco {
|
||||
toolVersion = "0.8.14"
|
||||
}
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
|
||||
package org.wpilib.examples.expansionhubsample;
|
||||
|
||||
import org.wpilib.opmode.Autonomous;
|
||||
import org.wpilib.opmode.PeriodicOpMode;
|
||||
import org.wpilib.system.Timer;
|
||||
|
||||
@Autonomous
|
||||
public class DefaultAutoMode extends PeriodicOpMode {
|
||||
private final Robot robot;
|
||||
private final Timer timer = new Timer();
|
||||
|
||||
@@ -6,7 +6,9 @@ package org.wpilib.examples.expansionhubsample;
|
||||
|
||||
import org.wpilib.driverstation.DefaultUserControls;
|
||||
import org.wpilib.opmode.PeriodicOpMode;
|
||||
import org.wpilib.opmode.Teleop;
|
||||
|
||||
@Teleop
|
||||
public class DefaultTeleMode extends PeriodicOpMode {
|
||||
private final Robot robot;
|
||||
private final DefaultUserControls userControls;
|
||||
|
||||
@@ -57,8 +57,8 @@ public class ConstructorMatch<T> {
|
||||
/**
|
||||
* Creates a new instance of the constructor's class using the given arguments. The arguments must
|
||||
* match the parameter types of the constructor, and must not be assignable to each other. The
|
||||
* order of the arguments does not matter, as they will be matched to the parameter types.
|
||||
* Duplicate arguments are ignored, as the first match will match.
|
||||
* order of the arguments does matter, as they will be matched to the constructor parameter types
|
||||
* in order.
|
||||
*
|
||||
* @param args the arguments to pass to the constructor
|
||||
* @return a new instance of the constructor's class
|
||||
@@ -90,8 +90,8 @@ public class ConstructorMatch<T> {
|
||||
* types must not be assignable to each other. If multiple constructors match, the one with the
|
||||
* most specific parameter types is chosen. If there is still a tie, the one with the most
|
||||
* specific first parameter type is chosen, then the second parameter type, and so on. The order
|
||||
* of the parameter types does not matter, as they will be matched to the constructor's parameter
|
||||
* types. Duplicate parameter types are ignored, as the first match will match.
|
||||
* of the parameter types does matter, as they will be matched to the constructor parameter types
|
||||
* in order.
|
||||
*
|
||||
* @param <T> the type of the class to find the constructor for
|
||||
* @param clazz the class to find the constructor for
|
||||
|
||||
Reference in New Issue
Block a user