Skip to content

Commit dce0216

Browse files
authored
[break] 1.export packAutoAtlas to lib 2.export queryAutoAtlasFileCache to lib (cocos#610)
1 parent dcf9cbf commit dce0216

4 files changed

Lines changed: 641 additions & 2 deletions

File tree

packages/cocos-cli-types/__tests__/__snapshots__/dts-snapshot.test.ts.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3832,6 +3832,7 @@ export declare class PacInfo implements IPacInfo {
38323832
private queryInvalidSpriteAssets;
38333833
toJSON(): void;
38343834
}
3835+
export declare function packAutoAtlas(pacUuid: string, option?: Partial<IPackOptions>): Promise<PreviewPackResult | null>;
38353836
export declare interface PacStoreInfo {
38363837
pac: StoreInfo;
38373838
sprites: ISpriteFrameInfo[];
@@ -4111,6 +4112,7 @@ export declare interface PreviewPackResult {
41114112
}
41124113
export declare type PureModulesOption = boolean | string[] | IsPureModule;
41134114
export declare function queryAssetsInBundle(uuid: string, bundleFilterConfig?: BundleFilterConfig[]): Promise<string[]>;
4115+
export declare function queryAutoAtlasFileCache(pacUuid: string): Promise<PreviewPackResult | null>;
41144116
export declare function queryBuildConfig(): Promise<BuildConfiguration>;
41154117
export declare function queryBundleConfig(): Promise<Record<string, BundleQueryConfig>>;
41164118
export declare function queryDefaultBuildConfigByPlatform(platform: Platform): Promise<IBuildTaskOption<string>>;
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
const pacUuid = '8c34f9fe-8120-4901-8201-5dedb4439693';
2+
const nestedPacUuid = 'c1d5901d-542d-4316-ad85-066d763d473b';
3+
const atlasImagePath = `project/temp/asset-db/assets/${pacUuid.slice(0, 2)}/${pacUuid}/build1.0.1/texture-packerpreview/atlas.png`;
4+
5+
function makePreviewPackResult(options: {
6+
uuid?: string;
7+
dirty: boolean;
8+
maxWidth?: number;
9+
maxHeight?: number;
10+
unpackedImages?: number;
11+
spriteNames?: string[];
12+
}) {
13+
const uuid = options.uuid || pacUuid;
14+
const spriteNames = options.spriteNames || ['sheep_0', 'sheep_1', 'sheep_2', 'sheep_3'];
15+
const imagePath = `project/temp/asset-db/assets/${uuid.slice(0, 2)}/${uuid}/build1.0.1/texture-packerpreview/atlas.png`;
16+
17+
return {
18+
atlasImagePaths: [imagePath],
19+
unpackedImages: Array.from({ length: options.unpackedImages ?? 1 }, (_, index) => ({
20+
imageUuid: `image-not-packed-${index}`,
21+
libraryPath: `project/library/imports/image-not-packed-${index}.png`,
22+
})),
23+
dirty: options.dirty,
24+
storeInfo: {
25+
pac: {
26+
uuid,
27+
path: uuid === nestedPacUuid ? 'db://assets/sheep-subPackage/sheep.pac' : 'db://assets/atlas/auto-atlas.pac',
28+
},
29+
sprites: spriteNames.map((name, index) => ({
30+
uuid: `${name}-sprite-frame-${index}`,
31+
name,
32+
imageUuid: `${name}-image-${index}`,
33+
})),
34+
options: {
35+
mode: 'preview',
36+
maxWidth: options.maxWidth ?? 1024,
37+
maxHeight: options.maxHeight ?? 1024,
38+
},
39+
},
40+
atlases: [
41+
{
42+
imagePath,
43+
imageUuid: 'atlas-image-uuid',
44+
textureUuid: 'atlas-image-uuid@texture',
45+
name: 'auto-atlas-0',
46+
width: 512,
47+
height: 256,
48+
},
49+
],
50+
};
51+
}
52+
53+
const packAutoAtlasMock = jest.fn(async (uuid: string, option?: { maxWidth?: number; maxHeight?: number }) => {
54+
if (uuid === nestedPacUuid) {
55+
return makePreviewPackResult({
56+
uuid,
57+
dirty: true,
58+
spriteNames: ['sheep_0', 'sheep_1', 'sheep_2', 'sheep_3'],
59+
});
60+
}
61+
62+
const cacheKey = `${uuid}:${option?.maxWidth ?? 1024}:${option?.maxHeight ?? 1024}`;
63+
const dirty = !previewCache.has(cacheKey);
64+
const unpackedImages = option?.maxWidth === 160 ? 2 : 1;
65+
const result = makePreviewPackResult({
66+
uuid,
67+
dirty,
68+
maxWidth: option?.maxWidth,
69+
maxHeight: option?.maxHeight,
70+
unpackedImages,
71+
});
72+
previewCache.set(cacheKey, makePreviewPackResult({
73+
uuid,
74+
dirty: false,
75+
maxWidth: option?.maxWidth,
76+
maxHeight: option?.maxHeight,
77+
unpackedImages,
78+
}));
79+
return result;
80+
});
81+
82+
const queryAutoAtlasFileCacheMock = jest.fn(async (uuid: string) => {
83+
return previewCache.get(`${uuid}:1024:1024`) || null;
84+
});
85+
86+
const previewCache = new Map<string, ReturnType<typeof makePreviewPackResult>>();
87+
88+
jest.mock('../worker/builder/asset-handler/texture-packer', () => ({
89+
packAutoAtlas: packAutoAtlasMock,
90+
queryAutoAtlasFileCache: queryAutoAtlasFileCacheMock,
91+
}));
92+
93+
jest.mock('../manager/plugin', () => ({
94+
pluginManager: {},
95+
}));
96+
97+
describe('lib/builder auto atlas preview APIs', () => {
98+
beforeEach(() => {
99+
previewCache.clear();
100+
packAutoAtlasMock.mockClear();
101+
queryAutoAtlasFileCacheMock.mockClear();
102+
});
103+
104+
async function getBuilderLib() {
105+
return import('../../../lib/builder/builder');
106+
}
107+
108+
it('returns null when querying preview cache before packing', async () => {
109+
const builderLib = await getBuilderLib();
110+
111+
const result = await builderLib.queryAutoAtlasFileCache(pacUuid);
112+
113+
expect(queryAutoAtlasFileCacheMock).toHaveBeenCalledWith(pacUuid);
114+
expect(result).toBeNull();
115+
});
116+
117+
it('packs auto atlas preview and marks first preview as dirty', async () => {
118+
const builderLib = await getBuilderLib();
119+
120+
const result = await builderLib.packAutoAtlas(pacUuid);
121+
122+
expect(packAutoAtlasMock).toHaveBeenCalledWith(pacUuid, undefined);
123+
expect(result).toMatchObject({
124+
atlasImagePaths: [atlasImagePath],
125+
dirty: true,
126+
});
127+
expect(result?.unpackedImages).toHaveLength(1);
128+
expect(result).toEqual(makePreviewPackResult({
129+
uuid: pacUuid,
130+
dirty: true,
131+
}));
132+
});
133+
134+
it('returns generated cache after packing preview', async () => {
135+
const builderLib = await getBuilderLib();
136+
137+
await builderLib.packAutoAtlas(pacUuid);
138+
const result = await builderLib.queryAutoAtlasFileCache(pacUuid);
139+
140+
expect(result).toMatchObject({
141+
atlasImagePaths: [atlasImagePath],
142+
dirty: false,
143+
});
144+
expect(result).toEqual(makePreviewPackResult({
145+
uuid: pacUuid,
146+
dirty: false,
147+
}));
148+
});
149+
150+
it('marks repeated preview query as clean when cache exists', async () => {
151+
const builderLib = await getBuilderLib();
152+
153+
await builderLib.packAutoAtlas(pacUuid);
154+
const result = await builderLib.packAutoAtlas(pacUuid);
155+
156+
expect(result?.dirty).toBe(false);
157+
});
158+
159+
it('keeps sprites from sibling folders and filters nested atlas sprites', async () => {
160+
const builderLib = await getBuilderLib();
161+
162+
const result = await builderLib.packAutoAtlas(nestedPacUuid);
163+
164+
expect(result?.storeInfo.sprites).toHaveLength(4);
165+
expect(result?.storeInfo.sprites.every((sprite) => sprite.name.startsWith('sheep_'))).toBe(true);
166+
expect(result).toEqual(makePreviewPackResult({
167+
uuid: nestedPacUuid,
168+
dirty: true,
169+
spriteNames: ['sheep_0', 'sheep_1', 'sheep_2', 'sheep_3'],
170+
}));
171+
});
172+
173+
it('passes custom pack options and marks first custom preview as dirty', async () => {
174+
const builderLib = await getBuilderLib();
175+
176+
const result = await builderLib.packAutoAtlas(pacUuid, {
177+
maxWidth: 160,
178+
maxHeight: 1024,
179+
});
180+
181+
expect(packAutoAtlasMock).toHaveBeenCalledWith(pacUuid, {
182+
maxWidth: 160,
183+
maxHeight: 1024,
184+
});
185+
expect(result?.dirty).toBe(true);
186+
expect(result?.unpackedImages).toHaveLength(2);
187+
expect(result).toEqual(makePreviewPackResult({
188+
uuid: pacUuid,
189+
dirty: true,
190+
maxWidth: 160,
191+
maxHeight: 1024,
192+
unpackedImages: 2,
193+
}));
194+
});
195+
196+
it('marks repeated custom preview query as clean', async () => {
197+
const builderLib = await getBuilderLib();
198+
const option = {
199+
maxWidth: 160,
200+
maxHeight: 1024,
201+
};
202+
203+
await builderLib.packAutoAtlas(pacUuid, option);
204+
const result = await builderLib.packAutoAtlas(pacUuid, option);
205+
206+
expect(result?.dirty).toBe(false);
207+
});
208+
});

0 commit comments

Comments
 (0)