From fe62217414f0d68da86d69720098fbeacb31579b Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Thu, 13 Jul 2023 10:12:29 +0700 Subject: [PATCH 1/4] change(web): TrackedPath -> GesturePath --- .../headless/{trackedPath.ts => gesturePath.ts} | 10 +++++----- .../src/engine/headless/trackedPoint.ts | 12 ++++++------ common/web/gesture-recognizer/src/engine/index.ts | 2 +- .../src/test/auto/headless/trackedPath.js | 14 +++++++------- 4 files changed, 19 insertions(+), 19 deletions(-) rename common/web/gesture-recognizer/src/engine/headless/{trackedPath.ts => gesturePath.ts} (94%) diff --git a/common/web/gesture-recognizer/src/engine/headless/trackedPath.ts b/common/web/gesture-recognizer/src/engine/headless/gesturePath.ts similarity index 94% rename from common/web/gesture-recognizer/src/engine/headless/trackedPath.ts rename to common/web/gesture-recognizer/src/engine/headless/gesturePath.ts index df1399272f..3cd8e2a5e8 100644 --- a/common/web/gesture-recognizer/src/engine/headless/trackedPath.ts +++ b/common/web/gesture-recognizer/src/engine/headless/gesturePath.ts @@ -5,7 +5,7 @@ import { CumulativePathStats } from "./cumulativePathStats.js"; /** * Documents the expected typing of serialized versions of the `TrackedPoint` class. */ -export type JSONTrackedPath = { +export type SerializedGesturePath = { coords: InputSample[]; // ensures type match with public class property. wasCancelled?: boolean; } @@ -42,7 +42,7 @@ interface EventMap { * the most recently-preceding 'segmentation' event. * - And possibly recognition Promise fulfillment. */ -export class TrackedPath extends EventEmitter> { +export class GesturePath extends EventEmitter> { private samples: InputSample[] = []; private _isComplete: boolean = false; @@ -63,8 +63,8 @@ export class TrackedPath extends EventEmitter> { * Deserializes a TrackedPath instance from its corresponding JSON.parse() object. * @param jsonObj */ - static deserialize(jsonObj: JSONTrackedPath): TrackedPath { - const instance = new TrackedPath(); + static deserialize(jsonObj: SerializedGesturePath): GesturePath { + const instance = new GesturePath(); instance.samples = [].concat(jsonObj.coords.map((obj) => ({...obj} as InputSample))); instance._isComplete = true; @@ -137,7 +137,7 @@ export class TrackedPath extends EventEmitter> { * `JSON.stringify`. */ toJSON() { - let jsonClone: JSONTrackedPath = { + let jsonClone: SerializedGesturePath = { // Replicate array and its entries, but with certain fields of each entry missing. // No .clientX, no .clientY. coords: [].concat(this.samples.map((obj) => ({ diff --git a/common/web/gesture-recognizer/src/engine/headless/trackedPoint.ts b/common/web/gesture-recognizer/src/engine/headless/trackedPoint.ts index 6fe49f4aee..6e346054cf 100644 --- a/common/web/gesture-recognizer/src/engine/headless/trackedPoint.ts +++ b/common/web/gesture-recognizer/src/engine/headless/trackedPoint.ts @@ -1,12 +1,12 @@ import { InputSample } from "./inputSample.js"; -import { JSONTrackedPath, TrackedPath } from "./trackedPath.js"; +import { SerializedGesturePath, GesturePath } from "./gesturePath.js"; /** * Documents the expected typing of serialized versions of the `TrackedPoint` class. */ export type JSONTrackedPoint = { isFromTouch: boolean; - path: JSONTrackedPath; + path: SerializedGesturePath; initialHoveredItem: HoveredItemType // identifier is not included b/c it's only needed during live processing. } @@ -27,14 +27,14 @@ export class TrackedPoint { */ public readonly rawIdentifier: number; - private _path: TrackedPath; + private _path: GesturePath; private static _jsonIdSeed: -1; /** * Tracks the coordinates and timestamps of each update for the lifetime of this `TrackedPoint`. */ - public get path(): TrackedPath { + public get path(): GesturePath { return this._path; } @@ -47,7 +47,7 @@ export class TrackedPoint { constructor(identifier: number, isFromTouch: boolean) { this.rawIdentifier = identifier; this.isFromTouch = isFromTouch; - this._path = new TrackedPath(); + this._path = new GesturePath(); } /** @@ -58,7 +58,7 @@ export class TrackedPoint { public static deserialize(jsonObj: JSONTrackedPoint, identifier: number) { const id = identifier !== undefined ? identifier : this._jsonIdSeed++; const isFromTouch = jsonObj.isFromTouch; - const path = TrackedPath.deserialize(jsonObj.path); + const path = GesturePath.deserialize(jsonObj.path); const instance = new TrackedPoint(id, isFromTouch); instance._path = path; diff --git a/common/web/gesture-recognizer/src/engine/index.ts b/common/web/gesture-recognizer/src/engine/index.ts index bec77fc5a5..56678ad7bf 100644 --- a/common/web/gesture-recognizer/src/engine/index.ts +++ b/common/web/gesture-recognizer/src/engine/index.ts @@ -5,7 +5,7 @@ export { GestureRecognizerConfiguration } from "./configuration/gestureRecognize export { InputEngineBase } from "./headless/inputEngineBase.js"; export { InputSample } from "./headless/inputSample.js"; export { JSONTrackedInput, TrackedInput } from "./headless/trackedInput.js"; -export { JSONTrackedPath, TrackedPath } from "./headless/trackedPath.js"; +export { SerializedGesturePath, GesturePath } from "./headless/gesturePath.js"; export { JSONTrackedPoint, TrackedPoint } from "./headless/trackedPoint.js"; export { MouseEventEngine } from "./mouseEventEngine.js"; export { PathSegmenter, Subsegmentation } from "./headless/subsegmentation/pathSegmenter.js"; diff --git a/common/web/gesture-recognizer/src/test/auto/headless/trackedPath.js b/common/web/gesture-recognizer/src/test/auto/headless/trackedPath.js index c4af818f27..99da19b8b5 100644 --- a/common/web/gesture-recognizer/src/test/auto/headless/trackedPath.js +++ b/common/web/gesture-recognizer/src/test/auto/headless/trackedPath.js @@ -1,13 +1,13 @@ import { assert } from 'chai' import sinon from 'sinon'; -import { TrackedPath } from '@keymanapp/gesture-recognizer'; +import { GesturePath } from '@keymanapp/gesture-recognizer'; import { timedPromise } from '@keymanapp/web-utils'; // End of "for the integrated style..." -describe("TrackedPath", function() { +describe("FingerPath", function() { // // File paths need to be from the package's / module's root folder // let testJSONtext = fs.readFileSync('src/test/resources/json/canaryRecording.json'); @@ -17,7 +17,7 @@ describe("TrackedPath", function() { const spyEventComplete = sinon.fake(); const spyEventInvalidated = sinon.fake(); - const touchpath = new TrackedPath(); + const touchpath = new GesturePath(); touchpath.on('step', spyEventStep); touchpath.on('complete', spyEventComplete); touchpath.on('invalidated', spyEventInvalidated); @@ -50,7 +50,7 @@ describe("TrackedPath", function() { const spyEventComplete = sinon.fake(); const spyEventInvalidated = sinon.fake(); - const touchpath = new TrackedPath(); + const touchpath = new GesturePath(); touchpath.on('step', spyEventStep); touchpath.on('complete', spyEventComplete); touchpath.on('invalidated', spyEventInvalidated); @@ -82,7 +82,7 @@ describe("TrackedPath", function() { const spyEventComplete = sinon.fake(); const spyEventInvalidated = sinon.fake(); - const touchpath = new TrackedPath(); + const touchpath = new GesturePath(); touchpath.on('step', spyEventStep); touchpath.on('complete', spyEventComplete); touchpath.on('invalidated', spyEventInvalidated); @@ -104,7 +104,7 @@ describe("TrackedPath", function() { const spyEventComplete = sinon.fake(); const spyEventInvalidated = sinon.fake(); - const touchpath = new TrackedPath(); + const touchpath = new GesturePath(); touchpath.on('step', spyEventStep); touchpath.on('complete', spyEventComplete); touchpath.on('invalidated', spyEventInvalidated); @@ -137,7 +137,7 @@ describe("TrackedPath", function() { const spyEventComplete = sinon.fake(); const spyEventInvalidated = sinon.fake(); - const touchpath = new TrackedPath(); + const touchpath = new GesturePath(); touchpath.on('step', spyEventStep); touchpath.on('complete', spyEventComplete); touchpath.on('invalidated', spyEventInvalidated); From 872a7db02eee75121103295cbe9a02991508d772 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Thu, 13 Jul 2023 10:27:22 +0700 Subject: [PATCH 2/4] change(web): TrackedPoint -> SimpleGestureSource --- .../docs/web-reintegration.md | 8 ++++ .../src/engine/headless/gesturePath.ts | 8 ++-- .../src/engine/headless/inputEngineBase.ts | 8 ++-- ...trackedPoint.ts => simpleGestureSource.ts} | 42 ++++++++++++------- .../subsegmentation/constructingSegment.ts | 2 +- .../headless/subsegmentation/pathSegmenter.ts | 2 +- .../engine/headless/touchpointCoordinator.ts | 4 +- .../src/engine/headless/trackedInput.ts | 10 ++--- .../gesture-recognizer/src/engine/index.ts | 2 +- .../src/engine/inputEventEngine.ts | 4 +- .../src/engine/mouseEventEngine.ts | 2 +- .../src/headlessInputEngine.ts | 8 ++-- .../src/inputSequenceSimulator.ts | 6 +-- 13 files changed, 64 insertions(+), 42 deletions(-) rename common/web/gesture-recognizer/src/engine/headless/{trackedPoint.ts => simpleGestureSource.ts} (65%) diff --git a/common/web/gesture-recognizer/docs/web-reintegration.md b/common/web/gesture-recognizer/docs/web-reintegration.md index 8b8688f000..6bd09ebf40 100644 --- a/common/web/gesture-recognizer/docs/web-reintegration.md +++ b/common/web/gesture-recognizer/docs/web-reintegration.md @@ -48,4 +48,12 @@ Further events for that "tracked point" are based on `TrackedPoint.path`. This perspective of each touch point individually for further processing... effectively splitting multi-touchpoint events into multiple _individual_ events while keeping the metadata organized over each touchpoint's lifetime. +## From change/web/internal-gesture-src-nomenclature + +In case someone has to trace this history on things: + +- `TrackedInput` is now `ComplexGestureSource`. +- `TrackedPoint` is now `SimpleGestureSource`. +- `TrackedPath` is now `GesturePath`. + diff --git a/common/web/gesture-recognizer/src/engine/headless/gesturePath.ts b/common/web/gesture-recognizer/src/engine/headless/gesturePath.ts index 3cd8e2a5e8..cf1dda8a64 100644 --- a/common/web/gesture-recognizer/src/engine/headless/gesturePath.ts +++ b/common/web/gesture-recognizer/src/engine/headless/gesturePath.ts @@ -3,7 +3,7 @@ import { InputSample } from "./inputSample.js"; import { CumulativePathStats } from "./cumulativePathStats.js"; /** - * Documents the expected typing of serialized versions of the `TrackedPoint` class. + * Documents the expected typing of serialized versions of the `GesturePath` class. */ export type SerializedGesturePath = { coords: InputSample[]; // ensures type match with public class property. @@ -60,7 +60,7 @@ export class GesturePath extends EventEmitter> { } /** - * Deserializes a TrackedPath instance from its corresponding JSON.parse() object. + * Deserializes a GesturePath instance from its corresponding JSON.parse() object. * @param jsonObj */ static deserialize(jsonObj: SerializedGesturePath): GesturePath { @@ -90,7 +90,7 @@ export class GesturePath extends EventEmitter> { */ extend(sample: InputSample) { if(this._isComplete) { - throw new Error("Invalid state: this TrackedPath has already terminated."); + throw new Error("Invalid state: this GesturePath has already terminated."); } // The tracked path should emit InputSample events before Segment events and @@ -106,7 +106,7 @@ export class GesturePath extends EventEmitter> { */ terminate(cancel: boolean = false) { if(this._isComplete) { - throw new Error("Invalid state: this TrackedPath has already terminated."); + throw new Error("Invalid state: this GesturePath has already terminated."); } this.wasCancelled = cancel; this._isComplete = true; diff --git a/common/web/gesture-recognizer/src/engine/headless/inputEngineBase.ts b/common/web/gesture-recognizer/src/engine/headless/inputEngineBase.ts index 1813e2de1c..a5839014c5 100644 --- a/common/web/gesture-recognizer/src/engine/headless/inputEngineBase.ts +++ b/common/web/gesture-recognizer/src/engine/headless/inputEngineBase.ts @@ -1,12 +1,12 @@ import EventEmitter from "eventemitter3"; -import { TrackedPoint } from "./trackedPoint.js"; +import { SimpleGestureSource } from "./simpleGestureSource.js"; interface EventMap { /** * Indicates that a new, ongoing touchpoint or mouse interaction has begun. * @param input The instance that tracks all future updates over the lifetime of the touchpoint / mouse interaction. */ - 'pointstart': (input: TrackedPoint) => void; + 'pointstart': (input: SimpleGestureSource) => void; // // idea for line below: to help multitouch gestures keep touchpaths in sync, rather than updated separately // 'eventcomplete': () => void; @@ -18,7 +18,7 @@ interface EventMap { * (headlessly). */ export abstract class InputEngineBase extends EventEmitter> { - private _activeTouchpoints: TrackedPoint[] = []; + private _activeTouchpoints: SimpleGestureSource[] = []; /** * @param identifier The identifier number corresponding to the input sequence. @@ -35,7 +35,7 @@ export abstract class InputEngineBase extends EventEmitter point.rawIdentifier != identifier); } - protected addTouchpoint(touchpoint: TrackedPoint) { + protected addTouchpoint(touchpoint: SimpleGestureSource) { this._activeTouchpoints.push(touchpoint); } } \ No newline at end of file diff --git a/common/web/gesture-recognizer/src/engine/headless/trackedPoint.ts b/common/web/gesture-recognizer/src/engine/headless/simpleGestureSource.ts similarity index 65% rename from common/web/gesture-recognizer/src/engine/headless/trackedPoint.ts rename to common/web/gesture-recognizer/src/engine/headless/simpleGestureSource.ts index 6e346054cf..723ad5fcfb 100644 --- a/common/web/gesture-recognizer/src/engine/headless/trackedPoint.ts +++ b/common/web/gesture-recognizer/src/engine/headless/simpleGestureSource.ts @@ -2,9 +2,9 @@ import { InputSample } from "./inputSample.js"; import { SerializedGesturePath, GesturePath } from "./gesturePath.js"; /** - * Documents the expected typing of serialized versions of the `TrackedPoint` class. + * Documents the expected typing of serialized versions of the `SimpleGestureSource` class. */ -export type JSONTrackedPoint = { +export type SerializedSimpleGestureSource = { isFromTouch: boolean; path: SerializedGesturePath; initialHoveredItem: HoveredItemType @@ -12,11 +12,25 @@ export type JSONTrackedPoint = { } /** - * Represents one 'tracked point' involved in a potential / recognized gesture as tracked over time. - * This 'tracked point' corresponds to one touch source as recognized by `Touch.identifier` or to + * Represents all metadata needed internally for tracking a single "touch contact point" / "touchpoint" + * involved in a potential / recognized gesture as tracked over time. + * + * Each instance corresponds to one unique contact point as recognized by `Touch.identifier` or to * one 'cursor-point' as represented by mouse-based motion. + * + * Refer to https://developer.mozilla.org/en-US/docs/Web/API/Touch and + * https://developer.mozilla.org/en-US/docs/Web/API/Navigator/maxTouchPoints re "touch contact point". + * + * May be one-to-many with recognized gestures: a keyboard longpress interaction generally only has one + * contact point but will have multiple realized gestures / components: + * - longpress: Enough time has elapsed + * - subkey: Subkey from the longpress subkey menu has been selected. + * + * Thus, it is a "gesture source". This is the level needed to model a single contact point, while some + * gestures expect multiple, hence "simple". + * */ -export class TrackedPoint { +export class SimpleGestureSource { /** * Indicates whether or not this tracked point's original source is a DOM `Touch`. */ @@ -32,14 +46,14 @@ export class TrackedPoint { private static _jsonIdSeed: -1; /** - * Tracks the coordinates and timestamps of each update for the lifetime of this `TrackedPoint`. + * Tracks the coordinates and timestamps of each update for the lifetime of this `SimpleGestureSource`. */ public get path(): GesturePath { return this._path; } /** - * Constructs a new TrackedPoint instance for tracking updates to an active input point over time. + * Constructs a new SimpleGestureSource instance for tracking updates to an active input point over time. * @param identifier The system identifier for the input point's events. * @param initialHoveredItem The initiating event's original target element * @param isFromTouch `true` if sourced from a `TouchEvent`; `false` otherwise. @@ -51,16 +65,16 @@ export class TrackedPoint { } /** - * Deserializes a TrackedPoint instance from its serialized-JSON form. + * Deserializes a SimpleGestureSource instance from its serialized-JSON form. * @param jsonObj The JSON representation to deserialize. * @param identifier The unique identifier to assign to this instance. */ - public static deserialize(jsonObj: JSONTrackedPoint, identifier: number) { + public static deserialize(jsonObj: SerializedSimpleGestureSource, identifier: number) { const id = identifier !== undefined ? identifier : this._jsonIdSeed++; const isFromTouch = jsonObj.isFromTouch; const path = GesturePath.deserialize(jsonObj.path); - const instance = new TrackedPoint(id, isFromTouch); + const instance = new SimpleGestureSource(id, isFromTouch); instance._path = path; return instance; } @@ -71,7 +85,7 @@ export class TrackedPoint { /** * The identifying metadata returned by the configuration's specified `itemIdentifier` for - * the target of the first `Event` that corresponded to this `TrackedPoint`. + * the target of the first `Event` that corresponded to this `SimpleGestureSource`. */ public get initialHoveredItem(): HoveredItemType { return this.path.coords[0].item; @@ -79,7 +93,7 @@ export class TrackedPoint { /** * The identifying metadata returned by the configuration's specified `itemIdentifier` for - * the target of the latest `Event` that corresponded to this `TrackedPoint`. + * the target of the latest `Event` that corresponded to this `SimpleGestureSource`. */ public get currentHoveredItem(): HoveredItemType { return this.path.coords[this.path.coords.length-1].item; @@ -98,8 +112,8 @@ export class TrackedPoint { * Creates a serialization-friendly version of this instance for use by * `JSON.stringify`. */ - toJSON(): JSONTrackedPoint { - let jsonClone: JSONTrackedPoint = { + toJSON(): SerializedSimpleGestureSource { + let jsonClone: SerializedSimpleGestureSource = { isFromTouch: this.isFromTouch, initialHoveredItem: this.initialHoveredItem, path: this.path.toJSON() diff --git a/common/web/gesture-recognizer/src/engine/headless/subsegmentation/constructingSegment.ts b/common/web/gesture-recognizer/src/engine/headless/subsegmentation/constructingSegment.ts index 28aef917a6..b31e403a2d 100644 --- a/common/web/gesture-recognizer/src/engine/headless/subsegmentation/constructingSegment.ts +++ b/common/web/gesture-recognizer/src/engine/headless/subsegmentation/constructingSegment.ts @@ -296,7 +296,7 @@ export class ConstructingSegment { } /** - * The in-construction Segment, as published to `TrackedPath.segments` & `TrackedPath`'s + * The in-construction Segment, as published to `GesturePath.segments` & `GesturePath`'s * 'segmentation' event. */ public get pathSegment() { diff --git a/common/web/gesture-recognizer/src/engine/headless/subsegmentation/pathSegmenter.ts b/common/web/gesture-recognizer/src/engine/headless/subsegmentation/pathSegmenter.ts index cc46013d7f..7b781a78db 100644 --- a/common/web/gesture-recognizer/src/engine/headless/subsegmentation/pathSegmenter.ts +++ b/common/web/gesture-recognizer/src/engine/headless/subsegmentation/pathSegmenter.ts @@ -554,7 +554,7 @@ export class PathSegmenter { /** * A closure used to 'forward' generated Segments, generally to their public-facing - * location on TrackedPath.segments. + * location on GesturePath.segments. */ private readonly segmentForwarder: (segment: Segment) => void; diff --git a/common/web/gesture-recognizer/src/engine/headless/touchpointCoordinator.ts b/common/web/gesture-recognizer/src/engine/headless/touchpointCoordinator.ts index 741a1b89a0..a2e4566c0a 100644 --- a/common/web/gesture-recognizer/src/engine/headless/touchpointCoordinator.ts +++ b/common/web/gesture-recognizer/src/engine/headless/touchpointCoordinator.ts @@ -1,7 +1,7 @@ import EventEmitter from "eventemitter3"; import { InputEngineBase } from "./inputEngineBase.js"; import { TrackedInput } from "./trackedInput.js"; -import { TrackedPoint } from "./trackedPoint.js"; +import { SimpleGestureSource } from "./simpleGestureSource.js"; interface EventMap { /** @@ -35,7 +35,7 @@ export class TouchpointCoordinator extends EventEmitter) => { + private readonly onNewTrackedPath = (touchpoint: SimpleGestureSource) => { const newInput = new TrackedInput(touchpoint); this._activeInputs[touchpoint.identifier] = newInput; diff --git a/common/web/gesture-recognizer/src/engine/headless/trackedInput.ts b/common/web/gesture-recognizer/src/engine/headless/trackedInput.ts index a173e84f24..7baa63830a 100644 --- a/common/web/gesture-recognizer/src/engine/headless/trackedInput.ts +++ b/common/web/gesture-recognizer/src/engine/headless/trackedInput.ts @@ -1,11 +1,11 @@ import EventEmitter from "eventemitter3"; -import { JSONTrackedPoint, TrackedPoint } from "./trackedPoint.js"; +import { SerializedSimpleGestureSource, SimpleGestureSource } from "./simpleGestureSource.js"; /** * Documents the expected typing of serialized versions of the `TrackedInput` class. */ export interface JSONTrackedInput { - touchpoints: JSONTrackedPoint[]; + touchpoints: SerializedSimpleGestureSource[]; // gesture: Gesture; } @@ -29,7 +29,7 @@ interface EventMap { * - Provides no parameters. */ export class TrackedInput extends EventEmitter { - public readonly touchpoints: TrackedPoint[]; + public readonly touchpoints: SimpleGestureSource[]; // --- Future design aspects --- // private _gesture: Gesture; @@ -37,14 +37,14 @@ export class TrackedInput extends EventEmitter { private isActive = true; - constructor(basePoint: TrackedPoint) { + constructor(basePoint: SimpleGestureSource) { super(); this.touchpoints = [ basePoint ]; this._attachPointHooks(basePoint); } - private _attachPointHooks(touchpoint: TrackedPoint) { + private _attachPointHooks(touchpoint: SimpleGestureSource) { touchpoint.path.on('complete', () => { this.isActive = false; this.emit('end'); diff --git a/common/web/gesture-recognizer/src/engine/index.ts b/common/web/gesture-recognizer/src/engine/index.ts index 56678ad7bf..4e71cb9b54 100644 --- a/common/web/gesture-recognizer/src/engine/index.ts +++ b/common/web/gesture-recognizer/src/engine/index.ts @@ -6,7 +6,7 @@ export { InputEngineBase } from "./headless/inputEngineBase.js"; export { InputSample } from "./headless/inputSample.js"; export { JSONTrackedInput, TrackedInput } from "./headless/trackedInput.js"; export { SerializedGesturePath, GesturePath } from "./headless/gesturePath.js"; -export { JSONTrackedPoint, TrackedPoint } from "./headless/trackedPoint.js"; +export { SerializedSimpleGestureSource, SimpleGestureSource } from "./headless/simpleGestureSource.js"; export { MouseEventEngine } from "./mouseEventEngine.js"; export { PathSegmenter, Subsegmentation } from "./headless/subsegmentation/pathSegmenter.js"; export { PaddedZoneSource } from './configuration/paddedZoneSource.js'; diff --git a/common/web/gesture-recognizer/src/engine/inputEventEngine.ts b/common/web/gesture-recognizer/src/engine/inputEventEngine.ts index c68f695bd4..c55408486d 100644 --- a/common/web/gesture-recognizer/src/engine/inputEventEngine.ts +++ b/common/web/gesture-recognizer/src/engine/inputEventEngine.ts @@ -2,7 +2,7 @@ import { GestureRecognizerConfiguration } from "./configuration/gestureRecognize import { InputEngineBase } from "./headless/inputEngineBase.js"; import { InputSample } from "./headless/inputSample.js"; import { Nonoptional } from "./nonoptional.js"; -import { TrackedPoint } from "./headless/trackedPoint.js"; +import { SimpleGestureSource } from "./headless/simpleGestureSource.js"; export abstract class InputEventEngine extends InputEngineBase { protected readonly config: Nonoptional>; @@ -32,7 +32,7 @@ export abstract class InputEventEngine extends InputEngineBase< } protected onInputStart(identifier: number, sample: InputSample, target: EventTarget, isFromTouch: boolean) { - const touchpoint = new TrackedPoint(identifier, isFromTouch); + const touchpoint = new SimpleGestureSource(identifier, isFromTouch); touchpoint.update(sample); this.addTouchpoint(touchpoint); diff --git a/common/web/gesture-recognizer/src/engine/mouseEventEngine.ts b/common/web/gesture-recognizer/src/engine/mouseEventEngine.ts index ac4d4e9eaa..1c2299cc30 100644 --- a/common/web/gesture-recognizer/src/engine/mouseEventEngine.ts +++ b/common/web/gesture-recognizer/src/engine/mouseEventEngine.ts @@ -23,7 +23,7 @@ export class MouseEventEngine extends InputEventEngine this.onMouseMove(event); this._mouseEnd = (event: MouseEvent) => this.onMouseEnd(event); - // IDs should be unique. Fortunately, they're disambiguated by their corresponding TrackedPoint, + // IDs should be unique. Fortunately, they're disambiguated by their corresponding SimpleGestureSource, // which has gives a globally-unique string-based identifier based partly on the numeric ID set here. MouseEventEngine.IDENTIFIER_SEED = 0; } diff --git a/common/web/gesture-recognizer/src/tools/unit-test-resources/src/headlessInputEngine.ts b/common/web/gesture-recognizer/src/tools/unit-test-resources/src/headlessInputEngine.ts index 739bcbc846..e90c1775a9 100644 --- a/common/web/gesture-recognizer/src/tools/unit-test-resources/src/headlessInputEngine.ts +++ b/common/web/gesture-recognizer/src/tools/unit-test-resources/src/headlessInputEngine.ts @@ -1,7 +1,7 @@ import { InputEngineBase, - JSONTrackedPoint, - TrackedPoint + SerializedSimpleGestureSource, + SimpleGestureSource } from '@keymanapp/gesture-recognizer'; import { RecordedCoordSequenceSet } from './inputRecording.js'; @@ -15,7 +15,7 @@ export class HeadlessInputEngine extends InputEngineBase { super(); } - public preparePathPlayback(recordedPoint: JSONTrackedPoint) { + public preparePathPlayback(recordedPoint: SerializedSimpleGestureSource) { const originalSamples = recordedPoint.path.coords; const sampleCount = originalSamples.length; @@ -23,7 +23,7 @@ export class HeadlessInputEngine extends InputEngineBase { const tailSamples = originalSamples.slice(1); const pathID = this.PATH_ID_SEED++; - let replayPoint = new TrackedPoint(pathID, recordedPoint.isFromTouch); + let replayPoint = new SimpleGestureSource(pathID, recordedPoint.isFromTouch); replayPoint.update(headSample); // is included before the point is made available. // Build promises designed to reproduce the events at the correct times. diff --git a/common/web/gesture-recognizer/src/tools/unit-test-resources/src/inputSequenceSimulator.ts b/common/web/gesture-recognizer/src/tools/unit-test-resources/src/inputSequenceSimulator.ts index 17d64e22e8..bcbcaf4ab6 100644 --- a/common/web/gesture-recognizer/src/tools/unit-test-resources/src/inputSequenceSimulator.ts +++ b/common/web/gesture-recognizer/src/tools/unit-test-resources/src/inputSequenceSimulator.ts @@ -1,5 +1,5 @@ import { - TrackedPoint, + SimpleGestureSource, type InputSample } from "@keymanapp/gesture-recognizer"; @@ -194,7 +194,7 @@ export class InputSequenceSimulator { for(let index=0; index < inputs.length; index++) { // TODO: does not iterate over all touchpoints. Not that we can have more than one at present... - const touchpoint = TrackedPoint.deserialize(inputs[index].touchpoints[0], index); + const touchpoint = SimpleGestureSource.deserialize(inputs[index].touchpoints[0], index); const indexInSequence = sequenceProgress[index]; if(indexInSequence == Number.MAX_VALUE) { @@ -207,7 +207,7 @@ export class InputSequenceSimulator { } } - const touchpoint = TrackedPoint.deserialize(inputs[selectedSequence].touchpoints[0], selectedSequence); + const touchpoint = SimpleGestureSource.deserialize(inputs[selectedSequence].touchpoints[0], selectedSequence); const indexInSequence = sequenceProgress[selectedSequence]; let state: string = "move"; From 811648edb657fdc0b500e30509b7514bef1b57f1 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Thu, 13 Jul 2023 10:29:35 +0700 Subject: [PATCH 3/4] change(web): TrackedInput -> ComplexGestureSource --- .../headless/{trackedInput.ts => complexGestureSource.ts} | 8 ++++---- .../src/engine/headless/touchpointCoordinator.ts | 8 ++++---- common/web/gesture-recognizer/src/engine/index.ts | 2 +- .../src/tools/unit-test-resources/src/inputRecording.ts | 4 ++-- .../src/tools/unit-test-resources/src/sequenceRecorder.ts | 6 +++--- 5 files changed, 14 insertions(+), 14 deletions(-) rename common/web/gesture-recognizer/src/engine/headless/{trackedInput.ts => complexGestureSource.ts} (90%) diff --git a/common/web/gesture-recognizer/src/engine/headless/trackedInput.ts b/common/web/gesture-recognizer/src/engine/headless/complexGestureSource.ts similarity index 90% rename from common/web/gesture-recognizer/src/engine/headless/trackedInput.ts rename to common/web/gesture-recognizer/src/engine/headless/complexGestureSource.ts index 7baa63830a..102ba42817 100644 --- a/common/web/gesture-recognizer/src/engine/headless/trackedInput.ts +++ b/common/web/gesture-recognizer/src/engine/headless/complexGestureSource.ts @@ -2,9 +2,9 @@ import EventEmitter from "eventemitter3"; import { SerializedSimpleGestureSource, SimpleGestureSource } from "./simpleGestureSource.js"; /** - * Documents the expected typing of serialized versions of the `TrackedInput` class. + * Documents the expected typing of serialized versions of the `ComplexGestureSource` class. */ -export interface JSONTrackedInput { +export interface SerializedComplexGestureSource { touchpoints: SerializedSimpleGestureSource[]; // gesture: Gesture; } @@ -28,7 +28,7 @@ interface EventMap { * `'end'`: all gesture recognition for this input is to be resolved. * - Provides no parameters. */ -export class TrackedInput extends EventEmitter { +export class ComplexGestureSource extends EventEmitter { public readonly touchpoints: SimpleGestureSource[]; // --- Future design aspects --- @@ -78,7 +78,7 @@ export class TrackedInput extends EventEmitter { * Creates a serialization-friendly version of this instance for use by * `JSON.stringify`. */ - toJSON(): JSONTrackedInput { + toJSON(): SerializedComplexGestureSource { return { touchpoints: this.touchpoints.map((point) => point.toJSON()) }; diff --git a/common/web/gesture-recognizer/src/engine/headless/touchpointCoordinator.ts b/common/web/gesture-recognizer/src/engine/headless/touchpointCoordinator.ts index a2e4566c0a..0b04046ac0 100644 --- a/common/web/gesture-recognizer/src/engine/headless/touchpointCoordinator.ts +++ b/common/web/gesture-recognizer/src/engine/headless/touchpointCoordinator.ts @@ -1,6 +1,6 @@ import EventEmitter from "eventemitter3"; import { InputEngineBase } from "./inputEngineBase.js"; -import { TrackedInput } from "./trackedInput.js"; +import { ComplexGestureSource } from "./complexGestureSource.js"; import { SimpleGestureSource } from "./simpleGestureSource.js"; interface EventMap { @@ -9,7 +9,7 @@ interface EventMap { * @param input * @returns */ - 'inputstart': (input: TrackedInput) => void; + 'inputstart': (input: ComplexGestureSource) => void; } /** @@ -23,7 +23,7 @@ interface EventMap { export class TouchpointCoordinator extends EventEmitter> { private inputEngines: InputEngineBase[]; - private _activeInputs: {[id: string]: TrackedInput} = {}; + private _activeInputs: {[id: string]: ComplexGestureSource} = {}; public constructor() { super(); @@ -36,7 +36,7 @@ export class TouchpointCoordinator extends EventEmitter) => { - const newInput = new TrackedInput(touchpoint); + const newInput = new ComplexGestureSource(touchpoint); this._activeInputs[touchpoint.identifier] = newInput; this.emit('inputstart', newInput); diff --git a/common/web/gesture-recognizer/src/engine/index.ts b/common/web/gesture-recognizer/src/engine/index.ts index 4e71cb9b54..dc3ec23101 100644 --- a/common/web/gesture-recognizer/src/engine/index.ts +++ b/common/web/gesture-recognizer/src/engine/index.ts @@ -4,7 +4,7 @@ export { GestureRecognizer } from "./gestureRecognizer.js"; export { GestureRecognizerConfiguration } from "./configuration/gestureRecognizerConfiguration.js"; export { InputEngineBase } from "./headless/inputEngineBase.js"; export { InputSample } from "./headless/inputSample.js"; -export { JSONTrackedInput, TrackedInput } from "./headless/trackedInput.js"; +export { SerializedComplexGestureSource, ComplexGestureSource } from "./headless/complexGestureSource.js"; export { SerializedGesturePath, GesturePath } from "./headless/gesturePath.js"; export { SerializedSimpleGestureSource, SimpleGestureSource } from "./headless/simpleGestureSource.js"; export { MouseEventEngine } from "./mouseEventEngine.js"; diff --git a/common/web/gesture-recognizer/src/tools/unit-test-resources/src/inputRecording.ts b/common/web/gesture-recognizer/src/tools/unit-test-resources/src/inputRecording.ts index c626d635cc..3ea9b520bc 100644 --- a/common/web/gesture-recognizer/src/tools/unit-test-resources/src/inputRecording.ts +++ b/common/web/gesture-recognizer/src/tools/unit-test-resources/src/inputRecording.ts @@ -1,4 +1,4 @@ -import { type JSONTrackedInput } from "@keymanapp/gesture-recognizer"; +import { type SerializedComplexGestureSource } from "@keymanapp/gesture-recognizer"; import { type FixtureLayoutConfiguration } from "./fixtureLayoutConfiguration.js"; import { type JSONObject } from "./jsonObject.js"; @@ -7,6 +7,6 @@ import { type JSONObject } from "./jsonObject.js"; * The top-level object produced by the "Test Sequence Recorder". */ export interface RecordedCoordSequenceSet { - inputs: JSONTrackedInput[]; + inputs: SerializedComplexGestureSource[]; config: JSONObject; } \ No newline at end of file diff --git a/common/web/gesture-recognizer/src/tools/unit-test-resources/src/sequenceRecorder.ts b/common/web/gesture-recognizer/src/tools/unit-test-resources/src/sequenceRecorder.ts index 7798273795..43b051b3f9 100644 --- a/common/web/gesture-recognizer/src/tools/unit-test-resources/src/sequenceRecorder.ts +++ b/common/web/gesture-recognizer/src/tools/unit-test-resources/src/sequenceRecorder.ts @@ -1,4 +1,4 @@ -import { TrackedInput } from "@keymanapp/gesture-recognizer"; +import { ComplexGestureSource } from "@keymanapp/gesture-recognizer"; import { HostFixtureLayoutController } from "./hostFixtureLayoutController.js"; import { RecordedCoordSequenceSet } from "./inputRecording.js"; @@ -7,11 +7,11 @@ import { RecordedCoordSequenceSet } from "./inputRecording.js"; * verification itself. */ -type WrappedInputSequence = TrackedInput; +type WrappedInputSequence = ComplexGestureSource; export class SequenceRecorder { controller: HostFixtureLayoutController; - records: {[identifier: string]: TrackedInput} = {}; + records: {[identifier: string]: ComplexGestureSource} = {}; /** * Tracks the order in which each sequence was first detected. From e4cef64fdc640f115ee252675f6c7e93563bd92a Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Thu, 13 Jul 2023 10:37:11 +0700 Subject: [PATCH 4/4] docs(web): extra documentation b/c nomenclature shift --- .../src/engine/headless/complexGestureSource.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/common/web/gesture-recognizer/src/engine/headless/complexGestureSource.ts b/common/web/gesture-recognizer/src/engine/headless/complexGestureSource.ts index 102ba42817..7b6efafbc0 100644 --- a/common/web/gesture-recognizer/src/engine/headless/complexGestureSource.ts +++ b/common/web/gesture-recognizer/src/engine/headless/complexGestureSource.ts @@ -16,13 +16,20 @@ interface EventMap { /** - * Models a single ongoing input event, which may or may not involve multiple - * touchpoints. + * Models all ongoing contact that is considered part of the same single gesture + * or sequence of chained Gestures over time. This may or may not involve + * multiple touch contact points / "SimpleGestureSource" instances. + * + * Note that multiple chained gestures may arise over the lifetime of a single + * instance of this class. For example, detecting a multitap requires + * multiple contact points over time, possibly with each tap arising as a + * potential 'last' tap gesture before new ones are received to continue the + * sequence. * * _Supported events_: * * `'cancel'`: all gesture recognition for this input is to be cancelled - * and left incomplete. + * and left incomplete. * - Provides no parameters. * * `'end'`: all gesture recognition for this input is to be resolved.