fix: 통일 완료 뒤 턴 실행을 중단
Ref처럼 isunited 2/3에서 예약 스케줄을 멈추고 processor 직접 호출도 no-op 처리한다. 이미 기본값으로 내려간 종료 게임의 refreshLimit만 식별해 복구하는 마이그레이션과 회귀 테스트를 추가한다.
This commit is contained in:
@@ -152,6 +152,12 @@ export class TurnDaemonLifecycle {
|
||||
this.status.state = 'idle';
|
||||
}
|
||||
|
||||
if ((await this.stateStore.shouldHaltScheduledRuns?.()) ?? false) {
|
||||
this.status.nextTurnTime = undefined;
|
||||
await this.clock.sleepMs(500);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this.pendingRun) {
|
||||
await this.runOnce(this.pendingRun);
|
||||
this.pendingRun = null;
|
||||
|
||||
@@ -52,6 +52,7 @@ export interface TurnStateStore {
|
||||
saveLastTurnTime(turnTime: Date): Promise<void>;
|
||||
loadCheckpoint(): Promise<TurnCheckpoint | undefined>;
|
||||
saveCheckpoint(checkpoint?: TurnCheckpoint): Promise<void>;
|
||||
shouldHaltScheduledRuns?(): Promise<boolean>;
|
||||
loadGameClock?(wallNow?: Date): Promise<{ mode: GameClockMode; now: Date }>;
|
||||
advanceGameClockTo?(target: Date, wallNow: Date): Promise<void>;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { TurnCheckpoint, TurnStateStore } from '../lifecycle/types.js';
|
||||
import { asNumber, asRecord } from '@sammo-ts/common';
|
||||
import type { InMemoryTurnWorld } from './inMemoryWorld.js';
|
||||
|
||||
export class InMemoryTurnStateStore implements TurnStateStore {
|
||||
@@ -29,6 +30,11 @@ export class InMemoryTurnStateStore implements TurnStateStore {
|
||||
this.world.setCheckpoint(checkpoint);
|
||||
}
|
||||
|
||||
async shouldHaltScheduledRuns(): Promise<boolean> {
|
||||
const meta = asRecord(this.world.getState().meta);
|
||||
return asNumber(meta.isunited ?? meta.isUnited, 0) >= 2;
|
||||
}
|
||||
|
||||
async loadGameClock(wallNow = new Date(Date.now())): Promise<{ mode: 'realtime' | 'manual'; now: Date }> {
|
||||
return {
|
||||
mode: this.world.getGameClockState().mode,
|
||||
|
||||
@@ -51,6 +51,17 @@ export class InMemoryTurnProcessor implements TurnProcessor {
|
||||
const deadlineMs = startMs + Math.max(0, budget.budgetMs);
|
||||
const isBudgetExpired = () => Date.now() >= deadlineMs;
|
||||
|
||||
if (isWorldUnited(this.world)) {
|
||||
return {
|
||||
lastTurnTime: this.world.getState().lastTurnTime.toISOString(),
|
||||
processedGenerals: 0,
|
||||
processedTurns: 0,
|
||||
durationMs: Math.max(0, Date.now() - startMs),
|
||||
partial: false,
|
||||
checkpoint,
|
||||
};
|
||||
}
|
||||
|
||||
this.world.setCheckpoint(checkpoint);
|
||||
this.world.updateWorldMeta({
|
||||
refreshLimit: calculateAccessRefreshLimit(this.world.getState().tickSeconds),
|
||||
|
||||
Reference in New Issue
Block a user