Expose opt-in automatic discovery for native controller reconnect - #71
Conversation
Reuse the existing event-driven automatic discovery policy so native hosts can recover controllers after timed discovery expires. Preserve radio-free creation, explicit stop, frozen ABI-v1 layouts, and ready-session/input-reader state. Add C-declaration, lifecycle, concurrency and long-absence policy regressions. AI-assisted implementation. Physical Bluetooth recovery remains to be validated.
|
Companion Dolphin implementation is open at jmonster/dolphin#3 and pins this PR's exact head It adds a saved, default-off Automatically connect Switch 2 controllers option, one-shot main-thread startup after SDL, continuous listening status, and an explicit-stop fence that polling/settings refresh cannot bypass. Turning discovery off retains ready controllers and mappings. The production Dolphin host wrapper passed local Clang and GCC ASan/UBSan checks; four new UI/startup wiring checks also passed. On this SDK head, Swift concurrency and the Linux debug/release package-test steps have completed successfully. Remaining workflow/app/hardware qualification is separate; no physical Mac/controller recovery test has been performed. Merge order: SDK first, then the pinned Dolphin change. |
Implement the new ControllerSource requirement in the shared SDLTestSource, recording policy changes without simulating a radio or disturbing input. Compile that exact fixture in a new SwiftPM test target and cover C-entry-point validation, idempotence, preserved queued input, and explicit stop/restart behavior. This addresses the native SDL, emulator-host, and Linux consumer build failures in #71. Production behavior and existing CI gates are unchanged. AI-assisted correction; native CI results remain separate from hardware qualification.
|
The reported native-consumer failures exposed an omission in my original change: Pushed correction
No production protocol fallback/no-op, CI bypass, or disabled assertion was added. Native CMake tests still compile the actual fixture separately with warnings as errors. Distribution products are unchanged. Local Swift syntax and manifest/target checks passed; fresh native CI is now the required validation and is not yet claimed green. I am also updating Dolphin #3 to pin this corrected SDK commit. |
Completion status
Merged as
38c57c5dcdfbfc42993345d50172a2001b39f6a6. All eight workflows for corrected feature heada9d43b1f63d94f8844755a510bf6ecc876bc8c51completed successfully. The previously failing native fixture and formerly pending native consumers, Linux Dolphin/Cemu builds, macOS application builds, and separate launch/shutdown checks pass.Companion Dolphin #3 is also merged and pins the corrected SDK commit. The SDK change is now on main, so it is no longer an outstanding PR dependency for that host feature. Both merges were observed through GitHub; the final completion audit verified CI and updated this description but did not execute either merge operation or make additional code changes.
Problem and implementation
Dolphin's finite 60-second native discovery window can expire while a controller is off during a long pause. The Swift engine already has an event-driven automatic policy; this PR exposes that policy to native hosts.
s2k_set_automatic_discovery(context, enabled)as an additive ABI-v1 symbol. Existing layouts, on-demand defaults, and old consumers remain unchanged..automatictransport policy: no host polling timer or repeated Find calls. Handshake serialization, capacity limits and bounded transport retries remain in force.The Dolphin companion supplies the persistent opt-in checkbox, main-thread startup and authoritative manual Disconnect. Automatic discovery admits available supported controllers, not arbitrary Bluetooth devices, and is not a remembered-device allowlist.
Native-fixture correction
The original change added
ControllerSource.setAutomaticDiscovery(_:)but missed the separateSDLTestSourceintests/sdl-inprocess/Fixture.swift. The investigated emulator-host, Apple Silicon SDL, Intel SDL, and Linux-consumer failures reported that missing protocol conformance after the production library built.The published correction implements the method in the actual shared fixture, recording policy changes under its mutex without starting a radio or changing ready sessions. A new
Switch2KitSDLFixtureTestsSwiftPM test target compiles that same file during ordinaryswift test; native CMake continues to compile it separately. Three additional regressions cover C-entry-point validation/idempotence/radio-free configuration, preserved sessions and queued input, and asynchronous stop/restart.No production protocol fallback, disabled check, relaxed warning policy or fabricated status was added. Distribution products are unchanged. The correction touches only the fixture, its new tests and their package-test registration.
Completed corrected-head CI
The completed Linux and emulator job/step results were inspected. These are results for the corrected feature head, not the failing predecessor or newly executed post-merge checks. No submitted reviews or unresolved review threads were present at the pre-merge completion check.
Test-source provenance and previously recorded local validation
The retained corrected-head CI source archive was previously checked: ZIP SHA-256
7b99eb4e74fdf141e59b821ef2ed56b80b372618c8925be024691a4d85c4903f; reconstructed treedf0adbaccb951bb014bcb037a87f4e217d6bcbd3; synthetic test merge53db7db74d73aff64ca02982e982ece0a4465d7b. This was the CI merge with the then-advanced base, not a claim that its entire tree equals the feature head. Main incorporated #68 before this PR was merged; the runs above are not relabeled as new CI on the final combined main tree.Previously recorded on Linux / Swift 6.2.1:
swift test --filter SDLFixtureTestsfail with the original conformance error. Restoring it passes all three tests.Fixture.swiftas a shared library with the CMake package-identity/module-map helper, warnings as errors; link and execute a C++ consumer against that fixture and the actual facade. Policy validation, radio-free configuration, preserved connected input, and stopped-state fencing pass.Those local results were recorded during implementation, not newly executed in this final audit. The first original debug invocation hit the execution limit; its completed incremental rerun passed all 100 tests. No incomplete run is counted as passing. Earlier syntax, public C11/C++20 declaration, simulated 48-hour policy, and whitespace checks remain supplemental.
Hardware boundary
No physical controller/radio or gameplay test was performed for this change. Acceptance must include more than 60 seconds of absence, paused gameplay, repeated wake cycles, Bluetooth off/on, two controllers, and explicit Disconnect staying stopped. Native builds and fixture regressions do not establish physical reconnection. Linux retains its experimental qualification boundary. No release was published by the completion audit.
Prepared with AI assistance.