Skip to content

Commit 1fba876

Browse files
Improve SDK and docs-site developer documentation.
Add comprehensive Swift API doc comments across VeltoKit and app modules, expand docs with Triki UI integration guidance, and reorganize documentation navigation with dedicated Cursor/Claude skill hubs and downloadable skill files for faster contributor onboarding. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 69e3d77 commit 1fba876

114 files changed

Lines changed: 1984 additions & 16 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Package.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// swift-tools-version: 5.9
22
import PackageDescription
33

4+
/// Stores `package` used by this scope.
45
let package = Package(
56
name: "veltokit",
67
platforms: [

VeltoKit/BLE/BLEByteProbe.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,50 @@ import Foundation
22

33
/// Pomocnik do znalezienia bajtu/bitów przycisku — porównuje kolejne pakiety RX.
44
@MainActor
5+
/// Represents blebyte probe.
56
public final class BLEByteProbe {
7+
/// Zmiana pojedynczego bajtu między kolejnymi pakietami.
68
public struct ByteChange: Equatable, Sendable {
9+
/// Indeks bajtu w pakiecie.
710
public let index: Int
11+
/// Poprzednia wartość bajtu.
812
public let from: UInt8
13+
/// Nowa wartość bajtu.
914
public let to: UInt8
1015

16+
/// Zwraca maskę, jeśli zmienił się dokładnie jeden bit.
1117
public var singleBitMask: UInt8? {
1218
let xor = from ^ to
1319
guard xor != 0, xor & (xor - 1) == 0 else { return nil }
1420
return xor
1521
}
1622
}
1723

24+
/// Zdarzenie zmiany stanu bajtu.
1825
public struct EdgeEvent: Identifiable, Sendable {
26+
/// Unikalny identyfikator zdarzenia.
1927
public let id = UUID()
28+
/// Indeks bajtu w pakiecie.
2029
public let index: Int
30+
/// Poprzednia wartość bajtu.
2131
public let from: UInt8
32+
/// Nowa wartość bajtu.
2233
public let to: UInt8
34+
/// Czas wykrycia zmiany.
2335
public let at: Date
2436
}
2537

38+
/// Ostatnio zarejestrowany pakiet bajtów.
2639
private(set) public var lastBytes: [UInt8] = []
2740
private var lastValuesByIndex: [Int: UInt8] = [:]
2841

42+
/// Ostatni pakiet w formacie HEX.
2943
public private(set) var lastPacketHex = ""
44+
/// Lista zmian wykrytych dla ostatniego pakietu.
3045
public private(set) var lastChanges: [ByteChange] = []
46+
/// Ostatnie zdarzenia krawędzi 0→1 i 1→0.
3147
public private(set) var edgeEvents: [EdgeEvent] = []
48+
/// Ostatnie linie logu diagnostycznego.
3249
public private(set) var recentLines: [String] = []
3350

3451
private let maxLines = 80
@@ -41,8 +58,10 @@ public final class BLEByteProbe {
4158
).sorted()
4259
}
4360

61+
/// Tworzy nowy analizator zmian pakietów BLE.
4462
public init() {}
4563

64+
/// Czyści stan analizatora i historię.
4665
public func reset() {
4766
lastBytes = []
4867
lastValuesByIndex = [:]
@@ -52,7 +71,16 @@ public final class BLEByteProbe {
5271
recentLines = []
5372
}
5473

74+
/// Zasila analizator kolejnym pakietem bajtów.
75+
///
76+
/// - Parameter bytes: Pakiet bajtów RX.
77+
/// - Returns: Lista wykrytych zmian bajtów względem poprzedniego pakietu.
5578
@discardableResult
79+
/// Handles `ingest`.
80+
///
81+
/// - Parameters:
82+
/// - bytes: Input used by this operation.
83+
/// - Returns: Result produced by this operation.
5684
public func ingest(_ bytes: [UInt8]) -> [ByteChange] {
5785
guard !bytes.isEmpty else { return [] }
5886

VeltoKit/BLE/BLEManager.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import Combine
44
import os
55

66
@MainActor
7+
/// Represents blemanager.
78
final class BLEManager: NSObject, ObservableObject {
9+
/// Represents status.
810
enum Status: String {
911
case idle
1012
case bluetoothOff
@@ -30,6 +32,7 @@ final class BLEManager: NSObject, ObservableObject {
3032
/// Pełny hex + diff bajtów w konsoli Xcode i w devRawLog (szukaj przycisku).
3133
@Published public var debugRXBytes = false
3234

35+
/// Stores `byteProbe` used by this scope.
3336
public let byteProbe = BLEByteProbe()
3437

3538
/// Domyślnie wyłączone — flow jak w Żappce: user wybiera urządzenie z listy.
@@ -42,6 +45,7 @@ final class BLEManager: NSObject, ObservableObject {
4245
private var didAutoConnectThisScan = false
4346

4447
private let rxBytesSubject = PassthroughSubject<[UInt8], Never>()
48+
/// Stores `rxBytes` used by this scope.
4549
var rxBytes: AnyPublisher<[UInt8], Never> { rxBytesSubject.eraseToAnyPublisher() }
4650

4751
private let log = Logger(subsystem: "com.koderteam.gametriki", category: "BLE")
@@ -51,12 +55,18 @@ final class BLEManager: NSObject, ObservableObject {
5155
central = CBCentralManager(delegate: self, queue: nil)
5256
}
5357

58+
/// Stores `isScanning` used by this scope.
5459
var isScanning: Bool { status == .scanning }
5560

61+
/// Stores `centralStateLabel` used by this scope.
5662
var centralStateLabel: String {
5763
"\(centralState.rawValue) (\(stateLabel(centralState)))"
5864
}
5965

66+
/// Handles `startScan`.
67+
///
68+
/// - Parameters:
69+
/// - clearList: Input used by this operation.
6070
func startScan(clearList: Bool = true) {
6171
guard isBluetoothReady else {
6272
status = .bluetoothOff
@@ -77,12 +87,17 @@ final class BLEManager: NSObject, ObservableObject {
7787
log.info("BLE scan started (no service filter, allow duplicates)")
7888
}
7989

90+
/// Handles `stopScan`.
8091
func stopScan() {
8192
central.stopScan()
8293
if status == .scanning { status = .idle }
8394
addDevLog("SCAN ■ stop")
8495
}
8596

97+
/// Handles `connect`.
98+
///
99+
/// - Parameters:
100+
/// - item: Input used by this operation.
86101
func connect(_ item: DiscoveredPeripheral) {
87102
stopScan()
88103
status = .connecting
@@ -92,18 +107,25 @@ final class BLEManager: NSObject, ObservableObject {
92107
addDevLog("CONN ▶ \(item.name)")
93108
}
94109

110+
/// Handles `disconnect`.
95111
func disconnect() {
96112
guard let p = activePeripheral else { return }
97113
central.cancelPeripheralConnection(p)
98114
}
99115

116+
/// Handles `sendInitAndStartIfReady`.
100117
func sendInitAndStartIfReady() {
101118
guard activePeripheral != nil, let rx = rxChar else { return }
102119
write([0x01, 0x00], to: rx, type: .withResponse)
103120
write([0x20, 0x10, 0x00, 0xD0, 0x07, 0x34, 0x00, 0x03], to: rx, type: .withoutResponse)
104121
addDevLog("TX ▶ INIT + START")
105122
}
106123

124+
/// Handles `writeHex`.
125+
///
126+
/// - Parameters:
127+
/// - hex: Input used by this operation.
128+
/// - withResponse: Input used by this operation.
107129
func writeHex(_ hex: String, withResponse: Bool) {
108130
guard let rx = rxChar else { return }
109131
let bytes = Hex.parse(hex)
@@ -187,14 +209,21 @@ final class BLEManager: NSObject, ObservableObject {
187209
}
188210
}
189211

212+
/// Represents discovered peripheral.
190213
struct DiscoveredPeripheral: Identifiable, Equatable {
214+
/// Stores `id` used by this scope.
191215
let id: UUID
216+
/// Stores `peripheral` used by this scope.
192217
let peripheral: CBPeripheral
218+
/// Stores `name` used by this scope.
193219
var name: String
220+
/// Stores `rssi` used by this scope.
194221
var rssi: Int
222+
/// Stores `isLikelyController` used by this scope.
195223
var isLikelyController: Bool
196224
}
197225

226+
/// Adds focused blemanager helpers.
198227
extension BLEManager: CBCentralManagerDelegate {
199228
nonisolated func centralManagerDidUpdateState(_ central: CBCentralManager) {
200229
Task { @MainActor in
@@ -255,6 +284,7 @@ extension BLEManager: CBCentralManagerDelegate {
255284
}
256285
}
257286

287+
/// Adds focused blemanager helpers.
258288
extension BLEManager: CBPeripheralDelegate {
259289
nonisolated func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
260290
Task { @MainActor in
@@ -353,6 +383,7 @@ extension BLEManager: CBPeripheralDelegate {
353383
}
354384
}
355385

386+
/// Represents hex.
356387
enum Hex {
357388
static func format(_ bytes: [UInt8]) -> String {
358389
bytes.map { String(format: "%02X", $0) }.joined(separator: " ")

VeltoKit/BLEButtonDecoder.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ import Foundation
22

33
/// Przycisk Triki w pakiecie NUS: `22` na [0], przycisk **0/1 na [1]** (edge 0→1).
44
public enum BLEButtonDecoder {
5+
/// Oczekiwany nagłówek pakietu BLE.
56
public static let packetHeader: UInt8 = 0x22
7+
/// Indeks bajtu przycisku w pakiecie.
68
public static let buttonIndex = 1
79

10+
/// Sprawdza, czy bajt reprezentuje stan wciśnięty.
811
public static func isPressed(_ byte: UInt8) -> Bool {
912
byte == 1
1013
}

VeltoKit/BLEGyroParser.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,24 @@ import Foundation
33
/// Parser BLE: bloki 0x22 0x00, 3× int16 LE, normalizacja / 2000.
44
/// Drugi blok w pakiecie = żyroskop (pierwszy = akcelerometr, ignorowany).
55
public enum BLEGyroParser {
6+
/// Sygnatura nagłówka bloku BLE Triki.
67
public static let header: [UInt8] = [0x22, 0x00]
8+
/// Rozmiar pojedynczego bloku osi w bajtach.
79
public static let blockByteCount = 8
10+
/// Domyślny dzielnik normalizacji danych gyro.
811
public static let gyroDivisor = 2000.0
12+
/// Dzielnik dla danych tilt.
913
public static let tiltDivisor = 80.0
14+
/// Alias dzielnika używanego do normalizacji.
1015
public static let normalizeDivisor = gyroDivisor
1116

17+
/// Znormalizowana próbka osi 3D.
1218
public struct GyroTriple: Equatable, Sendable {
19+
/// Oś X.
1320
public var x: Double
21+
/// Oś Y.
1422
public var y: Double
23+
/// Oś Z.
1524
public var z: Double
1625
}
1726

@@ -24,6 +33,7 @@ public enum BLEGyroParser {
2433
return Double(value)
2534
}
2635

36+
/// Alias kompatybilności do odczytu surowej osi Y.
2737
public static func gyroRawYFromPacket(_ data: [UInt8]) -> Double? {
2838
gyroRawFromPacket(data)
2939
}
@@ -148,10 +158,12 @@ public enum BLEGyroParser {
148158
return Int16(bitPattern: lo | (hi << 8))
149159
}
150160

161+
/// Normalizuje surową wartość int16 do zakresu roboczego.
151162
public static func normalize(_ v: Int16, divisor: Double = gyroDivisor) -> Double {
152163
MotionMath.clamp(Double(v) / divisor)
153164
}
154165

166+
/// Skaluje blok tilt do jednostek używanych przez żyroskop.
155167
public static func scaledTiltBlock(_ block: GyroTriple) -> GyroTriple {
156168
let scale = gyroDivisor / tiltDivisor
157169
return GyroTriple(x: block.x * scale, y: block.y * scale, z: block.z * scale)

VeltoKit/ButtonDetector.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ import Foundation
22

33
/// Wykrywanie kliknięcia z BLE (`0x22`, bajt [1], zbocze 0→1).
44
@MainActor
5+
/// Wykrywa zbocze narastające przycisku w strumieniu BLE.
56
final class ButtonDetector {
7+
/// Ostatnia wartość bajtu przycisku odebrana z pakietu.
68
private(set) var lastSeenButtonByte: UInt8 = 0
79
private var lastButton: UInt8 = 0
810
private var pendingClick = false
911

12+
/// Informuje, czy oczekuje nieodebrany impuls kliknięcia.
1013
var didClick: Bool { pendingClick }
1114

15+
/// Przetwarza pojedynczy pakiet BLE i wykrywa zbocze 0→1.
1216
func process(_ data: [UInt8]) {
1317
guard !data.isEmpty else { return }
1418
if data.count > BLEButtonDecoder.buttonIndex, data[0] == BLEButtonDecoder.packetHeader {
@@ -25,6 +29,7 @@ final class ButtonDetector {
2529
return edge
2630
}
2731

32+
/// Resetuje stan detektora kliknięć.
2833
func reset() {
2934
lastButton = 0
3035
lastSeenButtonByte = 0

0 commit comments

Comments
 (0)