@mirasen/chessboard 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 +7 -0
- package/LICENSE +21 -0
- package/README.md +96 -0
- package/assets/pieces/chessnut/ATTRIBUTION.md +13 -0
- package/assets/pieces/chessnut/LICENSE.txt +202 -0
- package/assets/pieces/chessnut/bB.svg +58 -0
- package/assets/pieces/chessnut/bK.svg +51 -0
- package/assets/pieces/chessnut/bN.svg +19 -0
- package/assets/pieces/chessnut/bP.svg +17 -0
- package/assets/pieces/chessnut/bQ.svg +97 -0
- package/assets/pieces/chessnut/bR.svg +34 -0
- package/assets/pieces/chessnut/wB.svg +61 -0
- package/assets/pieces/chessnut/wK.svg +71 -0
- package/assets/pieces/chessnut/wN.svg +19 -0
- package/assets/pieces/chessnut/wP.svg +17 -0
- package/assets/pieces/chessnut/wQ.svg +40 -0
- package/assets/pieces/chessnut/wR.svg +38 -0
- package/dist/animation/planner.d.ts +6 -0
- package/dist/animation/planner.js +128 -0
- package/dist/animation/render/fade.d.ts +7 -0
- package/dist/animation/render/fade.js +24 -0
- package/dist/animation/render/move.d.ts +7 -0
- package/dist/animation/render/move.js +28 -0
- package/dist/animation/render/plan.d.ts +14 -0
- package/dist/animation/render/plan.js +69 -0
- package/dist/animation/render/static.d.ts +7 -0
- package/dist/animation/render/static.js +21 -0
- package/dist/animation/render/types.d.ts +21 -0
- package/dist/animation/render/types.js +1 -0
- package/dist/animation/types.d.ts +46 -0
- package/dist/animation/types.js +6 -0
- package/dist/extensions/animation/factory.d.ts +3 -0
- package/dist/extensions/animation/factory.js +88 -0
- package/dist/extensions/animation/types.d.ts +11 -0
- package/dist/extensions/animation/types.js +1 -0
- package/dist/extensions/factory/main.d.ts +2 -0
- package/dist/extensions/factory/main.js +101 -0
- package/dist/extensions/factory/runtime.d.ts +5 -0
- package/dist/extensions/factory/runtime.js +43 -0
- package/dist/extensions/first-party/active-target/factory.d.ts +2 -0
- package/dist/extensions/first-party/active-target/factory.js +109 -0
- package/dist/extensions/first-party/active-target/types.d.ts +25 -0
- package/dist/extensions/first-party/active-target/types.js +15 -0
- package/dist/extensions/first-party/board-events/factory.d.ts +2 -0
- package/dist/extensions/first-party/board-events/factory.js +65 -0
- package/dist/extensions/first-party/board-events/types.d.ts +27 -0
- package/dist/extensions/first-party/board-events/types.js +2 -0
- package/dist/extensions/first-party/common/helpers.d.ts +8 -0
- package/dist/extensions/first-party/common/helpers.js +33 -0
- package/dist/extensions/first-party/common/types.d.ts +10 -0
- package/dist/extensions/first-party/common/types.js +1 -0
- package/dist/extensions/first-party/last-move/factory.d.ts +2 -0
- package/dist/extensions/first-party/last-move/factory.js +106 -0
- package/dist/extensions/first-party/last-move/types.d.ts +19 -0
- package/dist/extensions/first-party/last-move/types.js +6 -0
- package/dist/extensions/first-party/legal-moves/factory.d.ts +2 -0
- package/dist/extensions/first-party/legal-moves/factory.js +101 -0
- package/dist/extensions/first-party/legal-moves/types.d.ts +29 -0
- package/dist/extensions/first-party/legal-moves/types.js +19 -0
- package/dist/extensions/first-party/main-renderer/animation/factory.d.ts +4 -0
- package/dist/extensions/first-party/main-renderer/animation/factory.js +35 -0
- package/dist/extensions/first-party/main-renderer/animation/render.d.ts +7 -0
- package/dist/extensions/first-party/main-renderer/animation/render.js +46 -0
- package/dist/extensions/first-party/main-renderer/animation/types.d.ts +24 -0
- package/dist/extensions/first-party/main-renderer/animation/types.js +1 -0
- package/dist/extensions/first-party/main-renderer/animation/update.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/animation/update.js +40 -0
- package/dist/extensions/first-party/main-renderer/board/factory.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/board/factory.js +16 -0
- package/dist/extensions/first-party/main-renderer/board/render.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/board/render.js +24 -0
- package/dist/extensions/first-party/main-renderer/board/types.d.ts +10 -0
- package/dist/extensions/first-party/main-renderer/board/types.js +1 -0
- package/dist/extensions/first-party/main-renderer/board/update.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/board/update.js +27 -0
- package/dist/extensions/first-party/main-renderer/coordinates/factory.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/coordinates/factory.js +9 -0
- package/dist/extensions/first-party/main-renderer/coordinates/render.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/coordinates/render.js +60 -0
- package/dist/extensions/first-party/main-renderer/coordinates/types.d.ts +8 -0
- package/dist/extensions/first-party/main-renderer/coordinates/types.js +1 -0
- package/dist/extensions/first-party/main-renderer/drag/factory.d.ts +4 -0
- package/dist/extensions/first-party/main-renderer/drag/factory.js +23 -0
- package/dist/extensions/first-party/main-renderer/drag/render.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/drag/render.js +27 -0
- package/dist/extensions/first-party/main-renderer/drag/types.d.ts +16 -0
- package/dist/extensions/first-party/main-renderer/drag/types.js +1 -0
- package/dist/extensions/first-party/main-renderer/drag/update.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/drag/update.js +23 -0
- package/dist/extensions/first-party/main-renderer/factory.d.ts +2 -0
- package/dist/extensions/first-party/main-renderer/factory.js +95 -0
- package/dist/extensions/first-party/main-renderer/normalize.d.ts +4 -0
- package/dist/extensions/first-party/main-renderer/normalize.js +27 -0
- package/dist/extensions/first-party/main-renderer/pieces/factory.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/pieces/factory.js +27 -0
- package/dist/extensions/first-party/main-renderer/pieces/render.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/pieces/render.js +45 -0
- package/dist/extensions/first-party/main-renderer/pieces/suppress.d.ts +5 -0
- package/dist/extensions/first-party/main-renderer/pieces/suppress.js +9 -0
- package/dist/extensions/first-party/main-renderer/pieces/types.d.ts +20 -0
- package/dist/extensions/first-party/main-renderer/pieces/types.js +1 -0
- package/dist/extensions/first-party/main-renderer/pieces/update.d.ts +6 -0
- package/dist/extensions/first-party/main-renderer/pieces/update.js +31 -0
- package/dist/extensions/first-party/main-renderer/types/extension.d.ts +15 -0
- package/dist/extensions/first-party/main-renderer/types/extension.js +10 -0
- package/dist/extensions/first-party/main-renderer/types/input.d.ts +4 -0
- package/dist/extensions/first-party/main-renderer/types/input.js +1 -0
- package/dist/extensions/first-party/main-renderer/types/instance.d.ts +16 -0
- package/dist/extensions/first-party/main-renderer/types/instance.js +1 -0
- package/dist/extensions/first-party/main-renderer/types/internal.d.ts +17 -0
- package/dist/extensions/first-party/main-renderer/types/internal.js +30 -0
- package/dist/extensions/first-party/main-renderer/types/template.d.ts +5 -0
- package/dist/extensions/first-party/main-renderer/types/template.js +1 -0
- package/dist/extensions/first-party/selected-square/factory.d.ts +2 -0
- package/dist/extensions/first-party/selected-square/factory.js +88 -0
- package/dist/extensions/first-party/selected-square/types.d.ts +18 -0
- package/dist/extensions/first-party/selected-square/types.js +6 -0
- package/dist/extensions/index.d.ts +8 -0
- package/dist/extensions/index.js +6 -0
- package/dist/extensions/invalidation/factory.d.ts +2 -0
- package/dist/extensions/invalidation/factory.js +22 -0
- package/dist/extensions/invalidation/types.d.ts +11 -0
- package/dist/extensions/invalidation/types.js +1 -0
- package/dist/extensions/types/basic/animation.d.ts +28 -0
- package/dist/extensions/types/basic/animation.js +6 -0
- package/dist/extensions/types/basic/events.d.ts +34 -0
- package/dist/extensions/types/basic/events.js +7 -0
- package/dist/extensions/types/basic/mount.d.ts +7 -0
- package/dist/extensions/types/basic/mount.js +14 -0
- package/dist/extensions/types/basic/render.d.ts +9 -0
- package/dist/extensions/types/basic/render.js +1 -0
- package/dist/extensions/types/basic/transient-visuals.d.ts +10 -0
- package/dist/extensions/types/basic/transient-visuals.js +1 -0
- package/dist/extensions/types/basic/update.d.ts +16 -0
- package/dist/extensions/types/basic/update.js +11 -0
- package/dist/extensions/types/context/animation.d.ts +31 -0
- package/dist/extensions/types/context/animation.js +9 -0
- package/dist/extensions/types/context/render.d.ts +6 -0
- package/dist/extensions/types/context/render.js +1 -0
- package/dist/extensions/types/context/transient-visuals.d.ts +7 -0
- package/dist/extensions/types/context/transient-visuals.js +1 -0
- package/dist/extensions/types/context/ui-move.d.ts +16 -0
- package/dist/extensions/types/context/ui-move.js +1 -0
- package/dist/extensions/types/context/update.d.ts +25 -0
- package/dist/extensions/types/context/update.js +10 -0
- package/dist/extensions/types/extension.d.ts +40 -0
- package/dist/extensions/types/extension.js +1 -0
- package/dist/extensions/types/main.d.ts +44 -0
- package/dist/extensions/types/main.js +1 -0
- package/dist/extensions/types/surface/commands.d.ts +26 -0
- package/dist/extensions/types/surface/commands.js +1 -0
- package/dist/extensions/types/surface/events.d.ts +5 -0
- package/dist/extensions/types/surface/events.js +1 -0
- package/dist/extensions/types/surface/main.d.ts +10 -0
- package/dist/extensions/types/surface/main.js +1 -0
- package/dist/extensions/types/surface/transient-visuals.d.ts +4 -0
- package/dist/extensions/types/surface/transient-visuals.js +1 -0
- package/dist/extensions/types/wrapper.d.ts +26 -0
- package/dist/extensions/types/wrapper.js +11 -0
- package/dist/extensions/update.d.ts +4 -0
- package/dist/extensions/update.js +29 -0
- package/dist/helpers/util.d.ts +1 -0
- package/dist/helpers/util.js +9 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +1 -0
- package/dist/layout/factory.d.ts +2 -0
- package/dist/layout/factory.js +33 -0
- package/dist/layout/geometry/factory.d.ts +12 -0
- package/dist/layout/geometry/factory.js +33 -0
- package/dist/layout/geometry/types.d.ts +20 -0
- package/dist/layout/geometry/types.js +1 -0
- package/dist/layout/helpers.d.ts +4 -0
- package/dist/layout/helpers.js +6 -0
- package/dist/layout/mutation.d.ts +6 -0
- package/dist/layout/mutation.js +1 -0
- package/dist/layout/reducers.d.ts +2 -0
- package/dist/layout/reducers.js +30 -0
- package/dist/layout/types.d.ts +23 -0
- package/dist/layout/types.js +1 -0
- package/dist/mutation/pipeline.d.ts +2 -0
- package/dist/mutation/pipeline.js +36 -0
- package/dist/mutation/session.d.ts +3 -0
- package/dist/mutation/session.js +66 -0
- package/dist/mutation/types.d.ts +26 -0
- package/dist/mutation/types.js +1 -0
- package/dist/render/factory.d.ts +2 -0
- package/dist/render/factory.js +117 -0
- package/dist/render/mount.d.ts +3 -0
- package/dist/render/mount.js +28 -0
- package/dist/render/rendering/animation.d.ts +13 -0
- package/dist/render/rendering/animation.js +92 -0
- package/dist/render/rendering/helpers.d.ts +3 -0
- package/dist/render/rendering/helpers.js +10 -0
- package/dist/render/rendering/state.d.ts +4 -0
- package/dist/render/rendering/state.js +48 -0
- package/dist/render/rendering/visuals.d.ts +3 -0
- package/dist/render/rendering/visuals.js +21 -0
- package/dist/render/scheduler/scheduler.d.ts +2 -0
- package/dist/render/scheduler/scheduler.js +53 -0
- package/dist/render/scheduler/types.d.ts +12 -0
- package/dist/render/scheduler/types.js +1 -0
- package/dist/render/svg/factory.d.ts +4 -0
- package/dist/render/svg/factory.js +38 -0
- package/dist/render/svg/helpers.d.ts +18 -0
- package/dist/render/svg/helpers.js +34 -0
- package/dist/render/types.d.ts +42 -0
- package/dist/render/types.js +1 -0
- package/dist/runtime/factory/helpers.d.ts +6 -0
- package/dist/runtime/factory/helpers.js +42 -0
- package/dist/runtime/factory/input.d.ts +3 -0
- package/dist/runtime/factory/input.js +98 -0
- package/dist/runtime/factory/main.d.ts +2 -0
- package/dist/runtime/factory/main.js +182 -0
- package/dist/runtime/factory/ui-move.d.ts +4 -0
- package/dist/runtime/factory/ui-move.js +84 -0
- package/dist/runtime/input/adapter/factory.d.ts +2 -0
- package/dist/runtime/input/adapter/factory.js +55 -0
- package/dist/runtime/input/adapter/helpers.d.ts +5 -0
- package/dist/runtime/input/adapter/helpers.js +23 -0
- package/dist/runtime/input/adapter/pointer.d.ts +13 -0
- package/dist/runtime/input/adapter/pointer.js +97 -0
- package/dist/runtime/input/adapter/types.d.ts +16 -0
- package/dist/runtime/input/adapter/types.js +1 -0
- package/dist/runtime/input/controller/factory.d.ts +2 -0
- package/dist/runtime/input/controller/factory.js +32 -0
- package/dist/runtime/input/controller/helpers.d.ts +3 -0
- package/dist/runtime/input/controller/helpers.js +12 -0
- package/dist/runtime/input/controller/pointer.d.ts +7 -0
- package/dist/runtime/input/controller/pointer.js +104 -0
- package/dist/runtime/input/controller/transient-visuals.d.ts +3 -0
- package/dist/runtime/input/controller/transient-visuals.js +12 -0
- package/dist/runtime/input/controller/types.d.ts +25 -0
- package/dist/runtime/input/controller/types.js +1 -0
- package/dist/runtime/layout.d.ts +2 -0
- package/dist/runtime/layout.js +10 -0
- package/dist/runtime/lifecycle.d.ts +12 -0
- package/dist/runtime/lifecycle.js +49 -0
- package/dist/runtime/mutation/extension-update.d.ts +2 -0
- package/dist/runtime/mutation/extension-update.js +26 -0
- package/dist/runtime/mutation/factory.d.ts +2 -0
- package/dist/runtime/mutation/factory.js +47 -0
- package/dist/runtime/mutation/interaction.d.ts +2 -0
- package/dist/runtime/mutation/interaction.js +34 -0
- package/dist/runtime/mutation/invalidation.d.ts +0 -0
- package/dist/runtime/mutation/invalidation.js +2 -0
- package/dist/runtime/mutation/last-move.d.ts +3 -0
- package/dist/runtime/mutation/last-move.js +19 -0
- package/dist/runtime/mutation/layout.d.ts +2 -0
- package/dist/runtime/mutation/layout.js +8 -0
- package/dist/runtime/mutation/pipeline.d.ts +22 -0
- package/dist/runtime/mutation/pipeline.js +1 -0
- package/dist/runtime/mutation/request-render.d.ts +2 -0
- package/dist/runtime/mutation/request-render.js +29 -0
- package/dist/runtime/mutation/run.d.ts +2 -0
- package/dist/runtime/mutation/run.js +3 -0
- package/dist/runtime/mutation/types.d.ts +14 -0
- package/dist/runtime/mutation/types.js +1 -0
- package/dist/runtime/types/main.d.ts +36 -0
- package/dist/runtime/types/main.js +1 -0
- package/dist/runtime/types/ui-move.d.ts +9 -0
- package/dist/runtime/types/ui-move.js +1 -0
- package/dist/state/board/check.d.ts +27 -0
- package/dist/state/board/check.js +148 -0
- package/dist/state/board/coords.d.ts +4 -0
- package/dist/state/board/coords.js +9 -0
- package/dist/state/board/denormalize.d.ts +11 -0
- package/dist/state/board/denormalize.js +77 -0
- package/dist/state/board/factory.d.ts +3 -0
- package/dist/state/board/factory.js +46 -0
- package/dist/state/board/mutation.d.ts +9 -0
- package/dist/state/board/mutation.js +1 -0
- package/dist/state/board/normalize.d.ts +8 -0
- package/dist/state/board/normalize.js +76 -0
- package/dist/state/board/piece.d.ts +3 -0
- package/dist/state/board/piece.js +11 -0
- package/dist/state/board/position.d.ts +4 -0
- package/dist/state/board/position.js +94 -0
- package/dist/state/board/reducers.d.ts +8 -0
- package/dist/state/board/reducers.js +80 -0
- package/dist/state/board/types/input.d.ts +35 -0
- package/dist/state/board/types/input.js +1 -0
- package/dist/state/board/types/internal.d.ts +54 -0
- package/dist/state/board/types/internal.js +17 -0
- package/dist/state/board/types/main.d.ts +18 -0
- package/dist/state/board/types/main.js +1 -0
- package/dist/state/board/types/output.d.ts +5 -0
- package/dist/state/board/types/output.js +1 -0
- package/dist/state/board/types/template.d.ts +23 -0
- package/dist/state/board/types/template.js +1 -0
- package/dist/state/change/factory.d.ts +2 -0
- package/dist/state/change/factory.js +28 -0
- package/dist/state/change/helpers.d.ts +8 -0
- package/dist/state/change/helpers.js +86 -0
- package/dist/state/change/mutation.d.ts +6 -0
- package/dist/state/change/mutation.js +1 -0
- package/dist/state/change/reducers.d.ts +5 -0
- package/dist/state/change/reducers.js +16 -0
- package/dist/state/change/types.d.ts +17 -0
- package/dist/state/change/types.js +1 -0
- package/dist/state/factory.d.ts +2 -0
- package/dist/state/factory.js +24 -0
- package/dist/state/interaction/factory.d.ts +2 -0
- package/dist/state/interaction/factory.js +83 -0
- package/dist/state/interaction/helpers.d.ts +4 -0
- package/dist/state/interaction/helpers.js +16 -0
- package/dist/state/interaction/movability.d.ts +5 -0
- package/dist/state/interaction/movability.js +87 -0
- package/dist/state/interaction/mutation.d.ts +11 -0
- package/dist/state/interaction/mutation.js +1 -0
- package/dist/state/interaction/normalize.d.ts +5 -0
- package/dist/state/interaction/normalize.js +50 -0
- package/dist/state/interaction/reducers.d.ts +11 -0
- package/dist/state/interaction/reducers.js +81 -0
- package/dist/state/interaction/types/input.d.ts +18 -0
- package/dist/state/interaction/types/input.js +1 -0
- package/dist/state/interaction/types/internal.d.ts +35 -0
- package/dist/state/interaction/types/internal.js +1 -0
- package/dist/state/interaction/types/main.d.ts +33 -0
- package/dist/state/interaction/types/main.js +1 -0
- package/dist/state/types.d.ts +30 -0
- package/dist/state/types.js +1 -0
- package/dist/state/view/factory.d.ts +2 -0
- package/dist/state/view/factory.js +24 -0
- package/dist/state/view/mutation.d.ts +5 -0
- package/dist/state/view/mutation.js +1 -0
- package/dist/state/view/reducers.d.ts +3 -0
- package/dist/state/view/reducers.js +6 -0
- package/dist/state/view/types/internal.d.ts +6 -0
- package/dist/state/view/types/internal.js +1 -0
- package/dist/state/view/types/main.d.ts +12 -0
- package/dist/state/view/types/main.js +1 -0
- package/dist/wrapper/factory.d.ts +3 -0
- package/dist/wrapper/factory.js +61 -0
- package/dist/wrapper/types.d.ts +56 -0
- package/dist/wrapper/types.js +1 -0
- package/package.json +98 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
function createMoveRequestContextInternal(sourceSquare, destination) {
|
|
2
|
+
return {
|
|
3
|
+
sourceSquare,
|
|
4
|
+
destination,
|
|
5
|
+
status: 'unresolved',
|
|
6
|
+
resolvedMoveRequest: null
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
function moveRequestContextCanBeAutoResolved(state) {
|
|
10
|
+
return (state.status === 'unresolved' &&
|
|
11
|
+
(state.destination.promotedTo === undefined || state.destination.promotedTo.length <= 1));
|
|
12
|
+
}
|
|
13
|
+
function assertCanBeDeferred(state) {
|
|
14
|
+
if (state.status !== 'unresolved') {
|
|
15
|
+
throw new Error('Only unresolved move requests can be deferred');
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function assertCanBeResolved(state) {
|
|
19
|
+
if (state.status === 'resolved') {
|
|
20
|
+
throw new Error('Move request is already resolved');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function assertCanBeAutoResolved(state) {
|
|
24
|
+
if (!moveRequestContextCanBeAutoResolved(state)) {
|
|
25
|
+
throw new Error('Move request cannot be auto-resolved. Either it is already resolved or deferred, or it requires a promotion choice.');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function moveRequestContextAutoResolve(state) {
|
|
29
|
+
assertCanBeAutoResolved(state);
|
|
30
|
+
const promotedTo = state.destination.promotedTo?.length === 1 ? state.destination.promotedTo[0] : undefined;
|
|
31
|
+
state.status = 'resolved';
|
|
32
|
+
state.resolvedMoveRequest = {
|
|
33
|
+
from: state.sourceSquare,
|
|
34
|
+
to: state.destination.to,
|
|
35
|
+
...(state.destination.capturedSquare !== undefined
|
|
36
|
+
? { capturedSquare: state.destination.capturedSquare }
|
|
37
|
+
: {}),
|
|
38
|
+
...(state.destination.secondary !== undefined
|
|
39
|
+
? { secondary: state.destination.secondary }
|
|
40
|
+
: {}),
|
|
41
|
+
...(promotedTo !== undefined ? { promotedTo } : {})
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export function createUIMoveRequestContext(sourceSquare, destination) {
|
|
45
|
+
const internalState = createMoveRequestContextInternal(sourceSquare, destination);
|
|
46
|
+
return {
|
|
47
|
+
get status() {
|
|
48
|
+
return internalState.status;
|
|
49
|
+
},
|
|
50
|
+
get sourceSquare() {
|
|
51
|
+
return internalState.sourceSquare;
|
|
52
|
+
},
|
|
53
|
+
get destination() {
|
|
54
|
+
return internalState.destination;
|
|
55
|
+
},
|
|
56
|
+
get canBeAutoResolved() {
|
|
57
|
+
return moveRequestContextCanBeAutoResolved(internalState);
|
|
58
|
+
},
|
|
59
|
+
get resolvedMoveRequest() {
|
|
60
|
+
return internalState.resolvedMoveRequest;
|
|
61
|
+
},
|
|
62
|
+
defer() {
|
|
63
|
+
assertCanBeDeferred(internalState);
|
|
64
|
+
internalState.status = 'deferred';
|
|
65
|
+
},
|
|
66
|
+
resolve(request) {
|
|
67
|
+
assertCanBeResolved(internalState);
|
|
68
|
+
internalState.status = 'resolved';
|
|
69
|
+
internalState.resolvedMoveRequest = request;
|
|
70
|
+
},
|
|
71
|
+
autoresolve() {
|
|
72
|
+
moveRequestContextAutoResolve(internalState);
|
|
73
|
+
},
|
|
74
|
+
getSnapshot() {
|
|
75
|
+
return {
|
|
76
|
+
status: internalState.status,
|
|
77
|
+
sourceSquare: internalState.sourceSquare,
|
|
78
|
+
destination: internalState.destination,
|
|
79
|
+
canBeAutoResolved: moveRequestContextCanBeAutoResolved(internalState),
|
|
80
|
+
resolvedMoveRequest: internalState.resolvedMoveRequest
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { isPointerRelevantEvent, onPointerCancel, onPointerDown, onPointerLeave, onPointerMove, onPointerUp, releaseCapture } from './pointer';
|
|
2
|
+
function createInputAdapterInternal(options) {
|
|
3
|
+
return {
|
|
4
|
+
container: options.container,
|
|
5
|
+
getGeometry: options.getGeometry,
|
|
6
|
+
controller: options.controller,
|
|
7
|
+
activePointerId: null
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function createInputAdapter(options) {
|
|
11
|
+
const internalState = createInputAdapterInternal(options);
|
|
12
|
+
const onPointerDownHandler = (e) => {
|
|
13
|
+
if (!isPointerRelevantEvent(e))
|
|
14
|
+
return;
|
|
15
|
+
onPointerDown(internalState, e);
|
|
16
|
+
};
|
|
17
|
+
const onPointerMoveHandler = (e) => {
|
|
18
|
+
if (!isPointerRelevantEvent(e))
|
|
19
|
+
return;
|
|
20
|
+
onPointerMove(internalState, e);
|
|
21
|
+
};
|
|
22
|
+
const onPointerUpHandler = (e) => {
|
|
23
|
+
if (!isPointerRelevantEvent(e))
|
|
24
|
+
return;
|
|
25
|
+
onPointerUp(internalState, e);
|
|
26
|
+
};
|
|
27
|
+
const onPointerCancelHandler = (e) => {
|
|
28
|
+
if (!isPointerRelevantEvent(e))
|
|
29
|
+
return;
|
|
30
|
+
onPointerCancel(internalState, e);
|
|
31
|
+
};
|
|
32
|
+
const onPointerLeaveHandler = (e) => {
|
|
33
|
+
if (!isPointerRelevantEvent(e))
|
|
34
|
+
return;
|
|
35
|
+
onPointerLeave(internalState, e);
|
|
36
|
+
};
|
|
37
|
+
const inputAdapter = {
|
|
38
|
+
destroy() {
|
|
39
|
+
if (internalState.activePointerId !== null) {
|
|
40
|
+
releaseCapture(internalState);
|
|
41
|
+
}
|
|
42
|
+
internalState.container.removeEventListener('pointerdown', onPointerDownHandler);
|
|
43
|
+
internalState.container.removeEventListener('pointermove', onPointerMoveHandler);
|
|
44
|
+
internalState.container.removeEventListener('pointerup', onPointerUpHandler);
|
|
45
|
+
internalState.container.removeEventListener('pointercancel', onPointerCancelHandler);
|
|
46
|
+
internalState.container.removeEventListener('pointerleave', onPointerLeaveHandler);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
internalState.container.addEventListener('pointerdown', onPointerDownHandler);
|
|
50
|
+
internalState.container.addEventListener('pointermove', onPointerMoveHandler);
|
|
51
|
+
internalState.container.addEventListener('pointerup', onPointerUpHandler);
|
|
52
|
+
internalState.container.addEventListener('pointercancel', onPointerCancelHandler);
|
|
53
|
+
internalState.container.addEventListener('pointerleave', onPointerLeaveHandler);
|
|
54
|
+
return inputAdapter;
|
|
55
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ScenePoint } from '../../../extensions/types/basic/transient-visuals';
|
|
2
|
+
import { RenderGeometry } from '../../../layout/geometry/types';
|
|
3
|
+
import { Square } from '../../../state/board/types/internal';
|
|
4
|
+
export declare function mapBoardPointToSquare(x: number, y: number, geometry: RenderGeometry): Square | null;
|
|
5
|
+
export declare function clampBoardPoint(point: ScenePoint, geometry: RenderGeometry): ScenePoint;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function mapBoardPointToSquare(x, y, geometry) {
|
|
2
|
+
if (!Number.isFinite(x) || !Number.isFinite(y))
|
|
3
|
+
return null;
|
|
4
|
+
const { boardSize, squareSize, orientation } = geometry;
|
|
5
|
+
if (x < 0 || x >= boardSize || y < 0 || y >= boardSize)
|
|
6
|
+
return null;
|
|
7
|
+
// Grid cell indices, each in [0, 7].
|
|
8
|
+
const xIndex = Math.floor(x / squareSize);
|
|
9
|
+
const yIndex = Math.floor(y / squareSize);
|
|
10
|
+
// Invert the orientation mapping used by geometry.squareRect:
|
|
11
|
+
// white: xIndex = file, yIndex = 7 - rank → file = xIndex, rank = 7 - yIndex
|
|
12
|
+
// black: xIndex = 7 - file, yIndex = rank → file = 7 - xIndex, rank = yIndex
|
|
13
|
+
const file = orientation === 0 /* ColorCode.White */ ? xIndex : 7 - xIndex;
|
|
14
|
+
const rank = orientation === 0 /* ColorCode.White */ ? 7 - yIndex : yIndex;
|
|
15
|
+
return (rank * 8 + file);
|
|
16
|
+
}
|
|
17
|
+
export function clampBoardPoint(point, geometry) {
|
|
18
|
+
const { boardSize } = geometry;
|
|
19
|
+
return {
|
|
20
|
+
x: Math.min(Math.max(point.x, 0), boardSize),
|
|
21
|
+
y: Math.min(Math.max(point.y, 0), boardSize)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ScenePointerEventType } from '../../../extensions/types/basic/events';
|
|
2
|
+
import { InputAdapterInternal } from './types';
|
|
3
|
+
export type PointerRelevantEvent = PointerEvent & {
|
|
4
|
+
type: ScenePointerEventType;
|
|
5
|
+
};
|
|
6
|
+
export declare function isPointerRelevantEvent(e: PointerEvent): e is PointerRelevantEvent;
|
|
7
|
+
/** Release capture for the currently tracked pointer and clear tracking state. */
|
|
8
|
+
export declare function releaseCapture(state: InputAdapterInternal): void;
|
|
9
|
+
export declare function onPointerDown(state: InputAdapterInternal, e: PointerRelevantEvent): void;
|
|
10
|
+
export declare function onPointerMove(state: InputAdapterInternal, e: PointerRelevantEvent): void;
|
|
11
|
+
export declare function onPointerUp(state: InputAdapterInternal, e: PointerRelevantEvent): void;
|
|
12
|
+
export declare function onPointerCancel(state: InputAdapterInternal, e: PointerRelevantEvent): void;
|
|
13
|
+
export declare function onPointerLeave(state: InputAdapterInternal, e: PointerRelevantEvent): void;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import assert from '@ktarmyshov/assert';
|
|
2
|
+
import { SCENE_POINTER_EVENT_TYPES } from '../../../extensions/types/basic/events';
|
|
3
|
+
import { clampBoardPoint, mapBoardPointToSquare } from './helpers';
|
|
4
|
+
const validPointerEventTypes = new Set(SCENE_POINTER_EVENT_TYPES);
|
|
5
|
+
export function isPointerRelevantEvent(e) {
|
|
6
|
+
return e instanceof PointerEvent && validPointerEventTypes.has(e.type);
|
|
7
|
+
}
|
|
8
|
+
/** Release capture for the currently tracked pointer and clear tracking state. */
|
|
9
|
+
export function releaseCapture(state) {
|
|
10
|
+
if (state.activePointerId === null)
|
|
11
|
+
return;
|
|
12
|
+
if (state.container.hasPointerCapture(state.activePointerId)) {
|
|
13
|
+
state.container.releasePointerCapture(state.activePointerId);
|
|
14
|
+
}
|
|
15
|
+
state.activePointerId = null;
|
|
16
|
+
}
|
|
17
|
+
function resolvePointerTarget(state, e) {
|
|
18
|
+
const geometry = state.getGeometry();
|
|
19
|
+
if (!geometry)
|
|
20
|
+
return { target: null, rawPoint: null, clampedPoint: null };
|
|
21
|
+
const rect = state.container.getBoundingClientRect();
|
|
22
|
+
const x = e.clientX - rect.left;
|
|
23
|
+
const y = e.clientY - rect.top;
|
|
24
|
+
const target = mapBoardPointToSquare(x, y, geometry);
|
|
25
|
+
const point = { x, y };
|
|
26
|
+
return { target, rawPoint: point, clampedPoint: clampBoardPoint(point, geometry) };
|
|
27
|
+
}
|
|
28
|
+
function makeBoardPointerEvent(e, pointerTarget) {
|
|
29
|
+
assert(e.defaultPrevented === false, 'Expected event to be unhandled before making BoardPointerEvent');
|
|
30
|
+
let defaultPrevented = false;
|
|
31
|
+
return {
|
|
32
|
+
type: e.type,
|
|
33
|
+
// DOM part
|
|
34
|
+
pointerId: e.pointerId,
|
|
35
|
+
isPrimary: e.isPrimary,
|
|
36
|
+
button: e.button,
|
|
37
|
+
buttons: e.buttons,
|
|
38
|
+
ctrlKey: e.ctrlKey,
|
|
39
|
+
altKey: e.altKey,
|
|
40
|
+
shiftKey: e.shiftKey,
|
|
41
|
+
metaKey: e.metaKey,
|
|
42
|
+
// Board part
|
|
43
|
+
rawPoint: pointerTarget.rawPoint,
|
|
44
|
+
clampedPoint: pointerTarget.clampedPoint,
|
|
45
|
+
target: pointerTarget.target,
|
|
46
|
+
// Mechanics
|
|
47
|
+
get defaultPrevented() {
|
|
48
|
+
return defaultPrevented;
|
|
49
|
+
},
|
|
50
|
+
preventDefault() {
|
|
51
|
+
defaultPrevented = true;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export function onPointerDown(state, e) {
|
|
56
|
+
if (!e.isPrimary)
|
|
57
|
+
return; // ignore non-primary pointers
|
|
58
|
+
if (state.activePointerId !== null)
|
|
59
|
+
return; // already tracking
|
|
60
|
+
state.activePointerId = e.pointerId;
|
|
61
|
+
state.container.setPointerCapture(e.pointerId);
|
|
62
|
+
const pointerTarget = resolvePointerTarget(state, e);
|
|
63
|
+
const boardEvent = makeBoardPointerEvent(e, pointerTarget);
|
|
64
|
+
e.preventDefault(); // prevent native text selection during drag
|
|
65
|
+
state.controller.onEvent(boardEvent);
|
|
66
|
+
}
|
|
67
|
+
export function onPointerMove(state, e) {
|
|
68
|
+
if (e.pointerId !== state.activePointerId)
|
|
69
|
+
return;
|
|
70
|
+
const pointerTarget = resolvePointerTarget(state, e);
|
|
71
|
+
const boardEvent = makeBoardPointerEvent(e, pointerTarget);
|
|
72
|
+
e.preventDefault(); // prevent native text selection during drag
|
|
73
|
+
state.controller.onEvent(boardEvent);
|
|
74
|
+
}
|
|
75
|
+
export function onPointerUp(state, e) {
|
|
76
|
+
if (e.pointerId !== state.activePointerId)
|
|
77
|
+
return;
|
|
78
|
+
const pointerTarget = resolvePointerTarget(state, e); // resolve before releasing capture
|
|
79
|
+
releaseCapture(state);
|
|
80
|
+
const boardEvent = makeBoardPointerEvent(e, pointerTarget);
|
|
81
|
+
state.controller.onEvent(boardEvent);
|
|
82
|
+
}
|
|
83
|
+
export function onPointerCancel(state, e) {
|
|
84
|
+
if (e.pointerId !== state.activePointerId)
|
|
85
|
+
return;
|
|
86
|
+
const pointerTarget = resolvePointerTarget(state, e); // resolve before releasing capture
|
|
87
|
+
releaseCapture(state);
|
|
88
|
+
const boardEvent = makeBoardPointerEvent(e, pointerTarget);
|
|
89
|
+
state.controller.onEvent(boardEvent);
|
|
90
|
+
}
|
|
91
|
+
export function onPointerLeave(state, e) {
|
|
92
|
+
if (e.pointerId !== state.activePointerId)
|
|
93
|
+
return;
|
|
94
|
+
const pointerTarget = resolvePointerTarget(state, e);
|
|
95
|
+
const boardEvent = makeBoardPointerEvent(e, pointerTarget);
|
|
96
|
+
state.controller.onEvent(boardEvent);
|
|
97
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { RenderGeometry } from '../../../layout/geometry/types';
|
|
2
|
+
import { InteractionController } from '../controller/types';
|
|
3
|
+
export interface InputAdapterInitOptions {
|
|
4
|
+
container: HTMLElement;
|
|
5
|
+
getGeometry: () => RenderGeometry | null;
|
|
6
|
+
controller: InteractionController;
|
|
7
|
+
}
|
|
8
|
+
export interface InputAdapterInternal {
|
|
9
|
+
readonly container: HTMLElement;
|
|
10
|
+
readonly getGeometry: () => RenderGeometry | null;
|
|
11
|
+
readonly controller: InteractionController;
|
|
12
|
+
activePointerId: number | null;
|
|
13
|
+
}
|
|
14
|
+
export interface InputAdapter {
|
|
15
|
+
destroy(): void;
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { handlePointerCancel, handlePointerDown, handlePointerLeave, handlePointerMove, handlePointerUp } from './pointer';
|
|
2
|
+
import { transmitTransientInput } from './transient-visuals';
|
|
3
|
+
function createInteractionControllerInternal(options) {
|
|
4
|
+
return {
|
|
5
|
+
surface: options.surface
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export function createInteractionController(options) {
|
|
9
|
+
const internalState = createInteractionControllerInternal(options);
|
|
10
|
+
return {
|
|
11
|
+
onEvent(event) {
|
|
12
|
+
switch (event.type) {
|
|
13
|
+
case 'pointerdown':
|
|
14
|
+
handlePointerDown(internalState, event);
|
|
15
|
+
break;
|
|
16
|
+
case 'pointermove':
|
|
17
|
+
handlePointerMove(internalState, event);
|
|
18
|
+
break;
|
|
19
|
+
case 'pointerup':
|
|
20
|
+
handlePointerUp(internalState, event);
|
|
21
|
+
break;
|
|
22
|
+
case 'pointercancel':
|
|
23
|
+
handlePointerCancel(internalState, event);
|
|
24
|
+
break;
|
|
25
|
+
case 'pointerleave':
|
|
26
|
+
handlePointerLeave(internalState, event);
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
transmitTransientInput(internalState, event);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function canMoveTo(snapshot, target) {
|
|
2
|
+
const { movability } = snapshot;
|
|
3
|
+
if (movability.mode === 0 /* MovabilityModeCode.Disabled */) {
|
|
4
|
+
return false;
|
|
5
|
+
}
|
|
6
|
+
if (movability.mode === 1 /* MovabilityModeCode.Free */) {
|
|
7
|
+
// Any square except the currently selected/source square is a valid drop target
|
|
8
|
+
return target !== snapshot.selected?.square;
|
|
9
|
+
}
|
|
10
|
+
// strict: target must be in the computed active destinations
|
|
11
|
+
return snapshot.activeDestinations.has(target);
|
|
12
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ScenePointerEvent } from '../../../extensions/types/basic/events';
|
|
2
|
+
import { InteractionControllerInternal } from './types';
|
|
3
|
+
export declare function handlePointerDown(state: InteractionControllerInternal, event: ScenePointerEvent): void;
|
|
4
|
+
export declare function handlePointerMove(state: InteractionControllerInternal, event: ScenePointerEvent): void;
|
|
5
|
+
export declare function handlePointerUp(state: InteractionControllerInternal, event: ScenePointerEvent): void;
|
|
6
|
+
export declare function handlePointerCancel(state: InteractionControllerInternal, event: ScenePointerEvent): void;
|
|
7
|
+
export declare function handlePointerLeave(state: InteractionControllerInternal, event: ScenePointerEvent): void;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import assert from '@ktarmyshov/assert';
|
|
2
|
+
import { isEmptyPieceCode, isNonEmptyPieceCode } from '../../../state/board/check';
|
|
3
|
+
import { fromPieceCode } from '../../../state/board/piece';
|
|
4
|
+
import { canMoveTo } from './helpers';
|
|
5
|
+
export function handlePointerDown(state, event) {
|
|
6
|
+
assert(event.type === 'pointerdown', 'handlePointerDown should only be called for pointerdown events');
|
|
7
|
+
if (event.button !== 0) {
|
|
8
|
+
// Only handle left-click for now
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const interaction = state.surface.getInteractionStateSnapshot();
|
|
12
|
+
if (interaction.dragSession) {
|
|
13
|
+
// Ignore pointer down events if there's already an active drag session
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (event.target !== null) {
|
|
17
|
+
/**
|
|
18
|
+
* If piece is already selected, and we have a valid target square event.target
|
|
19
|
+
* AND it's a different square AND (it's empty OR (has an opponent piece AND is a legal move target))
|
|
20
|
+
* THEN start a release-targeting drag session
|
|
21
|
+
*/
|
|
22
|
+
if (interaction.selected && event.target !== interaction.selected.square) {
|
|
23
|
+
const selectedPieceCode = interaction.selected.pieceCode;
|
|
24
|
+
assert(isNonEmptyPieceCode(selectedPieceCode), 'Selected piece code must be non-zero');
|
|
25
|
+
const targetPieceCode = state.surface.getPieceCodeAt(event.target);
|
|
26
|
+
if (isEmptyPieceCode(targetPieceCode)) {
|
|
27
|
+
state.surface.startReleaseTargetingDrag(interaction.selected.square, event.target);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const isLegalMoveTarget = interaction.movability.mode === 1 /* MovabilityModeCode.Free */ ||
|
|
31
|
+
(interaction.movability.mode === 2 /* MovabilityModeCode.Strict */ &&
|
|
32
|
+
interaction.activeDestinations.has(event.target));
|
|
33
|
+
if (fromPieceCode(targetPieceCode).color !== fromPieceCode(selectedPieceCode).color &&
|
|
34
|
+
isLegalMoveTarget) {
|
|
35
|
+
state.surface.startReleaseTargetingDrag(interaction.selected.square, event.target);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* If we are here, then it's not release-targeting.
|
|
41
|
+
* So it's either a new lift or re-lift of the same piece. In either case, we can just start a lifted drag session if the target is valid.
|
|
42
|
+
*/
|
|
43
|
+
const pieceCode = state.surface.getPieceCodeAt(event.target);
|
|
44
|
+
if (!isEmptyPieceCode(pieceCode)) {
|
|
45
|
+
state.surface.startLiftedDrag(event.target, event.target);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function handlePointerMove(state, event) {
|
|
50
|
+
assert(event.type === 'pointermove', 'handlePointerMove should only be called for pointermove events');
|
|
51
|
+
const interaction = state.surface.getInteractionStateSnapshot();
|
|
52
|
+
if (interaction.dragSession) {
|
|
53
|
+
state.surface.updateDragSessionCurrentTarget(event.target);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function handlePointerUp(state, event) {
|
|
57
|
+
assert(event.type === 'pointerup', 'handlePointerUp should only be called for pointerup events');
|
|
58
|
+
const interaction = state.surface.getInteractionStateSnapshot();
|
|
59
|
+
if (!interaction.dragSession) {
|
|
60
|
+
// No active drag session, so nothing to do on pointer up
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Check if the square is the same as the source square of the drag session.
|
|
64
|
+
// If it is, then we can end the drag session without making a move.
|
|
65
|
+
if (event.target === interaction.dragSession.sourceSquare) {
|
|
66
|
+
state.surface.cancelActiveInteraction();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
// Check if the target square is a valid destination for the selected piece.
|
|
70
|
+
if (event.target !== null && canMoveTo(interaction, event.target)) {
|
|
71
|
+
if (interaction.dragSession.type === 'lifted-piece-drag') {
|
|
72
|
+
state.surface.dropTo(event.target);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
state.surface.releaseTo(event.target);
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// Invalid target: piece returns to source for lifted drag (selection preserved),
|
|
80
|
+
// or selection is cleared for release targeting.
|
|
81
|
+
if (interaction.dragSession.type === 'lifted-piece-drag') {
|
|
82
|
+
state.surface.cancelActiveInteraction();
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
state.surface.cancelInteraction();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export function handlePointerCancel(state, event) {
|
|
89
|
+
assert(event.type === 'pointercancel', 'handlePointerCancel should only be called for pointercancel events');
|
|
90
|
+
const interaction = state.surface.getInteractionStateSnapshot();
|
|
91
|
+
if (!interaction.dragSession) {
|
|
92
|
+
// No active drag session, so nothing to do on pointer cancel
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
// Cancel the active interaction on pointer cancel
|
|
96
|
+
state.surface.cancelActiveInteraction();
|
|
97
|
+
}
|
|
98
|
+
export function handlePointerLeave(state, event) {
|
|
99
|
+
assert(event.type === 'pointerleave', 'handlePointerLeave should only be called for pointerleave events');
|
|
100
|
+
const interaction = state.surface.getInteractionStateSnapshot();
|
|
101
|
+
if (interaction.dragSession) {
|
|
102
|
+
state.surface.updateDragSessionCurrentTarget(event.target);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
function isPointerEvent(event) {
|
|
2
|
+
return event.type.startsWith('pointer');
|
|
3
|
+
}
|
|
4
|
+
export function transmitTransientInput(state, event) {
|
|
5
|
+
if (isPointerEvent(event) && event.rawPoint && event.clampedPoint) {
|
|
6
|
+
state.surface.transientInput({
|
|
7
|
+
target: event.target,
|
|
8
|
+
rawPoint: event.rawPoint,
|
|
9
|
+
clampedPoint: event.clampedPoint
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { SceneEvent } from '../../../extensions/types/basic/events';
|
|
2
|
+
import { TransientInput } from '../../../extensions/types/basic/transient-visuals';
|
|
3
|
+
import { PieceCode, Square } from '../../../state/board/types/internal';
|
|
4
|
+
import { InteractionStateSnapshot } from '../../../state/interaction/types/main';
|
|
5
|
+
export interface RuntimeInteractionSurface {
|
|
6
|
+
getInteractionStateSnapshot(): InteractionStateSnapshot;
|
|
7
|
+
getPieceCodeAt(square: Square): PieceCode;
|
|
8
|
+
startLiftedDrag(source: Square, target: Square): void;
|
|
9
|
+
dropTo(target: Square): void;
|
|
10
|
+
startReleaseTargetingDrag(source: Square, target: Square): void;
|
|
11
|
+
releaseTo(target: Square): void;
|
|
12
|
+
updateDragSessionCurrentTarget(target: Square | null): void;
|
|
13
|
+
cancelActiveInteraction(): void;
|
|
14
|
+
cancelInteraction(): void;
|
|
15
|
+
transientInput(input: TransientInput): void;
|
|
16
|
+
}
|
|
17
|
+
export interface InteractionControllerInternal {
|
|
18
|
+
readonly surface: RuntimeInteractionSurface;
|
|
19
|
+
}
|
|
20
|
+
export interface InteractionControllerInitOptions {
|
|
21
|
+
surface: RuntimeInteractionSurface;
|
|
22
|
+
}
|
|
23
|
+
export interface InteractionController {
|
|
24
|
+
onEvent(event: SceneEvent): void;
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { runtimeValidateIsMounted } from './lifecycle';
|
|
2
|
+
import { runtimeRunMutationPipeline } from './mutation/run';
|
|
3
|
+
export function runtimeRefreshGeometry(state) {
|
|
4
|
+
runtimeValidateIsMounted(state);
|
|
5
|
+
state.layout.refreshGeometry({
|
|
6
|
+
orientation: state.state.view.orientation,
|
|
7
|
+
container: state.renderSystem.container
|
|
8
|
+
}, state.mutation.getSession());
|
|
9
|
+
runtimeRunMutationPipeline(state);
|
|
10
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { RenderSystem } from '../render/types';
|
|
2
|
+
import { RuntimeInternal } from './types/main';
|
|
3
|
+
export declare function runtimeIsMounted(state: RuntimeInternal): boolean;
|
|
4
|
+
export declare function runtimeValidateIsMounted(state: RuntimeInternal): asserts state is RuntimeInternal & {
|
|
5
|
+
readonly renderSystem: RuntimeInternal['renderSystem'] & {
|
|
6
|
+
readonly container: NonNullable<RenderSystem['container']>;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
export declare function runtimeValidateIsNotMounted(state: RuntimeInternal): void;
|
|
10
|
+
export declare function runtimeMount(state: RuntimeInternal, container: HTMLElement): void;
|
|
11
|
+
export declare function runtimeUnmount(state: RuntimeInternal): void;
|
|
12
|
+
export declare function runtimeDestroy(state: RuntimeInternal): void;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import assert from '@ktarmyshov/assert';
|
|
2
|
+
import { createInputAdapter } from './input/adapter/factory';
|
|
3
|
+
import { runtimeRefreshGeometry } from './layout';
|
|
4
|
+
export function runtimeIsMounted(state) {
|
|
5
|
+
return state.renderSystem.isMounted;
|
|
6
|
+
}
|
|
7
|
+
export function runtimeValidateIsMounted(state) {
|
|
8
|
+
if (!runtimeIsMounted(state)) {
|
|
9
|
+
throw new Error('Runtime is not mounted. Please call mount() before performing this action.');
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export function runtimeValidateIsNotMounted(state) {
|
|
13
|
+
if (runtimeIsMounted(state)) {
|
|
14
|
+
throw new Error('Runtime is already mounted. This action cannot be performed after mounting.');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export function runtimeMount(state, container) {
|
|
18
|
+
runtimeValidateIsNotMounted(state);
|
|
19
|
+
state.renderSystem.mount(container);
|
|
20
|
+
state.resizeObserver = new ResizeObserver(() => {
|
|
21
|
+
runtimeRefreshGeometry(state);
|
|
22
|
+
});
|
|
23
|
+
// Observe will cause immediate first callback!
|
|
24
|
+
state.resizeObserver.observe(container);
|
|
25
|
+
assert(state.inputAdapter === null, 'Input adapter should not be initialized before mounting');
|
|
26
|
+
state.inputAdapter = createInputAdapter({
|
|
27
|
+
container,
|
|
28
|
+
getGeometry: () => state.layout.geometry,
|
|
29
|
+
controller: state.interactionController
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
export function runtimeUnmount(state) {
|
|
33
|
+
runtimeValidateIsMounted(state);
|
|
34
|
+
assert(state.inputAdapter !== null, 'Input adapter should be initialized when mounted');
|
|
35
|
+
state.inputAdapter.destroy();
|
|
36
|
+
state.inputAdapter = null;
|
|
37
|
+
if (state.resizeObserver) {
|
|
38
|
+
state.resizeObserver.disconnect();
|
|
39
|
+
state.resizeObserver = null;
|
|
40
|
+
}
|
|
41
|
+
state.renderSystem.unmount();
|
|
42
|
+
state.extensionSystem.onUnmount();
|
|
43
|
+
}
|
|
44
|
+
export function runtimeDestroy(state) {
|
|
45
|
+
if (runtimeIsMounted(state)) {
|
|
46
|
+
runtimeUnmount(state);
|
|
47
|
+
}
|
|
48
|
+
state.extensionSystem.onDestroy();
|
|
49
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export const extensionSystemUpdatePipe = (context, mutationSession) => {
|
|
2
|
+
const { current } = context;
|
|
3
|
+
const hasMutation = mutationSession.hasMutation({
|
|
4
|
+
prefixes: ['state.', 'layout.']
|
|
5
|
+
});
|
|
6
|
+
if (hasMutation) {
|
|
7
|
+
const stateSnapshot = current.state.getSnapshot();
|
|
8
|
+
current.extensionSystem.onUpdate({
|
|
9
|
+
state: current.renderSystem.isMounted
|
|
10
|
+
? {
|
|
11
|
+
isMounted: true,
|
|
12
|
+
state: stateSnapshot,
|
|
13
|
+
layout: current.layout.getSnapshot()
|
|
14
|
+
}
|
|
15
|
+
: {
|
|
16
|
+
isMounted: false,
|
|
17
|
+
state: stateSnapshot
|
|
18
|
+
},
|
|
19
|
+
mutation: mutationSession
|
|
20
|
+
});
|
|
21
|
+
// check if extension system has submitted animations and we need to request an animation pass
|
|
22
|
+
if (current.extensionSystem.hasSubmittedAnimations) {
|
|
23
|
+
current.renderSystem.requestRenderAnimation();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
};
|