using NUnit.Framework; using System; using System.Collections.Generic; using Unity.Burst; using Unity.Burst.Editor; using Unity.Jobs; // This concrete generic type is only referenced in this assembly-level attribute, // not anywhere else in code. This is to test that such types can be picked up // by BurstReflection. [assembly: BurstReflectionTests.RegisterGenericJobType(typeof(BurstReflectionTests.GenericParallelForJob))] [TestFixture] public class BurstReflectionTests { private List _assemblies; [OneTimeSetUp] public void SetUp() { _assemblies = BurstReflection.EditorAssembliesThatCanPossiblyContainJobs; } [Test] public void CanGetAssemblyList() { Assert.That(_assemblies, Has.Count.GreaterThan(0)); } [Test] [TestCase("BurstReflectionTests.MyJob - (IJob)")] [TestCase("BurstReflectionTests.MyGenericJob`1[System.Int32] - (IJob)")] [TestCase("BurstReflectionTests.MyGenericJob2`1[System.Int32] - (BurstReflectionTests.IMyGenericJob`1[System.Int32])")] [TestCase("BurstReflectionTests.MyGenericJob2`1[System.Double] - (BurstReflectionTests.IMyGenericJob`1[System.Double])")] [TestCase("BurstReflectionTests.NonGenericType.TestMethod1()")] [TestCase("BurstReflectionTests.GenericType`1[System.Int32].TestMethod1()")] [TestCase("BurstReflectionTests.GenericType`1.NestedNonGeneric[System.Int32].TestMethod2()")] [TestCase("BurstReflectionTests.GenericType`1.NestedGeneric`1[System.Int32,System.Single].TestMethod3()")] [TestCase("BurstReflectionTests.MyGenericJobSeparateAssembly`1[System.Int32] - (BurstReflectionTestsSeparateAssembly.IMyGenericJobSeparateAssembly`1[System.Int32])")] [TestCase("BurstReflectionTests.GenericParallelForJob`1[System.Int32] - (IJobParallelFor)")] public void CanFindJobType(string compileTargetName) { var result = BurstReflection.FindExecuteMethods(_assemblies, BurstReflectionAssemblyOptions.None); Assert.That(result.LogMessages, Is.Empty); var compileTarget = result.CompileTargets.Find(x => x.GetDisplayName() == compileTargetName); Assert.That(compileTarget, Is.Not.Null); } [BurstCompile] private struct MyJob : IJob { public void Execute() { } } [BurstCompile] private struct MyGenericJob : IJob { public void Execute() { } private static void UseConcreteType() { new MyGenericJob().Execute(); } } [Unity.Jobs.LowLevel.Unsafe.JobProducerType(typeof(MyJobProducer<,>))] private interface IMyGenericJob { void Execute(); } [BurstCompile] private struct MyGenericJob2 : IMyGenericJob { public void Execute() { } private static void UseConcreteType() { new MyGenericJob2().Execute(); } } private static class MyJobProducer { public static void Execute(ref TJob job) { } } private struct MyGenericJob2Wrapper { public MyGenericJob2 Job; private static void UseConcreteType() { var x = new MyGenericJob2Wrapper(); x.Job.Execute(); } } [BurstCompile] private struct NonGenericType { [BurstCompile] public static void TestMethod1() { } } [BurstCompile] private struct GenericType { public static Action Delegate1; public static Action Delegate2; public static Action Delegate3; [BurstCompile] public static void TestMethod1() { } [BurstCompile] public class NestedNonGeneric { [BurstCompile] public static void TestMethod2() { } } [BurstCompile] public class NestedGeneric { [BurstCompile] public static void TestMethod3() { } } private static void UseConcreteType() { // Store the delegates to static fields to avoid // them being optimized-away in Release builds Delegate1 = GenericType.TestMethod1; Delegate2 = GenericType.NestedNonGeneric.TestMethod2; Delegate3 = GenericType.NestedGeneric.TestMethod3; } } [BurstCompile] private struct MyGenericJobSeparateAssembly : BurstReflectionTestsSeparateAssembly.IMyGenericJobSeparateAssembly { public void Execute() { } private static void UseConcreteType() { new MyGenericJobSeparateAssembly().Execute(); } } [Test] [TestCase("BurstReflectionTests.GenericMethodContainer.GenericMethod(T)")] public void ExcludesGenericMethods(string compileTargetName) { var result = BurstReflection.FindExecuteMethods(_assemblies, BurstReflectionAssemblyOptions.None); Assert.That(result.LogMessages, Is.Empty); var compileTarget = result.CompileTargets.Find(x => x.GetDisplayName() == compileTargetName); Assert.That(compileTarget, Is.Null); } [BurstCompile] private static class GenericMethodContainer { [BurstCompile] private static void GenericMethod(T p) { } } [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal class RegisterGenericJobTypeAttribute : Attribute { public Type ConcreteType; public RegisterGenericJobTypeAttribute(Type type) { ConcreteType = type; } } [BurstCompile] internal struct GenericParallelForJob : IJobParallelFor where T : struct { public void Execute(int index) { throw new System.NotImplementedException(); } } }