fix: 优化 BangDream 试炼分列渲染性能
This commit is contained in:
parent
9bf2b0792e
commit
bbd30ba2ea
@ -364,7 +364,7 @@ export interface TsuguHook {
|
|||||||
- 已新增 `gacha-simulate-spec.spec.ts`,覆盖 10 抽网格、汇总模式、重复卡叠层、计数字样和横幅尺寸;本地生成 `gacha-simulate-spec-10-259.jpg` 和 `gacha-simulate-spec-50-259-after-cache-fix.jpg`,验证抽卡模拟两种布局模式图片输出正常。
|
- 已新增 `gacha-simulate-spec.spec.ts`,覆盖 10 抽网格、汇总模式、重复卡叠层、计数字样和横幅尺寸;本地生成 `gacha-simulate-spec-10-259.jpg` 和 `gacha-simulate-spec-50-259-after-cache-fix.jpg`,验证抽卡模拟两种布局模式图片输出正常。
|
||||||
- 抽卡模拟 50 抽 smoke 暴露资源下载短时失败会把 URL 写入无过期错误缓存,导致后续重试直接输出 `asset error`;已改为只有 HTTP 404 进入错误缓存,超时/网络抖动不污染 URL,并新增 `file-cache-client.spec.ts` 覆盖瞬时失败后可再次下载、404 缓存缺失资源两种路径。
|
- 抽卡模拟 50 抽 smoke 暴露资源下载短时失败会把 URL 写入无过期错误缓存,导致后续重试直接输出 `asset error`;已改为只有 HTTP 404 进入错误缓存,超时/网络抖动不污染 URL,并新增 `file-cache-client.spec.ts` 覆盖瞬时失败后可再次下载、404 缓存缺失资源两种路径。
|
||||||
- 已新增 `render-blocks/event-stage-spec.ts`,收口试炼列表最大列高、歌曲单元格/封面/ID/难度条尺寸、试炼类型顶部文字规格和换列判断;`event-stage.ts` 与 `list-event-stage.ts` 改为消费 spec,活动/歌曲选择和输出结构保持不变。
|
- 已新增 `render-blocks/event-stage-spec.ts`,收口试炼列表最大列高、歌曲单元格/封面/ID/难度条尺寸、试炼类型顶部文字规格和换列判断;`event-stage.ts` 与 `list-event-stage.ts` 改为消费 spec,活动/歌曲选择和输出结构保持不变。
|
||||||
- 线上 smoke 暴露 `/查试炼 310 -m` 将所有列横向拼成一张巨大 canvas 会触发 Pod `OOMKilled exit=137`;已改为边绘制边按列输出多张 CQ 图片,不再创建最终横向巨图,普通版和 meta 版均拆成 5 张输出。
|
- 线上 smoke 暴露 `/查试炼 310 -m` 将所有列横向拼成一张巨大 canvas 会触发 Pod `OOMKilled exit=137`;已改为按小批次绘制 stage、边分列边输出多张 CQ 图片,不再创建最终横向巨图,普通版和 meta 版均拆成 5 张输出,同时避免完全串行导致冷缓存首条命令耗时过长。
|
||||||
- 已新增 `event-stage-spec.spec.ts`,覆盖试炼歌曲行尺寸、类型顶部文字规格、换列判断和按列高拆分算法;本地生成 `event-stage-split-310*.jpg`、`event-stage-split-310-meta*.jpg`,验证 `/查试炼 310` 与 `/查试炼 310 -m` 图片输出正常。
|
- 已新增 `event-stage-spec.spec.ts`,覆盖试炼歌曲行尺寸、类型顶部文字规格、换列判断和按列高拆分算法;本地生成 `event-stage-split-310*.jpg`、`event-stage-split-310-meta*.jpg`,验证 `/查试炼 310` 与 `/查试炼 310 -m` 图片输出正常。
|
||||||
- smoke/Jenkins/远程调试卡点继续按已固化规则处理:同一卡点第二次尝试前必须改变可验证变量;Jenkins 查询 URL 含方括号时用 `curl -g` 或改查 Jenkins home;线上图片 smoke 必须查询 `commandId`、拉回图片、展示图片、查日志并清理本轮临时目录;PowerShell 双引号 here-string 中不要写 JS `${...}` 模板字面量,避免被 PowerShell 提前插值;smoke 没有真实图片落盘时必须失败。
|
- smoke/Jenkins/远程调试卡点继续按已固化规则处理:同一卡点第二次尝试前必须改变可验证变量;Jenkins 查询 URL 含方括号时用 `curl -g` 或改查 Jenkins home;线上图片 smoke 必须查询 `commandId`、拉回图片、展示图片、查日志并清理本轮临时目录;PowerShell 双引号 here-string 中不要写 JS `${...}` 模板字面量,避免被 PowerShell 提前插值;smoke 没有真实图片落盘时必须失败。
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,10 @@ import {
|
|||||||
import { outputEasyImages } from '@/qqbot/plugins/bangDream/tsugu/canvas/output';
|
import { outputEasyImages } from '@/qqbot/plugins/bangDream/tsugu/canvas/output';
|
||||||
import { drawDataBlock } from '@/qqbot/plugins/bangDream/tsugu/render-blocks/data-block';
|
import { drawDataBlock } from '@/qqbot/plugins/bangDream/tsugu/render-blocks/data-block';
|
||||||
import { stackImage } from '@/qqbot/plugins/bangDream/tsugu/render-blocks/image-stack';
|
import { stackImage } from '@/qqbot/plugins/bangDream/tsugu/render-blocks/image-stack';
|
||||||
import { shouldStartNewEventStageColumn } from '@/qqbot/plugins/bangDream/tsugu/render-blocks/event-stage-spec';
|
import {
|
||||||
|
getEventStageStageBatchSize,
|
||||||
|
shouldStartNewEventStageColumn,
|
||||||
|
} from '@/qqbot/plugins/bangDream/tsugu/render-blocks/event-stage-spec';
|
||||||
import { Canvas } from 'skia-canvas';
|
import { Canvas } from 'skia-canvas';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,6 +61,7 @@ export async function drawEventStage(
|
|||||||
let currentColumn: Canvas[] = [];
|
let currentColumn: Canvas[] = [];
|
||||||
let currentHeight = 0;
|
let currentHeight = 0;
|
||||||
let pageIndex = 0;
|
let pageIndex = 0;
|
||||||
|
const stageBatchSize = getEventStageStageBatchSize();
|
||||||
|
|
||||||
//绘制活动stage,每个stage一个图片
|
//绘制活动stage,每个stage一个图片
|
||||||
/**
|
/**
|
||||||
@ -83,19 +87,23 @@ export async function drawEventStage(
|
|||||||
pageIndex += 1;
|
pageIndex += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const stage of stageList) {
|
for (let start = 0; start < stageList.length; start += stageBatchSize) {
|
||||||
const stageImage = await drawStageSong(stage);
|
const stageImages = await Promise.all(
|
||||||
if (
|
stageList.slice(start, start + stageBatchSize).map(drawStageSong),
|
||||||
shouldStartNewEventStageColumn(
|
);
|
||||||
currentHeight,
|
for (const stageImage of stageImages) {
|
||||||
stageImage.height,
|
if (
|
||||||
currentColumn.length,
|
shouldStartNewEventStageColumn(
|
||||||
)
|
currentHeight,
|
||||||
) {
|
stageImage.height,
|
||||||
await flushColumn();
|
currentColumn.length,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
await flushColumn();
|
||||||
|
}
|
||||||
|
currentColumn.push(stageImage);
|
||||||
|
currentHeight += stageImage.height;
|
||||||
}
|
}
|
||||||
currentColumn.push(stageImage);
|
|
||||||
currentHeight += stageImage.height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await flushColumn();
|
await flushColumn();
|
||||||
|
|||||||
@ -5,6 +5,7 @@ export interface EventStageCanvasLike {
|
|||||||
export const BANGDREAM_EVENT_STAGE_SPEC = {
|
export const BANGDREAM_EVENT_STAGE_SPEC = {
|
||||||
list: {
|
list: {
|
||||||
maxColumnHeight: 6000,
|
maxColumnHeight: 6000,
|
||||||
|
stageBatchSize: 8,
|
||||||
},
|
},
|
||||||
songRow: {
|
songRow: {
|
||||||
difficultyHeightScale: 10,
|
difficultyHeightScale: 10,
|
||||||
@ -66,6 +67,13 @@ export function getEventStageSongRowSize(): { height: number; width: number } {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取试炼 stage 绘制批大小。
|
||||||
|
*/
|
||||||
|
export function getEventStageStageBatchSize(): number {
|
||||||
|
return BANGDREAM_EVENT_STAGE_SPEC.list.stageBatchSize;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断下一张试炼 stage 图是否应该换到新列。
|
* 判断下一张试炼 stage 图是否应该换到新列。
|
||||||
*
|
*
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import {
|
|||||||
getEventStageSongCellWidth,
|
getEventStageSongCellWidth,
|
||||||
getEventStageSongJacketHeight,
|
getEventStageSongJacketHeight,
|
||||||
getEventStageSongRowSize,
|
getEventStageSongRowSize,
|
||||||
|
getEventStageStageBatchSize,
|
||||||
shouldStartNewEventStageColumn,
|
shouldStartNewEventStageColumn,
|
||||||
splitEventStageImagesByColumnHeight,
|
splitEventStageImagesByColumnHeight,
|
||||||
} from '@/qqbot/plugins/bangDream/tsugu/render-blocks/event-stage-spec';
|
} from '@/qqbot/plugins/bangDream/tsugu/render-blocks/event-stage-spec';
|
||||||
@ -23,6 +24,7 @@ describe('BangDream event stage spec', () => {
|
|||||||
expect(BANGDREAM_EVENT_STAGE_SPEC.typeTop.fontSize).toBe(25);
|
expect(BANGDREAM_EVENT_STAGE_SPEC.typeTop.fontSize).toBe(25);
|
||||||
expect(BANGDREAM_EVENT_STAGE_SPEC.typeTop.strokeWidth).toBe(4.5);
|
expect(BANGDREAM_EVENT_STAGE_SPEC.typeTop.strokeWidth).toBe(4.5);
|
||||||
expect(BANGDREAM_EVENT_STAGE_SPEC.list.maxColumnHeight).toBe(6000);
|
expect(BANGDREAM_EVENT_STAGE_SPEC.list.maxColumnHeight).toBe(6000);
|
||||||
|
expect(getEventStageStageBatchSize()).toBe(8);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('splits stage images by max column height', () => {
|
it('splits stage images by max column height', () => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user