@@ -2,6 +2,7 @@ import Combine
22import Foundation
33
44private let motionHudPublishInterval : TimeInterval = 0.12
5+ private let buttonClickHighlightDuration : TimeInterval = 0.12
56
67/// Adds focused motion sdk helpers.
78extension MotionSDK {
@@ -36,12 +37,21 @@ extension MotionSDK {
3637 trikiController? . tick ( deltaTime: deltaTime)
3738 applyTrikiGamepadToEngine ( )
3839
40+ let now = Date ( ) . timeIntervalSince1970
41+
3942 guard let parser = streamParser else {
4043 updateFrame ( deltaTime: deltaTime)
41- return input
44+ let buttonClick = resolveButtonClick ( impulses: ( false , false ) , now: now)
45+ var copy = input
46+ copy. bleButtonClick = buttonClick
47+ if config. mode == . paddle {
48+ copy. primaryAction = buttonClick
49+ } else if buttonClick {
50+ copy. primaryAction = copy. primaryAction || buttonClick
51+ }
52+ latestEnrichedInput = copy
53+ return copy
4254 }
43-
44- let now = Date ( ) . timeIntervalSince1970
4555 let stale = trikiBLEMode. packetStaleSeconds
4656 if now - lastPacketAt > stale, isReceiving { isReceiving = false }
4757 syncTrikiPublishedState ( )
@@ -51,11 +61,13 @@ extension MotionSDK {
5161 parser. flushImpulsesOnly ( )
5262 let impulses = parser. consumeImpulses ( )
5363 let out = updateFrame ( deltaTime: deltaTime)
64+ let buttonClick = resolveButtonClick ( impulses: impulses, now: now)
5465 var enriched = makeEnrichedGameInput (
5566 output: out,
5667 sdkInput: input,
5768 parser: parser,
58- impulses: impulses
69+ impulses: impulses,
70+ buttonClick: buttonClick
5971 )
6072 applyTrikiGamepadSignals ( & enriched)
6173 finalizeAdaptiveInput ( & enriched)
@@ -72,11 +84,13 @@ extension MotionSDK {
7284 )
7385 let out = updateFrame ( deltaTime: deltaTime)
7486 let impulses = parser. consumeImpulses ( )
87+ let buttonClick = resolveButtonClick ( impulses: impulses, now: now)
7588 var enriched = makeEnrichedGameInput (
7689 output: out,
7790 sdkInput: input,
7891 parser: parser,
79- impulses: impulses
92+ impulses: impulses,
93+ buttonClick: buttonClick
8094 )
8195 applyTrikiGamepadSignals ( & enriched)
8296 finalizeAdaptiveInput ( & enriched)
@@ -287,19 +301,39 @@ extension MotionSDK {
287301 lastFramePosY = input. posY
288302 }
289303
304+ /// Jednorazowe zebranie impulsu przycisku BLE na końcu `pollInput` (nie w `publishInput`).
305+ func resolveButtonClick( impulses: ( click: Bool , shake: Bool ) , now: TimeInterval ) -> Bool {
306+ if trikiController? . consumeButtonEdge ( ) == true {
307+ button. latchClick ( )
308+ }
309+ let packetEdge = button. consumeClick ( )
310+ let currentByte = button. lastSeenButtonByte
311+ let levelEdge = BLEButtonDecoder . isPressed ( currentByte)
312+ && !BLEButtonDecoder. isPressed ( lastSampledButtonByte)
313+ lastSampledButtonByte = currentByte
314+
315+ let freshEdge = packetEdge || impulses. click || levelEdge
316+ if freshEdge {
317+ buttonClickHighlightUntil = now + buttonClickHighlightDuration
318+ }
319+ return freshEdge || now < buttonClickHighlightUntil
320+ }
321+
290322 /// Builds a UI/game-friendly input snapshot from raw engine output and parser state.
291323 ///
292324 /// - Parameters:
293325 /// - output: Current processed motion output frame.
294326 /// - sdkInput: Base input snapshot that will be enriched.
295327 /// - parser: Optional parser containing latest sensor payload.
296328 /// - impulses: Edge-triggered click/shake impulses for this frame.
329+ /// - buttonClick: Resolved BLE button edge for this poll (includes short HUD latch).
297330 /// - Returns: Enriched `GameInput` used by HUD and gameplay layers.
298331 func makeEnrichedGameInput(
299332 output: MotionOutput ,
300333 sdkInput: GameInput ,
301334 parser: MotionParser ? ,
302- impulses: ( click: Bool , shake: Bool )
335+ impulses: ( click: Bool , shake: Bool ) ,
336+ buttonClick: Bool = false
303337 ) -> GameInput {
304338 let dbg = debug
305339 var enriched = sdkInput
@@ -321,13 +355,13 @@ extension MotionSDK {
321355 enriched. sensors = parser. sensors
322356 enriched. pointerDirection = pointerDirection ( posX: output. x, posY: output. y)
323357 }
324- let buttonEdge = impulses . click || sdkInput . primaryAction
358+ enriched . bleButtonClick = buttonClick
325359 if config. mode == . paddle {
326- enriched. primaryAction = buttonEdge
327- } else if impulses . click {
328- enriched. primaryAction = true
360+ enriched. primaryAction = buttonClick
361+ } else if buttonClick {
362+ enriched. primaryAction = enriched . primaryAction || buttonClick
329363 }
330- applyClickToSensors ( & enriched, clickEdge: buttonEdge )
364+ applyClickToSensors ( & enriched, clickEdge: buttonClick )
331365 return enriched
332366 }
333367
0 commit comments