fix: 顺序渲染BangDream歌曲列表
This commit is contained in:
parent
1deb2dc8b6
commit
e19f573699
@ -54,20 +54,10 @@ export async function drawSongList(
|
||||
let tempSongImageList: Canvas[] = [];
|
||||
const songImageListHorizontal: Canvas[] = [];
|
||||
let tempH = 0;
|
||||
const songPromises: Promise<Canvas>[] = [];
|
||||
|
||||
for (let i = 0; i < tempSongList.length; i++) {
|
||||
songPromises.push(
|
||||
drawSongInList(
|
||||
tempSongList[i],
|
||||
undefined,
|
||||
undefined,
|
||||
displayedServerList,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
const songImages = await Promise.all(songPromises);
|
||||
const songImages = await renderSongListItemsSequentially(
|
||||
tempSongList,
|
||||
displayedServerList,
|
||||
);
|
||||
|
||||
for (let i = 0; i < songImages.length; i++) {
|
||||
const tempImage = songImages[i];
|
||||
@ -131,3 +121,31 @@ export const matchSongList = createBangDreamEntityMatcher<Song>({
|
||||
*/
|
||||
relationValue: (song) => song.songId,
|
||||
});
|
||||
|
||||
export type SongListItemRenderer = (
|
||||
song: Song,
|
||||
difficulty: number | undefined,
|
||||
text: string | undefined,
|
||||
displayedServerList: Server[],
|
||||
) => Promise<Canvas>;
|
||||
|
||||
/**
|
||||
* 在歌曲列表中顺序渲染单项,避免并发 Skia 图片解码导致 native 内存峰值过高。
|
||||
*
|
||||
* @param songs - 待绘制歌曲列表。
|
||||
* @param displayedServerList - 允许展示或下载资源的服务器优先级列表。
|
||||
* @param renderItem - 单项渲染函数,未传入时使用默认歌曲列表渲染器。
|
||||
*/
|
||||
export async function renderSongListItemsSequentially(
|
||||
songs: Song[],
|
||||
displayedServerList: Server[],
|
||||
renderItem: SongListItemRenderer = drawSongInList,
|
||||
): Promise<Canvas[]> {
|
||||
const songImages: Canvas[] = [];
|
||||
for (const song of songs) {
|
||||
songImages.push(
|
||||
await renderItem(song, undefined, undefined, displayedServerList),
|
||||
);
|
||||
}
|
||||
return songImages;
|
||||
}
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
import { Server } from '@/modules/qqbot/plugins/bangdream/src/domain/catalog/server.model';
|
||||
import type { Song } from '@/modules/qqbot/plugins/bangdream/src/domain/song/song.model';
|
||||
|
||||
describe('BangDream song search rendering', () => {
|
||||
it('renders song list items sequentially to keep canvas memory bounded', async () => {
|
||||
const { renderSongListItemsSequentially } = await import(
|
||||
'@/modules/qqbot/plugins/bangdream/src/domain/song/song-search.renderer'
|
||||
);
|
||||
let active = 0;
|
||||
let maxActive = 0;
|
||||
const order: number[] = [];
|
||||
const songs = [1, 2, 3].map(
|
||||
(songId) =>
|
||||
({
|
||||
songId,
|
||||
}) as Song,
|
||||
);
|
||||
|
||||
const images = await renderSongListItemsSequentially(
|
||||
songs,
|
||||
[Server.cn, Server.jp],
|
||||
async (song) => {
|
||||
active++;
|
||||
maxActive = Math.max(maxActive, active);
|
||||
await Promise.resolve();
|
||||
order.push(song.songId);
|
||||
active--;
|
||||
return {
|
||||
height: song.songId,
|
||||
width: song.songId,
|
||||
} as any;
|
||||
},
|
||||
);
|
||||
|
||||
expect(maxActive).toBe(1);
|
||||
expect(order).toEqual([1, 2, 3]);
|
||||
expect(images.map((image) => image.width)).toEqual([1, 2, 3]);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user