rn-gamekit 0.1.0
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.
- package/CHANGELOG.md +18 -0
- package/LICENSE +21 -0
- package/README.md +131 -0
- package/lib/module/assets/defineAssets.js +48 -0
- package/lib/module/assets/defineAssets.js.map +1 -0
- package/lib/module/assets/errors.js +38 -0
- package/lib/module/assets/errors.js.map +1 -0
- package/lib/module/assets/types.js +2 -0
- package/lib/module/assets/types.js.map +1 -0
- package/lib/module/assets/validation.js +99 -0
- package/lib/module/assets/validation.js.map +1 -0
- package/lib/module/core/frameDriver.js +20 -0
- package/lib/module/core/frameDriver.js.map +1 -0
- package/lib/module/core/input/createInputBuffer.js +296 -0
- package/lib/module/core/input/createInputBuffer.js.map +1 -0
- package/lib/module/core/input/types.js +4 -0
- package/lib/module/core/input/types.js.map +1 -0
- package/lib/module/core/session/createGameSession.js +554 -0
- package/lib/module/core/session/createGameSession.js.map +1 -0
- package/lib/module/core/session/deepFreeze.js +155 -0
- package/lib/module/core/session/deepFreeze.js.map +1 -0
- package/lib/module/core/session/diagnostics.js +2 -0
- package/lib/module/core/session/diagnostics.js.map +1 -0
- package/lib/module/core/session/types.js +43 -0
- package/lib/module/core/session/types.js.map +1 -0
- package/lib/module/definition/defineGame.js +57 -0
- package/lib/module/definition/defineGame.js.map +1 -0
- package/lib/module/definition/types.js +4 -0
- package/lib/module/definition/types.js.map +1 -0
- package/lib/module/geometry/types.js +2 -0
- package/lib/module/geometry/types.js.map +1 -0
- package/lib/module/index.js +12 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/react/GamePointerInput.js +385 -0
- package/lib/module/react/GamePointerInput.js.map +1 -0
- package/lib/module/react/GameView.js +223 -0
- package/lib/module/react/GameView.js.map +1 -0
- package/lib/module/react/alphaClock.js +42 -0
- package/lib/module/react/alphaClock.js.map +1 -0
- package/lib/module/react/assets/createGameAssetStore.js +358 -0
- package/lib/module/react/assets/createGameAssetStore.js.map +1 -0
- package/lib/module/react/assets/decodeSkiaImage.js +54 -0
- package/lib/module/react/assets/decodeSkiaImage.js.map +1 -0
- package/lib/module/react/assets/errors.js +10 -0
- package/lib/module/react/assets/errors.js.map +1 -0
- package/lib/module/react/assets/useGameAssets.js +160 -0
- package/lib/module/react/assets/useGameAssets.js.map +1 -0
- package/lib/module/react/bindAppLifecycle.js +58 -0
- package/lib/module/react/bindAppLifecycle.js.map +1 -0
- package/lib/module/react/bindGameSession.js +37 -0
- package/lib/module/react/bindGameSession.js.map +1 -0
- package/lib/module/react/gestureLifecycle.js +68 -0
- package/lib/module/react/gestureLifecycle.js.map +1 -0
- package/lib/module/react/instrumentation.js +4 -0
- package/lib/module/react/instrumentation.js.map +1 -0
- package/lib/module/react/pointerBinding.js +196 -0
- package/lib/module/react/pointerBinding.js.map +1 -0
- package/lib/module/react/pointerCoalescer.js +224 -0
- package/lib/module/react/pointerCoalescer.js.map +1 -0
- package/lib/module/react/pointerContainment.js +27 -0
- package/lib/module/react/pointerContainment.js.map +1 -0
- package/lib/module/react/sprites/GameSprite.js +116 -0
- package/lib/module/react/sprites/GameSprite.js.map +1 -0
- package/lib/module/react/sprites/GameWorld2D.js +44 -0
- package/lib/module/react/sprites/GameWorld2D.js.map +1 -0
- package/lib/module/react/sprites/Sprite.js +147 -0
- package/lib/module/react/sprites/Sprite.js.map +1 -0
- package/lib/module/react/sprites/SpriteBatch.js +173 -0
- package/lib/module/react/sprites/SpriteBatch.js.map +1 -0
- package/lib/module/react/sprites/spriteBatchPolicy.js +25 -0
- package/lib/module/react/sprites/spriteBatchPolicy.js.map +1 -0
- package/lib/module/react/sprites/spriteTransform.js +135 -0
- package/lib/module/react/sprites/spriteTransform.js.map +1 -0
- package/lib/module/react/viewportBinding.js +101 -0
- package/lib/module/react/viewportBinding.js.map +1 -0
- package/lib/module/react.js +13 -0
- package/lib/module/react.js.map +1 -0
- package/lib/module/scene/defineScene.js +29 -0
- package/lib/module/scene/defineScene.js.map +1 -0
- package/lib/module/scene/types.js +4 -0
- package/lib/module/scene/types.js.map +1 -0
- package/lib/module/sprites/sampleSpriteClip.js +50 -0
- package/lib/module/sprites/sampleSpriteClip.js.map +1 -0
- package/lib/module/sprites/spriteAnimationState.js +165 -0
- package/lib/module/sprites/spriteAnimationState.js.map +1 -0
- package/lib/module/testing.js +57 -0
- package/lib/module/testing.js.map +1 -0
- package/lib/module/viewport2d/index.js +4 -0
- package/lib/module/viewport2d/index.js.map +1 -0
- package/lib/module/viewport2d/math.js +129 -0
- package/lib/module/viewport2d/math.js.map +1 -0
- package/lib/module/viewport2d/types.js +2 -0
- package/lib/module/viewport2d/types.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/assets/defineAssets.d.ts +20 -0
- package/lib/typescript/src/assets/defineAssets.d.ts.map +1 -0
- package/lib/typescript/src/assets/errors.d.ts +20 -0
- package/lib/typescript/src/assets/errors.d.ts.map +1 -0
- package/lib/typescript/src/assets/types.d.ts +138 -0
- package/lib/typescript/src/assets/types.d.ts.map +1 -0
- package/lib/typescript/src/assets/validation.d.ts +15 -0
- package/lib/typescript/src/assets/validation.d.ts.map +1 -0
- package/lib/typescript/src/core/frameDriver.d.ts +12 -0
- package/lib/typescript/src/core/frameDriver.d.ts.map +1 -0
- package/lib/typescript/src/core/input/createInputBuffer.d.ts +12 -0
- package/lib/typescript/src/core/input/createInputBuffer.d.ts.map +1 -0
- package/lib/typescript/src/core/input/types.d.ts +64 -0
- package/lib/typescript/src/core/input/types.d.ts.map +1 -0
- package/lib/typescript/src/core/session/createGameSession.d.ts +18 -0
- package/lib/typescript/src/core/session/createGameSession.d.ts.map +1 -0
- package/lib/typescript/src/core/session/deepFreeze.d.ts +27 -0
- package/lib/typescript/src/core/session/deepFreeze.d.ts.map +1 -0
- package/lib/typescript/src/core/session/diagnostics.d.ts +36 -0
- package/lib/typescript/src/core/session/diagnostics.d.ts.map +1 -0
- package/lib/typescript/src/core/session/types.d.ts +104 -0
- package/lib/typescript/src/core/session/types.d.ts.map +1 -0
- package/lib/typescript/src/definition/defineGame.d.ts +66 -0
- package/lib/typescript/src/definition/defineGame.d.ts.map +1 -0
- package/lib/typescript/src/definition/types.d.ts +56 -0
- package/lib/typescript/src/definition/types.d.ts.map +1 -0
- package/lib/typescript/src/geometry/types.d.ts +8 -0
- package/lib/typescript/src/geometry/types.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +18 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/react/GamePointerInput.d.ts +37 -0
- package/lib/typescript/src/react/GamePointerInput.d.ts.map +1 -0
- package/lib/typescript/src/react/GameView.d.ts +61 -0
- package/lib/typescript/src/react/GameView.d.ts.map +1 -0
- package/lib/typescript/src/react/alphaClock.d.ts +29 -0
- package/lib/typescript/src/react/alphaClock.d.ts.map +1 -0
- package/lib/typescript/src/react/assets/createGameAssetStore.d.ts +33 -0
- package/lib/typescript/src/react/assets/createGameAssetStore.d.ts.map +1 -0
- package/lib/typescript/src/react/assets/decodeSkiaImage.d.ts +12 -0
- package/lib/typescript/src/react/assets/decodeSkiaImage.d.ts.map +1 -0
- package/lib/typescript/src/react/assets/errors.d.ts +8 -0
- package/lib/typescript/src/react/assets/errors.d.ts.map +1 -0
- package/lib/typescript/src/react/assets/useGameAssets.d.ts +35 -0
- package/lib/typescript/src/react/assets/useGameAssets.d.ts.map +1 -0
- package/lib/typescript/src/react/bindAppLifecycle.d.ts +32 -0
- package/lib/typescript/src/react/bindAppLifecycle.d.ts.map +1 -0
- package/lib/typescript/src/react/bindGameSession.d.ts +14 -0
- package/lib/typescript/src/react/bindGameSession.d.ts.map +1 -0
- package/lib/typescript/src/react/gestureLifecycle.d.ts +37 -0
- package/lib/typescript/src/react/gestureLifecycle.d.ts.map +1 -0
- package/lib/typescript/src/react/instrumentation.d.ts +47 -0
- package/lib/typescript/src/react/instrumentation.d.ts.map +1 -0
- package/lib/typescript/src/react/pointerBinding.d.ts +104 -0
- package/lib/typescript/src/react/pointerBinding.d.ts.map +1 -0
- package/lib/typescript/src/react/pointerCoalescer.d.ts +106 -0
- package/lib/typescript/src/react/pointerCoalescer.d.ts.map +1 -0
- package/lib/typescript/src/react/pointerContainment.d.ts +12 -0
- package/lib/typescript/src/react/pointerContainment.d.ts.map +1 -0
- package/lib/typescript/src/react/sprites/GameSprite.d.ts +75 -0
- package/lib/typescript/src/react/sprites/GameSprite.d.ts.map +1 -0
- package/lib/typescript/src/react/sprites/GameWorld2D.d.ts +29 -0
- package/lib/typescript/src/react/sprites/GameWorld2D.d.ts.map +1 -0
- package/lib/typescript/src/react/sprites/Sprite.d.ts +43 -0
- package/lib/typescript/src/react/sprites/Sprite.d.ts.map +1 -0
- package/lib/typescript/src/react/sprites/SpriteBatch.d.ts +41 -0
- package/lib/typescript/src/react/sprites/SpriteBatch.d.ts.map +1 -0
- package/lib/typescript/src/react/sprites/spriteBatchPolicy.d.ts +10 -0
- package/lib/typescript/src/react/sprites/spriteBatchPolicy.d.ts.map +1 -0
- package/lib/typescript/src/react/sprites/spriteTransform.d.ts +86 -0
- package/lib/typescript/src/react/sprites/spriteTransform.d.ts.map +1 -0
- package/lib/typescript/src/react/viewportBinding.d.ts +42 -0
- package/lib/typescript/src/react/viewportBinding.d.ts.map +1 -0
- package/lib/typescript/src/react.d.ts +20 -0
- package/lib/typescript/src/react.d.ts.map +1 -0
- package/lib/typescript/src/scene/defineScene.d.ts +26 -0
- package/lib/typescript/src/scene/defineScene.d.ts.map +1 -0
- package/lib/typescript/src/scene/types.d.ts +71 -0
- package/lib/typescript/src/scene/types.d.ts.map +1 -0
- package/lib/typescript/src/sprites/sampleSpriteClip.d.ts +24 -0
- package/lib/typescript/src/sprites/sampleSpriteClip.d.ts.map +1 -0
- package/lib/typescript/src/sprites/spriteAnimationState.d.ts +45 -0
- package/lib/typescript/src/sprites/spriteAnimationState.d.ts.map +1 -0
- package/lib/typescript/src/testing.d.ts +28 -0
- package/lib/typescript/src/testing.d.ts.map +1 -0
- package/lib/typescript/src/viewport2d/index.d.ts +3 -0
- package/lib/typescript/src/viewport2d/index.d.ts.map +1 -0
- package/lib/typescript/src/viewport2d/math.d.ts +25 -0
- package/lib/typescript/src/viewport2d/math.d.ts.map +1 -0
- package/lib/typescript/src/viewport2d/types.d.ts +59 -0
- package/lib/typescript/src/viewport2d/types.d.ts.map +1 -0
- package/package.json +120 -0
- package/src/assets/defineAssets.ts +62 -0
- package/src/assets/errors.ts +64 -0
- package/src/assets/types.ts +164 -0
- package/src/assets/validation.ts +158 -0
- package/src/core/frameDriver.ts +31 -0
- package/src/core/input/createInputBuffer.ts +337 -0
- package/src/core/input/types.ts +67 -0
- package/src/core/session/createGameSession.ts +652 -0
- package/src/core/session/deepFreeze.ts +158 -0
- package/src/core/session/diagnostics.ts +35 -0
- package/src/core/session/types.ts +122 -0
- package/src/definition/defineGame.ts +94 -0
- package/src/definition/types.ts +67 -0
- package/src/geometry/types.ts +7 -0
- package/src/index.ts +84 -0
- package/src/react/GamePointerInput.tsx +478 -0
- package/src/react/GameView.tsx +317 -0
- package/src/react/alphaClock.ts +59 -0
- package/src/react/assets/createGameAssetStore.ts +459 -0
- package/src/react/assets/decodeSkiaImage.ts +64 -0
- package/src/react/assets/errors.ts +7 -0
- package/src/react/assets/useGameAssets.ts +171 -0
- package/src/react/bindAppLifecycle.ts +79 -0
- package/src/react/bindGameSession.ts +41 -0
- package/src/react/gestureLifecycle.ts +73 -0
- package/src/react/instrumentation.ts +54 -0
- package/src/react/pointerBinding.ts +226 -0
- package/src/react/pointerCoalescer.ts +234 -0
- package/src/react/pointerContainment.ts +23 -0
- package/src/react/sprites/GameSprite.tsx +192 -0
- package/src/react/sprites/GameWorld2D.tsx +46 -0
- package/src/react/sprites/Sprite.tsx +194 -0
- package/src/react/sprites/SpriteBatch.tsx +219 -0
- package/src/react/sprites/spriteBatchPolicy.ts +21 -0
- package/src/react/sprites/spriteTransform.ts +163 -0
- package/src/react/viewportBinding.ts +104 -0
- package/src/react.ts +37 -0
- package/src/scene/defineScene.ts +38 -0
- package/src/scene/types.ts +79 -0
- package/src/sprites/sampleSpriteClip.ts +51 -0
- package/src/sprites/spriteAnimationState.ts +176 -0
- package/src/testing.ts +61 -0
- package/src/viewport2d/index.ts +7 -0
- package/src/viewport2d/math.ts +134 -0
- package/src/viewport2d/types.ts +63 -0
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
|
+
import { StyleSheet, View } from 'react-native';
|
|
5
|
+
import { GestureDetector, GestureStateManager, useManualGesture } from 'react-native-gesture-handler';
|
|
6
|
+
import { useFrameCallback, useSharedValue } from 'react-native-reanimated';
|
|
7
|
+
import { scheduleOnRN } from 'react-native-worklets';
|
|
8
|
+
import { GameViewportContext } from "./GameView.js";
|
|
9
|
+
import { canBeginPrimaryPointer, cancelOnActiveFinalize, deactivateAfterUp, reduceSamplerMirrorState, samplerMirrorFromBatch } from "./gestureLifecycle.js";
|
|
10
|
+
import { isBeginAllowed } from "./pointerContainment.js";
|
|
11
|
+
import { createPointerCoalescerState, reducePointerCoalescer } from "./pointerCoalescer.js";
|
|
12
|
+
import { PointerBinding } from "./pointerBinding.js";
|
|
13
|
+
|
|
14
|
+
/** Declared pointer action names of an input map. */
|
|
15
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
16
|
+
/** Monotonic adapter-owned binding generation; never resets to zero (F3). */
|
|
17
|
+
let nextBindingGeneration = 1;
|
|
18
|
+
|
|
19
|
+
/** Props for the pointer input adapter that covers the game surface. */
|
|
20
|
+
|
|
21
|
+
function advanceSharedCoalescer(sharedState, input) {
|
|
22
|
+
'worklet';
|
|
23
|
+
|
|
24
|
+
const transition = reducePointerCoalescer(sharedState.value, input);
|
|
25
|
+
sharedState.value = transition.state;
|
|
26
|
+
return transition.events;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* F2 trailing-flush sampler (review fix).
|
|
31
|
+
*
|
|
32
|
+
* Mounted only while the coalescer owns a pointer: the frame callback starts
|
|
33
|
+
* active at creation (autostart), forwards a deferred trailing move whenever
|
|
34
|
+
* the flush interval elapses, and the component unmounts — unregistering the
|
|
35
|
+
* callback — when the final pointer exits. No permanent frame callback and
|
|
36
|
+
* no runtime activation calls.
|
|
37
|
+
*/
|
|
38
|
+
function TrailingFlushSampler({
|
|
39
|
+
coalescerState,
|
|
40
|
+
forwardEventOnJS,
|
|
41
|
+
instrumentation,
|
|
42
|
+
layoutEpoch,
|
|
43
|
+
forwardSeq,
|
|
44
|
+
generation
|
|
45
|
+
}) {
|
|
46
|
+
// F2 acceptance: report the sampler's mounted lifecycle so the lab can
|
|
47
|
+
// prove no idle frame callback survives pointer exit, replacement, or
|
|
48
|
+
// screen close/reopen.
|
|
49
|
+
const instrumentationRef = useRef(instrumentation);
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
instrumentationRef.current?.onSamplerChanged?.(true);
|
|
52
|
+
return () => {
|
|
53
|
+
instrumentationRef.current?.onSamplerChanged?.(false);
|
|
54
|
+
};
|
|
55
|
+
}, []);
|
|
56
|
+
useFrameCallback(() => {
|
|
57
|
+
'worklet';
|
|
58
|
+
|
|
59
|
+
const batch = advanceSharedCoalescer(coalescerState, {
|
|
60
|
+
kind: 'flush',
|
|
61
|
+
nowMs: Date.now()
|
|
62
|
+
});
|
|
63
|
+
for (const forwarded of batch) {
|
|
64
|
+
instrumentation?.onForwarded?.(forwarded.kind, 'pointerId' in forwarded ? forwarded.pointerId : -1, Date.now());
|
|
65
|
+
forwardSeq.value += 1;
|
|
66
|
+
scheduleOnRN(forwardEventOnJS, {
|
|
67
|
+
...forwarded,
|
|
68
|
+
generation,
|
|
69
|
+
layoutEpoch: layoutEpoch.value,
|
|
70
|
+
seq: forwardSeq.value,
|
|
71
|
+
atMs: Date.now()
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Bind one primary pointer to a declared pointer action.
|
|
80
|
+
*
|
|
81
|
+
* Gesture Handler is an implementation detail: the manual gesture activates
|
|
82
|
+
* explicitly on touch down, mirrors the letterbox containment check on the UI
|
|
83
|
+
* runtime (failing the gesture before activation), forwards plain touch data
|
|
84
|
+
* through a coalescer that crosses runtimes at most once per fixed step
|
|
85
|
+
* (latest dirty position only; edges never throttled or dropped), and ends
|
|
86
|
+
* explicitly when the last touch lifts. Ownership and edge sampling stay
|
|
87
|
+
* authoritative in the session input buffer, which re-validates every
|
|
88
|
+
* forwarded event on the JS side.
|
|
89
|
+
*
|
|
90
|
+
* All separately registered touch-handler worklets share one explicit
|
|
91
|
+
* coalescer SharedValue; closure-local mutation is not used because each
|
|
92
|
+
* handler can receive its own serialized closure copy. The binding is stable
|
|
93
|
+
* across ordinary React renders and is recreated only when its semantic
|
|
94
|
+
* session, action, or viewport owner changes.
|
|
95
|
+
*/
|
|
96
|
+
export function GamePointerInput({
|
|
97
|
+
game,
|
|
98
|
+
action,
|
|
99
|
+
instrumentation
|
|
100
|
+
}) {
|
|
101
|
+
const viewportContext = useContext(GameViewportContext);
|
|
102
|
+
if (viewportContext === null) {
|
|
103
|
+
throw new Error('GamePointerInput must be rendered inside a GameView');
|
|
104
|
+
}
|
|
105
|
+
const viewportShared = viewportContext.viewport;
|
|
106
|
+
const maxMoveIntervalMs = game.getRenderFrame().stepMs;
|
|
107
|
+
const coalescerState = useSharedValue(() => createPointerCoalescerState(maxMoveIntervalMs));
|
|
108
|
+
const viewportBinding = viewportContext.binding;
|
|
109
|
+
// F3 follow-up: the binding identity includes the declared action, the
|
|
110
|
+
// session input controller, and the viewport owner; changing any of them
|
|
111
|
+
// creates a fresh binding stamped with a NEW monotonic generation that
|
|
112
|
+
// never resets to zero. The worklet closures created in the same render
|
|
113
|
+
// stamp packets with that same generation, so the packet producer and
|
|
114
|
+
// consumer agree by construction — no post-commit synchronization.
|
|
115
|
+
const binding = useMemo(() => new PointerBinding(action, game.input, () => viewportBinding.resolved, nextBindingGeneration++), [action, game, viewportBinding]);
|
|
116
|
+
const generation = binding.generation;
|
|
117
|
+
// F6/F3: the layout epoch is adapter-owned (ref + UI mirror), bumped only
|
|
118
|
+
// on layout revisions and unmount; it never resets, so replacement cannot
|
|
119
|
+
// desynchronize it. The RN-side dispatch check rejects old-layout packets.
|
|
120
|
+
const layoutEpochRef = useRef(0);
|
|
121
|
+
const layoutEpoch = useSharedValue(0);
|
|
122
|
+
const bumpLayoutEpoch = useCallback(() => {
|
|
123
|
+
layoutEpochRef.current += 1;
|
|
124
|
+
layoutEpoch.value = layoutEpochRef.current;
|
|
125
|
+
}, [layoutEpoch]);
|
|
126
|
+
// F1: monotonic forward sequence carried with every packet so the RN side
|
|
127
|
+
// can attribute latency causally (never by reading a separate "latest").
|
|
128
|
+
const forwardSeq = useSharedValue(0);
|
|
129
|
+
|
|
130
|
+
// F2 follow-up: the sampler mirror is keyed by binding generation, so a
|
|
131
|
+
// replacement binding is inactive by construction and a stale terminal
|
|
132
|
+
// edge from an older generation can never alter the current generation's
|
|
133
|
+
// sampler state.
|
|
134
|
+
const [samplerState, setSamplerState] = useState({
|
|
135
|
+
generation: -1,
|
|
136
|
+
active: false
|
|
137
|
+
});
|
|
138
|
+
const reportSamplerState = useCallback(next => {
|
|
139
|
+
setSamplerState(previous => reduceSamplerMirrorState(generation, previous, next));
|
|
140
|
+
}, [generation]);
|
|
141
|
+
|
|
142
|
+
// F2 review: `autostart` is only consulted at creation (changing it later
|
|
143
|
+
// re-registers but never activates) and `setActive` from an effect proved
|
|
144
|
+
// unreliable in this stack, so the sampler is a conditionally mounted
|
|
145
|
+
// component (see TrailingFlushSampler): it mounts with autostart active
|
|
146
|
+
// exactly while this mirror is true and unmounts when the pointer exits.
|
|
147
|
+
|
|
148
|
+
// JS-thread handler (never captured by gesture worklets): the binding
|
|
149
|
+
// rejects packets stamped with a stale epoch (layout revision, binding
|
|
150
|
+
// replacement, unmount) and re-validates the viewport before forwarding
|
|
151
|
+
// into the session input buffer.
|
|
152
|
+
const forwardEventOnJS = useCallback(packet => {
|
|
153
|
+
// F6/F3: adapter-owned layout epoch — packets scheduled under an older
|
|
154
|
+
// layout die here, before the binding sees them.
|
|
155
|
+
if (packet.layoutEpoch !== layoutEpochRef.current) {
|
|
156
|
+
instrumentation?.onDispatchResult?.(packet.seq, packet.atMs, false);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const accepted = binding.dispatch(packet);
|
|
160
|
+
instrumentation?.onDispatchResult?.(packet.seq, packet.atMs, accepted);
|
|
161
|
+
}, [binding, instrumentation]);
|
|
162
|
+
const handleTouchesDown = useCallback(event => {
|
|
163
|
+
'worklet';
|
|
164
|
+
|
|
165
|
+
const touch = event.changedTouches[0];
|
|
166
|
+
if (touch === undefined) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
instrumentation?.onRawTouch?.('down', touch.id, Date.now());
|
|
170
|
+
// This adapter owns one primary pointer for the whole native gesture.
|
|
171
|
+
// If another touch is already present, it cannot replace a pointer that
|
|
172
|
+
// ended earlier while the manual recognizer is still active.
|
|
173
|
+
if (!canBeginPrimaryPointer(event.numberOfTouches)) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
// UI-side containment mirror: an invalid layout or `fit` letterbox
|
|
177
|
+
// begin fails the gesture before it activates. JS re-validates.
|
|
178
|
+
if (!isBeginAllowed(viewportShared.value, touch.x, touch.y)) {
|
|
179
|
+
GestureStateManager.fail(event.handlerTag);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const batch = advanceSharedCoalescer(coalescerState, {
|
|
183
|
+
kind: 'down',
|
|
184
|
+
pointerId: touch.id,
|
|
185
|
+
x: touch.x,
|
|
186
|
+
y: touch.y,
|
|
187
|
+
nowMs: Date.now()
|
|
188
|
+
});
|
|
189
|
+
for (const forwarded of batch) {
|
|
190
|
+
instrumentation?.onForwarded?.(forwarded.kind, 'pointerId' in forwarded ? forwarded.pointerId : -1, Date.now());
|
|
191
|
+
forwardSeq.value += 1;
|
|
192
|
+
scheduleOnRN(forwardEventOnJS, {
|
|
193
|
+
...forwarded,
|
|
194
|
+
generation,
|
|
195
|
+
layoutEpoch: layoutEpoch.value,
|
|
196
|
+
seq: forwardSeq.value,
|
|
197
|
+
atMs: Date.now()
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
const nextActive = samplerMirrorFromBatch(batch);
|
|
201
|
+
if (nextActive !== undefined) {
|
|
202
|
+
scheduleOnRN(reportSamplerState, {
|
|
203
|
+
generation,
|
|
204
|
+
active: nextActive
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
GestureStateManager.activate(event.handlerTag);
|
|
208
|
+
}, [coalescerState, forwardEventOnJS, generation, instrumentation, layoutEpoch, reportSamplerState, viewportShared]);
|
|
209
|
+
const handleTouchesMove = useCallback(event => {
|
|
210
|
+
'worklet';
|
|
211
|
+
|
|
212
|
+
for (const touch of event.changedTouches) {
|
|
213
|
+
instrumentation?.onRawTouch?.('move', touch.id, Date.now());
|
|
214
|
+
const batch = advanceSharedCoalescer(coalescerState, {
|
|
215
|
+
kind: 'move',
|
|
216
|
+
pointerId: touch.id,
|
|
217
|
+
x: touch.x,
|
|
218
|
+
y: touch.y,
|
|
219
|
+
nowMs: Date.now()
|
|
220
|
+
});
|
|
221
|
+
for (const forwarded of batch) {
|
|
222
|
+
instrumentation?.onForwarded?.(forwarded.kind, 'pointerId' in forwarded ? forwarded.pointerId : -1, Date.now());
|
|
223
|
+
forwardSeq.value += 1;
|
|
224
|
+
scheduleOnRN(forwardEventOnJS, {
|
|
225
|
+
...forwarded,
|
|
226
|
+
generation,
|
|
227
|
+
layoutEpoch: layoutEpoch.value,
|
|
228
|
+
seq: forwardSeq.value,
|
|
229
|
+
atMs: Date.now()
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}, [coalescerState, forwardEventOnJS, generation, instrumentation, layoutEpoch]);
|
|
234
|
+
const handleTouchesUp = useCallback(event => {
|
|
235
|
+
'worklet';
|
|
236
|
+
|
|
237
|
+
let nextActive;
|
|
238
|
+
for (const touch of event.changedTouches) {
|
|
239
|
+
instrumentation?.onRawTouch?.('up', touch.id, Date.now());
|
|
240
|
+
const batch = advanceSharedCoalescer(coalescerState, {
|
|
241
|
+
kind: 'up',
|
|
242
|
+
pointerId: touch.id,
|
|
243
|
+
x: touch.x,
|
|
244
|
+
y: touch.y,
|
|
245
|
+
nowMs: Date.now()
|
|
246
|
+
});
|
|
247
|
+
for (const forwarded of batch) {
|
|
248
|
+
instrumentation?.onForwarded?.(forwarded.kind, 'pointerId' in forwarded ? forwarded.pointerId : -1, Date.now());
|
|
249
|
+
forwardSeq.value += 1;
|
|
250
|
+
scheduleOnRN(forwardEventOnJS, {
|
|
251
|
+
...forwarded,
|
|
252
|
+
generation,
|
|
253
|
+
layoutEpoch: layoutEpoch.value,
|
|
254
|
+
seq: forwardSeq.value,
|
|
255
|
+
atMs: Date.now()
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
const mirror = samplerMirrorFromBatch(batch);
|
|
259
|
+
if (mirror !== undefined) {
|
|
260
|
+
nextActive = mirror;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (nextActive !== undefined) {
|
|
264
|
+
scheduleOnRN(reportSamplerState, {
|
|
265
|
+
generation,
|
|
266
|
+
active: nextActive
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
if (deactivateAfterUp(event.numberOfTouches)) {
|
|
270
|
+
GestureStateManager.deactivate(event.handlerTag);
|
|
271
|
+
}
|
|
272
|
+
}, [coalescerState, forwardEventOnJS, generation, instrumentation, layoutEpoch, reportSamplerState]);
|
|
273
|
+
const handleTouchesCancel = useCallback(() => {
|
|
274
|
+
'worklet';
|
|
275
|
+
|
|
276
|
+
instrumentation?.onRawTouch?.('cancel', -1, Date.now());
|
|
277
|
+
const batch = advanceSharedCoalescer(coalescerState, {
|
|
278
|
+
kind: 'cancel',
|
|
279
|
+
nowMs: Date.now()
|
|
280
|
+
});
|
|
281
|
+
for (const forwarded of batch) {
|
|
282
|
+
instrumentation?.onForwarded?.(forwarded.kind, -1, Date.now());
|
|
283
|
+
forwardSeq.value += 1;
|
|
284
|
+
scheduleOnRN(forwardEventOnJS, {
|
|
285
|
+
...forwarded,
|
|
286
|
+
generation,
|
|
287
|
+
layoutEpoch: layoutEpoch.value,
|
|
288
|
+
seq: forwardSeq.value,
|
|
289
|
+
atMs: Date.now()
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
const nextActive = samplerMirrorFromBatch(batch);
|
|
293
|
+
if (nextActive !== undefined) {
|
|
294
|
+
scheduleOnRN(reportSamplerState, {
|
|
295
|
+
generation,
|
|
296
|
+
active: nextActive
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}, [coalescerState, forwardEventOnJS, generation, instrumentation, layoutEpoch, reportSamplerState]);
|
|
300
|
+
const handleFinalize = useCallback(() => {
|
|
301
|
+
'worklet';
|
|
302
|
+
|
|
303
|
+
if (!cancelOnActiveFinalize(coalescerState.value.active?.pointerId)) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
instrumentation?.onRawTouch?.('cancel', -1, Date.now());
|
|
307
|
+
const batch = advanceSharedCoalescer(coalescerState, {
|
|
308
|
+
kind: 'cancel',
|
|
309
|
+
nowMs: Date.now()
|
|
310
|
+
});
|
|
311
|
+
for (const forwarded of batch) {
|
|
312
|
+
instrumentation?.onForwarded?.(forwarded.kind, -1, Date.now());
|
|
313
|
+
forwardSeq.value += 1;
|
|
314
|
+
scheduleOnRN(forwardEventOnJS, {
|
|
315
|
+
...forwarded,
|
|
316
|
+
generation,
|
|
317
|
+
layoutEpoch: layoutEpoch.value,
|
|
318
|
+
seq: forwardSeq.value,
|
|
319
|
+
atMs: Date.now()
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
const nextActive = samplerMirrorFromBatch(batch);
|
|
323
|
+
if (nextActive !== undefined) {
|
|
324
|
+
scheduleOnRN(reportSamplerState, {
|
|
325
|
+
generation,
|
|
326
|
+
active: nextActive
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
}, [coalescerState, forwardEventOnJS, generation, instrumentation, layoutEpoch, reportSamplerState]);
|
|
330
|
+
|
|
331
|
+
// RNGH 3 re-registers its gesture callbacks whenever this config identity
|
|
332
|
+
// changes. Keep both the config and its worklets stable across unrelated
|
|
333
|
+
// React renders (for example, a score HUD update during a live drag).
|
|
334
|
+
const gestureConfig = useMemo(() => ({
|
|
335
|
+
shouldCancelWhenOutside: false,
|
|
336
|
+
onTouchesDown: handleTouchesDown,
|
|
337
|
+
onTouchesMove: handleTouchesMove,
|
|
338
|
+
onTouchesUp: handleTouchesUp,
|
|
339
|
+
onTouchesCancel: handleTouchesCancel,
|
|
340
|
+
onFinalize: handleFinalize
|
|
341
|
+
}), [handleFinalize, handleTouchesCancel, handleTouchesDown, handleTouchesMove, handleTouchesUp]);
|
|
342
|
+
const gesture = useManualGesture(gestureConfig);
|
|
343
|
+
useEffect(() => {
|
|
344
|
+
// F6/F3: a layout revision advances the adapter-owned layout epoch so
|
|
345
|
+
// queued old-layout packets die on arrival, while the active gesture
|
|
346
|
+
// keeps flowing (the binding reads the viewport lazily and the
|
|
347
|
+
// coalescer state is preserved). Binding replacement needs no epoch
|
|
348
|
+
// synchronization: the generation agreement is by construction.
|
|
349
|
+
const unsubscribeLayout = viewportBinding.subscribe(() => {
|
|
350
|
+
bumpLayoutEpoch();
|
|
351
|
+
});
|
|
352
|
+
return () => {
|
|
353
|
+
unsubscribeLayout();
|
|
354
|
+
// Unmount or replacement: bump the layout epoch so packets already in
|
|
355
|
+
// flight become harmless no-ops, neutralize old input ownership exactly
|
|
356
|
+
// once, reset the coalescer, remove the old sampler (generation
|
|
357
|
+
// mismatch makes it inactive by construction), and dispose the binding.
|
|
358
|
+
bumpLayoutEpoch();
|
|
359
|
+
setSamplerState({
|
|
360
|
+
generation: -1,
|
|
361
|
+
active: false
|
|
362
|
+
});
|
|
363
|
+
if (game.status !== 'disposed') {
|
|
364
|
+
binding.cancel();
|
|
365
|
+
}
|
|
366
|
+
coalescerState.value = createPointerCoalescerState(maxMoveIntervalMs);
|
|
367
|
+
binding.dispose();
|
|
368
|
+
};
|
|
369
|
+
}, [binding, bumpLayoutEpoch, coalescerState, game, layoutEpoch, maxMoveIntervalMs, viewportBinding]);
|
|
370
|
+
return /*#__PURE__*/_jsx(GestureDetector, {
|
|
371
|
+
gesture: gesture,
|
|
372
|
+
children: /*#__PURE__*/_jsx(View, {
|
|
373
|
+
style: StyleSheet.absoluteFill,
|
|
374
|
+
children: samplerState.active && samplerState.generation === generation ? /*#__PURE__*/_jsx(TrailingFlushSampler, {
|
|
375
|
+
coalescerState: coalescerState,
|
|
376
|
+
forwardEventOnJS: forwardEventOnJS,
|
|
377
|
+
instrumentation: instrumentation,
|
|
378
|
+
layoutEpoch: layoutEpoch,
|
|
379
|
+
forwardSeq: forwardSeq,
|
|
380
|
+
generation: generation
|
|
381
|
+
}) : null
|
|
382
|
+
})
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
//# sourceMappingURL=GamePointerInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useCallback","useContext","useEffect","useMemo","useRef","useState","StyleSheet","View","GestureDetector","GestureStateManager","useManualGesture","useFrameCallback","useSharedValue","scheduleOnRN","GameViewportContext","canBeginPrimaryPointer","cancelOnActiveFinalize","deactivateAfterUp","reduceSamplerMirrorState","samplerMirrorFromBatch","isBeginAllowed","createPointerCoalescerState","reducePointerCoalescer","PointerBinding","jsx","_jsx","nextBindingGeneration","advanceSharedCoalescer","sharedState","input","transition","value","state","events","TrailingFlushSampler","coalescerState","forwardEventOnJS","instrumentation","layoutEpoch","forwardSeq","generation","instrumentationRef","current","onSamplerChanged","batch","kind","nowMs","Date","now","forwarded","onForwarded","pointerId","seq","atMs","GamePointerInput","game","action","viewportContext","Error","viewportShared","viewport","maxMoveIntervalMs","getRenderFrame","stepMs","viewportBinding","binding","resolved","layoutEpochRef","bumpLayoutEpoch","samplerState","setSamplerState","active","reportSamplerState","next","previous","packet","onDispatchResult","accepted","dispatch","handleTouchesDown","event","touch","changedTouches","undefined","onRawTouch","id","numberOfTouches","x","y","fail","handlerTag","nextActive","activate","handleTouchesMove","handleTouchesUp","mirror","deactivate","handleTouchesCancel","handleFinalize","gestureConfig","shouldCancelWhenOutside","onTouchesDown","onTouchesMove","onTouchesUp","onTouchesCancel","onFinalize","gesture","unsubscribeLayout","subscribe","status","cancel","dispose","children","style","absoluteFill"],"sourceRoot":"../../../src","sources":["react/GamePointerInput.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { Canvas } from '@shopify/react-native-skia';
|
|
4
|
+
import { createContext, useCallback, useEffect, useMemo, useRef } from 'react';
|
|
5
|
+
import { AppState, StyleSheet, View } from 'react-native';
|
|
6
|
+
import { useFrameCallback, useSharedValue } from 'react-native-reanimated';
|
|
7
|
+
import { scheduleOnRN } from 'react-native-worklets';
|
|
8
|
+
import { advanceAlpha } from "./alphaClock.js";
|
|
9
|
+
import { bindAppLifecycle } from "./bindAppLifecycle.js";
|
|
10
|
+
import { bindGameSession } from "./bindGameSession.js";
|
|
11
|
+
import { bindingForViewport } from "./viewportBinding.js";
|
|
12
|
+
|
|
13
|
+
/** Stable imperative values supplied to a Skia renderer component. */
|
|
14
|
+
|
|
15
|
+
/** Props for the Skia-backed GameKit view. */
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Context supplying the resolved viewport to pointer input children.
|
|
19
|
+
*
|
|
20
|
+
* `GamePointerInput` consumes the binding for JS-side conversion and the
|
|
21
|
+
* shared value for the UI-side containment mirror, so drawing and hit
|
|
22
|
+
* testing always use the same resolved viewport instance for a layout
|
|
23
|
+
* revision.
|
|
24
|
+
*/
|
|
25
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
26
|
+
export const GameViewportContext = /*#__PURE__*/createContext(null);
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Mount a headless GameSession into a Skia canvas.
|
|
30
|
+
*
|
|
31
|
+
* Simulation commits update the frame shared value at commit frequency (one
|
|
32
|
+
* per fixed step, never per display frame); the presentation fraction lives
|
|
33
|
+
* on the UI runtime and is advanced by a frame callback that resets on every
|
|
34
|
+
* new commit, clamps at 1, and never extrapolates. The clock is gated by a
|
|
35
|
+
* `running` shared value so pause, background, unmount, and dispose hold the
|
|
36
|
+
* presentation. React owns the surface and static overlay tree; it is never
|
|
37
|
+
* the frame store. The session is started while mounted, paused on cleanup
|
|
38
|
+
* and app backgrounding, and is never disposed by this component — the
|
|
39
|
+
* creator owns disposal.
|
|
40
|
+
*/
|
|
41
|
+
/**
|
|
42
|
+
* Per-session presentation binding (RF6).
|
|
43
|
+
*
|
|
44
|
+
* Keyed by the session so the frame, alpha, epoch, and clock initialize from
|
|
45
|
+
* the new session BEFORE its renderer can execute — a replacement renderer
|
|
46
|
+
* never observes the previous session's frame, even when both scenes are
|
|
47
|
+
* named the same.
|
|
48
|
+
*/
|
|
49
|
+
function GamePresentation({
|
|
50
|
+
game,
|
|
51
|
+
assets,
|
|
52
|
+
renderer,
|
|
53
|
+
viewportValue,
|
|
54
|
+
instrumentationRef
|
|
55
|
+
}) {
|
|
56
|
+
const Renderer = renderer;
|
|
57
|
+
const frame = useSharedValue(() => game.getRenderFrame());
|
|
58
|
+
const alpha = useSharedValue(0);
|
|
59
|
+
const running = useSharedValue(true);
|
|
60
|
+
// Binding epoch: bumped per (re)subscription so a replacement session whose
|
|
61
|
+
// revision restarts at zero is still accepted by the UI clock.
|
|
62
|
+
const epoch = useSharedValue(0);
|
|
63
|
+
const clockEpoch = useSharedValue(0);
|
|
64
|
+
const clockRevision = useSharedValue(-1);
|
|
65
|
+
// F1: last revision/epoch the UI clock observed, so the instrumentation can
|
|
66
|
+
// report the FIRST UI frame that saw a new commit.
|
|
67
|
+
const observedRevision = useSharedValue(-1);
|
|
68
|
+
const observedEpoch = useSharedValue(-1);
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
epoch.value += 1;
|
|
71
|
+
// RF6: the frame is seeded at mount from this session; the keyed remount
|
|
72
|
+
// guarantees the renderer below never reads the previous session's frame.
|
|
73
|
+
frame.value = game.getRenderFrame();
|
|
74
|
+
const cleanupBinding = bindGameSession(game, nextFrame => {
|
|
75
|
+
frame.value = nextFrame;
|
|
76
|
+
instrumentationRef.current?.onPresentCommit?.(nextFrame.revision, Date.now());
|
|
77
|
+
});
|
|
78
|
+
const cleanupLifecycle = bindAppLifecycle(AppState, {
|
|
79
|
+
getStatus: () => game.status,
|
|
80
|
+
pause: () => {
|
|
81
|
+
running.value = false;
|
|
82
|
+
if (game.status !== 'disposed') {
|
|
83
|
+
game.pause();
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
resume: () => {
|
|
87
|
+
if (game.status !== 'disposed') {
|
|
88
|
+
game.start();
|
|
89
|
+
running.value = true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
return () => {
|
|
94
|
+
cleanupLifecycle();
|
|
95
|
+
cleanupBinding();
|
|
96
|
+
};
|
|
97
|
+
}, [epoch, frame, game, running]);
|
|
98
|
+
|
|
99
|
+
// F1: the first UI frame that sees a new commit revision is reported back
|
|
100
|
+
// to the RN runtime through scheduleOnRN — never by calling the JS hook
|
|
101
|
+
// directly from the UI worklet (cross-runtime calls crash the app).
|
|
102
|
+
const reportUiObserved = useCallback((revision, atMs) => {
|
|
103
|
+
instrumentationRef.current?.onUiRevisionObserved?.(revision, atMs);
|
|
104
|
+
}, []);
|
|
105
|
+
|
|
106
|
+
// UI-owned alpha clock: advances only while the session is running,
|
|
107
|
+
// resets on every new commit, clamps at 1 and holds (no extrapolation).
|
|
108
|
+
useFrameCallback(frameInfo => {
|
|
109
|
+
'worklet';
|
|
110
|
+
|
|
111
|
+
if (!running.value) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const envelope = frame.value;
|
|
115
|
+
if (observedEpoch.value !== epoch.value || observedRevision.value !== envelope.revision) {
|
|
116
|
+
observedEpoch.value = epoch.value;
|
|
117
|
+
observedRevision.value = envelope.revision;
|
|
118
|
+
scheduleOnRN(reportUiObserved, envelope.revision, Date.now());
|
|
119
|
+
}
|
|
120
|
+
const previousState = {
|
|
121
|
+
epoch: clockEpoch.value,
|
|
122
|
+
revision: clockRevision.value,
|
|
123
|
+
alpha: alpha.value
|
|
124
|
+
};
|
|
125
|
+
const nextState = advanceAlpha(previousState, {
|
|
126
|
+
epoch: epoch.value,
|
|
127
|
+
revision: envelope.revision,
|
|
128
|
+
stepMs: envelope.stepMs
|
|
129
|
+
}, frameInfo.timeSincePreviousFrame ?? 1000 / 60);
|
|
130
|
+
clockEpoch.value = nextState.epoch;
|
|
131
|
+
clockRevision.value = nextState.revision;
|
|
132
|
+
alpha.value = nextState.alpha;
|
|
133
|
+
});
|
|
134
|
+
return /*#__PURE__*/_jsx(Renderer, {
|
|
135
|
+
frame: frame,
|
|
136
|
+
alpha: alpha,
|
|
137
|
+
viewport: viewportValue,
|
|
138
|
+
...(assets === undefined ? {} : {
|
|
139
|
+
assets
|
|
140
|
+
})
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Stable per-session fallback identity (T8.6): one incrementing id per
|
|
145
|
+
// session object for the life of the module. A replaced session is a new
|
|
146
|
+
// object and therefore a new id; the same session keeps its id across
|
|
147
|
+
// renders so the presentation never remounts spuriously.
|
|
148
|
+
const sessionPresentationIds = new WeakMap();
|
|
149
|
+
let nextSessionPresentationId = 1;
|
|
150
|
+
function sessionPresentationId(game) {
|
|
151
|
+
let id = sessionPresentationIds.get(game);
|
|
152
|
+
if (id === undefined) {
|
|
153
|
+
id = nextSessionPresentationId;
|
|
154
|
+
nextSessionPresentationId += 1;
|
|
155
|
+
sessionPresentationIds.set(game, id);
|
|
156
|
+
}
|
|
157
|
+
return id;
|
|
158
|
+
}
|
|
159
|
+
export function GameView({
|
|
160
|
+
game,
|
|
161
|
+
presentationKey,
|
|
162
|
+
assets,
|
|
163
|
+
renderer: Renderer,
|
|
164
|
+
children,
|
|
165
|
+
style,
|
|
166
|
+
instrumentation
|
|
167
|
+
}) {
|
|
168
|
+
const instrumentationRef = useRef(instrumentation);
|
|
169
|
+
const bindingRef = useRef(null);
|
|
170
|
+
bindingRef.current = bindingForViewport(game.viewport, bindingRef.current);
|
|
171
|
+
const binding = bindingRef.current;
|
|
172
|
+
const viewportValue = useSharedValue(undefined);
|
|
173
|
+
const viewportContext = useMemo(() => ({
|
|
174
|
+
binding,
|
|
175
|
+
viewport: viewportValue
|
|
176
|
+
}), [binding, viewportValue]);
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
instrumentationRef.current = instrumentation;
|
|
179
|
+
}, [instrumentation]);
|
|
180
|
+
useEffect(() => {
|
|
181
|
+
viewportValue.value = binding.resolved;
|
|
182
|
+
}, [binding, viewportValue]);
|
|
183
|
+
useEffect(() => () => {
|
|
184
|
+
binding.dispose();
|
|
185
|
+
}, [binding]);
|
|
186
|
+
return /*#__PURE__*/_jsx(GameViewportContext.Provider, {
|
|
187
|
+
value: viewportContext,
|
|
188
|
+
children: /*#__PURE__*/_jsxs(View, {
|
|
189
|
+
style: [styles.surface, style],
|
|
190
|
+
onLayout: event => {
|
|
191
|
+
const {
|
|
192
|
+
width,
|
|
193
|
+
height
|
|
194
|
+
} = event.nativeEvent.layout;
|
|
195
|
+
binding.setSurfaceSize({
|
|
196
|
+
width,
|
|
197
|
+
height
|
|
198
|
+
});
|
|
199
|
+
viewportValue.value = binding.resolved;
|
|
200
|
+
},
|
|
201
|
+
children: [/*#__PURE__*/_jsx(Canvas, {
|
|
202
|
+
style: StyleSheet.absoluteFill,
|
|
203
|
+
children: /*#__PURE__*/_jsx(GamePresentation, {
|
|
204
|
+
game: game,
|
|
205
|
+
assets: assets,
|
|
206
|
+
renderer: Renderer,
|
|
207
|
+
viewportValue: viewportValue,
|
|
208
|
+
instrumentationRef: instrumentationRef
|
|
209
|
+
}, presentationKey ?? sessionPresentationId(game))
|
|
210
|
+
}), children === undefined ? null : /*#__PURE__*/_jsx(View, {
|
|
211
|
+
pointerEvents: "box-none",
|
|
212
|
+
style: StyleSheet.absoluteFill,
|
|
213
|
+
children: children
|
|
214
|
+
})]
|
|
215
|
+
})
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
const styles = StyleSheet.create({
|
|
219
|
+
surface: {
|
|
220
|
+
overflow: 'hidden'
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
//# sourceMappingURL=GameView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Canvas","createContext","useCallback","useEffect","useMemo","useRef","AppState","StyleSheet","View","useFrameCallback","useSharedValue","scheduleOnRN","advanceAlpha","bindAppLifecycle","bindGameSession","bindingForViewport","jsx","_jsx","jsxs","_jsxs","GameViewportContext","GamePresentation","game","assets","renderer","viewportValue","instrumentationRef","Renderer","frame","getRenderFrame","alpha","running","epoch","clockEpoch","clockRevision","observedRevision","observedEpoch","value","cleanupBinding","nextFrame","current","onPresentCommit","revision","Date","now","cleanupLifecycle","getStatus","status","pause","resume","start","reportUiObserved","atMs","onUiRevisionObserved","frameInfo","envelope","previousState","nextState","stepMs","timeSincePreviousFrame","viewport","undefined","sessionPresentationIds","WeakMap","nextSessionPresentationId","sessionPresentationId","id","get","set","GameView","presentationKey","children","style","instrumentation","bindingRef","binding","viewportContext","resolved","dispose","Provider","styles","surface","onLayout","event","width","height","nativeEvent","layout","setSurfaceSize","absoluteFill","pointerEvents","create","overflow"],"sourceRoot":"../../../src","sources":["react/GameView.tsx"],"mappings":"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","ignoreList":[]}
|