Skip to content

Conversation

@J0EK3R
Copy link

@J0EK3R J0EK3R commented Aug 30, 2025

I've added the missing ControllerManagement for iOS, as it's already implemented for Android and Windows.

Then, I've removed the generic parameter of GameControllerServiceBase to handle different types of input devices/controllers, such as MCPServer ;). IGameController is now used instead.

And I've cleaned up the code:

  • Removed unused properties of IGameController and GamepadControllerBase
  • Removed unused code

@vicocz vicocz requested a review from Copilot September 2, 2025 20:56
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements ControllerManagement for iOS to bring feature parity with Android and Windows platforms. It refactors the GameControllerServiceBase to use IGameController directly instead of generic types, enabling support for different controller types like MCP servers.

  • Adds complete iOS GameController implementation with proper device management
  • Removes generic constraint from GameControllerServiceBase to handle diverse controller types
  • Cleans up unused properties and code across the codebase

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
IGameController.cs Removes unused VendorId and ProductId properties from interface
GamepadControllerBase.cs Updates generic parameter naming and removes unused properties
GameControllers.cs Removes unused GetControllerIdFromIndex helper method
GameControllerServiceBase.cs Removes generic constraint and adds proper disposal handling
GamepadController.cs (iOS) New iOS controller implementation with complete input handling
GameControllerService.cs (iOS) New iOS service implementation extending the base class
GamepadController.cs (WinUI) Updates to use new ControllerDevice property naming
GameControllerService.cs (WinUI) Updates method calls to use new generic TryRemove signature
GamepadController.cs (Android) Removes unused properties and imports
GameControllerService.cs (Android) Updates method calls to use new generic TryRemove signature
InputDeviceExtensions.cs (Android) Removes entire unused extension class

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@J0EK3R J0EK3R force-pushed the merge/vicocz/GameControllerService_iOS branch from e96e681 to a76760d Compare September 3, 2025 09:11
@J0EK3R J0EK3R marked this pull request as ready for review September 3, 2025 09:13
_ = _mainThreadService.RunOnMainThread(() =>
{
if (TryRemove(x => x.Gamepad == gamepad, out var controller))
if (TryRemove<GamepadController>(x => x.ControllerDevice == gamepad, out var controller))
Copy link
Owner

Choose a reason for hiding this comment

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

Why is type of GamepadController needed to be defined for TryRemove? What is the benefit of such change, if it has to be specified here?

Copy link
Author

Choose a reason for hiding this comment

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

It's because we lost the generic in the base class - it's just the interface IGameController now

    /// <summary>
    /// Collection of available gamepads having <see cref="IGameController.ControllerId"/>
    /// </summary>
    private readonly List<IGameController> _availableControllers = [];

But to distinguish the controllers we neet to handle the real type to be able to access properties not defined in the interface.

If there is another remove-event for another controller type to handle - i.e. for the McpServer ;) - the generic paramater of TryRemove<> would be that special type of controller:

    private void McpServerRemoved(object? sender, McpServer e)
    {
        lock (_lockObject)
        {
            // ensure stopped in UI thread
            _ = _mainThreadService.RunOnMainThread(() =>
            {
                if (TryRemove<McpServerController>(x => x.ControllerDevice is McpServer, out var controller))
                {
                    _logger.LogInformation("McpServer has been removed");
                }
            });
        }
    }

Copy link
Owner

Choose a reason for hiding this comment

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

I d not like this desgin as:

  • it enforces hard coupling of MCP server to controller service for each platform
image * additionally it seems to me in your follow up (#165), MCP platform inplementations are nearly the same. Is it?

Shortly said, it should be done differently. May be there might be some game controller providers, which are providing different types of game controllers, the gamepad ones, MCP ones. Just a quick idea.

Copy link
Author

Choose a reason for hiding this comment

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

Yes, if I understood you correctly, I see it that way too.
It would be a clean solution if there were a central instance that manages all types of input devices and handles event signaling (gamepad 🕹️ events, gyro events, mcp server events, etc.).
Then there should be providers for the different types of input devices that register and deregister the input devices with the central instance und call the event invoking methods...

If I find some time these days I'll suggest an implementation of that.

@J0EK3R J0EK3R marked this pull request as draft September 13, 2025 03:22
@J0EK3R J0EK3R force-pushed the merge/vicocz/GameControllerService_iOS branch from 30147ed to e3e78a2 Compare September 23, 2025 03:47
@J0EK3R J0EK3R changed the title ControllerManagement for iOS [outdated] ControllerManagement for iOS Oct 7, 2025
@J0EK3R
Copy link
Author

J0EK3R commented Oct 7, 2025

It's included in #172 (comment)

@vicocz
Copy link
Owner

vicocz commented Nov 25, 2025

Please close this one as it's outdated due to the recent merge.

@J0EK3R J0EK3R closed this Nov 26, 2025
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.

2 participants