Skip to content

Commit d9907de

Browse files
committed
fix(scene): create scene assets through Asset Manager
1 parent 2b3f513 commit d9907de

2 files changed

Lines changed: 128 additions & 10 deletions

File tree

src/api/scene/scene.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ import {
1818
} from './schema';
1919
import { description, param, result, title, tool } from '../decorator/decorator.js';
2020
import { COMMON_STATUS, CommonResultType, getCommonErrorStatus } from '../base/schema-base';
21-
import { Scene, TSceneTemplateType } from '../../core/scene';
21+
import { Scene } from '../../core/scene';
22+
import { assetManager } from '../../core/assets';
2223
import { ComponentApi } from './component';
2324
import { NodeApi } from './node';
2425
import { PrefabApi } from './prefab';
25-
import { options } from '../../core/builder/platforms/android/i18n/en';
2626

2727
export class SceneApi {
2828
public component: ComponentApi;
@@ -126,16 +126,22 @@ export class SceneApi {
126126
@result(SchemaCreateResult)
127127
async createScene(@param(SchemaCreateOptions) options: TCreateOptions): Promise<CommonResultType<TCreateResult>> {
128128
try {
129-
const data = await Scene.create({
130-
type: 'scene',
131-
baseName: options.baseName,
132-
targetDirectory: options.dbURL,
133-
templateType: options.templateType as TSceneTemplateType,
134-
});
135-
129+
const assetInfo = await assetManager.createAssetByType(
130+
'scene',
131+
options.dbURL,
132+
options.baseName,
133+
{ templateName: options.templateType ?? '2d' },
134+
);
135+
const data: TCreateResult = {
136+
assetName: assetInfo.name,
137+
assetUuid: assetInfo.uuid,
138+
assetUrl: assetInfo.url,
139+
assetType: assetInfo.type,
140+
};
141+
136142
return {
137143
code: COMMON_STATUS.SUCCESS,
138-
data: data as TCreateResult,
144+
data,
139145
};
140146
} catch (e) {
141147
console.error(e);
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
const mockCreateAssetByType = jest.fn();
2+
const mockSceneCreate = jest.fn();
3+
4+
jest.mock('../src/api/decorator/decorator.js', () => ({
5+
description: () => jest.fn(),
6+
param: () => jest.fn(),
7+
result: () => jest.fn(),
8+
title: () => jest.fn(),
9+
tool: () => jest.fn(),
10+
}), { virtual: true });
11+
12+
jest.mock('../src/core/assets', () => ({
13+
assetManager: {
14+
createAssetByType: (...args: unknown[]) => mockCreateAssetByType(...args),
15+
},
16+
}));
17+
18+
jest.mock('../src/core/scene', () => ({
19+
NodeType: {
20+
EMPTY: 'Node',
21+
SPRITE: 'Sprite',
22+
},
23+
SCENE_TEMPLATE_TYPE: ['2d', '3d'],
24+
Scene: {
25+
create: (...args: unknown[]) => mockSceneCreate(...args),
26+
},
27+
}));
28+
29+
import { SceneApi } from '../src/api/scene/scene';
30+
import { COMMON_STATUS } from '../src/api/base/schema-base';
31+
32+
describe('scene-create AssetManager backend', () => {
33+
beforeEach(() => {
34+
mockCreateAssetByType.mockReset();
35+
mockSceneCreate.mockReset();
36+
jest.spyOn(console, 'error').mockImplementation(() => undefined);
37+
});
38+
39+
afterEach(() => {
40+
jest.restoreAllMocks();
41+
});
42+
43+
it('creates the scene through AssetManager and maps the legacy identifier result', async () => {
44+
mockCreateAssetByType.mockResolvedValue({
45+
name: 'Main.scene',
46+
uuid: 'scene-uuid',
47+
url: 'db://assets/scenes/Main.scene',
48+
type: 'cc.SceneAsset',
49+
});
50+
51+
const result = await new SceneApi().createScene({
52+
baseName: 'Main',
53+
dbURL: 'db://assets/scenes',
54+
templateType: '3d',
55+
});
56+
57+
expect(mockCreateAssetByType).toHaveBeenCalledWith(
58+
'scene',
59+
'db://assets/scenes',
60+
'Main',
61+
{ templateName: '3d' },
62+
);
63+
expect(result).toEqual({
64+
code: COMMON_STATUS.SUCCESS,
65+
data: {
66+
assetName: 'Main.scene',
67+
assetUuid: 'scene-uuid',
68+
assetUrl: 'db://assets/scenes/Main.scene',
69+
assetType: 'cc.SceneAsset',
70+
},
71+
});
72+
expect(mockSceneCreate).not.toHaveBeenCalled();
73+
});
74+
75+
it('uses the 2d template by default and still performs zero Scene RPCs', async () => {
76+
mockCreateAssetByType.mockResolvedValue({
77+
name: 'Default.scene',
78+
uuid: 'default-scene-uuid',
79+
url: 'db://assets/Default.scene',
80+
type: 'cc.SceneAsset',
81+
});
82+
83+
const result = await new SceneApi().createScene({
84+
baseName: 'Default',
85+
dbURL: 'db://assets',
86+
});
87+
88+
expect(result.code).toBe(COMMON_STATUS.SUCCESS);
89+
expect(mockCreateAssetByType).toHaveBeenCalledWith(
90+
'scene',
91+
'db://assets',
92+
'Default',
93+
{ templateName: '2d' },
94+
);
95+
expect(mockSceneCreate).not.toHaveBeenCalled();
96+
});
97+
98+
it('returns the existing scene-create failure contract without falling back to Scene RPC', async () => {
99+
mockCreateAssetByType.mockRejectedValue(new Error('asset creation failed'));
100+
101+
const result = await new SceneApi().createScene({
102+
baseName: 'Broken',
103+
dbURL: 'db://assets',
104+
});
105+
106+
expect(result).toEqual({
107+
code: COMMON_STATUS.FAIL,
108+
reason: 'asset creation failed',
109+
});
110+
expect(mockSceneCreate).not.toHaveBeenCalled();
111+
});
112+
});

0 commit comments

Comments
 (0)