fly-stick 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fly_stick-0.1.0/.github/workflows/release.yml +110 -0
- fly_stick-0.1.0/.gitignore +21 -0
- fly_stick-0.1.0/.python-version +1 -0
- fly_stick-0.1.0/CLAUDE.md +100 -0
- fly_stick-0.1.0/Cargo.lock +865 -0
- fly_stick-0.1.0/Cargo.toml +40 -0
- fly_stick-0.1.0/LICENSE +21 -0
- fly_stick-0.1.0/PKG-INFO +336 -0
- fly_stick-0.1.0/README.md +324 -0
- fly_stick-0.1.0/devices/Microsoft X-Box 360/pad.toml +73 -0
- fly_stick-0.1.0/devices/Microsoft X-Box 360/series_sx.toml +87 -0
- fly_stick-0.1.0/devices/Thrustmaster/t16000m.toml +92 -0
- fly_stick-0.1.0/devices/Thrustmaster/ta320.toml +96 -0
- fly_stick-0.1.0/devices/Thrustmaster/tca_qeng.toml +53 -0
- fly_stick-0.1.0/devices/Thrustmaster/twcs.toml +85 -0
- fly_stick-0.1.0/devices/Thrustmaster/twcs_with_tfrp.toml +103 -0
- fly_stick-0.1.0/examples/alias.py +41 -0
- fly_stick-0.1.0/examples/btn_mode.py +42 -0
- fly_stick-0.1.0/examples/device_pool.py +39 -0
- fly_stick-0.1.0/examples/device_pool_block.py +39 -0
- fly_stick-0.1.0/examples/multi_device.py +152 -0
- fly_stick-0.1.0/examples/single_device.py +87 -0
- fly_stick-0.1.0/figures/Thrustmaster T.16000M.drawio +184 -0
- fly_stick-0.1.0/figures/Thrustmaster T.16000M.drawio.png +0 -0
- fly_stick-0.1.0/figures/Thrustmaster T.Flight Rudder Pedals.drawio +55 -0
- fly_stick-0.1.0/figures/Thrustmaster T.Flight Rudder Pedals.drawio.png +0 -0
- fly_stick-0.1.0/figures/Thrustmaster TCA Q-Eng 1&2.drawio +124 -0
- fly_stick-0.1.0/figures/Thrustmaster TCA Q-Eng 1&2.drawio.png +0 -0
- fly_stick-0.1.0/figures/Thrustmaster_TA320_Copilot.drawio +196 -0
- fly_stick-0.1.0/figures/Thrustmaster_TA320_Copilot.drawio.png +0 -0
- fly_stick-0.1.0/figures/Thrustmaster_TWCS_Throttle.drawio +220 -0
- fly_stick-0.1.0/figures/Thrustmaster_TWCS_Throttle.drawio.png +0 -0
- fly_stick-0.1.0/pyproject.toml +32 -0
- fly_stick-0.1.0/src/fly_stick/__init__.py +22 -0
- fly_stick-0.1.0/src/fly_stick/_core.pyi +299 -0
- fly_stick-0.1.0/src/inner/description.rs +409 -0
- fly_stick-0.1.0/src/inner/device_pool.rs +540 -0
- fly_stick-0.1.0/src/inner/joystick.rs +166 -0
- fly_stick-0.1.0/src/inner/mod.rs +3 -0
- fly_stick-0.1.0/src/lib.rs +23 -0
- fly_stick-0.1.0/src/utils.rs +312 -0
- fly_stick-0.1.0/src/wrapper/device_pool_wrapper.rs +130 -0
- fly_stick-0.1.0/src/wrapper/joystick_wrapper.rs +27 -0
- fly_stick-0.1.0/src/wrapper/mod.rs +2 -0
- fly_stick-0.1.0/uv.lock +207 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*.*.*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build-wheels:
|
|
13
|
+
name: Build Linux wheels
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
strategy:
|
|
16
|
+
matrix:
|
|
17
|
+
target: [x86_64, aarch64]
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- uses: astral-sh/setup-uv@v5
|
|
22
|
+
with:
|
|
23
|
+
version: "latest"
|
|
24
|
+
|
|
25
|
+
- name: Install Python
|
|
26
|
+
run: uv python install 3.12
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: uv sync
|
|
30
|
+
|
|
31
|
+
- name: Build wheels
|
|
32
|
+
uses: PyO3/maturin-action@v1
|
|
33
|
+
with:
|
|
34
|
+
target: ${{ matrix.target }}
|
|
35
|
+
manylinux: auto
|
|
36
|
+
args: --release --out dist
|
|
37
|
+
sccache: "true"
|
|
38
|
+
|
|
39
|
+
- name: Upload wheels
|
|
40
|
+
uses: actions/upload-artifact@v4
|
|
41
|
+
with:
|
|
42
|
+
name: wheels-${{ matrix.target }}
|
|
43
|
+
path: dist/*.whl
|
|
44
|
+
|
|
45
|
+
build-sdist:
|
|
46
|
+
name: Build source distribution
|
|
47
|
+
runs-on: ubuntu-latest
|
|
48
|
+
steps:
|
|
49
|
+
- uses: actions/checkout@v4
|
|
50
|
+
|
|
51
|
+
- uses: astral-sh/setup-uv@v5
|
|
52
|
+
with:
|
|
53
|
+
version: "latest"
|
|
54
|
+
|
|
55
|
+
- name: Install Python
|
|
56
|
+
run: uv python install 3.12
|
|
57
|
+
|
|
58
|
+
- name: Install dependencies
|
|
59
|
+
run: uv sync
|
|
60
|
+
|
|
61
|
+
- name: Build sdist
|
|
62
|
+
uses: PyO3/maturin-action@v1
|
|
63
|
+
with:
|
|
64
|
+
command: sdist
|
|
65
|
+
args: --out dist
|
|
66
|
+
|
|
67
|
+
- name: Upload sdist
|
|
68
|
+
uses: actions/upload-artifact@v4
|
|
69
|
+
with:
|
|
70
|
+
name: sdist
|
|
71
|
+
path: dist/*.tar.gz
|
|
72
|
+
|
|
73
|
+
publish-pypi:
|
|
74
|
+
name: Publish to PyPI
|
|
75
|
+
runs-on: ubuntu-latest
|
|
76
|
+
needs: [build-wheels, build-sdist]
|
|
77
|
+
environment:
|
|
78
|
+
name: pypi
|
|
79
|
+
url: https://pypi.org/p/fly-stick
|
|
80
|
+
permissions:
|
|
81
|
+
id-token: write
|
|
82
|
+
steps:
|
|
83
|
+
- name: Download all artifacts
|
|
84
|
+
uses: actions/download-artifact@v4
|
|
85
|
+
with:
|
|
86
|
+
path: dist
|
|
87
|
+
merge-multiple: true
|
|
88
|
+
|
|
89
|
+
- name: Publish to PyPI
|
|
90
|
+
uses: PyO3/maturin-action@v1
|
|
91
|
+
with:
|
|
92
|
+
command: upload
|
|
93
|
+
args: --non-interactive --skip-existing dist/*
|
|
94
|
+
|
|
95
|
+
github-release:
|
|
96
|
+
name: Create GitHub Release
|
|
97
|
+
runs-on: ubuntu-latest
|
|
98
|
+
needs: [build-wheels, build-sdist]
|
|
99
|
+
steps:
|
|
100
|
+
- name: Download all artifacts
|
|
101
|
+
uses: actions/download-artifact@v4
|
|
102
|
+
with:
|
|
103
|
+
path: dist
|
|
104
|
+
merge-multiple: true
|
|
105
|
+
|
|
106
|
+
- name: Create Release
|
|
107
|
+
uses: softprops/action-gh-release@v2
|
|
108
|
+
with:
|
|
109
|
+
files: dist/*
|
|
110
|
+
generate_release_notes: true
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.10
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project overview
|
|
6
|
+
|
|
7
|
+
`fly_stick` is a **Linux-only** Python extension built with Rust and PyO3. It reads game-controller input via the Linux `evdev` subsystem and exposes `PyJoystick`, `PyDevicePool`, and descriptor types to Python. The Rust crate is built as a `cdylib` and PyO3 is configured with `abi3-py39`, so a single manylinux wheel covers CPython 3.9+ on Linux x86_64.
|
|
8
|
+
|
|
9
|
+
## Build & development commands
|
|
10
|
+
|
|
11
|
+
All commands assume the working directory is the repository root (`toolkit/fly_stick/`).
|
|
12
|
+
|
|
13
|
+
Install Python dependencies:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
uv sync
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Build and install the extension into the active virtualenv for local development:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
uv run maturin develop
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Run Rust tests:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
cargo test
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Run Python tests:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
uv run pytest
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Build a release wheel:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
uv run maturin build --release
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Format and lint Rust:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
cargo fmt
|
|
47
|
+
cargo clippy
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Python linting is not currently configured. Add a ruff/mypy setup only if you introduce non-trivial Python logic beyond `src/fly_stick/__init__.py`.
|
|
51
|
+
|
|
52
|
+
## Running a single test
|
|
53
|
+
|
|
54
|
+
Rust single test:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
cargo test <test_name>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Python single test:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
uv run pytest tests/test_<name>.py -v
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Architecture
|
|
67
|
+
|
|
68
|
+
### Extension boundary
|
|
69
|
+
|
|
70
|
+
`src/lib.rs` defines the PyO3 `_core` extension module. It is gated with `#[cfg(target_os = "linux")]` because the only backend uses `evdev`. On non-Linux builds the module symbol is absent and the crate will not produce a usable Python extension.
|
|
71
|
+
|
|
72
|
+
### Rust layers
|
|
73
|
+
|
|
74
|
+
- `src/inner/` — core logic with no direct PyO3 dependency.
|
|
75
|
+
- `description.rs` — `DeviceDescription` and `DeviceItem` parsed from TOML; defines expected axes/buttons/hats and builds default `JoystickState`.
|
|
76
|
+
- `joystick.rs` — opens a single `/dev/input/event*` device via `evdev::Device`, normalizes ABS axis values, and reads events into `JoystickState`.
|
|
77
|
+
- `device_pool.rs` — manages multiple logical devices, spawns async Tokio tasks per device to update a shared input register, supports `fetch()` (await change/timeout) and `fetch_nowait()`, plus debouncing and trigger/hold button modes.
|
|
78
|
+
- `src/utils.rs` — cross-cutting types exposed to Python: `JoystickInfo`, `JoystickState`, `DeviceButtonMode`, plus `fetch_connected_joysticks()` wrapping `evdev::enumerate()`.
|
|
79
|
+
- `src/wrapper/` — thin PyO3 wrappers around the inner types.
|
|
80
|
+
- `joystick_wrapper.rs` — `PyJoystick`.
|
|
81
|
+
- `device_pool_wrapper.rs` — `PyDevicePool`; its async methods are exposed as Rust `async fn` and can be awaited from Python asyncio.
|
|
82
|
+
|
|
83
|
+
### Python side
|
|
84
|
+
|
|
85
|
+
- `src/fly_stick/__init__.py` re-exports all public symbols from `fly_stick._core`.
|
|
86
|
+
- `src/fly_stick/_core.pyi` provides the type stubs.
|
|
87
|
+
|
|
88
|
+
### Concurrency model
|
|
89
|
+
|
|
90
|
+
`DevicePool` uses Tokio via `pyo3-async-runtimes`. Each monitored device gets a Tokio task that reads `evdev` events and updates a shared input register protected by `std::sync::Mutex`. `stop()` or `reset()` sends a shutdown signal through an `mpsc` channel to abort those tasks.
|
|
91
|
+
|
|
92
|
+
### Device descriptions
|
|
93
|
+
|
|
94
|
+
Devices are configured with TOML files under `devices/`. `DeviceDescription.from_toml(path)` is exposed to Python and expects the file format shown in `README.md`. Example files and button-mapping diagrams live in `examples/` and `figures/`.
|
|
95
|
+
|
|
96
|
+
### Platform constraints
|
|
97
|
+
|
|
98
|
+
- Only Linux is supported.
|
|
99
|
+
- Do not add Windows/macOS-specific API calls without also adding a corresponding platform backend; `evdev` itself is Linux-only.
|
|
100
|
+
- When modifying `Cargo.toml`, keep `evdev` under a Linux-only dependency section or gate usages with `#[cfg(target_os = "linux")]`.
|