From 50e6c75245e682c1272a234da828fa442cfe0d43 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Mon, 28 Sep 2026 02:01:48 -0400 Subject: [PATCH 1/6] feat(gamepad): Gamepad API for iOS, Android and Windows New @nativescript/canvas-gamepad package: navigator.getGamepads() plus gamepadconnected/gamepaddisconnected, standard mapping, up to 4 pads. Native code writes controller state into one shared Float32Array as input arrives; getGamepads() reads it in TS, so polling makes no native calls on iOS/Android and one per frame on Windows. - iOS/tvOS/visionOS: GameController GCExtendedGamepad (ObjC) - Android: KeyEvent/MotionEvent taken at the activity's Window.Callback - Windows: Windows.Gaming.Input poller (crates/canvas-gamepad-napi) - canvas-polyfill: getGamepads() and window events use the package when installed; events go through the iOS runtime's own EventTarget --- Cargo.toml | 1 + Makefile | 6 + apps/demo/package.json | 1 + apps/demo/src/main-page.xml | 1 + apps/demo/src/plugin-demos/canvas-gamepad.ts | 9 + apps/demo/src/plugin-demos/canvas-gamepad.xml | 9 + apps/demo/tsconfig.json | 1 + crates/canvas-gamepad-napi/Cargo.toml | 29 ++ crates/canvas-gamepad-napi/build.rs | 3 + crates/canvas-gamepad-napi/package.json | 16 + crates/canvas-gamepad-napi/src/lib.rs | 204 ++++++++++ packages/canvas-gamepad/.eslintrc.json | 18 + packages/canvas-gamepad/README.md | 53 +++ .../canvas-gamepad/__test__/common.test.mjs | 132 +++++++ packages/canvas-gamepad/backend.android.ts | 19 + packages/canvas-gamepad/backend.d.ts | 3 + packages/canvas-gamepad/backend.ios.ts | 9 + packages/canvas-gamepad/backend.windows.ts | 36 ++ packages/canvas-gamepad/common.ts | 163 ++++++++ packages/canvas-gamepad/index.ts | 11 + packages/canvas-gamepad/package.json | 38 ++ .../platforms/android/canvas_gamepad.aar | Bin 0 -> 10015 bytes .../platforms/android/include.gradle | 10 + .../canvas/gamepad/GamepadWindowCallback.java | 161 ++++++++ .../canvas/gamepad/NSCGamepadManager.java | 367 ++++++++++++++++++ .../platforms/ios/build.xcconfig | 1 + .../ios/src/NSCCanvasGamepadUmbrella.h | 1 + .../platforms/ios/src/NSCGamepadManager.h | 17 + .../platforms/ios/src/NSCGamepadManager.m | 191 +++++++++ .../platforms/ios/src/module.modulemap | 5 + .../platforms/windows/plugin.props | 2 + .../platforms/windows/plugin.targets | 19 + packages/canvas-gamepad/project.json | 70 ++++ packages/canvas-gamepad/references.d.ts | 1 + packages/canvas-gamepad/tsconfig.json | 9 + packages/canvas-gamepad/typings/android.d.ts | 18 + .../typings/objc!NSCCanvasGamepad.d.ts | 11 + packages/canvas-polyfill/gamepad.ts | 43 ++ packages/canvas-polyfill/navigator.ts | 4 +- packages/canvas-polyfill/window.ts | 2 + tools/demo/canvas-gamepad/index.ts | 92 +++++ tools/demo/index.ts | 1 + tools/scripts/build-napi.sh | 6 +- tools/workspace-scripts.js | 11 + tsconfig.base.json | 1 + 45 files changed, 1801 insertions(+), 4 deletions(-) create mode 100644 apps/demo/src/plugin-demos/canvas-gamepad.ts create mode 100644 apps/demo/src/plugin-demos/canvas-gamepad.xml create mode 100644 crates/canvas-gamepad-napi/Cargo.toml create mode 100644 crates/canvas-gamepad-napi/build.rs create mode 100644 crates/canvas-gamepad-napi/package.json create mode 100644 crates/canvas-gamepad-napi/src/lib.rs create mode 100644 packages/canvas-gamepad/.eslintrc.json create mode 100644 packages/canvas-gamepad/README.md create mode 100644 packages/canvas-gamepad/__test__/common.test.mjs create mode 100644 packages/canvas-gamepad/backend.android.ts create mode 100644 packages/canvas-gamepad/backend.d.ts create mode 100644 packages/canvas-gamepad/backend.ios.ts create mode 100644 packages/canvas-gamepad/backend.windows.ts create mode 100644 packages/canvas-gamepad/common.ts create mode 100644 packages/canvas-gamepad/index.ts create mode 100644 packages/canvas-gamepad/package.json create mode 100644 packages/canvas-gamepad/platforms/android/canvas_gamepad.aar create mode 100644 packages/canvas-gamepad/platforms/android/include.gradle create mode 100644 packages/canvas-gamepad/platforms/android/java/org/nativescript/canvas/gamepad/GamepadWindowCallback.java create mode 100644 packages/canvas-gamepad/platforms/android/java/org/nativescript/canvas/gamepad/NSCGamepadManager.java create mode 100644 packages/canvas-gamepad/platforms/ios/build.xcconfig create mode 100644 packages/canvas-gamepad/platforms/ios/src/NSCCanvasGamepadUmbrella.h create mode 100644 packages/canvas-gamepad/platforms/ios/src/NSCGamepadManager.h create mode 100644 packages/canvas-gamepad/platforms/ios/src/NSCGamepadManager.m create mode 100644 packages/canvas-gamepad/platforms/ios/src/module.modulemap create mode 100644 packages/canvas-gamepad/platforms/windows/plugin.props create mode 100644 packages/canvas-gamepad/platforms/windows/plugin.targets create mode 100644 packages/canvas-gamepad/project.json create mode 100644 packages/canvas-gamepad/references.d.ts create mode 100644 packages/canvas-gamepad/tsconfig.json create mode 100644 packages/canvas-gamepad/typings/android.d.ts create mode 100644 packages/canvas-gamepad/typings/objc!NSCCanvasGamepad.d.ts create mode 100644 packages/canvas-polyfill/gamepad.ts create mode 100644 tools/demo/canvas-gamepad/index.ts diff --git a/Cargo.toml b/Cargo.toml index 2675f76fa..2c3a24ff0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ members = [ "crates/canvas-svg-napi", "crates/audio-context-napi", "crates/canvas-media-napi", + "crates/canvas-gamepad-napi", "crates/canvas-svg-ios", "crates/canvas-svg-android", ] diff --git a/Makefile b/Makefile index 8517b8711..db0afa888 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,8 @@ windows-audio: $(addsuffix _audio_napi,$(ARCHS_WINDOWS)) windows-media: $(addsuffix _media_napi,$(ARCHS_WINDOWS)) +windows-gamepad: $(addsuffix _gamepad_napi,$(ARCHS_WINDOWS)) + ios-svg: GENERATE_IOS_SVG visionos-svg: GENERATE_VISIONOS_SVG @@ -104,6 +106,10 @@ $(addsuffix _audio_napi,$(ARCHS_WINDOWS)): %_audio_napi: $(addsuffix _media_napi,$(ARCHS_WINDOWS)): %_media_napi: ./tools/scripts/build-napi.sh $* release-napi canvas-media-napi +.PHONY: windows-gamepad $(addsuffix _gamepad_napi,$(ARCHS_WINDOWS)) +$(addsuffix _gamepad_napi,$(ARCHS_WINDOWS)): %_gamepad_napi: + ./tools/scripts/build-napi.sh $* release-napi canvas-gamepad-napi + .PHONY: GENERATE_ANDROID GENERATE_ANDROID: $(ARCHS_ANDROID) diff --git a/apps/demo/package.json b/apps/demo/package.json index dd2a2e6b8..79f7a8bab 100644 --- a/apps/demo/package.json +++ b/apps/demo/package.json @@ -8,6 +8,7 @@ "@nativescript/canvas": "file:../../packages/canvas", "@nativescript/canvas-babylon": "file:../../packages/canvas-babylon", "@nativescript/canvas-chartjs": "file:../../packages/canvas-chartjs", + "@nativescript/canvas-gamepad": "file:../../packages/canvas-gamepad", "@nativescript/canvas-media": "file:../../packages/canvas-media", "@nativescript/canvas-phaser": "file:../../packages/canvas-phaser", "@nativescript/canvas-phaser-ce": "file:../../packages/canvas-phaser-ce", diff --git a/apps/demo/src/main-page.xml b/apps/demo/src/main-page.xml index 651727419..e86cd2456 100644 --- a/apps/demo/src/main-page.xml +++ b/apps/demo/src/main-page.xml @@ -10,6 +10,7 @@