Search Unity

Question Is this the correct form of nested collections?

Discussion in 'Scripting' started by TheGabelle, Sep 13, 2021.

  1. TheGabelle

    TheGabelle

    Joined:
    Aug 23, 2013
    Posts:
    242
    I'm looking to have a NativeList where each item has it's own list. I know nested native collections will only work if the children collections are unsafe. I've included my quick and dirty test code which works correctly as far as I can tell.

    Two questions:
    1. Will this manner of disposal cause a memory leak?
    2. Will this manner of adding / removing Data and nodes work with burst in parallel?

    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3. using Unity.Mathematics;
    4. using Unity.Collections;
    5. using Unity.Collections.LowLevel.Unsafe;
    6.  
    7.  
    8. public class UnsafeListTest : MonoBehaviour
    9. {
    10.  
    11.     struct Data : IDisposable{
    12.         public uint ID;
    13.         public Matrix4x4 matrix;
    14.         public Bounds bounds;
    15.         public bool isOpen;
    16.  
    17.         public UnsafeList<float3> nodes;
    18.  
    19.         public void Dispose()
    20.         {
    21.             nodes.Dispose();
    22.         }
    23.     }
    24.  
    25.     NativeList<Data> datas;
    26.     Unity.Mathematics.Random rand;
    27.    
    28.  
    29.     void Start()
    30.     {
    31.         rand = new Unity.Mathematics.Random(1234);
    32.         datas = new NativeList<Data>(3, Allocator.Persistent);
    33.         for(uint i = 0; i < 3; i++){
    34.             datas.Add(CreateData(i+1) );
    35.         }
    36.  
    37.         Dump();
    38.     }
    39.  
    40.     Data CreateData(uint ID){
    41.         var data = new Data();
    42.            
    43.         data.ID = ID; // zero is 'null'
    44.        
    45.         data.matrix = new Matrix4x4();
    46.         data.matrix.SetTRS(rand.NextFloat3(), rand.NextQuaternionRotation(), new float3(1f,1f,1f));
    47.        
    48.         data.bounds = new Bounds(transform.position, Vector3.zero);
    49.        
    50.         data.nodes = new UnsafeList<float3>(4, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
    51.        
    52.         for(var j = 0; j < 4; j++){
    53.             var pt = rand.NextFloat3();
    54.             data.nodes.AddNoResize(pt);
    55.             data.bounds.Encapsulate(pt);
    56.         }
    57.         return data;
    58.     }
    59.  
    60.     void Dump() {
    61.         var log = "[\n";
    62.         for(var i = 0; i < datas.Length; i++){
    63.             log +=  "\t{" +
    64.                     "\n\t\t ID : " + datas[i].ID +
    65.                     "\n\t\t matrix:\n" + datas[i].matrix.ToString() +
    66.                     "\n\t\t bounds: " + datas[i].bounds.ToString() +
    67.                     "\n\t\t isOpen: " + datas[i].isOpen.ToString() +
    68.                     "\n\t\t nodes: [";
    69.             for (var j = 0; j < datas[i].nodes.Length; j++){
    70.                 log +=  "\n\t\t\t" + datas[i].nodes[j].ToString();
    71.             }
    72.             log += "\n\t\t]\n\t}\n";
    73.         }
    74.         log += "]";
    75.         Debug.Log(log);
    76.     }
    77.  
    78.     // Update is called once per frame
    79.     void Update()
    80.     {
    81.         if(Input.GetMouseButtonUp(0)){
    82.             datas.Add(CreateData((uint) datas.Length+1) );
    83.             Dump();
    84.         }
    85.         if(Input.GetMouseButtonUp(1)){
    86.             datas[0].Dispose();
    87.             datas.RemoveAt(0);
    88.             Dump();
    89.         }
    90.  
    91.     }
    92.  
    93.     void OnDestroy(){
    94.         for(var i = 0; i < datas.Length; i++){
    95.             datas[i].Dispose();
    96.         }
    97.         datas.Dispose();
    98.     }
    99. }