Skip to content

Commit

Permalink
Support parse method result (#2485)
Browse files Browse the repository at this point in the history
* feat: support callback props in parser
  • Loading branch information
zhuxudong authored Jan 6, 2025
1 parent 7fae92c commit 1337ddd
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 32 deletions.
23 changes: 9 additions & 14 deletions packages/loader/src/SceneLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
AssetPromise,
AssetType,
BackgroundMode,
BloomEffect,
DiffuseMode,
Font,
Loader,
Expand All @@ -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<Scene> {
Expand Down Expand Up @@ -144,14 +142,11 @@ class SceneLoader extends Loader<Scene> {
}
}

ReflectionParser.registerCustomParseComponent(
"TextRenderer",
async (instance: any, item: Omit<IClassObject, "class">) => {
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<IClass, "class">) => {
const { props } = item;
if (!props.font) {
// @ts-ignore
instance.font = Font.createFromOS(instance.engine, props.fontFamily || "Arial");
}
);
return instance;
});
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -34,15 +37,15 @@ 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)))
.then((resultParams) => new Class(...resultParams))
.then((instance) => this.parsePropsAndMethods(instance, item));
}

parsePropsAndMethods(instance: any, item: Omit<IClassObject, "class">) {
parsePropsAndMethods(instance: any, item: Omit<IClass, "class">) {
const promises = [];
if (item.methods) {
for (let methodName in item.methods) {
Expand Down Expand Up @@ -70,17 +73,27 @@ export class ReflectionParser {
});
}

parseMethod(instance: any, methodName: string, methodParams: Array<IBasicType>) {
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;
}
});
}

parseBasicType(value: IBasicType, originValue?: any): Promise<any> {
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)) {
Expand Down Expand Up @@ -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;
}
Expand All @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ export interface IHierarchyFile {
entities: Array<IEntity>;
}

export type IMethodParams = Array<IBasicType>;
export type IMethod = {
params: Array<IBasicType>;
result?: IInstance;
};

export type IMethodParams = Array<IBasicType> | IMethod;

export interface IBasicEntity {
name?: string;
Expand All @@ -49,11 +54,9 @@ export interface IRefEntity extends IBasicEntity {
assetRefId: string;
key?: string;
isClone?: boolean;
modifications: {
modifications: (IInstance & {
target: IPrefabModifyTarget;
methods?: { [methodName: string]: Array<IMethodParams> };
props?: { [key: string]: IBasicType | IMethodParams };
}[];
})[];
removedEntities: IPrefabModifyTarget[];
removedComponents: IPrefabModifyTarget[];
}
Expand All @@ -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<IBasicType>;
} & IInstance;

export interface IInstance {
methods?: { [methodName: string]: Array<IMethodParams> };
props?: { [key: string]: IBasicType | IMethodParams };
}

export type IClassType = {
classType: string;
};

export type IBasicType =
Expand All @@ -85,7 +95,8 @@ export type IBasicType =
| null
| undefined
| IAssetRef
| IClassObject
| IClass
| IClassType
| IMethodParams
| IEntityRef;

Expand Down

0 comments on commit 1337ddd

Please sign in to comment.