@forgeax/engine-input 0.1.31 → 0.1.32
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/dist/composite-backend.d.ts +24 -0
- package/dist/composite-backend.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +204 -30
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/composite-backend.test.ts +55 -0
- package/src/composite-backend.ts +276 -33
- package/src/index.ts +1 -0
|
@@ -30,8 +30,32 @@ export interface CompositeInputBackend extends InputBackend {
|
|
|
30
30
|
* emit one clean release edge so a previously observed hold is closed.
|
|
31
31
|
*/
|
|
32
32
|
clearInjected(): void;
|
|
33
|
+
/** Open a fresh synthetic-input lease after a previous revoke boundary. */
|
|
34
|
+
beginInjectedLease(): void;
|
|
35
|
+
/** Revoke the current lease and fence later injections until reopened. */
|
|
36
|
+
revokeInjectedLease(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Create the one execution-scoped injection view. Creating a lease
|
|
39
|
+
* invalidates every previously-created view; an invalid view remains a
|
|
40
|
+
* no-op even after a later lease is opened.
|
|
41
|
+
*/
|
|
42
|
+
createInjectedLease(): CompositeInputLease;
|
|
33
43
|
/** Toggle the yield-to-human gate at runtime. */
|
|
34
44
|
setYieldToHuman(yield_: boolean): void;
|
|
35
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Synthetic input exposed to one eval/execution. It deliberately has no
|
|
48
|
+
* `beginInjectedLease` method: a script can release its own lease, but it
|
|
49
|
+
* cannot reopen an old reference after the host has moved to another job.
|
|
50
|
+
*/
|
|
51
|
+
export interface CompositeInputLease extends InputBackend {
|
|
52
|
+
press(key: string): void;
|
|
53
|
+
release(key: string): void;
|
|
54
|
+
setButton(slot: 0 | 1 | 2, down: boolean): void;
|
|
55
|
+
addMovement(dx: number, dy: number): void;
|
|
56
|
+
addWheel(notches: number): void;
|
|
57
|
+
clearInjected(): void;
|
|
58
|
+
revokeInjectedLease(): void;
|
|
59
|
+
}
|
|
36
60
|
export declare function makeCompositeBackend(inner: InputBackend, options?: CompositeBackendOptions): CompositeInputBackend;
|
|
37
61
|
//# sourceMappingURL=composite-backend.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"composite-backend.d.ts","sourceRoot":"","sources":["../src/composite-backend.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,YAAY,EAAsB,MAAM,kBAAkB,CAAC;AAEzE,sDAAsD;AACtD,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAsB,SAAQ,YAAY;IACzD,uDAAuD;IACvD,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,iFAAiF;IACjF,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,4DAA4D;IAC5D,SAAS,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAChD,gFAAgF;IAChF,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC;;;OAGG;IACH,aAAa,IAAI,IAAI,CAAC;IACtB,iDAAiD;IACjD,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;CACxC;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,YAAY,EACnB,OAAO,CAAC,EAAE,uBAAuB,GAChC,qBAAqB,
|
|
1
|
+
{"version":3,"file":"composite-backend.d.ts","sourceRoot":"","sources":["../src/composite-backend.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,YAAY,EAAsB,MAAM,kBAAkB,CAAC;AAEzE,sDAAsD;AACtD,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAsB,SAAQ,YAAY;IACzD,uDAAuD;IACvD,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,iFAAiF;IACjF,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,4DAA4D;IAC5D,SAAS,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAChD,gFAAgF;IAChF,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC;;;OAGG;IACH,aAAa,IAAI,IAAI,CAAC;IACtB,2EAA2E;IAC3E,kBAAkB,IAAI,IAAI,CAAC;IAC3B,0EAA0E;IAC1E,mBAAmB,IAAI,IAAI,CAAC;IAC5B;;;;OAIG;IACH,mBAAmB,IAAI,mBAAmB,CAAC;IAC3C,iDAAiD;IACjD,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;CACxC;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACvD,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAChD,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,aAAa,IAAI,IAAI,CAAC;IACtB,mBAAmB,IAAI,IAAI,CAAC;CAC7B;AA+DD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,YAAY,EACnB,OAAO,CAAC,EAAE,uBAAuB,GAChC,qBAAqB,CAmVvB"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export type { ActionBinding, ActionConfig, ActionState, GetVectorOptions, } from
|
|
|
2
2
|
export { deriveActionStates, getAxis, getVector, INPUT_MAP_KEY, } from './action-state';
|
|
3
3
|
export { attachBrowserInputBackend, type BrowserInputBackendOptions, type PointerLockProvider, } from './browser-backend';
|
|
4
4
|
export { type CanvasInputBoundary, createCanvasInputBoundary, } from './canvas-input-boundary';
|
|
5
|
-
export { type CompositeBackendOptions, type CompositeInputBackend, makeCompositeBackend, } from './composite-backend';
|
|
5
|
+
export { type CompositeBackendOptions, type CompositeInputBackend, type CompositeInputLease, makeCompositeBackend, } from './composite-backend';
|
|
6
6
|
export { FRAME_START_SCAN_SYSTEM_NAME, INPUT_BACKEND_KEY, InputFrameStartScan, InputSet, } from './frame-start-scan-system';
|
|
7
7
|
export type { GestureEvent, GestureState, SwipeDirection, } from './gesture-recognizer';
|
|
8
8
|
export { DOUBLE_TAP_DISTANCE, DOUBLE_TAP_INTERVAL_MS, IDENTITY_GESTURE, LONG_PRESS_DURATION_MS, LONG_PRESS_SLOP, SWIPE_VELOCITY_THRESHOLD, SWIPE_WINDOW_MS, } from './gesture-recognizer';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA0BA,YAAY,EACV,aAAa,EACb,YAAY,EACZ,WAAW,EACX,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,kBAAkB,EAClB,OAAO,EACP,SAAS,EACT,aAAa,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,yBAAyB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,KAAK,mBAAmB,EACxB,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,4BAA4B,EAC5B,iBAAiB,EACjB,mBAAmB,EACnB,QAAQ,GACT,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,EACf,wBAAwB,EACxB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EACL,0BAA0B,EAC1B,cAAc,EACd,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAChC,KAAK,iBAAiB,GACvB,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA0BA,YAAY,EACV,aAAa,EACb,YAAY,EACZ,WAAW,EACX,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,kBAAkB,EAClB,OAAO,EACP,SAAS,EACT,aAAa,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,yBAAyB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,KAAK,mBAAmB,EACxB,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,4BAA4B,EAC5B,iBAAiB,EACjB,mBAAmB,EACnB,QAAQ,GACT,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,EACf,wBAAwB,EACxB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EACL,0BAA0B,EAC1B,cAAc,EACd,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAChC,KAAK,iBAAiB,GACvB,MAAM,gBAAgB,CAAC"}
|
package/dist/index.mjs
CHANGED
|
@@ -1408,36 +1408,118 @@ function createCanvasInputBoundary(source) {
|
|
|
1408
1408
|
}
|
|
1409
1409
|
|
|
1410
1410
|
// src/composite-backend.ts
|
|
1411
|
+
var CODE_TO_KEY = {
|
|
1412
|
+
Space: " ",
|
|
1413
|
+
ShiftLeft: "Shift",
|
|
1414
|
+
ShiftRight: "Shift",
|
|
1415
|
+
ControlLeft: "Control",
|
|
1416
|
+
ControlRight: "Control",
|
|
1417
|
+
AltLeft: "Alt",
|
|
1418
|
+
AltRight: "Alt",
|
|
1419
|
+
MetaLeft: "Meta",
|
|
1420
|
+
MetaRight: "Meta",
|
|
1421
|
+
BracketLeft: "[",
|
|
1422
|
+
BracketRight: "]",
|
|
1423
|
+
Backslash: "\\",
|
|
1424
|
+
Semicolon: ";",
|
|
1425
|
+
Quote: "'",
|
|
1426
|
+
Comma: ",",
|
|
1427
|
+
Period: ".",
|
|
1428
|
+
Slash: "/",
|
|
1429
|
+
Minus: "-",
|
|
1430
|
+
Equal: "=",
|
|
1431
|
+
Backquote: "`"
|
|
1432
|
+
};
|
|
1433
|
+
function keyForCode(code) {
|
|
1434
|
+
if (CODE_TO_KEY[code] !== void 0) return CODE_TO_KEY[code];
|
|
1435
|
+
if (/^Key[A-Z]$/.test(code)) return code.slice(3).toLowerCase();
|
|
1436
|
+
if (/^Digit[0-9]$/.test(code)) return code.slice(5);
|
|
1437
|
+
if (/^Numpad[0-9]$/.test(code)) return code.slice(6);
|
|
1438
|
+
if (/^F(?:[1-9]|1[0-2])$/.test(code)) return code;
|
|
1439
|
+
if (/^Arrow(?:Up|Down|Left|Right)$/.test(code)) return code;
|
|
1440
|
+
if (/^(?:Escape|Enter|Tab|Backspace|Delete|Home|End|PageUp|PageDown|Insert)$/.test(code))
|
|
1441
|
+
return code;
|
|
1442
|
+
return void 0;
|
|
1443
|
+
}
|
|
1444
|
+
function codeForKey(key) {
|
|
1445
|
+
if (/^[a-zA-Z]$/.test(key)) return `Key${key.toUpperCase()}`;
|
|
1446
|
+
if (/^[0-9]$/.test(key)) return `Digit${key}`;
|
|
1447
|
+
if (key === " ") return "Space";
|
|
1448
|
+
if (/^(?:Arrow(?:Up|Down|Left|Right)|Escape|Enter|Tab|Backspace|Delete|Home|End|PageUp|PageDown|Insert)$/.test(
|
|
1449
|
+
key
|
|
1450
|
+
))
|
|
1451
|
+
return key;
|
|
1452
|
+
if (/^F(?:[1-9]|1[0-2])$/.test(key)) return key;
|
|
1453
|
+
const entry = Object.entries(CODE_TO_KEY).find(([, value]) => value === key);
|
|
1454
|
+
return entry?.[0];
|
|
1455
|
+
}
|
|
1456
|
+
function normalizeKey(value) {
|
|
1457
|
+
const logical = keyForCode(value);
|
|
1458
|
+
return logical === void 0 ? { key: value, code: codeForKey(value) } : { key: logical, code: value };
|
|
1459
|
+
}
|
|
1411
1460
|
function makeCompositeBackend(inner, options) {
|
|
1412
1461
|
let yieldToHuman = options?.yieldToHuman ?? true;
|
|
1462
|
+
let leaseRevoked = false;
|
|
1463
|
+
let leaseGeneration = 0;
|
|
1413
1464
|
const heldKeys = /* @__PURE__ */ new Set();
|
|
1465
|
+
const heldCodes = /* @__PURE__ */ new Set();
|
|
1414
1466
|
const buttons = [false, false, false];
|
|
1415
1467
|
const upEdges = /* @__PURE__ */ new Set();
|
|
1468
|
+
const upCodeEdges = /* @__PURE__ */ new Set();
|
|
1416
1469
|
const pressedKeys = /* @__PURE__ */ new Set();
|
|
1470
|
+
const pressedCodes = /* @__PURE__ */ new Set();
|
|
1417
1471
|
const pressedButtons = [false, false, false];
|
|
1418
1472
|
const releasedButtons = [false, false, false];
|
|
1419
1473
|
let mvx = 0;
|
|
1420
1474
|
let mvy = 0;
|
|
1421
1475
|
let wheel = 0;
|
|
1422
1476
|
function injectionActive() {
|
|
1423
|
-
return heldKeys.size > 0 || upEdges.size > 0 || pressedKeys.size > 0 || buttons.some((b) => b) || pressedButtons.some((b) => b) || releasedButtons.some((b) => b);
|
|
1477
|
+
return heldKeys.size > 0 || heldCodes.size > 0 || upEdges.size > 0 || upCodeEdges.size > 0 || pressedKeys.size > 0 || pressedCodes.size > 0 || buttons.some((b) => b) || pressedButtons.some((b) => b) || releasedButtons.some((b) => b);
|
|
1424
1478
|
}
|
|
1425
1479
|
function sample() {
|
|
1426
1480
|
const base = inner.sample();
|
|
1427
1481
|
const downKeys = new Set(base.downKeys);
|
|
1482
|
+
const downCodes = base.downCodes === void 0 && heldCodes.size === 0 ? void 0 : new Set(base.downCodes ?? []);
|
|
1428
1483
|
for (const k of heldKeys) {
|
|
1429
|
-
|
|
1484
|
+
const code = codeForKey(k);
|
|
1485
|
+
if (yieldToHuman && (base.downKeys.has(k) || code !== void 0 && base.downCodes?.has(code) === true))
|
|
1486
|
+
continue;
|
|
1430
1487
|
downKeys.add(k);
|
|
1431
1488
|
}
|
|
1489
|
+
for (const code of heldCodes) {
|
|
1490
|
+
const key = keyForCode(code);
|
|
1491
|
+
if (yieldToHuman && (base.downCodes?.has(code) === true || key !== void 0 && base.downKeys.has(key)))
|
|
1492
|
+
continue;
|
|
1493
|
+
downCodes?.add(code);
|
|
1494
|
+
}
|
|
1432
1495
|
const mergedUp = new Set(base.upKeys);
|
|
1433
1496
|
for (const k of upEdges) {
|
|
1434
|
-
|
|
1497
|
+
const code = codeForKey(k);
|
|
1498
|
+
if (yieldToHuman && (base.downKeys.has(k) || code !== void 0 && base.downCodes?.has(code) === true))
|
|
1499
|
+
continue;
|
|
1435
1500
|
mergedUp.add(k);
|
|
1436
1501
|
}
|
|
1502
|
+
const mergedUpCodes = base.upCodes === void 0 && upCodeEdges.size === 0 ? void 0 : new Set(base.upCodes ?? []);
|
|
1503
|
+
for (const code of upCodeEdges) {
|
|
1504
|
+
const key = keyForCode(code);
|
|
1505
|
+
if (yieldToHuman && (base.downCodes?.has(code) === true || key !== void 0 && base.downKeys.has(key)))
|
|
1506
|
+
continue;
|
|
1507
|
+
mergedUpCodes?.add(code);
|
|
1508
|
+
}
|
|
1437
1509
|
const mergedPressed = base.pressedKeys === void 0 && pressedKeys.size === 0 ? void 0 : /* @__PURE__ */ new Set([...base.pressedKeys ?? [], ...pressedKeys]);
|
|
1438
|
-
if (yieldToHuman && base.downKeys.size > 0 && mergedPressed !== void 0) {
|
|
1510
|
+
if (yieldToHuman && (base.downKeys.size > 0 || (base.downCodes?.size ?? 0) > 0) && mergedPressed !== void 0) {
|
|
1439
1511
|
for (const key of pressedKeys) {
|
|
1440
|
-
|
|
1512
|
+
const code = codeForKey(key);
|
|
1513
|
+
if (base.downKeys.has(key) || code !== void 0 && base.downCodes?.has(code) === true)
|
|
1514
|
+
mergedPressed.delete(key);
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
const mergedPressedCodes = base.pressedCodes === void 0 && pressedCodes.size === 0 ? void 0 : new Set(base.pressedCodes ?? []);
|
|
1518
|
+
if (yieldToHuman && mergedPressedCodes !== void 0) {
|
|
1519
|
+
for (const code of pressedCodes) {
|
|
1520
|
+
const key = keyForCode(code);
|
|
1521
|
+
if (base.downCodes?.has(code) === true || key !== void 0 && base.downKeys.has(key))
|
|
1522
|
+
mergedPressedCodes.delete(code);
|
|
1441
1523
|
}
|
|
1442
1524
|
}
|
|
1443
1525
|
const mergedButtons = [
|
|
@@ -1461,8 +1543,10 @@ function makeCompositeBackend(inner, options) {
|
|
|
1461
1543
|
// carry inner optional fields (pointers/gamepads/gestures/...) untouched
|
|
1462
1544
|
downKeys,
|
|
1463
1545
|
upKeys: mergedUp,
|
|
1546
|
+
...downCodes === void 0 ? {} : { downCodes },
|
|
1547
|
+
...mergedUpCodes === void 0 ? {} : { upCodes: mergedUpCodes },
|
|
1464
1548
|
...mergedPressed === void 0 ? {} : { pressedKeys: mergedPressed },
|
|
1465
|
-
...
|
|
1549
|
+
...mergedPressedCodes === void 0 ? {} : { pressedCodes: mergedPressedCodes },
|
|
1466
1550
|
buttons: mergedButtons,
|
|
1467
1551
|
...mergedPressedButtons === void 0 ? {} : { pressedButtons: mergedPressedButtons },
|
|
1468
1552
|
...mergedReleasedButtons === void 0 ? {} : { releasedButtons: mergedReleasedButtons },
|
|
@@ -1474,7 +1558,9 @@ function makeCompositeBackend(inner, options) {
|
|
|
1474
1558
|
// AI never fabricates a lock
|
|
1475
1559
|
};
|
|
1476
1560
|
upEdges.clear();
|
|
1561
|
+
upCodeEdges.clear();
|
|
1477
1562
|
pressedKeys.clear();
|
|
1563
|
+
pressedCodes.clear();
|
|
1478
1564
|
pressedButtons[0] = false;
|
|
1479
1565
|
pressedButtons[1] = false;
|
|
1480
1566
|
pressedButtons[2] = false;
|
|
@@ -1487,49 +1573,137 @@ function makeCompositeBackend(inner, options) {
|
|
|
1487
1573
|
return out;
|
|
1488
1574
|
}
|
|
1489
1575
|
const lockGate = inner.setPointerLockAllowed ? { setPointerLockAllowed: (allowed) => inner.setPointerLockAllowed?.(allowed) } : {};
|
|
1576
|
+
const clearInjected = () => {
|
|
1577
|
+
upEdges.clear();
|
|
1578
|
+
upCodeEdges.clear();
|
|
1579
|
+
pressedKeys.clear();
|
|
1580
|
+
pressedCodes.clear();
|
|
1581
|
+
for (const k of heldKeys) upEdges.add(k);
|
|
1582
|
+
for (const code of heldCodes) upCodeEdges.add(code);
|
|
1583
|
+
heldKeys.clear();
|
|
1584
|
+
heldCodes.clear();
|
|
1585
|
+
pressedButtons[0] = false;
|
|
1586
|
+
pressedButtons[1] = false;
|
|
1587
|
+
pressedButtons[2] = false;
|
|
1588
|
+
releasedButtons[0] = false;
|
|
1589
|
+
releasedButtons[1] = false;
|
|
1590
|
+
releasedButtons[2] = false;
|
|
1591
|
+
if (buttons[0]) releasedButtons[0] = true;
|
|
1592
|
+
if (buttons[1]) releasedButtons[1] = true;
|
|
1593
|
+
if (buttons[2]) releasedButtons[2] = true;
|
|
1594
|
+
buttons[0] = buttons[1] = buttons[2] = false;
|
|
1595
|
+
mvx = 0;
|
|
1596
|
+
mvy = 0;
|
|
1597
|
+
wheel = 0;
|
|
1598
|
+
};
|
|
1599
|
+
const beginInjectedLease = () => {
|
|
1600
|
+
leaseGeneration += 1;
|
|
1601
|
+
leaseRevoked = false;
|
|
1602
|
+
clearInjected();
|
|
1603
|
+
};
|
|
1604
|
+
const revokeInjectedLease = () => {
|
|
1605
|
+
leaseGeneration += 1;
|
|
1606
|
+
leaseRevoked = true;
|
|
1607
|
+
clearInjected();
|
|
1608
|
+
};
|
|
1609
|
+
const createInjectedLease = () => {
|
|
1610
|
+
beginInjectedLease();
|
|
1611
|
+
const generation = leaseGeneration;
|
|
1612
|
+
const active = () => !leaseRevoked && generation === leaseGeneration;
|
|
1613
|
+
return {
|
|
1614
|
+
sample,
|
|
1615
|
+
detach: () => {
|
|
1616
|
+
},
|
|
1617
|
+
press(key) {
|
|
1618
|
+
if (!active()) return;
|
|
1619
|
+
const normalized = normalizeKey(key);
|
|
1620
|
+
if (!heldKeys.has(normalized.key)) pressedKeys.add(normalized.key);
|
|
1621
|
+
heldKeys.add(normalized.key);
|
|
1622
|
+
if (normalized.code !== void 0) {
|
|
1623
|
+
if (!heldCodes.has(normalized.code)) pressedCodes.add(normalized.code);
|
|
1624
|
+
heldCodes.add(normalized.code);
|
|
1625
|
+
}
|
|
1626
|
+
},
|
|
1627
|
+
release(key) {
|
|
1628
|
+
if (!active()) return;
|
|
1629
|
+
const normalized = normalizeKey(key);
|
|
1630
|
+
if (heldKeys.delete(normalized.key)) upEdges.add(normalized.key);
|
|
1631
|
+
if (normalized.code !== void 0 && heldCodes.delete(normalized.code))
|
|
1632
|
+
upCodeEdges.add(normalized.code);
|
|
1633
|
+
},
|
|
1634
|
+
setButton(slot, down) {
|
|
1635
|
+
if (!active()) return;
|
|
1636
|
+
if (down && !buttons[slot]) pressedButtons[slot] = true;
|
|
1637
|
+
if (!down && buttons[slot]) releasedButtons[slot] = true;
|
|
1638
|
+
buttons[slot] = down;
|
|
1639
|
+
},
|
|
1640
|
+
addMovement(dx, dy) {
|
|
1641
|
+
if (!active()) return;
|
|
1642
|
+
mvx += dx;
|
|
1643
|
+
mvy += dy;
|
|
1644
|
+
},
|
|
1645
|
+
addWheel(notches) {
|
|
1646
|
+
if (!active()) return;
|
|
1647
|
+
wheel += notches;
|
|
1648
|
+
},
|
|
1649
|
+
clearInjected() {
|
|
1650
|
+
if (active()) clearInjected();
|
|
1651
|
+
},
|
|
1652
|
+
revokeInjectedLease() {
|
|
1653
|
+
if (active()) revokeInjectedLease();
|
|
1654
|
+
}
|
|
1655
|
+
};
|
|
1656
|
+
};
|
|
1490
1657
|
return {
|
|
1491
1658
|
sample,
|
|
1492
1659
|
...lockGate,
|
|
1493
|
-
// Teardown belongs to the human backend --
|
|
1494
|
-
|
|
1660
|
+
// Teardown belongs to the human backend -- revoke the synthetic lease
|
|
1661
|
+
// first, then forward the physical listener teardown. `clear()` is also
|
|
1662
|
+
// exposed so an owner can revoke input without detaching the browser.
|
|
1663
|
+
clear: () => {
|
|
1664
|
+
clearInjected();
|
|
1665
|
+
inner.clear?.();
|
|
1666
|
+
},
|
|
1667
|
+
detach: () => {
|
|
1668
|
+
clearInjected();
|
|
1669
|
+
inner.detach();
|
|
1670
|
+
},
|
|
1495
1671
|
press(key) {
|
|
1496
|
-
if (
|
|
1497
|
-
|
|
1672
|
+
if (leaseRevoked) return;
|
|
1673
|
+
const normalized = normalizeKey(key);
|
|
1674
|
+
if (!heldKeys.has(normalized.key)) pressedKeys.add(normalized.key);
|
|
1675
|
+
heldKeys.add(normalized.key);
|
|
1676
|
+
if (normalized.code !== void 0) {
|
|
1677
|
+
if (!heldCodes.has(normalized.code)) pressedCodes.add(normalized.code);
|
|
1678
|
+
heldCodes.add(normalized.code);
|
|
1679
|
+
}
|
|
1498
1680
|
},
|
|
1499
1681
|
release(key) {
|
|
1500
|
-
if (
|
|
1682
|
+
if (leaseRevoked) return;
|
|
1683
|
+
const normalized = normalizeKey(key);
|
|
1684
|
+
if (heldKeys.delete(normalized.key)) upEdges.add(normalized.key);
|
|
1685
|
+
if (normalized.code !== void 0 && heldCodes.delete(normalized.code))
|
|
1686
|
+
upCodeEdges.add(normalized.code);
|
|
1501
1687
|
},
|
|
1502
1688
|
setButton(slot, down) {
|
|
1689
|
+
if (leaseRevoked) return;
|
|
1503
1690
|
if (down && !buttons[slot]) pressedButtons[slot] = true;
|
|
1504
1691
|
if (!down && buttons[slot]) releasedButtons[slot] = true;
|
|
1505
1692
|
buttons[slot] = down;
|
|
1506
1693
|
},
|
|
1507
1694
|
addMovement(dx, dy) {
|
|
1695
|
+
if (leaseRevoked) return;
|
|
1508
1696
|
mvx += dx;
|
|
1509
1697
|
mvy += dy;
|
|
1510
1698
|
},
|
|
1511
1699
|
addWheel(notches) {
|
|
1700
|
+
if (leaseRevoked) return;
|
|
1512
1701
|
wheel += notches;
|
|
1513
1702
|
},
|
|
1514
|
-
clearInjected
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
heldKeys.clear();
|
|
1519
|
-
pressedButtons[0] = false;
|
|
1520
|
-
pressedButtons[1] = false;
|
|
1521
|
-
pressedButtons[2] = false;
|
|
1522
|
-
releasedButtons[0] = false;
|
|
1523
|
-
releasedButtons[1] = false;
|
|
1524
|
-
releasedButtons[2] = false;
|
|
1525
|
-
if (buttons[0]) releasedButtons[0] = true;
|
|
1526
|
-
if (buttons[1]) releasedButtons[1] = true;
|
|
1527
|
-
if (buttons[2]) releasedButtons[2] = true;
|
|
1528
|
-
buttons[0] = buttons[1] = buttons[2] = false;
|
|
1529
|
-
mvx = 0;
|
|
1530
|
-
mvy = 0;
|
|
1531
|
-
wheel = 0;
|
|
1532
|
-
},
|
|
1703
|
+
clearInjected,
|
|
1704
|
+
beginInjectedLease,
|
|
1705
|
+
revokeInjectedLease,
|
|
1706
|
+
createInjectedLease,
|
|
1533
1707
|
setYieldToHuman(yield_) {
|
|
1534
1708
|
yieldToHuman = yield_;
|
|
1535
1709
|
}
|