HumanBreak/src/game/system.ts

229 lines
6.9 KiB
TypeScript
Raw Normal View History

2024-01-24 21:32:49 +08:00
import type { AudioPlayer } from '@/core/audio/audio';
import type { BgmController } from '@/core/audio/bgm';
import type { SoundController, SoundEffect } from '@/core/audio/sound';
import type { Disposable } from '@/core/common/disposable';
import type {
EventEmitter,
IndexedEventEmitter
} from '@/core/common/eventEmitter';
import type { loading } from '@/core/loader/load';
import type {
Resource,
ResourceStore,
ResourceType,
ZippedResource
} from '@/core/loader/resource';
import type { Hotkey } from '@/core/main/custom/hotkey';
import type { Keyboard } from '@/core/main/custom/keyboard';
import type { CustomToolbar } from '@/core/main/custom/toolbar';
import type { Focus, GameUi, UiController } from '@/core/main/custom/ui';
import type { gameListener, hook } from '@/core/main/game';
import type {
MotaSetting,
SettingDisplayer,
SettingStorage
} from '@/core/main/setting';
import type { GameStorage } from '@/core/main/storage';
import type { DamageEnemy, EnemyCollection } from '@/plugin/game/enemy/damage';
import type { enemySpecials } from '@/plugin/game/enemy/special';
import type { Range } from '@/plugin/game/range';
import type { KeyCode } from '@/plugin/keyCodes';
interface ClassInterface {
// 渲染进程与游戏进程通用
EventEmitter: typeof EventEmitter;
IndexedEventEmitter: typeof IndexedEventEmitter;
Disposable: typeof Disposable;
// 定义于渲染进程录像中会进行polyfill但是不执行任何内容
GameStorage: typeof GameStorage;
MotaSetting: typeof MotaSetting;
SettingDisplayer: typeof SettingDisplayer;
Resource: typeof Resource;
ZippedResource: typeof ZippedResource;
ResourceStore: typeof ResourceStore;
Focus: typeof Focus;
GameUi: typeof GameUi;
UiController: typeof UiController;
Hotkey: typeof Hotkey;
Keyboard: typeof Keyboard;
CustomToolbar: typeof CustomToolbar;
AudioPlayer: typeof AudioPlayer;
SoundEffect: typeof SoundEffect;
SoundController: typeof SoundController;
BgmController: typeof BgmController;
// todo: 放到插件 ShaderEffect: typeof ShaderEffect;
// 定义于游戏进程,渲染进程依然可用
Range: typeof Range;
EnemyCollection: typeof EnemyCollection;
DamageEnemy: typeof DamageEnemy;
}
interface FunctionInterface {
// 定义于渲染进程录像中会进行polyfill但是不执行任何内容
readyAllResource(): void;
// 定义于游戏进程,渲染进程依然可用
// todo
}
interface VariableInterface {
// 定义于渲染进程录像中会进行polyfill
loading: typeof loading;
hook: typeof hook;
gameListener: typeof gameListener;
mainSetting: MotaSetting;
gameKey: Hotkey;
mainUi: UiController;
fixedUi: UiController;
KeyCode: typeof KeyCode;
// isMobile: boolean;
bgm: BgmController;
sound: SoundController;
resource: ResourceStore<Exclude<ResourceType, 'zip'>>;
zipResource: ResourceStore<'zip'>;
settingStorage: GameStorage<SettingStorage>;
// 定义于游戏进程,渲染进程依然可用
haloSpecials: number[];
enemySpecials: typeof enemySpecials;
}
interface SystemInterfaceMap {
class: ClassInterface;
fn: FunctionInterface;
var: VariableInterface;
}
type InterfaceType = keyof SystemInterfaceMap;
export interface IMota {
/**
*
* @param type
* @param key
*/
require<T extends InterfaceType, K extends keyof SystemInterfaceMap[T]>(
type: T,
key: K
): SystemInterfaceMap[T][K];
/**
*
* @param type
* @param key
*/
require(type: InterfaceType, key: string): any;
/**
*
* @param type
*/
requireAll<T extends InterfaceType>(type: T): SystemInterfaceMap[T];
/**
*
* @param type
* @param key
* @param data
*/
register<T extends InterfaceType, K extends keyof SystemInterfaceMap[T]>(
type: T,
key: K,
data: SystemInterfaceMap[T][K]
): void;
/**
*
* @param type
* @param key
* @param data
*/
register(type: InterfaceType, key: string, data: any): void;
}
/**
* Mota
*/
class Mota {
private static classes: Record<string, any> = {};
private static functions: Record<string, any> = {};
private static variables: Record<string, any> = {};
constructor() {
throw new Error(`System interface class cannot be constructed.`);
}
/**
*
* @param type
* @param key
*/
static require<
T extends InterfaceType,
K extends keyof SystemInterfaceMap[T]
>(type: T, key: K): SystemInterfaceMap[T][K];
/**
*
* @param type
* @param key
*/
static require(type: InterfaceType, key: string): any;
static require(type: InterfaceType, key: string): any {
const data = this.getByType(type)[key];
if (!!data) return data;
else {
throw new Error(
`Cannot resolve require: type='${type}',key='${key}'`
);
}
}
/**
*
* @param type
*/
static requireAll<T extends InterfaceType>(type: T): SystemInterfaceMap[T] {
return this.getByType(type) as SystemInterfaceMap[T];
}
/**
*
* @param type
* @param key
* @param data
*/
static register<
T extends InterfaceType,
K extends keyof SystemInterfaceMap[T]
>(type: T, key: K, data: SystemInterfaceMap[T][K]): void;
/**
*
* @param type
* @param key
* @param data
*/
static register(type: InterfaceType, key: string, data: any): void;
static register(type: InterfaceType, key: string, data: any) {
const obj = this.getByType(type);
if (key in obj) {
console.warn(
`重复的样板接口注册: type='${type}', key='${key}',已将其覆盖`
);
}
obj[key] = data;
}
private static getByType(type: InterfaceType) {
return type === 'class'
? this.classes
: type === 'fn'
? this.functions
: this.variables;
}
}
declare global {
interface Window {
Mota: IMota;
}
}
window.Mota = Mota;