refactor: 插件系统结构

This commit is contained in:
unanmed 2026-10-20 20:44:33 +08:00
parent 3cc97e5ed3
commit e6f4346924
30 changed files with 260 additions and 169 deletions

View File

@ -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
/**
* 进行地图渲染拓展初始化
*/

View File

@ -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>;
}

View File

@ -13,7 +13,7 @@ function createPlugin(
): IDataPluginDefine {
return {
id,
dependencies,
dataDeps: dependencies,
awake: () => {
calls.push(`${id}.awake`);
},

View File

@ -51,6 +51,8 @@ import {
ICoreStateConfig,
IDataPlugin,
IDataPluginDefine,
IPluginDefine,
IPluginBase,
ISaveableExecutor,
PluginStatus
} from './types';
@ -96,12 +98,10 @@ export class CoreState
ISaveableExecutor<any>
> = new Map();
/** 已注册的插件 */
private readonly plugins: Map<string, IDataPlugin<IDataPluginDefine>> =
new Map();
private readonly orderedDataPlugins: IPluginOrderResult<
IDataPlugin<IDataPluginDefine>
>;
/** 已注册的数据端插件 */
private readonly dataPlugins: Map<string, IDataPlugin> = new Map();
/** 排序后的数据端插件 */
private readonly orderedDataPlugins: IPluginOrderResult;
constructor(config: Readonly<ICoreStateConfig>) {
super();
@ -134,16 +134,20 @@ export class CoreState
// 数据端插件注册表
for (const define of config.dataPlugins) {
if (this.plugins.has(define.id)) {
if (this.dataPlugins.has(define.id)) {
logger.error(78, define.id);
continue;
}
this.plugins.set(define.id, {
this.dataPlugins.set(define.id, {
status: PluginStatus.NotAwakened,
plugin: define
});
}
this.orderedDataPlugins = orderPlugins(this.plugins);
const deps = new Map<string, readonly string[]>();
for (const [id, plugin] of this.dataPlugins) {
deps.set(id, plugin.plugin.dataDeps);
}
this.orderedDataPlugins = orderPlugins(deps);
this.awake();
}
@ -159,6 +163,41 @@ export class CoreState
//#region 插件方法
/**
* 检查插件加载状态
* @param plugin 插件状态对象
* @param expected 预期的插件加载状态
*/
protected checkPluginStatus(
plugin: IPluginDefine<IPluginBase>,
expected: PluginStatus
) {
if (plugin.status === expected) {
return true;
} else {
logger.error(
80,
plugin.plugin.id,
expected.toString(),
plugin.status.toString()
);
return false;
}
}
/**
* 获取指定插件的所有数据端插件依赖对象
* @param plugin 目标插件定义对象
*/
protected getDataDependencies(plugin: IPluginBase): IDataPlugin[] {
const dependencies: IDataPlugin[] = [];
for (const dependency of plugin.dataDeps) {
const plugin = this.dataPlugins.get(dependency);
if (plugin) dependencies.push(plugin);
}
return dependencies;
}
/**
* 插件同步初始化
*/
@ -172,14 +211,14 @@ export class CoreState
logger.error(77, pluginId, dependency);
}
}
for (const holder of result.order) {
if (holder.status !== PluginStatus.NotAwakened) continue;
const dependencies: IDataPlugin<IDataPluginDefine>[] = [];
for (const dependency of holder.plugin.dependencies) {
const plugin = this.plugins.get(dependency);
if (plugin) dependencies.push(plugin);
for (const id of result.order) {
const holder = this.dataPlugins.get(id)!;
const plugin = holder.plugin;
if (!this.checkPluginStatus(holder, PluginStatus.NotAwakened)) {
continue;
}
holder.plugin.awake(this, dependencies);
const dependencies = this.getDataDependencies(plugin);
plugin.awake(this, dependencies);
holder.status = PluginStatus.Awakened;
}
}
@ -189,14 +228,14 @@ export class CoreState
*/
protected async initialize(): Promise<void> {
const result = this.orderedDataPlugins;
for (const holder of result.order) {
if (holder.status !== PluginStatus.Awakened) continue;
const dependencies: IDataPlugin<IDataPluginDefine>[] = [];
for (const dependency of holder.plugin.dependencies) {
const plugin = this.plugins.get(dependency);
if (plugin) dependencies.push(plugin);
for (const id of result.order) {
const holder = this.dataPlugins.get(id)!;
const plugin = holder.plugin;
if (!this.checkPluginStatus(holder, PluginStatus.Awakened)) {
continue;
}
await holder.plugin.initialize(this, dependencies);
const dependencies = this.getDataDependencies(plugin);
await plugin.initialize(this, dependencies);
holder.status = PluginStatus.Initialized;
}
}
@ -206,14 +245,14 @@ export class CoreState
*/
protected async afterLoad(): Promise<void> {
const result = this.orderedDataPlugins;
for (const holder of result.order) {
if (holder.status !== PluginStatus.Initialized) continue;
const dependencies: IDataPlugin<IDataPluginDefine>[] = [];
for (const dependency of holder.plugin.dependencies) {
const plugin = this.plugins.get(dependency);
if (plugin) dependencies.push(plugin);
for (const id of result.order) {
const holder = this.dataPlugins.get(id)!;
const plugin = holder.plugin;
if (!this.checkPluginStatus(holder, PluginStatus.Initialized)) {
continue;
}
await holder.plugin.afterLoad(this, dependencies);
const dependencies = this.getDataDependencies(plugin);
await plugin.afterLoad(this, dependencies);
holder.status = PluginStatus.Loaded;
}
}
@ -221,7 +260,7 @@ export class CoreState
getDataPlugin<T extends IDataPluginDefine>(
id: string
): Readonly<IDataPlugin<T>> | null {
return (this.plugins.get(id) as IDataPlugin<T>) ?? null;
return (this.dataPlugins.get(id) as IDataPlugin<T>) ?? null;
}
//#endregion
@ -232,6 +271,11 @@ export class CoreState
await this.initialize();
yield* this.loader.start();
await this.afterLoad();
for (const plugin of this.dataPlugins.values()) {
if (plugin.status !== PluginStatus.Loaded) {
logger.error(81, plugin.plugin.id);
}
}
}
//#endregion

View File

@ -1,20 +1,8 @@
//#region 插件排序接口
export interface IPluginDepends {
/** 插件标识符 */
readonly id: string;
/** 插件所依赖的其他插件 id */
readonly dependencies: readonly string[];
}
export interface IPluginHolder<T extends IPluginDepends> {
/** 插件内容 */
readonly plugin: T;
}
export interface IPluginOrderResult<T> {
export interface IPluginOrderResult {
/** 可初始化的插件拓扑序 */
readonly order: T[];
readonly order: string[];
/** 处于依赖环中的插件 id */
readonly cyclic: Set<string>;
/** 直接引用了不存在依赖的插件 id,与其缺失的依赖 id 列表 */
@ -29,33 +17,31 @@ export interface IPluginOrderResult<T> {
* 依据插件的依赖关系计算可初始化的拓扑序,并检测依赖环与不存在的依赖
* @param plugins 以插件 id 为键的插件映射表
*/
export function orderPlugins<H extends IPluginHolder<IPluginDepends>>(
plugins: ReadonlyMap<string, H>
): IPluginOrderResult<H> {
export function orderPlugins(
plugins: ReadonlyMap<string, readonly string[]>
): IPluginOrderResult {
const cyclic = new Set<string>();
const missing = new Map<string, string[]>();
// 依赖不存在检测:记录直接引用了不存在依赖的插件及其缺失的依赖
for (const holder of plugins.values()) {
const define = holder.plugin;
for (const [id, deps] of plugins) {
const lacked: string[] = [];
for (const dependency of define.dependencies) {
for (const dependency of deps) {
if (!plugins.has(dependency)) {
lacked.push(dependency);
}
}
if (lacked.length > 0) {
missing.set(define.id, lacked);
missing.set(id, lacked);
}
}
// 环检测:从每个插件出发沿依赖边搜索,若能回到自身则其处于依赖环中
for (const id of plugins.keys()) {
const start = plugins.get(id)!;
for (const [id, deps] of plugins) {
const visited = new Set<string>();
const pending: string[] = [];
for (const dependency of start.plugin.dependencies) {
pending.push(dependency);
for (const dep of deps) {
pending.push(dep);
}
while (pending.length > 0) {
const current = pending.pop()!;
@ -67,7 +53,7 @@ export function orderPlugins<H extends IPluginHolder<IPluginDepends>>(
visited.add(current);
const node = plugins.get(current);
if (!node) continue;
for (const dependency of node.plugin.dependencies) {
for (const dependency of node) {
pending.push(dependency);
}
}
@ -81,12 +67,11 @@ export function orderPlugins<H extends IPluginHolder<IPluginDepends>>(
let expanded = true;
while (expanded) {
expanded = false;
for (const holder of plugins.values()) {
const define = holder.plugin;
if (blocked.has(define.id)) continue;
for (const dependency of define.dependencies) {
if (blocked.has(dependency)) {
blocked.add(define.id);
for (const [id, deps] of plugins) {
if (blocked.has(id)) continue;
for (const dep of deps) {
if (blocked.has(dep)) {
blocked.add(id);
expanded = true;
break;
}
@ -95,24 +80,23 @@ export function orderPlugins<H extends IPluginHolder<IPluginDepends>>(
}
// 拓扑排序:反复扫描,逐轮输出依赖均已就绪的插件,保证依赖先于被依赖者
const order: H[] = [];
const order: string[] = [];
const emitted = new Set<string>();
let progressed = true;
while (progressed) {
progressed = false;
for (const holder of plugins.values()) {
const define = holder.plugin;
if (blocked.has(define.id) || emitted.has(define.id)) continue;
for (const [id, deps] of plugins) {
if (blocked.has(id) || emitted.has(id)) continue;
let ready = true;
for (const dependency of define.dependencies) {
if (!emitted.has(dependency)) {
for (const dep of deps) {
if (!emitted.has(dep)) {
ready = false;
break;
}
}
if (!ready) continue;
order.push(holder);
emitted.add(define.id);
order.push(id);
emitted.add(id);
progressed = true;
}
}

View File

@ -18,49 +18,52 @@ export const enum PluginStatus {
Loaded
}
export interface IDataPlugin<T extends IDataPluginDefine> {
export interface IPluginDefine<T> {
/** 插件的当前状态 */
status: PluginStatus;
/** 插件内容 */
plugin: T;
}
export interface IDataPluginDefine {
export interface IDataPlugin<
T extends IDataPluginDefine = IDataPluginDefine
> extends IPluginDefine<T> {}
export interface IPluginBase {
/** 插件标识符 */
readonly id: string;
/** 插件所依赖的其他插件 id。依赖插件不允许循环依赖,否则会抛出错误,且所有在环上的插件都不会初始化 */
readonly dependencies: string[];
/** 插件所依赖的其他数据端插件 id。依赖插件不允许循环依赖,否则会抛出错误,且所有在环上的插件都不会初始化 */
readonly dataDeps: readonly string[];
}
export interface IDataPluginDefine extends IPluginBase {
/**
* 插件同步初始化,在数据端主对象创建完毕,初始化之前时调用
* @param state 数据端主对象
* @param dependencies 此插件的依赖插件对象
* @param dependencies 此插件的数据端依赖插件对象
*/
awake(
state: ICoreState,
dependencies: IDataPlugin<IDataPluginDefine>[]
): void;
awake(state: ICoreState, dependencies: Readonly<IDataPlugin>[]): void;
/**
* 插件异步初始化,在主对象创建完毕,初始化时,加载开始前调用。
* 此方法具有阻塞效果,如果返回值迟迟不兑现,那么会导致依赖其的插件不会开始异步初始化,游戏加载也不会开始
* @param state 数据端主对象
* @param dependencies 此插件的依赖插件对象
* @param dependencies 此插件的数据端依赖插件对象
*/
initialize(
state: ICoreState,
dependencies: IDataPlugin<IDataPluginDefine>[]
dependencies: Readonly<IDataPlugin>[]
): Promise<void>;
/**
* 当主对象加载完毕后调用,可以用于依赖加载内容的初始化。
* 此方法具有阻塞效果,如果返回值迟迟不兑现,那么会导致依赖其的插件不会开始加载初始化,游戏也不会开始
* @param state 数据端主对象
* @param dependencies 此插件的依赖插件对象
* @param dependencies 此插件的数据端依赖插件对象
*/
afterLoad(
state: ICoreState,
dependencies: IDataPlugin<IDataPluginDefine>[]
dependencies: Readonly<IDataPlugin>[]
): Promise<void>;
}

View File

@ -79,6 +79,8 @@
"77": "Plugin $1 depends on a non-existent plugin: $2. Related plugins will not be initialized.",
"78": "Duplicate plugin id: $1. The duplicate will not be registered.",
"79": "$1 side initialize failed since no core config loaded.",
"80": "Plugin $1 load failed since plugin has an unexpected loading status. Expect: $1, Real: $2.",
"81": "Plugin $1 not loaded after game loaded, please check the issues above. Or this maybe an internal bug of engine, please report.",
"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.",

View File

@ -1,3 +1,4 @@
import { IExcitation } from '@motajs/animate';
import { KeyCode } from './keyCodes';
export const enum HotkeyEmitType {
@ -7,6 +8,13 @@ export const enum HotkeyEmitType {
KeyUp
}
export const enum HotkeyEmitMode {
/** 只会触发一次 */
Once,
/** 按下后依据激励源进行触发 */
Excited
}
export interface IHotkeyEmitContext {
/** 按键触发方式 */
readonly type: HotkeyEmitType;
@ -62,6 +70,17 @@ export interface IHotkeyCommand {
* 迭代所有的按键组合
*/
iterateKeyCombinations(): Iterable<[index: number, key: KeyCode[]][]>;
/**
* 按下时只触发一次,不会连续触发
*/
once(): void;
/**
* 当按下后立刻进行一次触发,之后在松开前,会按照激励源的激励触发
* @param excitation 触发激励源
*/
continuous(excitation: IExcitation<unknown>): void;
}
export interface IHotkeySystem {

View File

@ -1,4 +1,4 @@
import { MAIN_HEIGHT, MAIN_WIDTH } from './ui';
import { MAIN_HEIGHT, MAIN_WIDTH } from './uiConstant';
// 本文件是游戏的底层核心配置,如果不懂的话千万不要动

View File

@ -1,3 +1,4 @@
export * from './constant';
export * from './entry';
export * from './initialize';
export * from './uiConstant';

View File

@ -16,7 +16,7 @@ import { ExcitationVariator } from '@motajs/animate';
export class MainClientPlugin implements IClientPluginDefine {
id: string = 'main-client-plugin';
dependencies: readonly string[] = [];
clientDeps: readonly string[] = [];
awake(state: IClientCore): void {
// 渲染调试配置

View File

@ -10,7 +10,8 @@ export interface IClientShopPlugin extends IClientPluginDefine {
export class ClientShopPlugin implements IClientShopPlugin {
id: string = 'client-shop-plugin';
dependencies: readonly string[] = [];
clientDeps: readonly string[] = [];
dataDeps: readonly string[] = [];
Shop: typeof Shop = Shop;
ShopUI: typeof ShopUI = ShopUI;

View File

@ -4,9 +4,9 @@ import { Font } from '@motajs/render';
import { Scroll, TextContent } from '@user/client-base';
import { IHeroState } from '@user/data-base';
import { IHeroAttr } from '@user/data-common';
import { FULL_LOC, IUIPropsBase, MAIN_WIDTH } from '@user/client-modules';
import { IUIPropsBase } from '@user/client-modules';
import { IShopState, IShopSystem } from '@dp/shop';
import { RENDER_WIDTH } from '@/constant';
import { FULL_LOC, MAIN_WIDTH, RENDER_WIDTH } from '@/client';
export interface IShopProps extends IUIPropsBase {
/** 商店状态对象 */

View File

@ -5,7 +5,7 @@ import {
} from '@motajs/system';
import { DefaultProps } from '@motajs/render-vue';
import { defineComponent } from 'vue';
import { MAIN_HEIGHT, MAIN_WIDTH } from './constant';
import { MAIN_HEIGHT, MAIN_WIDTH } from '@/client';
export interface MainBackgroundProps
extends DefaultProps, IUIDefaultPropsBase {}

View File

@ -7,7 +7,7 @@ import { IEnemyView } from '@user/data-system';
import { IReadonlyEnemy } from '@user/data-base';
import { IEnemyAttr } from '@user/data-common';
import { BookDetailUI } from './bookDetail';
import { FULL_LOC, MAIN_HEIGHT, MAIN_WIDTH } from './constant';
import { FULL_LOC, MAIN_HEIGHT, MAIN_WIDTH } from '@/client';
import { IUIPropsBase } from '@user/client-modules';
export interface BookProps extends IUIPropsBase {}

View File

@ -6,7 +6,7 @@ import { Scroll, TextContent } from '@user/client-base';
import { IEnemyCritical, IEnemyView, EnemyView } from '@user/data-system';
import { IEnemy, IReadonlyEnemy } from '@user/data-base';
import { IEnemyAttr } from '@user/data-common';
import { FULL_LOC, MAIN_HEIGHT, MAIN_WIDTH } from './constant';
import { FULL_LOC, MAIN_HEIGHT, MAIN_WIDTH } from '@/client';
import { IUIPropsBase } from '@user/client-modules';
/** 详情当前展示的属性模式 */

View File

@ -5,7 +5,7 @@ import { Font } from '@motajs/render';
import { Scroll, TextContent } from '@user/client-base';
import { EquipStatus, IHeroState } from '@user/data-base';
import { IHeroAttr } from '@user/data-common';
import { FULL_LOC, MAIN_HEIGHT, MAIN_WIDTH } from './constant';
import { FULL_LOC, MAIN_HEIGHT, MAIN_WIDTH } from '@/client';
import { IUIPropsBase } from '@user/client-modules';
interface IHeroAttrItem {

View File

@ -1,14 +1,13 @@
import { DefaultProps } from '@motajs/render-vue';
import { GameUI, SetupComponentOptions } from '@motajs/system';
import { defineComponent } from 'vue';
import { FULL_LOC, MAIN_HEIGHT, MAIN_WIDTH } from './constant';
import { FULL_LOC, MAIN_HEIGHT, MAIN_WIDTH } from '@/client';
import { ElementLocator, Font, MotaOffscreenCanvas2D } from '@motajs/render';
import { transitioned } from '../../../packages-user/client-modules/src/render/use';
import { cosh, CurveMode, linear } from '@motajs/animate';
import { clamp } from 'lodash-es';
import { sleep } from '@motajs/common';
import { GameTitleUI } from './title';
import { IUIPropsBase } from '@user/client-modules';
import { IUIPropsBase, transitioned } from '@user/client-modules';
/** 加载界面的任务进度条半径 */
export const LOAD_TASK_RADIUS = Math.min(MAIN_WIDTH, MAIN_HEIGHT) / 6;

View File

@ -12,7 +12,7 @@ import {
RIGHT_STATUS_POS,
STATUS_BAR_HEIGHT,
STATUS_BAR_WIDTH
} from './constant';
} from '@/client';
import { LeftStatusBar, RightStatusBar } from './statusBar';
import { isNil } from 'lodash-es';
import { IUIPropsBase, using } from '@user/client-modules';

View File

@ -17,7 +17,7 @@ import {
IGameUIPropsBase,
MAP_BLOCK_WIDTH
} from '@user/client-base';
import { HALF_HEIGHT, HALF_WIDTH, MAP_WIDTH, POP_BOX_WIDTH } from './constant';
import { HALF_HEIGHT, HALF_WIDTH, MAP_WIDTH, POP_BOX_WIDTH } from '@/client';
import { adjustGrid, IGridLayoutData } from '@user/client-base';
import { getSave, IUIPropsBase, SaveData, useKey } from '@user/client-modules';

View File

@ -16,7 +16,7 @@ import { openStatistics } from './statistics';
import { saveWithExist } from './save';
import { compressToBase64 } from 'lz-string';
import { ViewMapUI } from './viewmap';
import { CENTER_LOC, FULL_LOC, MAIN_HEIGHT, POP_BOX_WIDTH } from './constant';
import { CENTER_LOC, FULL_LOC, MAIN_HEIGHT, POP_BOX_WIDTH } from '@/client';
import { IUIPropsBase, useKey } from '@user/client-modules';
export interface MainSettingsProps extends Partial<ChoicesProps>, IUIPropsBase {

View File

@ -16,7 +16,7 @@ import {
MAIN_WIDTH,
STATUS_BAR_HEIGHT,
STATUS_BAR_WIDTH
} from './constant';
} from '@/client';
import { IUIPropsBase } from '@user/client-modules';
import { DefaultProps } from '@motajs/render-vue';

View File

@ -1,7 +1,7 @@
import { DefaultProps } from '@motajs/render-vue';
import { GameUI, SetupComponentOptions } from '@motajs/system';
import { defineComponent, nextTick, onMounted, ref } from 'vue';
import { HALF_HEIGHT, HALF_WIDTH, MAIN_HEIGHT, MAIN_WIDTH } from './constant';
import { HALF_HEIGHT, HALF_WIDTH, MAIN_HEIGHT, MAIN_WIDTH } from '@/client';
import { ElementLocator, Font } from '@motajs/render';
import {
ExitFullscreen,

View File

@ -13,12 +13,12 @@ import {
} from '@user/client-base';
import { gameKey, generateKeyboardEvent } from '@motajs/system';
import { linear } from 'mutate-animate';
import { KeyCode } from '@motajs/client-base';
import { KeyCode } from '@motajs/system';
import { Progress } from '@user/client-base';
import { generateBinary } from '@motajs/legacy-common';
import { SetupComponentOptions } from '@motajs/system';
import { saveSave, saveLoad } from './save';
import { MAIN_HEIGHT, FULL_LOC, POP_BOX_WIDTH, CENTER_LOC } from './constant';
import { MAIN_HEIGHT, FULL_LOC, POP_BOX_WIDTH, CENTER_LOC } from '@/client';
import { openReplay, openSettings } from './settings';
import { openViewMap } from './viewmap';
import { DefaultProps } from '@motajs/render-vue';

View File

@ -4,7 +4,7 @@ import { Font } from '@motajs/render';
import { Scroll, TextContent } from '@user/client-base';
import { IHeroItemState, IHeroState } from '@user/data-base';
import { IHeroAttr } from '@user/data-common';
import { FULL_LOC, MAIN_HEIGHT, MAIN_WIDTH } from './constant';
import { FULL_LOC, MAIN_HEIGHT, MAIN_WIDTH } from '@/client';
import { IUIPropsBase } from '@user/client-modules';
export interface ToolBoxProps extends IUIPropsBase {

View File

@ -38,7 +38,7 @@ import {
RIGHT_STATUS_POS,
STATUS_BAR_HEIGHT,
STATUS_BAR_WIDTH
} from './constant';
} from '@/client';
import { useKey } from '@user/client-modules';
export interface ViewMapProps extends IUIDefaultPropsBase, BaseProps {

View File

@ -16,7 +16,7 @@ import { initializeHooks } from './hook';
export class MainDataPlugin implements IDataMainPlugin {
readonly id: string = 'main-data-plugin';
readonly dependencies: string[] = [];
readonly dataDeps: string[] = [];
weak!: ICombatWeakHandler;

View File

@ -6,7 +6,7 @@ import { ShopSystem } from './system';
export class DataShopPlugin implements IShopPlugin {
id: string = 'data-shop-plugin';
dependencies: string[] = [];
dataDeps: string[] = [];
shop!: IShopSystem;
manager!: IShopManager;

View File

@ -1,7 +1,19 @@
{
"name": "@user/main",
"dependencies": {
"@motajs/animate": "workspace:*",
"@motajs/anon-tokyo": "workspace:*",
"@motajs/audio": "workspace:*",
"@motajs/common": "workspace:*",
"@motajs/loader": "workspace:*",
"@motajs/render": "workspace:*",
"@motajs/render-vue": "workspace:*",
"@motajs/system": "workspace:*",
"@user/client-base": "workspace:*",
"@user/client-modules": "workspace:*",
"@user/data-common": "workspace:*",
"@user/data-base": "workspace:*",
"@user/data-system": "workspace:*",
"@user/data-state": "workspace:*"
}
}