diff --git a/packages-user/client-modules/src/client.ts b/packages-user/client-modules/src/client.ts index ac7578d..6311bd9 100644 --- a/packages-user/client-modules/src/client.ts +++ b/packages-user/client-modules/src/client.ts @@ -1,5 +1,5 @@ import { CoreState } from '@user/data-state'; -import { IClientCore } from './types'; +import { IClientCore, IClientCoreConfig } from './types'; import { IMotaAudioContext, ISoundPlayer, @@ -60,7 +60,7 @@ export class ClientCore extends CoreState implements IClientCore { readonly soundPlayer: ISoundPlayer; readonly bgmPlayer: IBGMPlayer; - constructor() { + constructor(config: IClientCoreConfig) { super({ loadStarter: new WebLoadStarter(), coreURL: 'placeholder' @@ -128,6 +128,8 @@ export class ClientCore extends CoreState implements IClientCore { }); //#endregion + + this.loader.addCoreConfig('client', config.clientURL); } /** diff --git a/packages-user/client-modules/src/loader/hook.ts b/packages-user/client-modules/src/loader/hook.ts index d3449c9..cc3ae18 100644 --- a/packages-user/client-modules/src/loader/hook.ts +++ b/packages-user/client-modules/src/loader/hook.ts @@ -1,21 +1,31 @@ -import { - IMotaDataLoader, - IMotaDataLoaderHooks, - ICoreStateCoreConfig -} from '@user/data-state'; +import { logger } from '@motajs/common'; +import { IMotaDataLoader, IMotaDataLoaderHooks } from '@user/data-state'; +import { IClientConfig } from '../common'; export class RenderLoaderHooks implements IMotaDataLoaderHooks { - constructor(readonly clientDir: string) {} + constructor() {} awake(): void {} destroy(): void {} - onCoreConfigLoaded?( - _: ICoreStateCoreConfig, - loader: IMotaDataLoader - ): Promise { - loader.addExtraConfig('client', this.clientDir); + onCoreConfigLoaded?(loader: IMotaDataLoader): Promise { + const client = loader.getConfig('client'); + if (!client) { + logger.error(69, 'Client'); + return Promise.resolve(); + } + + const content = client.content; + loader.addExtraConfig('texture-list', content.textureListDir); + loader.addExtraConfig('audio-list', content.audioListDir); + loader.addExtraConfig('animation-list', content.animationListDir); + loader.addExtraConfig('font-list', content.fontListDir); + const defaults = content.defaults; + loader.addExtraConfig('texture-default', defaults.textureDefault); + loader.addExtraConfig('audio-default', defaults.audioDefault); + loader.addExtraConfig('animation-default', defaults.animationDefault); + loader.addExtraConfig('font-default', defaults.fontDefault); return Promise.resolve(); } diff --git a/packages-user/client-modules/src/types.ts b/packages-user/client-modules/src/types.ts index 84148ef..01c53e9 100644 --- a/packages-user/client-modules/src/types.ts +++ b/packages-user/client-modules/src/types.ts @@ -2,6 +2,11 @@ import { IMapExtensionManager, IMapRenderer } from './render/map'; import { IClientBase } from '@user/client-base'; import { IExcitation, IExcitationDivider } from '@motajs/animate'; +export interface IClientCoreConfig { + /** 渲染端数据配置文件路径,相对于 `src/content` */ + readonly clientURL: string; +} + export interface IClientCore extends IClientBase { /** 用于渲染系统的 Raf 激励源 */ readonly rafExcitation: IExcitation; diff --git a/packages-user/data-state/src/core.ts b/packages-user/data-state/src/core.ts index 0a58aaf..b7fd4c4 100644 --- a/packages-user/data-state/src/core.ts +++ b/packages-user/data-state/src/core.ts @@ -203,12 +203,9 @@ export class CoreState implements ICoreState { // 加载 this.loadManager = new LoadManager(); - this.loader = new MotaDataLoader( - this.loadManager, - config.coreURL, - config.loadStarter - ); + this.loader = new MotaDataLoader(this.loadManager, config.loadStarter); this.loader.addHook(new DefaultDataLoaderHook()); + this.loader.addCoreConfig('core', config.coreURL); // 存档内容 this.addSaveableContent('@system/hero', this.hero); diff --git a/packages-user/data-state/src/loader/hook.ts b/packages-user/data-state/src/loader/hook.ts index 524f55a..4e1acac 100644 --- a/packages-user/data-state/src/loader/hook.ts +++ b/packages-user/data-state/src/loader/hook.ts @@ -1,3 +1,4 @@ +import { logger } from '@motajs/common'; import { ICoreStateCoreConfig } from '../common'; import { IMotaDataLoader, IMotaDataLoaderHooks } from './types'; @@ -6,10 +7,12 @@ export class DefaultDataLoaderHook implements IMotaDataLoaderHooks { destroy(): void {} - onCoreConfigLoaded( - coreConfig: ICoreStateCoreConfig, - loader: IMotaDataLoader - ): Promise { + onCoreConfigLoaded(loader: IMotaDataLoader): Promise { + const coreConfig = loader.getConfig('core'); + if (!coreConfig) { + logger.error(69, 'Data'); + return Promise.resolve(); + } const content = coreConfig.content; loader.addExtraConfig('enemy', content.enemyDir); loader.addExtraConfig('item', content.itemDir); diff --git a/packages-user/data-state/src/loader/loader.ts b/packages-user/data-state/src/loader/loader.ts index 1f82a87..b158e6b 100644 --- a/packages-user/data-state/src/loader/loader.ts +++ b/packages-user/data-state/src/loader/loader.ts @@ -28,6 +28,8 @@ export class MotaDataLoader /** 当前是否已经加载完毕 */ private dataLoaded: boolean = false; + /** 核心配置文件路径 */ + private coreConfigs: Map = new Map(); /** 额外配置对象的路径 */ private extraConfigs: Map = new Map(); /** 配置文件列表 */ @@ -38,7 +40,6 @@ export class MotaDataLoader constructor( readonly manager: ILoadManager, - readonly coreDir: string, readonly starter: ILoadTaskStarter ) { super(); @@ -53,6 +54,10 @@ export class MotaDataLoader return new HookController(this, hook); } + addCoreConfig(identifier: string, url: string): void { + this.coreConfigs.set(identifier, url); + } + addExtraConfig(identifier: string, url: string): void { this.extraConfigs.set(identifier, url); } @@ -83,23 +88,24 @@ export class MotaDataLoader const processor = new PrefixedJSONCProcessor( '// --- SYSTEM PREFIX END --- //' ); - const coreTask = new LoadTask({ - identifier: 'data-core-config', - url: this.resolveURL(this.coreDir), - dataType: LoadDataType.Text - }); - coreTask.setProcessor(processor); - coreTask.setStarter(this.starter); - this.manager.addTask(coreTask); + for (const [id, url] of this.coreConfigs) { + const coreTask = new LoadTask< + LoadDataType.Text, + ICoreStateCoreConfig + >({ + identifier: id, + url: this.resolveURL(url), + dataType: LoadDataType.Text + }); + coreTask.setProcessor(processor); + coreTask.setStarter(this.starter); + this.manager.addTask(coreTask); + } yield* this.manager.load(); // 然后加载其他配置文件 - const coreConfig = await coreTask.loaded(); - this.configMap.set('core', coreConfig); await Promise.all( - this.forEachHook(hook => - hook.onCoreConfigLoaded?.(coreConfig, this) - ) + this.forEachHook(hook => hook.onCoreConfigLoaded?.(this)) ); for (const [id, url] of this.extraConfigs) { diff --git a/packages-user/data-state/src/loader/types.ts b/packages-user/data-state/src/loader/types.ts index 0f66649..25d01d9 100644 --- a/packages-user/data-state/src/loader/types.ts +++ b/packages-user/data-state/src/loader/types.ts @@ -1,6 +1,5 @@ import { IHookable, IHookBase } from '@motajs/common'; import { ILoadManager, LoadDataType, LoadTask } from '@motajs/loader'; -import { ICoreStateCoreConfig } from '../common'; export interface IMotaDataLoaderHooks extends IHookBase { /** @@ -8,10 +7,7 @@ export interface IMotaDataLoaderHooks extends IHookBase { * @param coreConfig 核心配置对象 * @param loader 数据端加载对象 */ - onCoreConfigLoaded?( - coreConfig: ICoreStateCoreConfig, - loader: IMotaDataLoader - ): Promise; + onCoreConfigLoaded?(loader: IMotaDataLoader): Promise; /** * 当所有的额外配置对象加载完毕后执行,往往用于根据配置文件添加额外加载任务 @@ -34,6 +30,19 @@ export interface IMotaDataLoader extends IHookable { */ loaded(): Promise; + /** + * 添加核心配置文件,仅允许在加载前调用,之后调用无效。 + * 文件必须放在 `src/content` 下,并填写相对于 `src/content` 文件夹的路径,文件包含如下要求: + * + * - 文件必须为 `jsonc` 格式 + * - 文件的注释必须全部集中在开头 + * - 文件中的最后一行注释必须是 `// --- SYSTEM PREFIX END --- //` + * + * @param identifier 加载任务与配置文件的标识符 + * @param url 核心配置文件路径 + */ + addCoreConfig(identifier: string, url: string): void; + /** * 添加额外配置文件,仅允许在 `onCoreConfigLoaded` 中调用或在加载前调用,加载中及加载后后调用无效。 * 文件必须放在 `src/content` 下,并填写相对于 `src/content` 文件夹的路径,文件包含如下要求: @@ -41,6 +50,7 @@ export interface IMotaDataLoader extends IHookable { * - 文件必须为 `jsonc` 格式 * - 文件的注释必须全部集中在开头 * - 文件中的最后一行注释必须是 `// --- SYSTEM PREFIX END --- //` + * * @param identifier 加载任务与配置文件的标识符 * @param url 额外配置文件路径 */ diff --git a/packages/common/src/logger.json b/packages/common/src/logger.json index c25feb1..716bc36 100644 --- a/packages/common/src/logger.json +++ b/packages/common/src/logger.json @@ -68,6 +68,7 @@ "66": "Load url '$1' error, since specified a prefixed jsonc parser, but no(or more than one) prefix split string '$2' found in response string.", "67": "Load url '$1' error since the raw json string splitted by prefix split string cannot be parsed to a valid JavaScript object. Parse error info: $2", "68": "Extra config identifier '$1' has conflicts. More than one extra config use this identifier, and the final load result is unpredictable since network decides which one to be loaded fast.", + "69": "$1 core config not loaded for the next loading phase.", "2001": "Replay($1): Replay parameter count mismatch: expected $2, got $3.", "2002": "Replay($1): Replay parameter type mismatch: index $2, expected $3, got $4.", "2003": "Replay(move): Expected hero to be stopped before execute moving step.",