diff --git a/packages/loader/src/SceneLoader.ts b/packages/loader/src/SceneLoader.ts index e9ea7eb41a..6ab3231ce1 100644 --- a/packages/loader/src/SceneLoader.ts +++ b/packages/loader/src/SceneLoader.ts @@ -2,7 +2,6 @@ import { AssetPromise, AssetType, BackgroundMode, - BloomEffect, DiffuseMode, Font, Loader, @@ -11,10 +10,9 @@ import { Mesh, resourceLoader, ResourceManager, - Scene, - TonemappingEffect + Scene } from "@galacean/engine-core"; -import { IClassObject, IScene, ReflectionParser, SceneParser, SpecularMode } from "./resource-deserialize"; +import { IClass, IScene, ReflectionParser, SceneParser, SpecularMode } from "./resource-deserialize"; @resourceLoader(AssetType.Scene, ["scene"], true) class SceneLoader extends Loader { @@ -144,14 +142,11 @@ class SceneLoader extends Loader { } } -ReflectionParser.registerCustomParseComponent( - "TextRenderer", - async (instance: any, item: Omit) => { - const { props } = item; - if (!props.font) { - // @ts-ignore - instance.font = Font.createFromOS(instance.engine, props.fontFamily || "Arial"); - } - return instance; +ReflectionParser.registerCustomParseComponent("TextRenderer", async (instance: any, item: Omit) => { + const { props } = item; + if (!props.font) { + // @ts-ignore + instance.font = Font.createFromOS(instance.engine, props.fontFamily || "Arial"); } -); + return instance; +}); diff --git a/packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts b/packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts index 47ad86b98d..a97adb9f22 100644 --- a/packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts +++ b/packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts @@ -2,11 +2,14 @@ import { EngineObject, Entity, Loader } from "@galacean/engine-core"; import type { IAssetRef, IBasicType, - IClassObject, + IClass, + IClassType, + IComponentRef, IEntity, IEntityRef, - IComponentRef, IHierarchyFile, + IMethod, + IMethodParams, IRefEntity } from "../schema"; import { ParserContext, ParserType } from "./ParserContext"; @@ -34,7 +37,7 @@ export class ReflectionParser { }); } - parseClassObject(item: IClassObject) { + parseClassObject(item: IClass) { const Class = Loader.getClass(item.class); const params = item.constructParams ?? []; return Promise.all(params.map((param) => this.parseBasicType(param))) @@ -42,7 +45,7 @@ export class ReflectionParser { .then((instance) => this.parsePropsAndMethods(instance, item)); } - parsePropsAndMethods(instance: any, item: Omit) { + parsePropsAndMethods(instance: any, item: Omit) { const promises = []; if (item.methods) { for (let methodName in item.methods) { @@ -70,9 +73,17 @@ export class ReflectionParser { }); } - parseMethod(instance: any, methodName: string, methodParams: Array) { - return Promise.all(methodParams.map((param) => this.parseBasicType(param))).then((result) => { - return instance[methodName](...result); + parseMethod(instance: any, methodName: string, methodParams: IMethodParams) { + const isMethodObject = ReflectionParser._isMethodObject(methodParams); + const params = isMethodObject ? methodParams.params : methodParams; + + return Promise.all(params.map((param) => this.parseBasicType(param))).then((result) => { + const methodResult = instance[methodName](...result); + if (isMethodObject && methodParams.result) { + return this.parsePropsAndMethods(methodResult, methodParams.result); + } else { + return methodResult; + } }); } @@ -80,7 +91,9 @@ export class ReflectionParser { if (Array.isArray(value)) { return Promise.all(value.map((item) => this.parseBasicType(item))); } else if (typeof value === "object" && value != null) { - if (ReflectionParser._isClass(value)) { + if (ReflectionParser._isClassType(value)) { + return Promise.resolve(Loader.getClass(value["classType"])); + } else if (ReflectionParser._isClass(value)) { // class object return this.parseClassObject(value); } else if (ReflectionParser._isAssetRef(value)) { @@ -154,10 +167,14 @@ export class ReflectionParser { } } - private static _isClass(value: any): value is IClassObject { + private static _isClass(value: any): value is IClass { return value["class"] !== undefined; } + private static _isClassType(value: any): value is IClassType { + return value["classType"] !== undefined; + } + private static _isAssetRef(value: any): value is IAssetRef { return value["refId"] !== undefined; } @@ -169,4 +186,8 @@ export class ReflectionParser { private static _isComponentRef(value: any): value is IComponentRef { return value["ownerId"] !== undefined && value["componentId"] !== undefined; } + + private static _isMethodObject(value: any): value is IMethod { + return Array.isArray(value?.params); + } } diff --git a/packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts b/packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts index 8243c46936..d33b1fdaa6 100644 --- a/packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts +++ b/packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts @@ -28,7 +28,12 @@ export interface IHierarchyFile { entities: Array; } -export type IMethodParams = Array; +export type IMethod = { + params: Array; + result?: IInstance; +}; + +export type IMethodParams = Array | IMethod; export interface IBasicEntity { name?: string; @@ -49,11 +54,9 @@ export interface IRefEntity extends IBasicEntity { assetRefId: string; key?: string; isClone?: boolean; - modifications: { + modifications: (IInstance & { target: IPrefabModifyTarget; - methods?: { [methodName: string]: Array }; - props?: { [key: string]: IBasicType | IMethodParams }; - }[]; + })[]; removedEntities: IPrefabModifyTarget[]; removedComponents: IPrefabModifyTarget[]; } @@ -69,13 +72,20 @@ export interface IStrippedEntity extends IBasicEntity { prefabSource: { assetId: string; entityId: string }; } -export type IComponent = { id: string; refId?: string } & IClassObject; +export type IComponent = { id: string; refId?: string } & IClass; -export type IClassObject = { +export type IClass = { class: string; - constructParams?: IMethodParams; + constructParams?: Array; +} & IInstance; + +export interface IInstance { methods?: { [methodName: string]: Array }; props?: { [key: string]: IBasicType | IMethodParams }; +} + +export type IClassType = { + classType: string; }; export type IBasicType = @@ -85,7 +95,8 @@ export type IBasicType = | null | undefined | IAssetRef - | IClassObject + | IClass + | IClassType | IMethodParams | IEntityRef;