Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Make UnityEngine.NoAllocHelpers accessible

Discussion in 'Entity Component System' started by GMore, Feb 19, 2020.

  1. GMore

    GMore

    Joined:
    Nov 16, 2015
    Posts:
    5
    Last edited: May 28, 2020
    IAmJustADog likes this.
  2. ddalacu

    ddalacu

    Joined:
    May 13, 2014
    Posts:
    31
    Try this
    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Reflection;
    4. using System.Runtime.CompilerServices;
    5. using JetBrains.Annotations;
    6. using Unity.Collections.LowLevel.Unsafe;
    7. using Unity.IL2CPP.CompilerServices;
    8.  
    9. public static class ListUtilities
    10. {
    11.     public static readonly int ItemsFieldOffset;
    12.     public static readonly int SizeFieldOffset;
    13.  
    14.     static ListUtilities()
    15.     {
    16.         var type = typeof(List<>);
    17.         var itemsMember = type.GetField("_items", BindingFlags.Instance | BindingFlags.NonPublic);
    18.         var sizeMember = type.GetField("_size", BindingFlags.Instance | BindingFlags.NonPublic);
    19.  
    20.         ItemsFieldOffset = UnsafeUtility.GetFieldOffset(itemsMember);
    21.         SizeFieldOffset = UnsafeUtility.GetFieldOffset(sizeMember);
    22.     }
    23.  
    24.     /// <summary>
    25.     /// Creates a list of T then set its internal array to the passed array, this method will only allocate the list and not the internal buffer of the list
    26.     /// </summary>
    27.     /// <param name="buffer"></param>
    28.     /// <returns></returns>
    29.     [Il2CppSetOption(Option.NullChecks, false)]
    30.     public static List<TMember> CreateFromBuffer<TMember>([NotNull] TMember[] buffer)
    31.     {
    32.         if (buffer == null)
    33.             throw new ArgumentNullException(nameof(buffer));
    34.  
    35.         var result = new List<TMember>(0);
    36.         UseBuffer(result, buffer);
    37.         return result;
    38.     }
    39.  
    40.     /// <summary>
    41.     /// Changes the internal array in the passed list
    42.     /// </summary>
    43.     /// <param name="list"></param>
    44.     /// <param name="buffer"></param>
    45.     [Il2CppSetOption(Option.NullChecks, false)]
    46.     public static unsafe void UseBuffer<TMember>([NotNull] List<TMember> list, TMember[] buffer)
    47.     {
    48.         if (list == null)
    49.             throw new ArgumentNullException(nameof(list));
    50.  
    51.         var ptr = (byte*)UnsafeUtility.PinGCObjectAndGetAddress(list, out var handle);
    52.         UnsafeUtility.CopyObjectAddressToPtr(buffer, ptr + ItemsFieldOffset);
    53.         *(int*)(ptr + SizeFieldOffset) = buffer.Length;
    54.         UnsafeUtility.ReleaseGCObject(handle);
    55.     }
    56.  
    57.     /// <summary>
    58.     /// Returns the internal array used by a list
    59.     /// </summary>
    60.     /// <param name="list"></param>
    61.     /// <returns></returns>
    62.     [Il2CppSetOption(Option.NullChecks, false)]
    63.     public static unsafe TMember[] ExtractBuffer<TMember>([NotNull] List<TMember> list)
    64.     {
    65.         //We could use UnityEngine.NoAllocHelpers.ExtractArrayFromList that method is faster but internal :(
    66.         if (list == null)
    67.             throw new ArgumentNullException(nameof(list));
    68.  
    69.         var ptr = (byte*)UnsafeUtility.PinGCObjectAndGetAddress(list, out var handle);
    70.         TMember[] objectContainer = null;
    71.         Unsafe.Copy(ref objectContainer, ptr + ItemsFieldOffset);
    72.         UnsafeUtility.ReleaseGCObject(handle);
    73.         return objectContainer;
    74.     }
    75.  
    76. }
    77.  
    You can also create delegates to the internal methods
     
    WeltenbauerRenn and Egad_McDad like this.
  3. GMore

    GMore

    Joined:
    Nov 16, 2015
    Posts:
    5
    Any news? I have added link to Unity github source related to this question. It is just one word change.
     
    IAmJustADog likes this.