mirror of
https://github.com/tuyoogame/YooAsset.git
synced 2026-05-30 13:38:46 +00:00
feat : 弱引用资源句柄
This commit is contained in:
@@ -47,6 +47,15 @@ namespace YooAsset
|
|||||||
/// WebGL平台强制同步加载资源对象
|
/// WebGL平台强制同步加载资源对象
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool WebGLForceSyncLoadAsset = false;
|
public bool WebGLForceSyncLoadAsset = false;
|
||||||
|
|
||||||
|
#if YOOASSET_EXPERIMENTAL
|
||||||
|
/// <summary>
|
||||||
|
/// 启用弱引用资源句柄
|
||||||
|
/// </summary>
|
||||||
|
public bool UseWeakReferenceHandle = false;
|
||||||
|
#else
|
||||||
|
internal bool UseWeakReferenceHandle = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace YooAsset
|
|||||||
AddChildOperation(_loadAllAssetsOp);
|
AddChildOperation(_loadAllAssetsOp);
|
||||||
|
|
||||||
#if UNITY_WEBGL
|
#if UNITY_WEBGL
|
||||||
if (_resManager.WebGLForceSyncLoadAsset())
|
if (_resManager.WebGLForceSyncLoadAsset)
|
||||||
_loadAllAssetsOp.WaitForAsyncComplete();
|
_loadAllAssetsOp.WaitForAsyncComplete();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace YooAsset
|
|||||||
AddChildOperation(_loadAssetOp);
|
AddChildOperation(_loadAssetOp);
|
||||||
|
|
||||||
#if UNITY_WEBGL
|
#if UNITY_WEBGL
|
||||||
if (_resManager.WebGLForceSyncLoadAsset())
|
if (_resManager.WebGLForceSyncLoadAsset)
|
||||||
_loadAssetOp.WaitForAsyncComplete();
|
_loadAssetOp.WaitForAsyncComplete();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace YooAsset
|
namespace YooAsset
|
||||||
{
|
{
|
||||||
@@ -72,6 +73,7 @@ namespace YooAsset
|
|||||||
private readonly LoadBundleFileOperation _mainBundleLoader;
|
private readonly LoadBundleFileOperation _mainBundleLoader;
|
||||||
private readonly List<LoadBundleFileOperation> _bundleLoaders = new List<LoadBundleFileOperation>(10);
|
private readonly List<LoadBundleFileOperation> _bundleLoaders = new List<LoadBundleFileOperation>(10);
|
||||||
private readonly HashSet<HandleBase> _handles = new HashSet<HandleBase>();
|
private readonly HashSet<HandleBase> _handles = new HashSet<HandleBase>();
|
||||||
|
private readonly LinkedList<WeakReference<HandleBase>> _weakReferences = new LinkedList<WeakReference<HandleBase>>();
|
||||||
|
|
||||||
public ProviderOperation(ResourceManager manager, string providerGUID, AssetInfo assetInfo)
|
public ProviderOperation(ResourceManager manager, string providerGUID, AssetInfo assetInfo)
|
||||||
{
|
{
|
||||||
@@ -210,6 +212,11 @@ namespace YooAsset
|
|||||||
if (_steps == ESteps.ProcessBundleResult)
|
if (_steps == ESteps.ProcessBundleResult)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (_resManager.UseWeakReferenceHandle)
|
||||||
|
{
|
||||||
|
TryCleanupWeakReference();
|
||||||
|
}
|
||||||
|
|
||||||
return RefCount <= 0;
|
return RefCount <= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,7 +229,15 @@ namespace YooAsset
|
|||||||
RefCount++;
|
RefCount++;
|
||||||
|
|
||||||
HandleBase handle = HandleFactory.CreateHandle(this, typeof(T));
|
HandleBase handle = HandleFactory.CreateHandle(this, typeof(T));
|
||||||
|
if (_resManager.UseWeakReferenceHandle)
|
||||||
|
{
|
||||||
|
var weakRef = new WeakReference<HandleBase>(handle);
|
||||||
|
_weakReferences.AddLast(weakRef);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_handles.Add(handle);
|
_handles.Add(handle);
|
||||||
|
}
|
||||||
return handle as T;
|
return handle as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,8 +249,16 @@ namespace YooAsset
|
|||||||
if (RefCount <= 0)
|
if (RefCount <= 0)
|
||||||
throw new System.Exception("Should never get here !");
|
throw new System.Exception("Should never get here !");
|
||||||
|
|
||||||
|
if (_resManager.UseWeakReferenceHandle)
|
||||||
|
{
|
||||||
|
if (RemoveWeakReference(handle) == false)
|
||||||
|
throw new System.Exception("Should never get here !");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (_handles.Remove(handle) == false)
|
if (_handles.Remove(handle) == false)
|
||||||
throw new System.Exception("Should never get here !");
|
throw new System.Exception("Should never get here !");
|
||||||
|
}
|
||||||
|
|
||||||
// 引用计数减少
|
// 引用计数减少
|
||||||
RefCount--;
|
RefCount--;
|
||||||
@@ -245,6 +268,19 @@ namespace YooAsset
|
|||||||
/// 释放所有资源句柄
|
/// 释放所有资源句柄
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ReleaseAllHandles()
|
public void ReleaseAllHandles()
|
||||||
|
{
|
||||||
|
if (_resManager.UseWeakReferenceHandle)
|
||||||
|
{
|
||||||
|
List<WeakReference<HandleBase>> tempers = _weakReferences.ToList();
|
||||||
|
foreach (var weakRef in tempers)
|
||||||
|
{
|
||||||
|
if (weakRef.TryGetTarget(out HandleBase target))
|
||||||
|
{
|
||||||
|
target.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
List<HandleBase> tempers = _handles.ToList();
|
List<HandleBase> tempers = _handles.ToList();
|
||||||
foreach (var handle in tempers)
|
foreach (var handle in tempers)
|
||||||
@@ -252,6 +288,7 @@ namespace YooAsset
|
|||||||
handle.Release();
|
handle.Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 结束流程
|
/// 结束流程
|
||||||
@@ -264,12 +301,29 @@ namespace YooAsset
|
|||||||
|
|
||||||
// 注意:创建临时列表是为了防止外部逻辑在回调函数内创建或者释放资源句柄。
|
// 注意:创建临时列表是为了防止外部逻辑在回调函数内创建或者释放资源句柄。
|
||||||
// 注意:回调方法如果发生异常,会阻断列表里的后续回调方法!
|
// 注意:回调方法如果发生异常,会阻断列表里的后续回调方法!
|
||||||
|
if (_resManager.UseWeakReferenceHandle)
|
||||||
|
{
|
||||||
|
List<WeakReference<HandleBase>> tempers = _weakReferences.ToList();
|
||||||
|
foreach (var weakRef in tempers)
|
||||||
|
{
|
||||||
|
if (weakRef.TryGetTarget(out HandleBase target))
|
||||||
|
{
|
||||||
|
if (target.IsValid)
|
||||||
|
{
|
||||||
|
target.InvokeCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
List<HandleBase> tempers = _handles.ToList();
|
List<HandleBase> tempers = _handles.ToList();
|
||||||
foreach (var hande in tempers)
|
foreach (var handle in tempers)
|
||||||
{
|
{
|
||||||
if (hande.IsValid)
|
if (handle.IsValid)
|
||||||
{
|
{
|
||||||
hande.InvokeCallback();
|
handle.InvokeCallback();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,6 +348,50 @@ namespace YooAsset
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移除指定句柄的弱引用对象
|
||||||
|
/// </summary>
|
||||||
|
private bool RemoveWeakReference(HandleBase handle)
|
||||||
|
{
|
||||||
|
bool removed = false;
|
||||||
|
var currentNode = _weakReferences.First;
|
||||||
|
while (currentNode != null)
|
||||||
|
{
|
||||||
|
var nextNode = currentNode.Next;
|
||||||
|
if (currentNode.Value.TryGetTarget(out HandleBase target))
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(target, handle))
|
||||||
|
{
|
||||||
|
_weakReferences.Remove(currentNode);
|
||||||
|
removed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentNode = nextNode;
|
||||||
|
}
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清理所有失效的弱引用
|
||||||
|
/// </summary>
|
||||||
|
private void TryCleanupWeakReference()
|
||||||
|
{
|
||||||
|
var currentNode = _weakReferences.First;
|
||||||
|
while (currentNode != null)
|
||||||
|
{
|
||||||
|
var nextNode = currentNode.Next;
|
||||||
|
if (currentNode.Value.TryGetTarget(out HandleBase target) == false)
|
||||||
|
{
|
||||||
|
_weakReferences.Remove(currentNode);
|
||||||
|
|
||||||
|
// 引用计数减少
|
||||||
|
RefCount--;
|
||||||
|
}
|
||||||
|
currentNode = nextNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#region 调试信息
|
#region 调试信息
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 出生的场景
|
/// 出生的场景
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace YooAsset
|
|||||||
AddChildOperation(_loadSubAssetsOp);
|
AddChildOperation(_loadSubAssetsOp);
|
||||||
|
|
||||||
#if UNITY_WEBGL
|
#if UNITY_WEBGL
|
||||||
if (_resManager.WebGLForceSyncLoadAsset())
|
if (_resManager.WebGLForceSyncLoadAsset)
|
||||||
_loadSubAssetsOp.WaitForAsyncComplete();
|
_loadSubAssetsOp.WaitForAsyncComplete();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,10 @@ namespace YooAsset
|
|||||||
private long _sceneCreateIndex = 0;
|
private long _sceneCreateIndex = 0;
|
||||||
private IBundleQuery _bundleQuery;
|
private IBundleQuery _bundleQuery;
|
||||||
private int _bundleLoadingMaxConcurrency;
|
private int _bundleLoadingMaxConcurrency;
|
||||||
private bool _webGLForceSyncLoadAsset;
|
|
||||||
|
// 开发者配置选项
|
||||||
|
public bool WebGLForceSyncLoadAsset { private set; get; }
|
||||||
|
public bool UseWeakReferenceHandle { private set; get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 所属包裹
|
/// 所属包裹
|
||||||
@@ -44,7 +47,8 @@ namespace YooAsset
|
|||||||
public void Initialize(InitializeParameters parameters, IBundleQuery bundleServices)
|
public void Initialize(InitializeParameters parameters, IBundleQuery bundleServices)
|
||||||
{
|
{
|
||||||
_bundleLoadingMaxConcurrency = parameters.BundleLoadingMaxConcurrency;
|
_bundleLoadingMaxConcurrency = parameters.BundleLoadingMaxConcurrency;
|
||||||
_webGLForceSyncLoadAsset = parameters.WebGLForceSyncLoadAsset;
|
WebGLForceSyncLoadAsset = parameters.WebGLForceSyncLoadAsset;
|
||||||
|
UseWeakReferenceHandle = parameters.UseWeakReferenceHandle;
|
||||||
_bundleQuery = bundleServices;
|
_bundleQuery = bundleServices;
|
||||||
SceneManager.sceneUnloaded += OnSceneUnloaded;
|
SceneManager.sceneUnloaded += OnSceneUnloaded;
|
||||||
}
|
}
|
||||||
@@ -331,10 +335,6 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
return BundleLoadingCounter >= _bundleLoadingMaxConcurrency;
|
return BundleLoadingCounter >= _bundleLoadingMaxConcurrency;
|
||||||
}
|
}
|
||||||
internal bool WebGLForceSyncLoadAsset()
|
|
||||||
{
|
|
||||||
return _webGLForceSyncLoadAsset;
|
|
||||||
}
|
|
||||||
|
|
||||||
private LoadBundleFileOperation CreateBundleFileLoaderInternal(BundleInfo bundleInfo)
|
private LoadBundleFileOperation CreateBundleFileLoaderInternal(BundleInfo bundleInfo)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user