664 lines
30 KiB
C#
664 lines
30 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|