Skip to content

Commit

Permalink
Fix NPE in Input.poll() introduced with 9481fd1
Browse files Browse the repository at this point in the history
After some reordering of the startup process in the above mentioned
commit, no updated instance of Input with a non-null ControllerInfo
got created, resulting in a NPE in the poll() method.

In order to prevent this problem, a new instance of Input gets created
after GLFW initialization with a ControllerInfo instance.

In addition, multiple defensive checks are introduced.
  • Loading branch information
bwRavencl committed Jan 9, 2025
1 parent 8e2e5bf commit e1eba2f
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 13 deletions.
35 changes: 24 additions & 11 deletions src/main/java/de/bwravencl/controllerbuddy/gui/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -1057,7 +1057,7 @@ public void windowOpened(final WindowEvent e) {
}
});

onControllersChanged(optionalPresentControllers.orElse(Collections.emptyList()), true);
onControllersChanged(optionalPresentControllers.orElseGet(Collections::emptyList), true);

// noinspection resource
taskRunner.run((Runnable) () -> GLFW.glfwSetJoystickCallback((jid, event) -> {
Expand Down Expand Up @@ -2364,14 +2364,23 @@ private void onControllersChanged(final List<ControllerInfo> presentControllers,
if (!controllerConnected) {
selectedController = null;
setSelectedControllerAndUpdateInput(null, null);
} else if (selectedController == null) {
setSelectedControllerAndUpdateInput(presentControllers.getFirst(), null);

if (isAutoRestartOutput()) {
restartOutput = switch (lastRunModeType) {
case NONE, CLIENT -> false;
case LOCAL, SERVER -> true;
};
} else {
final ControllerInfo controller;
if (selectedController != null && presentControllers.contains(selectedController)) {
controller = selectedController;
} else {
controller = presentControllers.getFirst();
}

if (selectedController == null || (input != null && !Objects.equals(input.getController(), controller))) {
setSelectedControllerAndUpdateInput(controller, null);

if (isAutoRestartOutput()) {
restartOutput = switch (lastRunModeType) {
case NONE, CLIENT -> false;
case LOCAL, SERVER -> true;
};
}
}
}

Expand Down Expand Up @@ -2596,6 +2605,10 @@ public void setOverlayText(final String text) {
}

private void setSelectedController(final ControllerInfo controller) {
if (Objects.equals(selectedController, controller)) {
return;
}

selectedController = controller;

if (controller != null) {
Expand Down Expand Up @@ -2688,7 +2701,7 @@ private void startClient() {
private void startLocal() {
lastRunModeType = RunModeType.LOCAL;

if (selectedController == null || isRunning()) {
if (selectedController == null || input.getController() == null || isRunning()) {
return;
}

Expand All @@ -2715,7 +2728,7 @@ private void startOverlayTimerTask() {
private void startServer() {
lastRunModeType = RunModeType.SERVER;

if (selectedController == null || isRunning()) {
if (selectedController == null || input.getController() == null || isRunning()) {
return;
}

Expand Down
2 changes: 2 additions & 0 deletions src/main/java/de/bwravencl/controllerbuddy/input/Input.java
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,8 @@ public void moveAxis(final VirtualAxis virtualAxis, final float targetValue) {
}

public boolean poll() {
Objects.requireNonNull(controller, "Field controller must not be null");

final var currentTime = System.currentTimeMillis();

axisToEndSuspensionTimestampMap.values().removeIf(timestamp -> timestamp < currentTime);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,12 @@ final void controllerDisconnected() {

Thread.startVirtualThread(() -> main.stopAll(true, !main.isAutoRestartOutput(), true));

log.log(Level.WARNING,
Main.assembleControllerLoggingMessage("Could not read from controller ", input.getController()));
final var controller = input.getController();
if (controller != null) {
log.log(Level.WARNING,
Main.assembleControllerLoggingMessage("Could not read from controller ", controller));
}

if (!main.isSkipControllerDialogs()) {
EventQueue.invokeLater(() -> GuiUtils.showMessageDialog(main, main.getFrame(),
Main.strings.getString("COULD_NOT_READ_FROM_CONTROLLER_DIALOG_TEXT"),
Expand Down

0 comments on commit e1eba2f

Please sign in to comment.