@akashic/headless-driver 2.17.10 → 2.18.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/lib/runner/Runner.d.ts +6 -0
- package/lib/runner/v1/RunnerV1.d.ts +1 -0
- package/lib/runner/v1/RunnerV1.js +5 -0
- package/lib/runner/v2/RunnerV2.d.ts +1 -0
- package/lib/runner/v2/RunnerV2.js +60 -0
- package/lib/runner/v3/RunnerV3.d.ts +1 -0
- package/lib/runner/v3/RunnerV3.js +60 -0
- package/package.json +5 -5
package/lib/runner/Runner.d.ts
CHANGED
|
@@ -92,6 +92,12 @@ export declare abstract class Runner {
|
|
|
92
92
|
* @param ms 進行するミリ秒。
|
|
93
93
|
*/
|
|
94
94
|
abstract advance(ms: number): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Runner を呼び出し時点で得られる最新状態まで進める。
|
|
97
|
+
* passive かつリアルタイムでのみ利用可能。
|
|
98
|
+
* @param timeout タイムアウトまでのミリ時間。省略時は `5000` 。ゲーム内時間ではなく実時間である点に注意。
|
|
99
|
+
*/
|
|
100
|
+
abstract advanceLatest(timeout?: number): Promise<void>;
|
|
95
101
|
/**
|
|
96
102
|
* Runner を一フレーム進行する。
|
|
97
103
|
*/
|
|
@@ -18,6 +18,7 @@ export declare class RunnerV1 extends Runner {
|
|
|
18
18
|
step(): Promise<void>;
|
|
19
19
|
protected _stepMinimal(): void;
|
|
20
20
|
advance(ms: number): Promise<void>;
|
|
21
|
+
advanceLatest(_timeout?: number): Promise<void>;
|
|
21
22
|
changeGameDriverState(param: gdr.GameDriverInitializeParameterObject): Promise<void>;
|
|
22
23
|
firePointEvent(event: RunnerPointEvent): void;
|
|
23
24
|
getPrimarySurface(): never;
|
|
@@ -125,6 +125,11 @@ class RunnerV1 extends Runner_1.Runner {
|
|
|
125
125
|
yield (0, promises_1.setImmediate)();
|
|
126
126
|
});
|
|
127
127
|
}
|
|
128
|
+
advanceLatest(_timeout) {
|
|
129
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
130
|
+
this.errorTrigger.fire(new Error("Runner#advanceLatest() is not supported in RunnerV1"));
|
|
131
|
+
});
|
|
132
|
+
}
|
|
128
133
|
changeGameDriverState(param) {
|
|
129
134
|
return new Promise((resolve, reject) => {
|
|
130
135
|
if (!this.driver) {
|
|
@@ -17,6 +17,7 @@ export declare class RunnerV2 extends Runner {
|
|
|
17
17
|
resume(): void;
|
|
18
18
|
step(): Promise<void>;
|
|
19
19
|
advance(ms: number): Promise<void>;
|
|
20
|
+
advanceLatest(timeout?: number): Promise<void>;
|
|
20
21
|
changeGameDriverState(param: gdr.GameDriverInitializeParameterObject): Promise<void>;
|
|
21
22
|
firePointEvent(event: RunnerPointEvent): void;
|
|
22
23
|
getPrimarySurface(): never;
|
|
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.RunnerV2 = void 0;
|
|
13
13
|
const promises_1 = require("node:timers/promises");
|
|
14
14
|
const engine_files_v2_1 = require("engine-files-v2");
|
|
15
|
+
const Logger_1 = require("../../Logger");
|
|
15
16
|
const Runner_1 = require("../Runner");
|
|
16
17
|
const PlatformV2_1 = require("./platform/PlatformV2");
|
|
17
18
|
class RunnerV2 extends Runner_1.Runner {
|
|
@@ -113,6 +114,65 @@ class RunnerV2 extends Runner_1.Runner {
|
|
|
113
114
|
yield (0, promises_1.setImmediate)();
|
|
114
115
|
});
|
|
115
116
|
}
|
|
117
|
+
advanceLatest() {
|
|
118
|
+
return __awaiter(this, arguments, void 0, function* (timeout = 5000) {
|
|
119
|
+
var _a, _b;
|
|
120
|
+
if (this.driver == null) {
|
|
121
|
+
this.errorTrigger.fire(new Error("Cannot call Runner#advanceLatest() before initialization"));
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (this.running) {
|
|
125
|
+
this.errorTrigger.fire(new Error("Cannot call Runner#advanceLatest() while running"));
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (this.executionMode !== "passive" || this.loopMode !== "realtime") {
|
|
129
|
+
(0, Logger_1.getSystemLogger)().warn("RunnerV2#advanceLatest() is only available when executionMode is 'passive' and loopMode is 'realtime'");
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const tickBuffer = (_b = (_a = this.driver) === null || _a === void 0 ? void 0 : _a._gameLoop) === null || _b === void 0 ? void 0 : _b._tickBuffer;
|
|
133
|
+
if (!tickBuffer) {
|
|
134
|
+
this.errorTrigger.fire(new Error("RunnerV2#advanceLatest() aborted because tickBuffer does not exist"));
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const startTime = performance.now();
|
|
138
|
+
// 最新の Tick をリクエストして、トリガーを待機する Promise を準備
|
|
139
|
+
const gotTickPromise = new Promise((resolve, reject) => {
|
|
140
|
+
const timeoutId = setTimeout(() => {
|
|
141
|
+
reject(new Error("RunnerV2#advanceLatest() timeout: no tick response"));
|
|
142
|
+
}, Math.max(0, timeout - (performance.now() - startTime)));
|
|
143
|
+
// 新しい Tick が存在した場合
|
|
144
|
+
tickBuffer.gotNextTickTrigger.addOnce(() => {
|
|
145
|
+
clearTimeout(timeoutId);
|
|
146
|
+
resolve();
|
|
147
|
+
});
|
|
148
|
+
// Tick がない場合
|
|
149
|
+
tickBuffer.gotNoTickTrigger.addOnce(() => {
|
|
150
|
+
clearTimeout(timeoutId);
|
|
151
|
+
resolve();
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
// 先に requestTicks を呼び出して、並行して Tick の取得を開始
|
|
155
|
+
tickBuffer.requestTicks();
|
|
156
|
+
// gotNoTickTrigger または gotNextTickTrigger が fire するまで待機
|
|
157
|
+
yield gotTickPromise;
|
|
158
|
+
// TickBuffer#currentAge === TickBuffer#knownLatestAge になるまで進める
|
|
159
|
+
while (tickBuffer.currentAge < tickBuffer.knownLatestAge) {
|
|
160
|
+
if (performance.now() - startTime > timeout) {
|
|
161
|
+
this.errorTrigger.fire(new Error("RunnerV2#advanceLatest() timeout: failed to catch up to knownLatestAge"));
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
// 一度に最大 100 ステップ実行
|
|
165
|
+
const batchSize = Math.min(100, tickBuffer.knownLatestAge - tickBuffer.currentAge);
|
|
166
|
+
for (let i = 0; i < batchSize; i++) {
|
|
167
|
+
if (tickBuffer.currentAge >= tickBuffer.knownLatestAge) {
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
this._stepMinimal();
|
|
171
|
+
}
|
|
172
|
+
yield (0, promises_1.setImmediate)();
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
116
176
|
changeGameDriverState(param) {
|
|
117
177
|
return new Promise((resolve, reject) => {
|
|
118
178
|
if (!this.driver) {
|
|
@@ -20,6 +20,7 @@ export declare class RunnerV3 extends Runner {
|
|
|
20
20
|
resume(): void;
|
|
21
21
|
step(): Promise<void>;
|
|
22
22
|
advance(ms: number): Promise<void>;
|
|
23
|
+
advanceLatest(timeout?: number): Promise<void>;
|
|
23
24
|
changeGameDriverState(param: gdr.GameDriverInitializeParameterObject): Promise<void>;
|
|
24
25
|
firePointEvent(event: RunnerPointEvent): void;
|
|
25
26
|
/**
|
|
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.RunnerV3 = void 0;
|
|
13
13
|
const promises_1 = require("node:timers/promises");
|
|
14
|
+
const Logger_1 = require("../../Logger");
|
|
14
15
|
const Runner_1 = require("../Runner");
|
|
15
16
|
const engineFiles_1 = require("./engineFiles");
|
|
16
17
|
const PlatformV3_1 = require("./platform/PlatformV3");
|
|
@@ -122,6 +123,65 @@ class RunnerV3 extends Runner_1.Runner {
|
|
|
122
123
|
yield (0, promises_1.setImmediate)();
|
|
123
124
|
});
|
|
124
125
|
}
|
|
126
|
+
advanceLatest() {
|
|
127
|
+
return __awaiter(this, arguments, void 0, function* (timeout = 5000) {
|
|
128
|
+
var _a, _b;
|
|
129
|
+
if (this.driver == null) {
|
|
130
|
+
this.errorTrigger.fire(new Error("Cannot call Runner#advanceLatest() before initialization"));
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (this.running) {
|
|
134
|
+
this.errorTrigger.fire(new Error("Cannot call Runner#advanceLatest() while running"));
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (this.executionMode !== "passive" || this.loopMode !== "realtime") {
|
|
138
|
+
(0, Logger_1.getSystemLogger)().warn("RunnerV3#advanceLatest() is only available when executionMode is 'passive' and loopMode is 'realtime'");
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const tickBuffer = (_b = (_a = this.driver) === null || _a === void 0 ? void 0 : _a._gameLoop) === null || _b === void 0 ? void 0 : _b._tickBuffer;
|
|
142
|
+
if (!tickBuffer) {
|
|
143
|
+
this.errorTrigger.fire(new Error("RunnerV3#advanceLatest() aborted because tickBuffer does not exist"));
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const startTime = performance.now();
|
|
147
|
+
// 最新の Tick をリクエストして、トリガーを待機する Promise を準備
|
|
148
|
+
const gotTickPromise = new Promise((resolve, reject) => {
|
|
149
|
+
const timeoutId = setTimeout(() => {
|
|
150
|
+
reject(new Error("RunnerV3#advanceLatest() timeout: no tick response"));
|
|
151
|
+
}, Math.max(0, timeout - (performance.now() - startTime)));
|
|
152
|
+
// 新しい Tick が存在した場合
|
|
153
|
+
tickBuffer.gotNextTickTrigger.addOnce(() => {
|
|
154
|
+
clearTimeout(timeoutId);
|
|
155
|
+
resolve();
|
|
156
|
+
});
|
|
157
|
+
// Tick がない場合
|
|
158
|
+
tickBuffer.gotNoTickTrigger.addOnce(() => {
|
|
159
|
+
clearTimeout(timeoutId);
|
|
160
|
+
resolve();
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
// 先に requestTicks を呼び出して、並行して Tick の取得を開始
|
|
164
|
+
tickBuffer.requestTicks();
|
|
165
|
+
// gotNoTickTrigger または gotNextTickTrigger が fire するまで待機
|
|
166
|
+
yield gotTickPromise;
|
|
167
|
+
// TickBuffer#currentAge === TickBuffer#knownLatestAge になるまで進める
|
|
168
|
+
while (tickBuffer.currentAge < tickBuffer.knownLatestAge) {
|
|
169
|
+
if (performance.now() - startTime > timeout) {
|
|
170
|
+
this.errorTrigger.fire(new Error("RunnerV3#advanceLatest() timeout: failed to catch up to knownLatestAge"));
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
// 一度に最大 100 ステップ実行
|
|
174
|
+
const batchSize = Math.min(100, tickBuffer.knownLatestAge - tickBuffer.currentAge);
|
|
175
|
+
for (let i = 0; i < batchSize; i++) {
|
|
176
|
+
if (tickBuffer.currentAge >= tickBuffer.knownLatestAge) {
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
this._stepMinimal();
|
|
180
|
+
}
|
|
181
|
+
yield (0, promises_1.setImmediate)();
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
125
185
|
changeGameDriverState(param) {
|
|
126
186
|
return new Promise((resolve, reject) => {
|
|
127
187
|
if (!this.driver) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akashic/headless-driver",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.18.0",
|
|
4
4
|
"description": "A library to execute contents using Akashic Engine headlessly",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"author": "DWANGO Co., Ltd.",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"@akashic/trigger": "^2.0.0",
|
|
34
34
|
"engine-files-v1": "npm:@akashic/engine-files@1.4.0",
|
|
35
35
|
"engine-files-v2": "npm:@akashic/engine-files@2.4.0",
|
|
36
|
-
"engine-files-v3": "npm:@akashic/engine-files@3.13.
|
|
36
|
+
"engine-files-v3": "npm:@akashic/engine-files@3.13.3",
|
|
37
37
|
"js-sha256": "^0.11.0",
|
|
38
38
|
"lodash.clonedeep": "^4.5.0",
|
|
39
39
|
"node-fetch": "^2.6.7"
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"@akashic/eslint-config": "^3.0.2",
|
|
43
43
|
"@akashic/remark-preset-lint": "^0.1.2",
|
|
44
44
|
"@napi-rs/canvas": "^0.1.66",
|
|
45
|
-
"@types/jest": "^
|
|
45
|
+
"@types/jest": "^30.0.0",
|
|
46
46
|
"@types/lodash.clonedeep": "^4.5.7",
|
|
47
47
|
"@types/node": "^24.0.0",
|
|
48
48
|
"@types/node-fetch": "^2.6.2",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"eslint-config-prettier": "^10.0.0",
|
|
53
53
|
"get-port": "^5.1.1",
|
|
54
54
|
"image-size": "^1.0.2",
|
|
55
|
-
"jest": "^
|
|
55
|
+
"jest": "^30.0.0",
|
|
56
56
|
"npm-run-all": "^4.1.5",
|
|
57
57
|
"pixelmatch": "^5.3.0",
|
|
58
58
|
"pngjs": "^7.0.0",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"remark-cli": "^12.0.0",
|
|
61
61
|
"rimraf": "^6.0.0",
|
|
62
62
|
"serve-handler": "^6.1.3",
|
|
63
|
-
"ts-jest": "^29.
|
|
63
|
+
"ts-jest": "^29.4.6",
|
|
64
64
|
"typescript": "^5.7.3"
|
|
65
65
|
},
|
|
66
66
|
"jest": {
|