2025-04-10 16:37:20 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let instanceMap = new Map();
|
|
|
|
|
|
2025-05-09 11:23:57 +08:00
|
|
|
|
export interface PrototypeType<T> extends Function {
|
2025-04-10 16:37:20 +08:00
|
|
|
|
prototype: T;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-09 11:23:57 +08:00
|
|
|
|
export interface ConstructorFunctionType<T = any> extends PrototypeType<T> {
|
2025-04-10 16:37:20 +08:00
|
|
|
|
new(...args: any[]): T;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type ConstructorType<T = unknown, Static extends Record<string, any> = PrototypeType<T>> = (ConstructorFunctionType<T> | PrototypeType<T>) & {
|
|
|
|
|
[Key in keyof Static]: Static[Key];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 构造单例类的静态类.
|
|
|
|
|
* # Example:
|
|
|
|
|
* class A extends Singleton(){};
|
|
|
|
|
* //获得单例
|
|
|
|
|
* let a = A.GetInstance();
|
|
|
|
|
*/
|
2025-05-09 11:23:57 +08:00
|
|
|
|
export class Singleton {
|
2025-04-10 16:37:20 +08:00
|
|
|
|
protected constructor() { }
|
|
|
|
|
|
|
|
|
|
//ref:https://github.com/Microsoft/TypeScript/issues/5863
|
2025-05-09 11:23:57 +08:00
|
|
|
|
static GetInstance<T extends Singleton>(this: ConstructorType<T, typeof Singleton>): T {
|
2025-04-10 16:37:20 +08:00
|
|
|
|
if (instanceMap.has(this))
|
|
|
|
|
return instanceMap.get(this);
|
|
|
|
|
//@ts-ignore
|
|
|
|
|
let __instance__ = new this.prototype.constructor();
|
|
|
|
|
instanceMap.set(this, __instance__);
|
|
|
|
|
return __instance__;
|
|
|
|
|
}
|
2025-05-09 11:23:57 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 释放指定类型的单例实例。
|
|
|
|
|
* @returns {boolean} 如果实例存在并被释放则返回 true,否则返回 false。
|
|
|
|
|
*/
|
|
|
|
|
static ReleaseInstance<T extends Singleton>(this: ConstructorType<T, typeof Singleton>): boolean {
|
|
|
|
|
if (instanceMap.has(this)) {
|
|
|
|
|
const instance = instanceMap.get(this);
|
|
|
|
|
// 如果实例有清理方法,可以在这里调用
|
|
|
|
|
if (typeof (instance as any).dispose === 'function') {
|
|
|
|
|
(instance as any).dispose();
|
|
|
|
|
}
|
|
|
|
|
instanceMap.delete(this);
|
|
|
|
|
console.log(`Singleton instance of ${this.name} has been released.`);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
console.log(`No singleton instance of ${this.name} found to release.`);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2025-04-10 16:37:20 +08:00
|
|
|
|
}
|