mirror of
https://github.com/motajs/template.git
synced 2026-11-05 08:44:30 +08:00
refactor: 插件系统结构
This commit is contained in:
1 parent
3cc97e5ed3
commit
e6f4346924
30 files changed
+260
-169
No files matched your search
@@ -41,8 +41,6 @@ import {
|
||||
} from '@motajs/animate';
|
||||
import { IRendererUsing, RendererUsing } from '@motajs/render-vue';
|
||||
import { IUIController, UIController } from '@motajs/system';
|
||||
import { createApp } from './render';
|
||||
import { LoadSceneUI } from '../../../src/client/ui/load';
|
||||
import { createUIPropsBase } from './ui/func';
|
||||
|
||||
export class ClientCore extends CoreState implements IClientCore {
|
||||
@@ -65,13 +63,9 @@ export class ClientCore extends CoreState implements IClientCore {
|
||||
// Layer 5 渲染顶层 - 目前没东西
|
||||
|
||||
/** 已注册的渲染端插件 */
|
||||
private readonly clientPlugins: Map<
|
||||
string,
|
||||
IClientPlugin<IClientPluginDefine>
|
||||
> = new Map();
|
||||
private readonly orderedClientPlugins: IPluginOrderResult<
|
||||
IClientPlugin<IClientPluginDefine>
|
||||
>;
|
||||
private readonly clientPlugins: Map<string, IClientPlugin> = new Map();
|
||||
/** 排序后的渲染端插件 */
|
||||
private readonly orderedClientPlugins: IPluginOrderResult;
|
||||
|
||||
constructor(config: IClientCoreConfig) {
|
||||
super(config);
|
||||
@@ -119,15 +113,28 @@ export class ClientCore extends CoreState implements IClientCore {
|
||||
plugin: define
|
||||
});
|
||||
}
|
||||
this.orderedClientPlugins = orderPlugins(this.clientPlugins);
|
||||
const deps = new Map<string, readonly string[]>();
|
||||
for (const [id, plugin] of this.clientPlugins) {
|
||||
deps.set(id, plugin.plugin.clientDeps);
|
||||
}
|
||||
this.orderedClientPlugins = orderPlugins(deps);
|
||||
}
|
||||
|
||||
//#region 插件方法
|
||||
|
||||
getClientPlugin<T extends IClientPluginDefine>(
|
||||
id: string
|
||||
): Readonly<IClientPlugin<T>> | null {
|
||||
return (this.clientPlugins.get(id) as IClientPlugin<T>) ?? null;
|
||||
/**
|
||||
* 获取指定插件的所有渲染端插件依赖对象
|
||||
* @param plugin 目标插件定义对象
|
||||
*/
|
||||
protected getClientDependencies(
|
||||
plugin: IClientPluginDefine
|
||||
): IClientPlugin[] {
|
||||
const dependencies: IClientPlugin[] = [];
|
||||
for (const dependency of plugin.dataDeps) {
|
||||
const plugin = this.clientPlugins.get(dependency);
|
||||
if (plugin) dependencies.push(plugin);
|
||||
}
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,14 +151,15 @@ export class ClientCore extends CoreState implements IClientCore {
|
||||
logger.error(77, pluginId, dependency);
|
||||
}
|
||||
}
|
||||
for (const holder of result.order) {
|
||||
if (holder.status !== PluginStatus.NotAwakened) continue;
|
||||
const dependencies: IClientPlugin<IClientPluginDefine>[] = [];
|
||||
for (const dependency of holder.plugin.dependencies) {
|
||||
const plugin = this.clientPlugins.get(dependency);
|
||||
if (plugin) dependencies.push(plugin);
|
||||
for (const id of result.order) {
|
||||
const holder = this.clientPlugins.get(id)!;
|
||||
const plugin = holder.plugin;
|
||||
if (!this.checkPluginStatus(holder, PluginStatus.NotAwakened)) {
|
||||
continue;
|
||||
}
|
||||
holder.plugin.awake(this, dependencies);
|
||||
const dataDeps = this.getDataDependencies(plugin);
|
||||
const clientDeps = this.getClientDependencies(plugin);
|
||||
plugin.awake(this, dataDeps, clientDeps);
|
||||
holder.status = PluginStatus.Awakened;
|
||||
}
|
||||
}
|
||||
@@ -162,14 +170,15 @@ export class ClientCore extends CoreState implements IClientCore {
|
||||
protected async initialize(): Promise<void> {
|
||||
await super.initialize();
|
||||
const result = this.orderedClientPlugins;
|
||||
for (const holder of result.order) {
|
||||
if (holder.status !== PluginStatus.Awakened) continue;
|
||||
const dependencies: IClientPlugin<IClientPluginDefine>[] = [];
|
||||
for (const dependency of holder.plugin.dependencies) {
|
||||
const plugin = this.clientPlugins.get(dependency);
|
||||
if (plugin) dependencies.push(plugin);
|
||||
for (const id of result.order) {
|
||||
const holder = this.clientPlugins.get(id)!;
|
||||
const plugin = holder.plugin;
|
||||
if (!this.checkPluginStatus(holder, PluginStatus.Awakened)) {
|
||||
continue;
|
||||
}
|
||||
await holder.plugin.initialize(this, dependencies);
|
||||
const dataDeps = this.getDataDependencies(plugin);
|
||||
const clientDeps = this.getClientDependencies(plugin);
|
||||
await plugin.initialize(this, dataDeps, clientDeps);
|
||||
holder.status = PluginStatus.Initialized;
|
||||
}
|
||||
}
|
||||
@@ -180,28 +189,36 @@ export class ClientCore extends CoreState implements IClientCore {
|
||||
protected async afterLoad(): Promise<void> {
|
||||
await super.afterLoad();
|
||||
const result = this.orderedClientPlugins;
|
||||
for (const holder of result.order) {
|
||||
if (holder.status !== PluginStatus.Initialized) continue;
|
||||
const dependencies: IClientPlugin<IClientPluginDefine>[] = [];
|
||||
for (const dependency of holder.plugin.dependencies) {
|
||||
const plugin = this.clientPlugins.get(dependency);
|
||||
if (plugin) dependencies.push(plugin);
|
||||
for (const id of result.order) {
|
||||
const holder = this.clientPlugins.get(id)!;
|
||||
const plugin = holder.plugin;
|
||||
if (!this.checkPluginStatus(holder, PluginStatus.Initialized)) {
|
||||
continue;
|
||||
}
|
||||
await holder.plugin.afterLoad(this, dependencies);
|
||||
const dataDeps = this.getDataDependencies(plugin);
|
||||
const clientDeps = this.getClientDependencies(plugin);
|
||||
await plugin.initialize(this, dataDeps, clientDeps);
|
||||
holder.status = PluginStatus.Loaded;
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
/**
|
||||
* 初始化渲染端主对象
|
||||
*/
|
||||
private async init() {
|
||||
createApp(this.sceneController.render()).mount(this.renderer);
|
||||
this.sceneController.open(LoadSceneUI, {});
|
||||
getClientPlugin<T extends IClientPluginDefine>(
|
||||
id: string
|
||||
): Readonly<IClientPlugin<T>> | null {
|
||||
return (this.clientPlugins.get(id) as IClientPlugin<T>) ?? null;
|
||||
}
|
||||
|
||||
async *load(): AsyncGenerator<number, void> {
|
||||
yield* super.load();
|
||||
for (const plugin of this.clientPlugins.values()) {
|
||||
if (plugin.status !== PluginStatus.Loaded) {
|
||||
logger.error(81, plugin.plugin.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
/**
|
||||
* 进行地图渲染拓展初始化
|
||||
*/
|
||||
|
||||
@@ -1,51 +1,60 @@
|
||||
import { IClientSystem } from '@user/client-system';
|
||||
import { ICoreStateConfig, PluginStatus } from '@user/data-state';
|
||||
import {
|
||||
ICoreStateConfig,
|
||||
IDataPlugin,
|
||||
IDataPluginDefine,
|
||||
IPluginDefine,
|
||||
IPluginBase
|
||||
} from '@user/data-state';
|
||||
|
||||
//#region 插件系统
|
||||
|
||||
export interface IClientPlugin<T extends IClientPluginDefine> {
|
||||
/** 插件的当前状态 */
|
||||
status: PluginStatus;
|
||||
/** 插件内容 */
|
||||
plugin: T;
|
||||
}
|
||||
export interface IClientPlugin<
|
||||
T extends IClientPluginDefine = IClientPluginDefine
|
||||
> extends IPluginDefine<T> {}
|
||||
|
||||
export interface IClientPluginDefine {
|
||||
/** 插件标识符 */
|
||||
readonly id: string;
|
||||
/** 插件所依赖的其他插件 id */
|
||||
readonly dependencies: readonly string[];
|
||||
export interface IClientPluginDefine extends IPluginBase {
|
||||
/** 插件所依赖的其他数据端插件 id,对于渲染端来说,可以依赖任何数据端插件 */
|
||||
readonly dataDeps: readonly string[];
|
||||
/** 插件所依赖的其他渲染端插件 id。依赖插件不允许循环依赖,否则会抛出错误,且所有在环上的插件都不会初始化 */
|
||||
readonly clientDeps: readonly string[];
|
||||
|
||||
/**
|
||||
* 插件同步初始化,在渲染端主对象创建完毕,初始化之前时调用
|
||||
* @param state 渲染端主对象
|
||||
* @param dependencies 此插件的依赖插件对象
|
||||
* @param dataDeps 此插件的数据端依赖插件对象
|
||||
* @param clientDeps 此插件的渲染端依赖插件对象
|
||||
*/
|
||||
awake(
|
||||
state: IClientCore,
|
||||
dependencies: IClientPlugin<IClientPluginDefine>[]
|
||||
dataDeps: IDataPlugin<IDataPluginDefine>[],
|
||||
clientDeps: IClientPlugin<IClientPluginDefine>[]
|
||||
): void;
|
||||
|
||||
/**
|
||||
* 插件异步初始化,在主对象创建完毕,初始化时,加载开始前调用。
|
||||
* 此方法具有阻塞效果,如果返回值迟迟不兑现,那么会导致依赖其的插件不会开始异步初始化
|
||||
* @param state 渲染端主对象
|
||||
* @param dependencies 此插件的依赖插件对象
|
||||
* @param dataDeps 此插件的数据端依赖插件对象
|
||||
* @param clientDeps 此插件的渲染端依赖插件对象
|
||||
*/
|
||||
initialize(
|
||||
state: IClientCore,
|
||||
dependencies: IClientPlugin<IClientPluginDefine>[]
|
||||
dataDeps: IDataPlugin<IDataPluginDefine>[],
|
||||
clientDeps: IClientPlugin<IClientPluginDefine>[]
|
||||
): Promise<void>;
|
||||
|
||||
/**
|
||||
* 当主对象加载完毕后调用,可以用于依赖加载内容的初始化。
|
||||
* 此方法具有阻塞效果,如果返回值迟迟不兑现,那么会导致依赖其的插件不会开始加载初始化
|
||||
* @param state 渲染端主对象
|
||||
* @param dependencies 此插件的依赖插件对象
|
||||
* @param dataDeps 此插件的数据端依赖插件对象
|
||||
* @param clientDeps 此插件的渲染端依赖插件对象
|
||||
*/
|
||||
afterLoad(
|
||||
state: IClientCore,
|
||||
dependencies: IClientPlugin<IClientPluginDefine>[]
|
||||
dataDeps: IDataPlugin<IDataPluginDefine>[],
|
||||
clientDeps: IClientPlugin<IClientPluginDefine>[]
|
||||
): Promise<void>;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user