initial commit

This commit is contained in:
Jo 2025-01-07 02:06:59 +01:00
parent 6715289efe
commit 788c3389af
37645 changed files with 2526849 additions and 80 deletions

View file

@ -0,0 +1,209 @@
using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.ResourceManagement.Util;
using UnityEngine.TestTools;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine.Networking;
using UnityEngine.TestTools.Constraints;
namespace UnityEngine.ResourceManagement.Tests
{
public class AsyncOperationHandleTests
{
class FakeTypedOperation : AsyncOperationBase<GameObject>
{
public FakeTypedOperation()
{
m_RM = new ResourceManager();
m_RM.postProfilerEvents = true;
}
public object GetResultAsObject()
{
return null;
}
protected override void Execute()
{
}
}
void IncreaseRefCount(AsyncOperationHandle handle, int count)
{
for (int i = 0; i < count; i++)
handle.Acquire();
}
void IncreaseRefCount<TObject>(AsyncOperationHandle<TObject> handle, int count)
{
for (int i = 0; i < count; i++)
handle.Acquire();
}
int DestructiveGetRefCount(AsyncOperationHandle handle)
{
int count = 0;
while (handle.IsValid())
{
count++;
var copy = handle;
copy.Release();
}
return count;
}
int DestructiveGetRefCount<TObject>(AsyncOperationHandle<TObject> handle)
{
int count = 0;
while (handle.IsValid())
{
count++;
var copy = handle;
copy.Release();
}
return count;
}
[Test]
public void AsyncOperationHandle_ConvertToTyped_WithInvalidOpThrows()
{
var op = new FakeTypedOperation();
AsyncOperationHandle handle = new AsyncOperationHandle(op);
AsyncOperationHandle handle2 = new AsyncOperationHandle(op);
handle2.Release();
Assert.Throws<Exception>(() => { handle.Convert<GameObject>(); });
}
[Test]
public void AsyncOperationHandle_ConvertToTyped_WithValidOpSucceeds()
{
var op = new FakeTypedOperation();
AsyncOperationHandle handle = new AsyncOperationHandle(op);
AsyncOperationHandle<GameObject> typedHandle = handle.Convert<GameObject>();
Assert.True(handle.IsValid());
Assert.True(typedHandle.IsValid());
}
[Test]
public void AsyncOperationHandle_ConvertToTypeless_MaintainsValidity()
{
var op = new FakeTypedOperation();
AsyncOperationHandle<GameObject> typedHandle = new AsyncOperationHandle<GameObject>(op);
//implicit conversion of valid op
AsyncOperationHandle typelessHandle = (AsyncOperationHandle)typedHandle;
Assert.IsNotNull(typelessHandle);
Assert.IsTrue(typedHandle.IsValid());
Assert.IsTrue(typelessHandle.IsValid());
//make handle invalid
AsyncOperationHandle<GameObject> typedHandle2 = new AsyncOperationHandle<GameObject>(op);
typedHandle2.Release();
//implicit conversion of invalid op
AsyncOperationHandle invalidHandle = (AsyncOperationHandle)typedHandle;
Assert.IsNotNull(invalidHandle);
Assert.IsFalse(invalidHandle.IsValid());
Assert.IsFalse(typedHandle.IsValid());
}
[Test]
public void AsyncOperationHandle_Release_DecrementsRefCount()
{
int expectedCount = 10;
var op = new FakeTypedOperation();
AsyncOperationHandle<GameObject> typedHandle = new AsyncOperationHandle<GameObject>(op);
AsyncOperationHandle<GameObject> validationHandle = new AsyncOperationHandle<GameObject>(op);
IncreaseRefCount(typedHandle, expectedCount - 1);
typedHandle.Release();
expectedCount--;
var actualRefCount = DestructiveGetRefCount(validationHandle);
Assert.AreEqual(expectedCount, actualRefCount);
op = new FakeTypedOperation();
AsyncOperationHandle typelessHandle = new AsyncOperationHandle(op);
AsyncOperationHandle typelessValidation = new AsyncOperationHandle(op);
IncreaseRefCount(typelessHandle, expectedCount - 1);
typelessHandle.Release();
expectedCount--;
actualRefCount = DestructiveGetRefCount(typelessValidation);
Assert.AreEqual(expectedCount, actualRefCount);
}
[Test]
public void AsyncOperationHandle_ReleaseToZero_InvalidatesAllHandles()
{
var op = new FakeTypedOperation();
AsyncOperationHandle<GameObject> typedHandle = new AsyncOperationHandle<GameObject>(op);
AsyncOperationHandle<GameObject> typedHandle2 = new AsyncOperationHandle<GameObject>(op);
typedHandle.Release();
Assert.IsFalse(typedHandle.IsValid());
Assert.IsFalse(typedHandle2.IsValid());
op = new FakeTypedOperation();
AsyncOperationHandle typelessHandle = new AsyncOperationHandle(op);
AsyncOperationHandle typelessHandle2 = new AsyncOperationHandle(op);
typelessHandle.Release();
Assert.IsFalse(typelessHandle.IsValid());
Assert.IsFalse(typelessHandle2.IsValid());
}
[Test]
public void AsyncOperationHandle_ReleaseToNonZero_InvalidatesOnlyCurrentHandle()
{
var op = new FakeTypedOperation();
AsyncOperationHandle<GameObject> typedHandle = new AsyncOperationHandle<GameObject>(op);
IncreaseRefCount(typedHandle, 1);
AsyncOperationHandle<GameObject> typedHandle2 = new AsyncOperationHandle<GameObject>(op);
typedHandle.Release();
Assert.IsFalse(typedHandle.IsValid());
Assert.IsTrue(typedHandle2.IsValid());
op = new FakeTypedOperation();
AsyncOperationHandle typelessHandle = new AsyncOperationHandle(op);
IncreaseRefCount(typelessHandle, 1);
AsyncOperationHandle typelessHandle2 = new AsyncOperationHandle(op);
typelessHandle.Release();
Assert.IsFalse(typelessHandle.IsValid());
Assert.IsTrue(typelessHandle2.IsValid());
}
[Test]
public void AsyncOperationHandle_Acquire_IncrementsRefCount()
{
int expectedCount = 2;
var op = new FakeTypedOperation();
AsyncOperationHandle<GameObject> typedHandle = new AsyncOperationHandle<GameObject>(op);
var copyTyped = typedHandle.Acquire();
Assert.True(copyTyped.IsValid());
Assert.True(typedHandle.IsValid());
int actualCount = DestructiveGetRefCount(typedHandle);
Assert.AreEqual(expectedCount, actualCount);
op = new FakeTypedOperation();
AsyncOperationHandle typelessHandle = new AsyncOperationHandle(op);
var copyTypeless = typelessHandle.Acquire();
Assert.True(copyTypeless.IsValid());
Assert.True(typelessHandle.IsValid());
actualCount = DestructiveGetRefCount(typelessHandle);
Assert.AreEqual(expectedCount, actualCount);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 68204acf7cb1bb74091cd6779c3da569
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,377 @@
using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.ResourceManagement.Util;
using UnityEngine.TestTools;
using System.Linq;
using UnityEngine.Scripting;
using UnityEngine.TestTools.Constraints;
[assembly: Preserve]
namespace UnityEngine.ResourceManagement.Tests
{
public class BaseOperationBehaviorTests
{
Action<AsyncOperationHandle, Exception> m_PrevHandler;
ResourceManager m_RM;
[OneTimeSetUp]
public void OneTimeSetup()
{
m_PrevHandler = ResourceManager.ExceptionHandler;
ResourceManager.ExceptionHandler = null;
}
[OneTimeTearDown]
public void OneTimeTeardown()
{
ResourceManager.ExceptionHandler = m_PrevHandler;
}
[SetUp]
public void Setup()
{
m_RM = new ResourceManager();
m_RM.CallbackHooksEnabled = false; // default for tests. disabled callback hooks. we will call update manually
}
[TearDown]
public void TearDown()
{
Assert.Zero(m_RM.OperationCacheCount);
m_RM.Dispose();
}
[Test]
public void WhenReferenceCountReachesZero_DestroyCallbackInvoked()
{
var op = m_RM.CreateCompletedOperation<int>(1, string.Empty);
int resultInDestroyCallback = 0;
op.Destroyed += (x) => resultInDestroyCallback = x.Convert<int>().Result;
op.Release();
Assert.AreEqual(1, resultInDestroyCallback);
}
[Test]
public void WhileCompletedCallbackIsDeferredOnCompletedOperation_ReferenceCountIsHeld()
{
var op = m_RM.CreateCompletedOperation<int>(1, string.Empty);
int refCount = op.ReferenceCount;
bool completedCalled = false;
op.Completed += (x) => completedCalled = true; // callback is deferred to next update
Assert.AreEqual(refCount + 1, op.ReferenceCount);
m_RM.Update(0.0f);
Assert.AreEqual(refCount, op.ReferenceCount);
Assert.AreEqual(true, completedCalled);
op.Release();
}
[Test]
public void WhenInDestroyCallback_IncrementAndDecrementReferenceCount_Throws()
{
var op = m_RM.CreateCompletedOperation<int>(1, string.Empty);
int resultInDestroyCallback = 0;
Exception onInc = null;
Exception onDec = null;
op.Destroyed += (x) =>
{
try
{
x.Acquire();
}
catch (Exception e)
{
onInc = e;
}
try
{
x.Release();
}
catch (Exception e)
{
onDec = e;
}
resultInDestroyCallback = x.Convert<int>().Result;
};
op.Release();
Assert.NotNull(onInc);
Assert.NotNull(onDec);
}
class MockOperation<T> : AsyncOperationBase<T>
{
public Action ExecuteCallback = () => { };
protected override void Execute()
{
ExecuteCallback();
}
}
[Test]
public void WhenOperationHasDependency_ExecuteNotCalledUntilDependencyCompletes()
{
var op1 = new MockOperation<int>();
var op2 = new MockOperation<int>();
var handle1 = m_RM.StartOperation(op1, default(AsyncOperationHandle));
op2.ExecuteCallback = () => { op2.Complete(0, true, string.Empty); };
var handle2 = m_RM.StartOperation(op2, handle1);
m_RM.Update(0.0f);
Assert.AreEqual(false, handle2.IsDone);
op1.Complete(0, true, null);
Assert.AreEqual(true, handle2.IsDone);
handle1.Release();
handle2.Release();
}
[Test]
public void WhenOperationIsSuccessfulButHasErrorMsg_FailsSilently_CompletesButExceptionHandlerIsCalled()
{
bool exceptionHandlerCalled = false;
ResourceManager.ExceptionHandler += (h, ex) => exceptionHandlerCalled = true;
var op = m_RM.CreateCompletedOperationInternal<int>(1, true, new Exception("An exception occured."));
var status = AsyncOperationStatus.None;
op.Completed += (x) => status = x.Status;
// callbacks are deferred to next update
m_RM.Update(0.0f);
Assert.AreEqual(true, exceptionHandlerCalled);
Assert.AreEqual(AsyncOperationStatus.Succeeded, status);
op.Release();
}
[UnityTest]
public IEnumerator AsyncOperationHandle_TaskIsDelayedUntilAfterDelayedCompletedCallbacks()
{
var op = m_RM.CreateCompletedOperationInternal<int>(1, true, null);
var status = AsyncOperationStatus.None;
op.Completed += (x) => status = x.Status;
var t = op.Task;
Assert.IsFalse(t.IsCompleted);
// callbacks are deferred to next update
m_RM.Update(0.0f);
// the Task may not yet have continues after at this point on the update,
// give the Synchronization a little time with a yield
yield return null;
Assert.IsTrue(t.IsCompleted);
op.Release();
}
[Test]
public void AsyncOperationHandle_TaskIsCompletedWhenHandleIsCompleteWithoutDelayedCallbacks()
{
var op = m_RM.CreateCompletedOperationInternal<int>(1, true, null);
var t = op.Task;
Assert.IsTrue(t.IsCompleted);
op.Release();
}
// TODO:
// public void WhenOperationHasDependency_AndDependencyFails_DependentOpStillExecutes()
// Bad derived class behavior
// public void CustomOperation_WhenCompleteCalledBeforeStartOperation_ThrowsOperationDoesNotComplete
// public void CustomOperation_WhenCompleteCalledMultipleTimes_Throws
// public void CustomOperation_WhenProgressCallbackThrowsException_ErrorLoggedAndHandleReturnsZero
// public void CustomOperation_WhenDestroyThrowsException_ErrorLogged
// public void CustomOperation_WhenExecuteThrows_ErrorLoggedAndOperationSetAsFailed
// TEST: Per operation update behavior
// public void AsyncOperationHandle_WhenReleaseOnInvalidHandle_Throws
// public void AsyncOperationHandle_WhenConvertToIncompatibleHandleType_Throws
//
[Test]
public void AsyncOperationHandle_EventSubscriptions_UnsubscribingToNonSubbedEventsShouldHaveNoEffect()
{
var op = new MockOperation<int>();
var handle = m_RM.StartOperation(op, default(AsyncOperationHandle));
Assert.False(op.CompletedEventHasListeners);
handle.Completed -= oph => { };
Assert.False(op.CompletedEventHasListeners);
Assert.False(op.DestroyedEventHasListeners);
handle.Destroyed -= oph => { };
Assert.False(op.DestroyedEventHasListeners);
handle.Release();
}
internal class ManualDownloadPercentCompleteOperation : AsyncOperationBase<IAssetBundleResource>
{
public long m_bytesDownloaded = 0;
public long m_totalBytes = 1024;
public bool m_IsDone = false;
protected override void Execute()
{
}
public void CompleteNow()
{
m_bytesDownloaded = m_totalBytes;
Complete(null, true, null);
}
internal override DownloadStatus GetDownloadStatus(HashSet<object> visited)
{
return new DownloadStatus() {DownloadedBytes = m_bytesDownloaded, TotalBytes = m_totalBytes, IsDone = m_IsDone};
}
}
static void AssertExpectedDownloadStatus(DownloadStatus dls, long dl, long tot, float per)
{
Assert.AreEqual(dl, dls.DownloadedBytes);
Assert.AreEqual(tot, dls.TotalBytes);
Assert.AreEqual(per, dls.Percent);
}
[Test]
public void DownloadStatusWithNoBytes_WithIsDoneFalse_Returns_PercentCompleteZero()
{
var dls = new DownloadStatus() {DownloadedBytes = 0, TotalBytes = 0, IsDone = false};
Assert.AreEqual(0f, dls.Percent);
}
[Test]
public void DownloadStatusWithNoBytes_WithIsDoneTrue_Returns_PercentCompleteOne()
{
var dls = new DownloadStatus() {DownloadedBytes = 0, TotalBytes = 0, IsDone = true};
Assert.AreEqual(1f, dls.Percent);
}
[Test]
public void GroupOperation_WithOpsThatImplementGetDownloadStatus_ComputesExpectedDownloadPercentComplete()
{
var ops = new List<AsyncOperationHandle>();
var mdpco = new List<ManualDownloadPercentCompleteOperation>();
for (int i = 0; i < 4; i++)
{
var o = m_RM.CreateOperation<ManualDownloadPercentCompleteOperation>(typeof(ManualDownloadPercentCompleteOperation), 1, null, null);
o.Start(m_RM, default, null);
mdpco.Add(o);
ops.Add(new AsyncOperationHandle(o));
}
var gOp = m_RM.CreateGenericGroupOperation(ops, true);
AssertExpectedDownloadStatus(gOp.GetDownloadStatus(), 0, 4096, 0);
mdpco[0].m_bytesDownloaded = 512;
AssertExpectedDownloadStatus(gOp.GetDownloadStatus(), 512, 4096, .125f);
foreach (var o in mdpco)
o.CompleteNow();
AssertExpectedDownloadStatus(gOp.GetDownloadStatus(), 4096, 4096, 1f);
m_RM.Release(gOp);
}
[Test]
public void ChainOperation_WithOpThatImplementGetDownloadStatus_ComputesExpectedDownloadPercentComplete()
{
var depOp = m_RM.CreateOperation<ManualDownloadPercentCompleteOperation>(typeof(ManualDownloadPercentCompleteOperation), 1, null, null);
depOp.Start(m_RM, default, null);
var chainOp = m_RM.CreateChainOperation<object>(new AsyncOperationHandle(depOp), s => m_RM.CreateCompletedOperationInternal<object>(null, true, null));
AssertExpectedDownloadStatus(chainOp.GetDownloadStatus(), 0, 1024, 0f);
depOp.m_bytesDownloaded = 512;
AssertExpectedDownloadStatus(chainOp.GetDownloadStatus(), 512, 1024, .5f);
depOp.CompleteNow();
m_RM.Update(.1f);
Assert.IsTrue(chainOp.IsDone);
AssertExpectedDownloadStatus(chainOp.GetDownloadStatus(), 1024, 1024, 1f);
m_RM.Release(chainOp);
}
[Test]
public void PercentComplete_ReturnsZero_WhenChainOperationHasNotBegun()
{
var baseOperation = m_RM.CreateChainOperation<AsyncOperationHandle>(
new AsyncOperationHandle(new ManualPercentCompleteOperation(1f)),
(obj) => { return new AsyncOperationHandle<AsyncOperationHandle>(); });
Assert.AreEqual(0, baseOperation.PercentComplete);
}
[Test]
public void GroupOperation_WithDuplicateOpThatImplementGetDownloadStatus_DoesNotOverCountValues()
{
var ops = new List<AsyncOperationHandle>();
var o = m_RM.CreateOperation<ManualDownloadPercentCompleteOperation>(typeof(ManualDownloadPercentCompleteOperation), 1, null, null);
o.Start(m_RM, default, null);
for (int i = 0; i < 4; i++)
ops.Add(new AsyncOperationHandle(o));
var gOp = m_RM.CreateGenericGroupOperation(ops, true);
AssertExpectedDownloadStatus(gOp.GetDownloadStatus(), 0, 1024, 0);
o.m_bytesDownloaded = 512;
AssertExpectedDownloadStatus(gOp.GetDownloadStatus(), 512, 1024, .5f);
o.CompleteNow();
AssertExpectedDownloadStatus(gOp.GetDownloadStatus(), 1024, 1024, 1f);
m_RM.Release(gOp);
}
class TestOp : AsyncOperationBase<int>
{
protected override void Execute()
{
InvokeCompletionEvent();
}
}
[Test]
public void CompletionEvents_AreInvoked_InOrderAdded()
{
var op = new TestOp();
int count = 0;
op.Completed += o =>
{
Assert.AreEqual(0, count);
count++;
};
op.CompletedTypeless += o =>
{
Assert.AreEqual(1, count);
count++;
};
op.Completed += o =>
{
Assert.AreEqual(2, count);
count++;
};
op.CompletedTypeless += o =>
{
Assert.AreEqual(3, count);
count++;
};
op.Start(null, default, null);
op.Complete(1, true, null);
}
[Test]
public void WhenOperationIsReused_HasExecutedIsReset()
{
var op = new TestOp();
op.Start(null, default, null);
op.Complete(1, true, null);
Assert.IsTrue(op.HasExecuted);
var dep = new AsyncOperationHandle(new TestOp());
op.Start(null, dep, null);
Assert.IsFalse(op.HasExecuted);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4f6ca99e013fe6c49bb6b98f8ec1897b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,46 @@
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.ResourceManagement;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
public class ChainOperationTests
{
[Test]
public void ChainOperationWithTypedDependency_DoesNotReturnInvalidDependencyHandles()
{
//Setup
ChainOperation<object, object> chainOp = new ChainOperation<object, object>();
AsyncOperationHandle<object> chainOpHandle = new AsyncOperationHandle<object>(new ProviderOperation<object>());
chainOp.Init(chainOpHandle, null, false);
//Test
List<AsyncOperationHandle> dependencies = new List<AsyncOperationHandle>();
AsyncOperationHandle handle = new AsyncOperationHandle(chainOp);
chainOpHandle.m_InternalOp.m_Version = 1;
handle.GetDependencies(dependencies);
//Assert
Assert.AreEqual(0, dependencies.Count);
}
[Test]
public void ChainOperationWithTypelessDependency_DoesNotReturnInvalidDependencyHandles()
{
//Setup
ChainOperationTypelessDepedency<object> chainOp = new ChainOperationTypelessDepedency<object>();
AsyncOperationHandle<object> chainOpHandle = new AsyncOperationHandle<object>(new ProviderOperation<object>());
chainOp.Init(chainOpHandle, null, false);
//Test
List<AsyncOperationHandle> dependencies = new List<AsyncOperationHandle>();
AsyncOperationHandle handle = new AsyncOperationHandle(chainOp);
chainOpHandle.m_InternalOp.m_Version = 1;
handle.GetDependencies(dependencies);
//Assert
Assert.AreEqual(0, dependencies.Count);
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b42ee6f5a38f94b4baafd3c426bee7f5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,664 @@
using NUnit.Framework;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.ResourceManagement.ResourceProviders;
namespace UnityEngine.ResourceManagement.Tests
{
internal class ManualPercentCompleteOperation : AsyncOperationBase<GameObject>
{
public ManualPercentCompleteOperation(float percentComplete)
{
m_PercentComplete = percentComplete;
}
public float m_PercentComplete;
protected override void Execute()
{
Complete(new GameObject(), true, "");
}
protected override float Progress => m_PercentComplete;
}
public class ProviderOperationTests
{
MockProvider m_Provider;
MockProvider m_Provider2;
Action<AsyncOperationHandle, Exception> m_PrevHandler;
ResourceManager m_RM;
[OneTimeSetUp]
public void OneTimeSetup()
{
m_PrevHandler = ResourceManager.ExceptionHandler;
ResourceManager.ExceptionHandler = null;
}
[OneTimeTearDown]
public void OneTimeTeardown()
{
ResourceManager.ExceptionHandler = m_PrevHandler;
}
private void ProvideBasicCallback(ProvideHandle provideHandle)
{
provideHandle.Complete(provideHandle.Location.InternalId, true, null);
}
[SetUp]
public void Setup()
{
m_RM = new ResourceManager();
m_RM.CallbackHooksEnabled = false;
m_RM.postProfilerEvents = true;
m_Provider = new MockProvider();
m_Provider.ProvideCallback = ProvideBasicCallback;
m_Provider2 = new MockProvider();
m_Provider2._ProviderId = "MockId2";
m_Provider2.ProvideCallback = ProvideBasicCallback;
m_RM.ResourceProviders.Add(m_Provider);
m_RM.ResourceProviders.Add(m_Provider2);
}
[TearDown]
public void TearDown()
{
m_RM.ResourceProviders.Remove(m_Provider);
m_RM.ResourceProviders.Remove(m_Provider2);
Assert.Zero(m_RM.OperationCacheCount);
m_RM.Dispose();
m_RM = null;
}
[Test]
public void WhenDependency_ProvideCalledAfterDependencyFinishes()
{
ProvideHandle provideHandle = default(ProvideHandle);
m_Provider2.ProvideCallback = x => { provideHandle = x; };
ResourceLocationBase depLoc = new ResourceLocationBase("dep", "dep", m_Provider2.ProviderId, typeof(object));
ResourceLocationBase loc = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object), depLoc);
var op = m_RM.ProvideResource<object>(loc);
m_RM.Update(0.0f);
Assert.False(op.IsDone);
provideHandle.Complete(2, true, null);
m_RM.Update(0.0f);
Assert.True(op.IsDone);
op.Release();
}
[Test]
public void OnDestroyed_DepOpReleasedAndProviderReleased()
{
ResourceLocationBase depLoc = new ResourceLocationBase("dep", "dep", m_Provider2.ProviderId, typeof(object));
ResourceLocationBase loc = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object), depLoc);
ResourceLocationBase loc2 = new ResourceLocationBase("2", "2", m_Provider.ProviderId, typeof(object), depLoc);
var op1 = m_RM.ProvideResource<object>(loc);
m_RM.Update(0.0f);
Assert.AreEqual(1, m_Provider2.ProvideLog.Count);
var op2 = m_RM.ProvideResource<object>(loc2);
m_RM.Update(0.0f);
Assert.AreEqual(1, m_Provider2.ProvideLog.Count);
Assert.AreEqual(2, m_Provider.ProvideLog.Count);
Assert.AreEqual(AsyncOperationStatus.Succeeded, op1.Status);
Assert.AreEqual(AsyncOperationStatus.Succeeded, op2.Status);
// decrement the first op. the second op should still be holding the dependency
op1.Release();
Assert.AreEqual(0, m_Provider2.ReleaseLog.Count);
// decrement the second op. the dependency should now have been released
op2.Release();
Assert.AreEqual(1, m_Provider2.ReleaseLog.Count);
Assert.AreEqual(2, m_Provider.ReleaseLog.Count);
Assert.AreEqual(1, m_Provider2.ReleaseLog.Count);
}
[Test]
public void WhenDependentOpFails_ProvideIsNotCalled()
{
ResourceLocationBase depLoc = new ResourceLocationBase("dep", "dep", "unknown provider", typeof(object));
ResourceLocationBase loc = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object), depLoc);
var op = m_RM.ProvideResource<object>(loc);
m_RM.Update(0.0f);
Assert.AreEqual(AsyncOperationStatus.Failed, op.Status);
op.Release();
Assert.AreEqual(0, m_Provider.ProvideLog.Count);
Assert.AreEqual(0, m_Provider.ReleaseLog.Count);
}
[Test]
public void WhenDependentOpFails_AndProviderSupportsFailedDependencies_OperationContinues()
{
m_Provider._BehaviourFlags = ProviderBehaviourFlags.CanProvideWithFailedDependencies;
ResourceLocationBase depLoc = new ResourceLocationBase("dep", "dep", "unknown provider", typeof(object));
ResourceLocationBase loc = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object), depLoc);
var op = m_RM.ProvideResource<object>(loc);
m_RM.Update(0.0f);
Assert.AreEqual(AsyncOperationStatus.Succeeded, op.Status);
Assert.AreEqual("1", op.Result);
op.Release();
Assert.AreEqual(1, m_Provider.ProvideLog.Count);
Assert.AreEqual(1, m_Provider.ReleaseLog.Count);
}
[Test]
public void WhenProviderCompletesInsideProvideCall_CallbackIsNotDeferred()
{
ResourceLocationBase depLoc = new ResourceLocationBase("dep", "dep", m_Provider2.ProviderId, typeof(object));
ResourceLocationBase loc = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object), depLoc);
ProvideHandle depHandle = new ProvideHandle();
m_Provider2.ProvideCallback = (x) => { depHandle = x; };
var op = m_RM.ProvideResource<object>(loc);
bool callbackCalled = false;
Assert.AreEqual(AsyncOperationStatus.None, op.Status);
op.Completed += x => callbackCalled = true;
// mark dependency complete
depHandle.Complete(1, true, null);
Assert.IsTrue(callbackCalled);
op.Release();
}
[Test]
public void WhenProviderCompletesOutsideProvideCall_CallbackIsImmediate()
{
ResourceLocationBase loc = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object));
ProvideHandle depHandle = new ProvideHandle();
m_Provider.ProvideCallback = (x) => { depHandle = x; };
var op = m_RM.ProvideResource<object>(loc);
bool callbackCalled = false;
Assert.AreEqual(AsyncOperationStatus.None, op.Status);
op.Completed += x => callbackCalled = true;
// mark dependency complete
Assert.IsFalse(callbackCalled);
depHandle.Complete(1, true, null);
Assert.IsTrue(callbackCalled);
op.Release();
}
[Test]
public void UsingProviderHandleWithInvalidVersion_ThrowsException()
{
ResourceLocationBase loc = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object));
ProvideHandle handle = new ProvideHandle();
m_Provider.ProvideCallback = (x) => { handle = x; };
var op = m_RM.ProvideResource<object>(loc);
handle.Complete<object>(null, true, null);
Assert.Catch(() => handle.Complete<object>(null, true, null), ProviderOperation<object>.kInvalidHandleMsg);
Assert.Catch(() => handle.GetDependencies(new List<object>()), ProviderOperation<object>.kInvalidHandleMsg);
op.Release();
}
[Test]
public void GetDependency_InsertsDependenciesIntoList()
{
List<object> deps = new List<object>();
ResourceLocationBase depLoc = new ResourceLocationBase("dep1", "dep1", m_Provider2.ProviderId, typeof(object));
ResourceLocationBase depLoc2 = new ResourceLocationBase("dep2", "dep2", m_Provider2.ProviderId, typeof(object));
ResourceLocationBase loc = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object), depLoc, depLoc2);
m_Provider.ProvideCallback = (handle) =>
{
handle.GetDependencies(deps);
handle.Complete(0, true, null);
};
var op = m_RM.ProvideResource<object>(loc);
m_RM.Update(0.0f);
Assert.AreEqual(AsyncOperationStatus.Succeeded, op.Status);
Assert.AreEqual(deps[0], "dep1");
Assert.AreEqual(deps[1], "dep2");
op.Release();
}
[Test]
public void ProviderOperation_PercentComplete_DoesNotDecreaseAfterPercentCallbackIsSet()
{
var providerOp = new ProviderOperation<GameObject>();
providerOp.m_DepOp = new AsyncOperationHandle<IList<AsyncOperationHandle>>();
providerOp.m_DepOp.m_InternalOp = new ProviderOperation<IList<AsyncOperationHandle>>();
providerOp.m_DepOp.m_InternalOp.Result = new List<AsyncOperationHandle>();
providerOp.m_DepOp.m_InternalOp.Result.Add(new ManualPercentCompleteOperation(1.0f).Handle);
Assert.AreEqual(0.5f, providerOp.PercentComplete);
providerOp.SetProgressCallback(() => 0.5f);
Assert.AreEqual(0.75f, providerOp.PercentComplete);
}
class Type1
{
}
class Type2
{
}
[Test]
public void WhenProviderCallsComplete_AndTypeIsIncorrect_Throws()
{
ResourceLocationBase loc = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object));
Exception testException = null;
m_Provider.ProvideCallback = (x) =>
{
try
{
x.Complete(new Type2(), true, null);
}
catch (Exception e)
{
testException = e;
}
};
var op = m_RM.ProvideResource<Type1>(loc);
m_RM.Update(0.0f);
Assert.IsNotNull(testException);
Assert.AreEqual(AsyncOperationStatus.Failed, op.Status);
Assert.IsNull(op.Result);
Assert.IsTrue(op.OperationException.Message.Contains("Provider of type"));
op.Release();
}
[Test]
public void WhenProviderThrowsExceptionOnProvide_OperationFails()
{
ResourceLocationBase loc = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object));
m_Provider.ProvideCallback = (x) => { throw new Exception("I have failed"); };
var op = m_RM.ProvideResource<Type1>(loc);
m_RM.Update(0.0f);
Assert.AreEqual(AsyncOperationStatus.Failed, op.Status);
op.Release();
}
[Test]
public void WhenProviderThrowsExceptionInProgressCallback_ProgressReturnsZero()
{
ResourceLocationBase loc = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object));
ProvideHandle handle = new ProvideHandle();
bool didThrow = false;
m_Provider.ProvideCallback = (x) =>
{
handle = x;
handle.SetProgressCallback(() =>
{
didThrow = true;
throw new Exception("I have failed");
});
};
var op = m_RM.ProvideResource<Type1>(loc);
Assert.AreEqual(0.0f, op.PercentComplete);
Assert.True(didThrow);
handle.Complete<object>(null, true, null);
op.Release();
}
public void ProvideWithoutSpecifiedType_UsesDefaultProviderType()
{
ResourceLocationBase depLoc = new ResourceLocationBase("dep", "dep", m_Provider2.ProviderId, typeof(object));
ResourceLocationBase loc = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object), depLoc);
ProvideHandle handle = default(ProvideHandle);
m_Provider2.ProvideCallback = (x) => { handle = x; };
m_Provider2.DefaultType = typeof(Type2);
var op = m_RM.ProvideResource<object>(loc);
Assert.AreEqual(typeof(Type2), handle.Type);
handle.Complete(new Type2(), true, null);
op.Release();
}
void ProviderCompleteTypeTest<TRequestType, TResultType>(TResultType result, string exceptionMessage)
{
ResourceLocationBase loc = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object));
ProvideHandle handle = default(ProvideHandle);
m_Provider.ProvideCallback = (x) => { handle = x; };
var op = m_RM.ProvideResource<TRequestType>(loc);
if (string.IsNullOrEmpty(exceptionMessage))
{
handle.Complete(result, true, null);
}
else
{
// TODO: assert contents of exception
Assert.Catch(() => handle.Complete(result, true, null));
}
Assert.True(op.IsDone);
op.Release();
}
class Type3 : Type2
{
}
[Test]
public void ProvideHandle_CompleteWithExactType_Succeeds()
{
ProviderCompleteTypeTest<Type2, Type2>(new Type2(), null);
}
[Test]
public void ProvideHandle_CompleteWithDerivedTypeAsResult_Succeeds()
{
ProviderCompleteTypeTest<Type2, Type3>(new Type3(), null);
}
[Test]
public void ProvideHandle_CompleteWithBaseTypeAsResult_Succeeds()
{
ProviderCompleteTypeTest<Type3, Type2>(new Type3(), null);
}
[Test]
public void ProvideHandle_CompleteWithNullForReferencedType_Succeeds()
{
ProviderCompleteTypeTest<Type1, Type1>(null, null);
}
[Test]
public void ProvideHandle_CompleteWithNonAssignableType_Throws()
{
ProviderCompleteTypeTest<Type2, Type1>(new Type1(), "Failed");
}
[Test]
public void ProvideResource_WhenDependencyFailsToLoad_AndProviderCannotLoadWithFailedDependencies_ProvideNotCalled()
{
m_Provider.ProvideCallback = (pi) => { throw new Exception("This Should Not Have Been Called"); };
m_RM.ResourceProviders.Add(m_Provider);
ResourceLocationBase locDep = new ResourceLocationBase("depasset", "depasset", "unkonwn", typeof(object));
ResourceLocationBase locRoot = new ResourceLocationBase("rootasset", "rootasset", m_Provider.ProviderId, typeof(object), locDep);
AsyncOperationHandle<object> op = m_RM.ProvideResource<object>(locRoot);
m_RM.Update(0.0f);
Assert.AreEqual(AsyncOperationStatus.Failed, op.Status);
op.Release();
}
[Test]
public void ProvideResource_WhenDependencyFailsToLoad_AndProviderCanLoadWithFailedDependencies_ProviderStillProvides()
{
m_Provider._BehaviourFlags = ProviderBehaviourFlags.CanProvideWithFailedDependencies;
m_Provider.ProvideCallback = (pi) => { pi.Complete(5, true, null); };
m_RM.ResourceProviders.Add(m_Provider);
ResourceLocationBase locDep = new ResourceLocationBase("depasset", "depasset", "unkonwn", typeof(object));
ResourceLocationBase locRoot = new ResourceLocationBase("rootasset", "rootasset", m_Provider.ProviderId, typeof(object), locDep);
AsyncOperationHandle<object> op = m_RM.ProvideResource<object>(locRoot);
m_RM.Update(0.0f);
Assert.AreEqual(AsyncOperationStatus.Succeeded, op.Status);
Assert.AreEqual(5, op.Result);
op.Release();
}
[Test]
public void ProvideResource_ReceiveDiagnosticsCallback_IGenericProviderOperationHasLocation()
{
m_Provider.ProvideCallback = (pi) => { pi.Complete(int.Parse(pi.Location.InternalId), true, null); };
m_RM.ResourceProviders.Add(m_Provider);
List<ResourceManager.DiagnosticEventContext> eventsRecieved = new List<ResourceManager.DiagnosticEventContext>();
m_RM.RegisterDiagnosticCallback(ctx => { eventsRecieved.Add(ctx); });
var locations = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object));
AsyncOperationHandle<object> op = m_RM.ProvideResource<object>(locations);
m_RM.Update(0.0f);
m_RM.ClearDiagnosticCallbacks();
for (int i = 0; i < eventsRecieved.Count; ++i)
{
if (eventsRecieved[i].OperationHandle.m_InternalOp is IGenericProviderOperation)
{
Assert.NotNull(eventsRecieved[i].Location);
Assert.IsTrue(eventsRecieved[i].Location.InternalId == "1");
}
}
op.Release();
}
[Test]
public void ProvideResource_ReceiveDiagnosticsCallback_CreateAndComplete()
{
m_Provider.ProvideCallback = (pi) => { pi.Complete(int.Parse(pi.Location.InternalId), true, null); };
m_RM.ResourceProviders.Add(m_Provider);
List<ResourceManager.DiagnosticEventContext> eventsRecieved = new List<ResourceManager.DiagnosticEventContext>();
m_RM.RegisterDiagnosticCallback(ctx => { eventsRecieved.Add(ctx); });
var locations = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object));
AsyncOperationHandle<object> op = m_RM.ProvideResource<object>(locations);
m_RM.Update(0.0f);
m_RM.ClearDiagnosticCallbacks();
bool created = false;
bool completed = false;
for (int i = 0; i < eventsRecieved.Count; ++i)
{
if (eventsRecieved[i].Type == ResourceManager.DiagnosticEventType.AsyncOperationCreate)
{
Assert.NotNull(eventsRecieved[i].Location);
Assert.IsTrue(eventsRecieved[i].Location.InternalId == "1");
Assert.IsFalse(completed);
Assert.IsFalse(created);
created = true;
}
else if (eventsRecieved[i].Type == ResourceManager.DiagnosticEventType.AsyncOperationComplete)
{
Assert.NotNull(eventsRecieved[i].Location);
Assert.True(eventsRecieved[i].Location.InternalId == "1");
Assert.IsFalse(completed);
Assert.IsTrue(created);
completed = true;
}
else if (eventsRecieved[i].Type == ResourceManager.DiagnosticEventType.AsyncOperationDestroy)
{
Assert.NotNull(eventsRecieved[i].Location);
Assert.True(eventsRecieved[i].Location.InternalId == "1");
Assert.IsTrue(completed);
Assert.IsTrue(created);
}
}
op.Release();
}
[Test]
public void ProvideResource_ReceiveDiagnosticsCallback_MultipleCallbacks()
{
m_Provider.ProvideCallback = (pi) => { pi.Complete(int.Parse(pi.Location.InternalId), true, null); };
m_RM.ResourceProviders.Add(m_Provider);
bool callback1 = false, callback2 = false;
m_RM.RegisterDiagnosticCallback(ctx => { callback1 = true; });
m_RM.RegisterDiagnosticCallback(ctx => { callback2 = true; });
var locations = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object));
AsyncOperationHandle<object> op = m_RM.ProvideResource<object>(locations);
m_RM.Update(0.0f);
m_RM.ClearDiagnosticCallbacks();
Assert.IsTrue(callback1);
Assert.IsTrue(callback2);
op.Release();
}
[Test]
public void ProvideResources_CanLoadAndUnloadMultipleResources()
{
m_Provider.ProvideCallback = (pi) => { pi.Complete(int.Parse(pi.Location.InternalId), true, null); };
m_RM.ResourceProviders.Add(m_Provider);
var locations = new List<IResourceLocation>()
{
new ResourceLocationBase("0", "0", m_Provider.ProviderId, typeof(object)),
new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object)),
};
AsyncOperationHandle<IList<object>> op = m_RM.ProvideResources<object>(locations);
m_RM.Update(0.0f);
for (int i = 0; i < locations.Count; i++)
{
Assert.AreEqual((int)op.Result[i], i);
}
op.Release();
}
[Test]
public void ProvideResource_CanLoadNestedDepdendencies()
{
m_Provider._BehaviourFlags = ProviderBehaviourFlags.CanProvideWithFailedDependencies;
List<IResourceLocation> loadOrder = new List<IResourceLocation>();
m_Provider.ProvideCallback = (pi) =>
{
loadOrder.Add(pi.Location);
pi.Complete(0, true, null);
};
IResourceLocation i3 = new ResourceLocationBase("3", "3", m_Provider.ProviderId, typeof(object));
IResourceLocation i2 = new ResourceLocationBase("2", "2", m_Provider.ProviderId, typeof(object), i3);
IResourceLocation i1 = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object), i2);
var op = m_RM.ProvideResource<object>(i1);
m_RM.Update(0.0f);
Assert.AreEqual(5, m_RM.OperationCacheCount);
Assert.AreSame(i3, loadOrder[0]);
Assert.AreSame(i2, loadOrder[1]);
Assert.AreSame(i1, loadOrder[2]);
op.Release();
}
[Test]
public void ProvideResource_WhenSomeDependenciesFail_SuccessfulDependenciesRelease()
{
ResourceLocationBase depLoc1 = new ResourceLocationBase("dep1", "dep1", "unknown provider", typeof(object));
ResourceLocationBase depLoc2 = new ResourceLocationBase("dep2", "dep2", m_Provider.ProviderId, typeof(object));
ResourceLocationBase loc = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object), depLoc1, depLoc2);
var op = m_RM.ProvideResource<object>(loc);
m_RM.Update(0.0f);
Assert.AreEqual(AsyncOperationStatus.Failed, op.Status);
Assert.AreEqual(1, m_Provider.ProvideLog.Count);
Assert.AreEqual(1, m_Provider.ReleaseLog.Count);
Assert.IsNull(op.Result);
}
[Test]
public void ProvideResources_PartialSuccess_AllowsForSomeFailures()
{
ResourceLocationBase loc_a = new ResourceLocationBase("dep1", "dep1", "unknown provider", typeof(object));
ResourceLocationBase loc_b = new ResourceLocationBase("dep2", "dep2", m_Provider.ProviderId, typeof(object));
var op = m_RM.ProvideResources<object>(
new List<IResourceLocation> {loc_a, loc_b},
false,
null);
m_RM.Update(0.0f);
Assert.AreEqual(AsyncOperationStatus.Failed, op.Status);
Assert.AreEqual(1, m_Provider.ProvideLog.Count);
Assert.AreEqual(0, m_Provider.ReleaseLog.Count);
Assert.IsNotNull(op.Result);
Assert.AreEqual(2, op.Result.Count);
Assert.IsNull(op.Result[0]);
Assert.AreEqual("dep2", op.Result[1]);
op.Release();
}
[Test]
public void ProvideResources_ReleaseDependenciesOnFailure_DoesApplyToLocationDependencies()
{
ResourceLocationBase depLoc1a = new ResourceLocationBase("dep1a", "dep1a", "unknown provider", typeof(object));
ResourceLocationBase depLoc2a = new ResourceLocationBase("dep2a", "dep2a", m_Provider.ProviderId, typeof(object));
ResourceLocationBase loc_a = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object), depLoc1a, depLoc2a);
ResourceLocationBase depLoc1b = new ResourceLocationBase("dep1b", "dep1b", "unknown provider", typeof(object));
ResourceLocationBase depLoc2b = new ResourceLocationBase("dep2b", "dep2b", m_Provider.ProviderId, typeof(object));
ResourceLocationBase loc_b = new ResourceLocationBase("2", "2", m_Provider.ProviderId, typeof(object), depLoc1b, depLoc2b);
var op = m_RM.ProvideResources<object>(new List<IResourceLocation> {loc_a, loc_b}, true, null);
m_RM.Update(0.0f);
Assert.AreEqual(AsyncOperationStatus.Failed, op.Status);
Assert.AreEqual(2, m_Provider.ProvideLog.Count);
Assert.AreEqual(2, m_Provider.ReleaseLog.Count);
Assert.IsNull(op.Result);
}
[Test]
public void ProvideResources_DoNotReleaseDependenciesOnFailure_DoesApplyToLocationDependencies()
{
ResourceLocationBase depLoc1a = new ResourceLocationBase("dep1a", "dep1a", "unknown provider", typeof(object));
ResourceLocationBase depLoc2a = new ResourceLocationBase("dep2a", "dep2a", m_Provider.ProviderId, typeof(object));
ResourceLocationBase loc_a = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object), depLoc1a, depLoc2a);
ResourceLocationBase depLoc1b = new ResourceLocationBase("dep1b", "dep1b", "unknown provider", typeof(object));
ResourceLocationBase depLoc2b = new ResourceLocationBase("dep2b", "dep2b", m_Provider.ProviderId, typeof(object));
ResourceLocationBase loc_b = new ResourceLocationBase("2", "2", m_Provider.ProviderId, typeof(object), depLoc1b, depLoc2b);
var op = m_RM.ProvideResources<object>(new List<IResourceLocation> {loc_a, loc_b}, false, null);
m_RM.Update(0.0f);
Assert.AreEqual(AsyncOperationStatus.Failed, op.Status);
Assert.AreEqual(2, m_Provider.ProvideLog.Count);
Assert.AreEqual(0, m_Provider.ReleaseLog.Count);
Assert.IsNull(op.Result);
op.Release();
}
[Test]
public void ProvideResources_DoNotReleaseDependenciesOnFailure_ReleaseAllLocationsAfterCallingRelease()
{
ResourceLocationBase depLoc1a = new ResourceLocationBase("dep1a", "dep1a", "unknown provider", typeof(object));
ResourceLocationBase depLoc2a = new ResourceLocationBase("dep2a", "dep2a", m_Provider.ProviderId, typeof(object));
ResourceLocationBase loc_a = new ResourceLocationBase("1", "1", m_Provider.ProviderId, typeof(object), depLoc1a, depLoc2a);
ResourceLocationBase depLoc1b = new ResourceLocationBase("dep1b", "dep1b", "unknown provider", typeof(object));
ResourceLocationBase depLoc2b = new ResourceLocationBase("dep2b", "dep2b", m_Provider.ProviderId, typeof(object));
ResourceLocationBase loc_b = new ResourceLocationBase("2", "2", m_Provider.ProviderId, typeof(object), depLoc1b, depLoc2b);
var op = m_RM.ProvideResources<object>(new List<IResourceLocation> {loc_a, loc_b}, false, null);
m_RM.Update(0.0f);
Assert.AreEqual(AsyncOperationStatus.Failed, op.Status);
Assert.AreEqual(2, m_Provider.ProvideLog.Count);
Assert.AreEqual(0, m_Provider.ReleaseLog.Count);
Assert.IsNull(op.Result);
op.Release();
Assert.AreEqual(2, m_Provider.ReleaseLog.Count);
}
[Test]
public void ProvideResources_ReleaseDependenciesOnFailure_DoesNotOverReleaseAfterCallingRelease()
{
ResourceLocationBase depLoc1a = new ResourceLocationBase("dep1a", "dep1a", "unknown provider", typeof(object));
ResourceLocationBase depLoc2a = new ResourceLocationBase("dep2a", "dep2a", m_Provider.ProviderId, typeof(object));
ResourceLocationBase loc_a = new ResourceLocationBase("loc_a", "1", m_Provider.ProviderId, typeof(object), depLoc1a, depLoc2a);
ResourceLocationBase depLoc1b = new ResourceLocationBase("dep1b", "dep1b", "unknown provider", typeof(object));
ResourceLocationBase depLoc2b = new ResourceLocationBase("dep2b", "dep2b", m_Provider.ProviderId, typeof(object));
ResourceLocationBase loc_b = new ResourceLocationBase("loc_b", "2", m_Provider.ProviderId, typeof(object), depLoc1b, depLoc2b);
ResourceLocationBase loc_shared = new ResourceLocationBase("loc_shared", "3", m_Provider.ProviderId, typeof(object), depLoc2a);
var op_shared = m_RM.ProvideResources<object>(new List<IResourceLocation> {loc_shared}, true, null);
var op = m_RM.ProvideResources<object>(new List<IResourceLocation> {loc_a, loc_b}, true, null);
m_RM.Update(0.0f);
Assert.AreEqual(AsyncOperationStatus.Failed, op.Status);
Assert.AreEqual(AsyncOperationStatus.Succeeded, op_shared.Status);
Assert.AreEqual(3, m_Provider.ProvideLog.Count);
Assert.AreEqual(1, m_Provider.ReleaseLog.Count);
Assert.IsNull(op.Result);
op.Release();
Assert.AreEqual(1, m_Provider.ReleaseLog.Count);
op_shared.Release();
Assert.AreEqual(3, m_Provider.ReleaseLog.Count);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d07c590681843734482b565ad928be3e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: