update extension sample

优化了小游戏文件系统的缓存机制。
This commit is contained in:
何冠峰
2025-02-07 15:30:53 +08:00
parent 37a663e0e1
commit a02b3fbf6e
14 changed files with 374 additions and 76 deletions
@@ -2,14 +2,17 @@
using System.Collections.Generic;
using UnityEngine;
using YooAsset;
using StarkSDKSpace;
using TTSDK;
using System.Linq;
using WeChatWASM;
using System;
public static class ByteGameFileSystemCreater
{
public static FileSystemParameters CreateByteGameFileSystemParameters(IRemoteServices remoteServices)
public static FileSystemParameters CreateByteGameFileSystemParameters(IRemoteServices remoteServices, string packageRoot)
{
string fileSystemClass = $"{nameof(ByteGameFileSystem)},YooAsset.RuntimeExtension";
var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
fileSystemParams.AddParameter("REMOTE_SERVICES", remoteServices);
return fileSystemParams;
}
@@ -51,8 +54,10 @@ internal class ByteGameFileSystem : IFileSystem
}
}
private readonly HashSet<string> _recorders = new HashSet<string>();
private readonly Dictionary<string, string> _cacheFilePaths = new Dictionary<string, string>(10000);
private StarkFileSystemManager _fileSystemManager;
private TTFileSystemManager _fileSystemMgr;
private string _ttCacheRoot = string.Empty;
/// <summary>
/// 包裹名称
@@ -66,7 +71,7 @@ internal class ByteGameFileSystem : IFileSystem
{
get
{
return string.Empty;
return _ttCacheRoot;
}
}
@@ -77,7 +82,7 @@ internal class ByteGameFileSystem : IFileSystem
{
get
{
return 0;
return _recorders.Count;
}
}
@@ -155,6 +160,12 @@ internal class ByteGameFileSystem : IFileSystem
public virtual void OnCreate(string packageName, string rootDirectory)
{
PackageName = packageName;
_ttCacheRoot = rootDirectory;
if (string.IsNullOrEmpty(_ttCacheRoot))
{
throw new System.Exception("请配置抖音小游戏的缓存根目录!");
}
// 注意:CDN服务未启用的情况下,使用抖音WEB服务器
if (RemoteServices == null)
@@ -163,7 +174,7 @@ internal class ByteGameFileSystem : IFileSystem
RemoteServices = new WebRemoteServices(webRoot);
}
_fileSystemManager = StarkSDK.API.GetStarkFileSystemManager();
_fileSystemMgr = TT.GetFileSystemManager();
}
public virtual void OnUpdate()
{
@@ -176,7 +187,7 @@ internal class ByteGameFileSystem : IFileSystem
public virtual bool Exists(PackageBundle bundle)
{
string filePath = GetCacheFileLoadPath(bundle);
return _fileSystemManager.AccessSync(filePath);
return _recorders.Contains(filePath);
}
public virtual bool NeedDownload(PackageBundle bundle)
{
@@ -196,27 +207,80 @@ internal class ByteGameFileSystem : IFileSystem
public virtual string GetBundleFilePath(PackageBundle bundle)
{
throw new System.NotImplementedException();
return GetCacheFileLoadPath(bundle);
}
public virtual byte[] ReadBundleFileData(PackageBundle bundle)
{
throw new System.NotImplementedException();
string filePath = GetCacheFileLoadPath(bundle);
if (CheckCacheFileExist(filePath))
return _fileSystemMgr.ReadFileSync(filePath);
else
return Array.Empty<byte>();
}
public virtual string ReadBundleFileText(PackageBundle bundle)
{
throw new System.NotImplementedException();
string filePath = GetCacheFileLoadPath(bundle);
if (CheckCacheFileExist(filePath))
return _fileSystemMgr.ReadFileSync(filePath, "utf8");
else
return string.Empty;
}
#region 内部方法
public TTFileSystemManager GetFileSystemMgr()
{
return _fileSystemMgr;
}
public bool CheckCacheFileExist(string filePath)
{
return _fileSystemMgr.AccessSync(filePath);
}
private string GetCacheFileLoadPath(PackageBundle bundle)
{
if (_cacheFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
filePath = _fileSystemManager.GetLocalCachedPathForUrl(bundle.FileName);
filePath = _fileSystemMgr.GetLocalCachedPathForUrl(bundle.FileName);
_cacheFilePaths.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
#endregion
#region 本地记录
public List<string> GetAllRecords()
{
return _recorders.ToList();
}
public bool RecordBundleFile(string filePath)
{
if (_recorders.Contains(filePath))
{
YooLogger.Error($"{nameof(WechatFileSystem)} has element : {filePath}");
return false;
}
_recorders.Add(filePath);
return true;
}
public void TryRecordBundle(PackageBundle bundle)
{
string filePath = GetCacheFileLoadPath(bundle);
if (_recorders.Contains(filePath) == false)
{
_recorders.Add(filePath);
}
}
public void ClearAllRecords()
{
_recorders.Clear();
}
public void ClearRecord(string filePath)
{
if (_recorders.Contains(filePath))
{
_recorders.Remove(filePath);
}
}
#endregion
}
#endif
@@ -3,7 +3,16 @@ using YooAsset;
internal partial class BGFSInitializeOperation : FSInitializeFileSystemOperation
{
private enum ESteps
{
None,
RecordCacheFiles,
Done,
}
private readonly ByteGameFileSystem _fileSystem;
private RecordTiktokCacheFilesOperation _recordTiktokCacheFilesOp;
private ESteps _steps = ESteps.None;
public BGFSInitializeOperation(ByteGameFileSystem fileSystem)
{
@@ -11,10 +20,36 @@ internal partial class BGFSInitializeOperation : FSInitializeFileSystemOperation
}
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
_steps = ESteps.RecordCacheFiles;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RecordCacheFiles)
{
if (_recordTiktokCacheFilesOp == null)
{
_recordTiktokCacheFilesOp = new RecordTiktokCacheFilesOperation(_fileSystem);
OperationSystem.StartOperation(_fileSystem.PackageName, _recordTiktokCacheFilesOp);
}
if (_recordTiktokCacheFilesOp.IsDone == false)
return;
if (_recordTiktokCacheFilesOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _recordTiktokCacheFilesOp.Error;
}
}
}
}
#endif
@@ -2,7 +2,7 @@
using UnityEngine;
using UnityEngine.Networking;
using YooAsset;
using StarkSDKSpace;
using TTSDK;
internal class BGFSLoadBundleOperation : FSLoadBundleOperation
{
@@ -0,0 +1,57 @@
#if UNITY_WEBGL && BYTEMINIGAME
using YooAsset;
using TTSDK;
internal class RecordTiktokCacheFilesOperation : AsyncOperationBase
{
private enum ESteps
{
None,
RecordCacheFiles,
WaitResponse,
Done,
}
private readonly ByteGameFileSystem _fileSystem;
private ESteps _steps = ESteps.None;
public RecordTiktokCacheFilesOperation(ByteGameFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
_steps = ESteps.RecordCacheFiles;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RecordCacheFiles)
{
_steps = ESteps.WaitResponse;
var fileSystemMgr = _fileSystem.GetFileSystemMgr();
var getSavedFileListParam = new GetSavedFileListParam();
getSavedFileListParam.success = (TTGetSavedFileListResponse response) =>
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
foreach (var fileInfo in response.fileList)
{
//TODO 需要确认存储文件为Bundle文件
_fileSystem.RecordBundleFile(fileInfo.filePath);
}
};
getSavedFileListParam.fail = (TTGetSavedFileListResponse response) =>
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = response.errMsg;
};
fileSystemMgr.GetSavedFileList(getSavedFileListParam);
}
}
}
#endif
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e4420bd73f37dec468a9b23425be68f2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: