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 { 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(AsyncOperationHandle 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(AsyncOperationHandle 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(() => { handle.Convert(); }); } [Test] public void AsyncOperationHandle_ConvertToTyped_WithValidOpSucceeds() { var op = new FakeTypedOperation(); AsyncOperationHandle handle = new AsyncOperationHandle(op); AsyncOperationHandle typedHandle = handle.Convert(); Assert.True(handle.IsValid()); Assert.True(typedHandle.IsValid()); } [Test] public void AsyncOperationHandle_ConvertToTypeless_MaintainsValidity() { var op = new FakeTypedOperation(); AsyncOperationHandle typedHandle = new AsyncOperationHandle(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 typedHandle2 = new AsyncOperationHandle(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 typedHandle = new AsyncOperationHandle(op); AsyncOperationHandle validationHandle = new AsyncOperationHandle(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 typedHandle = new AsyncOperationHandle(op); AsyncOperationHandle typedHandle2 = new AsyncOperationHandle(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 typedHandle = new AsyncOperationHandle(op); IncreaseRefCount(typedHandle, 1); AsyncOperationHandle typedHandle2 = new AsyncOperationHandle(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 typedHandle = new AsyncOperationHandle(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); } } }