Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor joystick handling #1811

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

cbrauers
Copy link
Contributor

@cbrauers cbrauers commented Aug 4, 2024

  • Modularize EnumerateDevices into smaller overridable chunks
  • Fix some issues with button and axis sorting and enable it

- Fix some issues with button and axis sorting and enable it
Copy link

github-actions bot commented Aug 4, 2024

Build for this pull request:
MobiFlightConnector.zip

Axes.Add(new JoystickDevice() { Name = axisName, Label = axisLabel, Type = DeviceType.AnalogInput, JoystickDeviceType = JoystickDeviceType.Axis});
Log.Instance.log($"Added {DIJoystick.Information.InstanceName} Aspect {aspect} + Offset: {offset} Usage: {usage} Axis: {name} Label: {axisLabel}.", LogSeverity.Debug);

RegisterAxis(device);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method has three sub-methods abstracted for more specific overrides in derived classes and to keep function length down - derived classes do not need to copy the full size of the method if all they want to change is a line or two.

var buttons = Buttons.ToArray().ToList();
buttons.Sort(SortByPositionInDefintion);
return Buttons;
return Buttons.OrderBy(button => GetIndexForJoystickDevice(button)).ToList();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This addresses two nuisances (cf. issue #1808):

  • The mix of member "Buttons" and local "buttons" led to the sorted list being completely ignored
  • List.Sort() uses an unstable sorting algorithm, effectively applying an undefined permutation to buttons without a sorting index.

The Lambda could also be a function pointer, writing it this way mainly makes it more explicit that it is acting on individual buttons.

Axes.Sort(SortByPositionInDefintion);

return Axes;
return Axes.OrderBy(axis => GetIndexForJoystickDevice(axis)).ToList();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the buttons, with the added fun that the sort function was run on the member axes, not the local axes.

// -2 = definition not found / no inputs in definition
// -1 = index not found
// 0 or greater: valid index
return Definition?.Inputs?.FindIndex(input => input.Name == key) ?? -2;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documented some outputs and changed the return value in case of null pointers from a valid index to something the caller can distinguish.
Added virtual keyword because this is something that derived classes may want to override: the naming scheme of derived classes is often not based on DirectInput numbers, whereas input.Name is always based on the "Button " scheme.

}

int SortByPositionInDefintion(JoystickDevice b1, JoystickDevice b2)
public int GetIndexForJoystickDevice(JoystickDevice button)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enumerable.OrderBy, unlike List.Sort, allows us to define what property to sort by. Therefore, the approach to integrate the index retrieval into the function is somewhat different.

// Ensure items in definition appear first
if(index < 0)
{
index = Int32.MaxValue; // force undefined stuff to the end of the list
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inputs most relevant to MobiFlight users are probably spelled out in the definition. Entries not in the definition are likely to be less relevant, so let us move them after the named ones.

LogInputAdded(device, name);
}

protected void LogInputAdded(DeviceObjectInstance device, string label)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trading debug information (calling function name) for DRYness here. If having the log point to dedicated logging methods is unwanted, I have a different compromise in mind as an alternative option (generate the string in a method and call Log.Instance.log with that).

@cbrauers cbrauers marked this pull request as ready for review August 7, 2024 21:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant