kunpolibrary/src/hotupdate/HotUpdateManager.ts

183 lines
5.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @Author: Gongxh
* @Date: 2025-03-20
* @Description: 热更新管理器
*/
import { native } from "cc";
import { ICheckUpdatePromiseResult } from "../interface/PromiseResult";
import { Platform } from "../kunpocc";
import { log } from "../tool/log";
import { HotUpdate, HotUpdateCode } from "./HotUpdate";
const TAG = "hotupdate:";
export class HotUpdateManager {
private static instance: HotUpdateManager;
public static getInstance(): HotUpdateManager {
if (!HotUpdateManager.instance) {
HotUpdateManager.instance = new HotUpdateManager();
}
return HotUpdateManager.instance;
}
/** 是否初始化了 */
private _isInitialized: boolean = false;
/** 本地manifest路径 */
private _manifestUrl: string = '';
/** 版本号 */
private _version: string = '';
/** 资源版本号 */
private _resVersion: string = null;
/** 可写路径 */
private _writablePath: string = '';
/** 是否正在更新 或者 正在检查更新 */
private _updating: boolean = false;
/** 更新实例 */
private _hotUpdate: HotUpdate = null;
/**
* 热更新文件存放的可写路径
*/
public get writablePath(): string {
return this._writablePath;
}
/**
* 本地manifest路径
*/
public get manifestUrl(): string {
return this._manifestUrl;
}
/**
* 传入的游戏版本号
*/
public get version(): string {
return this._version;
}
/**
* 获取资源版本号, 须初始化成功后再使用
* @return 资源版本号 默认值 0
*/
public get resVersion(): string {
if (this._resVersion === null) {
this._resVersion = new HotUpdate().resVersion;
}
return this._resVersion;
}
public set resVersion(version: string) {
if (this._resVersion === null) {
this._resVersion = version;
}
}
/**
* 1. 初始化热更新管理器
* @param manifestUrl 传入本地manifest文件地址 资源的assets.nativeUrl
* @param version 游戏版本号 eg: 1.0.0
*/
public init(manifestUrl: string, version: string): void {
if (this._isInitialized) {
log(`${TAG} 热更新管理器不需要重复初始化`);
return;
}
this._isInitialized = true;
this._manifestUrl = manifestUrl;
this._version = version;
let writablePath = native?.fileUtils?.getWritablePath() || "";
if (!writablePath.endsWith("/")) {
writablePath += "/";
}
this._writablePath = `${writablePath}hot-update/${version}/`;
log(`${TAG}可写路径:${this._writablePath}`);
}
/**
* 检查是否存在热更新
* 提供一个对外的方法检查是否存在热更新
* @return {Promise<ICheckUpdatePromiseResult>}
*/
public checkUpdate(): Promise<ICheckUpdatePromiseResult> {
return new Promise((resolve, reject) => {
if (!Platform.isNativeMobile) {
reject({ code: HotUpdateCode.PlatformNotSupported, message: "当前平台不需要热更新" });
return;
}
if (!this._isInitialized) {
reject({ code: HotUpdateCode.NotInitialized, message: "未初始化, 需要先调用init方法" });
return;
}
if (this._updating) {
reject({ code: HotUpdateCode.Updating, message: "正在更新或者正在检查更新中" });
return;
}
this._updating = true;
this._hotUpdate = new HotUpdate();
this._hotUpdate.checkUpdate().then((res) => {
this._updating = false;
// 有更新
resolve(res);
}).catch((res: ICheckUpdatePromiseResult) => {
this._updating = false;
// 无更新
reject(res);
});
});
}
/**
* 开始热更新
* @param res.skipCheck 是否跳过检查更新
* @param res.progress 更新进度回调 kb: 已下载的资源大小, total: 总资源大小 (kb)
* @param res.complete 更新结束回调 根据错误码判断 跳过还是重试失败资源
*/
public startUpdate(res: { skipCheck: boolean, progress: (kb: number, total: number) => void, complete: (code: HotUpdateCode, message: string) => void }): void {
if (!Platform.isNativeMobile) {
res.complete(HotUpdateCode.PlatformNotSupported, "当前平台不需要热更新");
return;
}
if (!this._isInitialized) {
res.complete(HotUpdateCode.NotInitialized, "未初始化, 需要先调用init方法");
return;
}
if (this._updating) {
res.complete(HotUpdateCode.Updating, "正在更新或者正在检查更新");
return;
}
this._updating = true;
if (res.skipCheck && this._hotUpdate) {
this._hotUpdate.startUpdate({
skipCheck: res.skipCheck,
progress: res.progress,
complete: (code: HotUpdateCode, message: string) => {
this._updating = false;
res.complete(code, message);
}
});
} else {
this._hotUpdate = new HotUpdate();
this._hotUpdate.startUpdate({
skipCheck: false,
progress: res.progress,
complete: (code: HotUpdateCode, message: string) => {
this._updating = false;
res.complete(code, message);
}
});
}
}
/** 重试失败的资源 */
public retryUpdate(): void {
if (!this._hotUpdate) {
throw new Error(`${TAG} 使用前 必须使用过startUpdate方法`);
}
this._hotUpdate.retryUpdate();
}
}