Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Bug Code generation for partial struct causes Unity to throw error because of duplicated class

Discussion in 'Entity Component System' started by Scub3d, Jan 7, 2023.

  1. Scub3d

    Scub3d

    Joined:
    Aug 3, 2016
    Posts:
    4
    Not sure if this is the appropriate place to post this but I am having issues when attempting to define partial structs for IJobEntity, specifically if that Job resides in a class that inherits from ScriptableObject or MonoBehaviour. I get the following error message: Temp\GeneratedCode\Assembly-CSharp\ErrorExample__JobEntity_1406895720.g.cs(8,14): error CS0101: The namespace '<global namespace>' already contains a definition for 'ErrorExample'

    Example of code that causes this problem:

    ErrorExample.cs:
    Code (CSharp):
    1.  
    2. using Unity.Collections;
    3. using Unity.Transforms;
    4. using UnityEngine;
    5. using Unity.Entities;
    6.  
    7. public class ErrorExample : MonoBehaviour {
    8.     [GenerateTestsForBurstCompatibility]
    9.     private partial struct ErrorExampleJob : IJobEntity {
    10.         public void Execute(in LocalTransform localTransfrom) {
    11.             // something here
    12.         }
    13.     }
    14. }
    15.  
    Generated code for ErrorExample.cs
    Code (CSharp):
    1.  
    2. #pragma warning disable 0219
    3. #line 1 "<system path was here>\Temp\GeneratedCode\Assembly-CSharp\ErrorExample__JobEntity_1406895720.g.cs"
    4. using Unity.Collections;
    5. using Unity.Transforms;
    6. using UnityEngine;
    7. using Unity.Entities;
    8.  
    9. public class ErrorExample : MonoBehaviour
    10. {
    11.     [global::System.Runtime.CompilerServices.CompilerGenerated]
    12.     partial struct ErrorExampleJob : global::Unity.Entities.IJobChunk, global::Unity.Entities.InternalCompilerInterface.IIsFullyUnmanaged
    13.     {
    14.         [Unity.Collections.ReadOnly]
    15.         public Unity.Entities.ComponentTypeHandle<Unity.Transforms.LocalTransform> __Unity_Transforms_LocalTransformComponentTypeHandle;
    16.         [global::System.Runtime.CompilerServices.CompilerGenerated]
    17.         public void Execute(in ArchetypeChunk chunk, int chunkIndexInQuery, bool useEnabledMask, in Unity.Burst.Intrinsics.v128 chunkEnabledMask)
    18.         {
    19.             var localTransformArray = InternalCompilerInterface.UnsafeGetChunkNativeArrayReadOnlyIntPtr<Unity.Transforms.LocalTransform>(chunk, ref __Unity_Transforms_LocalTransformComponentTypeHandle);
    20.             int chunkEntityCount = chunk.Count;
    21.             int matchingEntityCount = 0;
    22.             if (!useEnabledMask)
    23.             {
    24.                 for (int entityIndexInChunk = 0; entityIndexInChunk < chunkEntityCount; ++entityIndexInChunk)
    25.                 {
    26.                     ref var localTransformArrayRef = ref InternalCompilerInterface.UnsafeGetRefToNativeArrayPtrElement<Unity.Transforms.LocalTransform>(localTransformArray, entityIndexInChunk);
    27.                     Execute(in localTransformArrayRef);
    28.                     matchingEntityCount++;
    29.                 }
    30.             }
    31.             else
    32.             {
    33.                 int edgeCount = Unity.Mathematics.math.countbits(chunkEnabledMask.ULong0 ^ (chunkEnabledMask.ULong0 << 1)) + Unity.Mathematics.math.countbits(chunkEnabledMask.ULong1 ^ (chunkEnabledMask.ULong1 << 1)) - 1;
    34.                 bool useRanges = edgeCount <= 4;
    35.                 if (useRanges)
    36.                 {
    37.                     var enabledMask = chunkEnabledMask;
    38.                     int entityIndexInChunk = 0;
    39.                     int chunkEndIndex = 0;
    40.                     while (EnabledBitUtility.GetNextRange(ref enabledMask, ref entityIndexInChunk, ref chunkEndIndex))
    41.                     {
    42.                         while (entityIndexInChunk < chunkEndIndex)
    43.                         {
    44.                             ref var localTransformArrayRef = ref InternalCompilerInterface.UnsafeGetRefToNativeArrayPtrElement<Unity.Transforms.LocalTransform>(localTransformArray, entityIndexInChunk);
    45.                             Execute(in localTransformArrayRef);
    46.                             entityIndexInChunk++;
    47.                             matchingEntityCount++;
    48.                         }
    49.                     }
    50.                 }
    51.                 else
    52.                 {
    53.                     ulong mask64 = chunkEnabledMask.ULong0;
    54.                     int count = Unity.Mathematics.math.min(64, chunkEntityCount);
    55.                     for (int entityIndexInChunk = 0; entityIndexInChunk < count; ++entityIndexInChunk)
    56.                     {
    57.                         if ((mask64 & 1) != 0)
    58.                         {
    59.                             ref var localTransformArrayRef = ref InternalCompilerInterface.UnsafeGetRefToNativeArrayPtrElement<Unity.Transforms.LocalTransform>(localTransformArray, entityIndexInChunk);
    60.                             Execute(in localTransformArrayRef);
    61.                             matchingEntityCount++;
    62.                         }
    63.  
    64.                         mask64 >>= 1;
    65.                     }
    66.  
    67.                     mask64 = chunkEnabledMask.ULong1;
    68.                     for (int entityIndexInChunk = 64; entityIndexInChunk < chunkEntityCount; ++entityIndexInChunk)
    69.                     {
    70.                         if ((mask64 & 1) != 0)
    71.                         {
    72.                             ref var localTransformArrayRef = ref InternalCompilerInterface.UnsafeGetRefToNativeArrayPtrElement<Unity.Transforms.LocalTransform>(localTransformArray, entityIndexInChunk);
    73.                             Execute(in localTransformArrayRef);
    74.                             matchingEntityCount++;
    75.                         }
    76.  
    77.                         mask64 >>= 1;
    78.                     }
    79.                 }
    80.             }
    81.         }
    82.  
    83.         public void Run() => __ThrowCodeGenException();
    84.         public void RunByRef() => __ThrowCodeGenException();
    85.         public void Run(global::Unity.Entities.EntityQuery query) => __ThrowCodeGenException();
    86.         public void RunByRef(global::Unity.Entities.EntityQuery query) => __ThrowCodeGenException();
    87.         Unity.Jobs.JobHandle __ThrowCodeGenException() => throw new global::System.Exception("This method should have been replaced by source gen.");
    88.         // Emitted to disambiguate scheduling method invocations
    89.         public global::Unity.Jobs.JobHandle Schedule(global::Unity.Jobs.JobHandle dependsOn) => __ThrowCodeGenException();
    90.         public global::Unity.Jobs.JobHandle ScheduleByRef(global::Unity.Jobs.JobHandle dependsOn) => __ThrowCodeGenException();
    91.         public global::Unity.Jobs.JobHandle Schedule(global::Unity.Entities.EntityQuery query, global::Unity.Jobs.JobHandle dependsOn) => __ThrowCodeGenException();
    92.         public global::Unity.Jobs.JobHandle ScheduleByRef(global::Unity.Entities.EntityQuery query, global::Unity.Jobs.JobHandle dependsOn) => __ThrowCodeGenException();
    93.         public void Schedule() => __ThrowCodeGenException();
    94.         public void ScheduleByRef() => __ThrowCodeGenException();
    95.         public void Schedule(global::Unity.Entities.EntityQuery query) => __ThrowCodeGenException();
    96.         public void ScheduleByRef(global::Unity.Entities.EntityQuery query) => __ThrowCodeGenException();
    97.         public global::Unity.Jobs.JobHandle ScheduleParallel(global::Unity.Jobs.JobHandle dependsOn) => __ThrowCodeGenException();
    98.         public global::Unity.Jobs.JobHandle ScheduleParallelByRef(global::Unity.Jobs.JobHandle dependsOn) => __ThrowCodeGenException();
    99.         public global::Unity.Jobs.JobHandle ScheduleParallel(global::Unity.Entities.EntityQuery query, global::Unity.Jobs.JobHandle dependsOn) => __ThrowCodeGenException();
    100.         public global::Unity.Jobs.JobHandle ScheduleParallelByRef(global::Unity.Entities.EntityQuery query, global::Unity.Jobs.JobHandle dependsOn) => __ThrowCodeGenException();
    101.         public global::Unity.Jobs.JobHandle ScheduleParallel(global::Unity.Entities.EntityQuery query, global::Unity.Jobs.JobHandle dependsOn, global::Unity.Collections.NativeArray<int> chunkBaseEntityIndices) => __ThrowCodeGenException();
    102.         public global::Unity.Jobs.JobHandle ScheduleParallelByRef(global::Unity.Entities.EntityQuery query, global::Unity.Jobs.JobHandle dependsOn, global::Unity.Collections.NativeArray<int> chunkBaseEntityIndices) => __ThrowCodeGenException();
    103.         public void ScheduleParallel() => __ThrowCodeGenException();
    104.         public void ScheduleParallelByRef() => __ThrowCodeGenException();
    105.         public void ScheduleParallel(global::Unity.Entities.EntityQuery query) => __ThrowCodeGenException();
    106.         public void ScheduleParallelByRef(global::Unity.Entities.EntityQuery query) => __ThrowCodeGenException();
    107.     }
    108. }
    109.  
    However, when I put the Job inside a class that inherits from SystemBase, the error does not occur.
    Code:
    Code (CSharp):
    1.  
    2. using Unity.Collections;
    3. using Unity.Transforms;
    4. using UnityEngine;
    5. using Unity.Entities;
    6.  
    7. public partial class ErrorExample : SystemBase {
    8.     protected override void OnUpdate()
    9.     {
    10.         throw new System.NotImplementedException();
    11.     }
    12.  
    13.     [GenerateTestsForBurstCompatibility]
    14.     private partial struct ErrorExampleJob : IJobEntity {
    15.         public void Execute(in LocalTransform localTransfrom) {
    16.             // something here
    17.         }
    18.     }
    19. }
    20.  
    Is this a bug or is it intended behaviour? Thanks!

    Misc Info:
    Unity: 2022.2.1f1
    OS: Windows 10
    IDE: Tried both Visual Studio 2022 & VS Code
     
  2. Spy-Master

    Spy-Master

    Joined:
    Aug 4, 2022
    Posts:
    510
    This is completely expected behavior. The top-level class was not marked as partial. This would mean other declarations of that type aren’t allowed. You need to mark everything in the hierarchy as partial if you want to be able to add a part of some partial nested type.
     
    ThatDan123 and DaxodeUnity like this.
  3. Scub3d

    Scub3d

    Joined:
    Aug 3, 2016
    Posts:
    4
    Thank you for the quick reply. This fixed the issue I had. This is my first time using partial classes/structs so I did not know that was needed