可动态识别属性
This commit is contained in:
@@ -57,40 +57,58 @@ export class ComponentLoaderService implements IService {
|
||||
modulePathTransform?: (filePath: string) => string
|
||||
): Promise<LoadedComponentInfo | null> {
|
||||
try {
|
||||
const modulePath = modulePathTransform
|
||||
? modulePathTransform(componentInfo.path)
|
||||
: this.convertToModulePath(componentInfo.path);
|
||||
|
||||
logger.debug(`Loading component from: ${modulePath}`);
|
||||
|
||||
const module = await import(/* @vite-ignore */ modulePath);
|
||||
|
||||
if (!componentInfo.className) {
|
||||
logger.warn(`No class name found for component: ${componentInfo.fileName}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const componentClass = module[componentInfo.className];
|
||||
let componentClass: typeof Component | undefined;
|
||||
|
||||
if (!componentClass || !(componentClass.prototype instanceof Component)) {
|
||||
logger.error(`Invalid component class: ${componentInfo.className}`);
|
||||
return null;
|
||||
if (modulePathTransform) {
|
||||
const modulePath = modulePathTransform(componentInfo.path);
|
||||
logger.info(`Attempting to load component from: ${modulePath}`);
|
||||
logger.info(`Looking for export: ${componentInfo.className}`);
|
||||
|
||||
try {
|
||||
const module = await import(/* @vite-ignore */ modulePath);
|
||||
logger.info(`Module loaded, exports:`, Object.keys(module));
|
||||
|
||||
componentClass = module[componentInfo.className] || module.default;
|
||||
|
||||
if (!componentClass) {
|
||||
logger.warn(`Component class ${componentInfo.className} not found in module exports`);
|
||||
logger.warn(`Available exports: ${Object.keys(module).join(', ')}`);
|
||||
} else {
|
||||
logger.info(`Successfully loaded component class: ${componentInfo.className}`);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(`Failed to import component module: ${modulePath}`, error);
|
||||
}
|
||||
}
|
||||
|
||||
this.componentRegistry.register({
|
||||
name: componentInfo.className,
|
||||
type: componentClass
|
||||
type: componentClass as any,
|
||||
category: componentInfo.className.includes('Transform') ? 'Transform' :
|
||||
componentInfo.className.includes('Render') || componentInfo.className.includes('Sprite') ? 'Rendering' :
|
||||
componentInfo.className.includes('Physics') || componentInfo.className.includes('RigidBody') ? 'Physics' :
|
||||
'Custom',
|
||||
description: `Component from ${componentInfo.fileName}`,
|
||||
metadata: {
|
||||
path: componentInfo.path,
|
||||
fileName: componentInfo.fileName
|
||||
}
|
||||
});
|
||||
|
||||
const loadedInfo: LoadedComponentInfo = {
|
||||
fileInfo: componentInfo,
|
||||
componentClass,
|
||||
componentClass: (componentClass || Component) as any,
|
||||
loadedAt: Date.now()
|
||||
};
|
||||
|
||||
this.loadedComponents.set(componentInfo.path, loadedInfo);
|
||||
|
||||
logger.info(`Component loaded and registered: ${componentInfo.className}`);
|
||||
logger.info(`Component ${componentClass ? 'loaded' : 'metadata registered'}: ${componentInfo.className}`);
|
||||
|
||||
return loadedInfo;
|
||||
} catch (error) {
|
||||
@@ -125,13 +143,7 @@ export class ComponentLoaderService implements IService {
|
||||
}
|
||||
|
||||
private convertToModulePath(filePath: string): string {
|
||||
const normalizedPath = filePath.replace(/\\/g, '/');
|
||||
|
||||
if (normalizedPath.startsWith('http://') || normalizedPath.startsWith('https://')) {
|
||||
return normalizedPath;
|
||||
}
|
||||
|
||||
return `file:///${normalizedPath}`;
|
||||
return filePath;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
|
||||
@@ -2,9 +2,14 @@ import { Injectable, IService, Component } from '@esengine/ecs-framework';
|
||||
|
||||
export interface ComponentTypeInfo {
|
||||
name: string;
|
||||
type: new (...args: any[]) => Component;
|
||||
type?: new (...args: any[]) => Component;
|
||||
category?: string;
|
||||
description?: string;
|
||||
metadata?: {
|
||||
path?: string;
|
||||
fileName?: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,7 +45,7 @@ export class ComponentRegistry implements IService {
|
||||
|
||||
public createInstance(name: string, ...args: any[]): Component | null {
|
||||
const info = this.components.get(name);
|
||||
if (!info) return null;
|
||||
if (!info || !info.type) return null;
|
||||
|
||||
return new info.type(...args);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { createLogger } from '@esengine/ecs-framework';
|
||||
|
||||
const logger = createLogger('PropertyMetadata');
|
||||
|
||||
export type PropertyType = 'number' | 'string' | 'boolean' | 'color' | 'vector2' | 'vector3';
|
||||
export type PropertyType = 'number' | 'string' | 'boolean' | 'color' | 'vector2' | 'vector3' | 'enum';
|
||||
|
||||
export interface PropertyMetadata {
|
||||
type: PropertyType;
|
||||
|
||||
Reference in New Issue
Block a user