Search Unity

How to decouple two system?

Discussion in 'Entity Component System' started by eterlan, Jun 14, 2019.

  1. eterlan

    eterlan

    Joined:
    Sep 29, 2018
    Posts:
    177
    Hi! I'm recently doing sth like Utility AI. Now I got a Decision system, I need to compare several Tendencies and know the index of the largest value. However, I thought to decouple sort task from decision system might be a good idea? So now I have Sort System, which' responsibility is find out which is the biggest element in the Dynamic Buffer. The challenge is how these two systems communicate with each other? And how to decouple these two systems nicely?

    I have several rough ideas now, but have no idea which is better.

    1. Use a generic sort system. Whenever I have a new Sorting requirement, I write a new System inherit from the SortSystem<T> base class.

    2. Sort System provides a generic static method, which accept a Dynamic Buffer<T> as parameter, and schedule a Sorting Job with this Buffer, then returns the index of the largest element.

    3. Use a wrapper Dynamic buffer

    4. Just combine this two system, but make these two become two job.

    So, how do you think about this? which is better, or do you have any better idea?
    Any suggestion is appreciated!
     
  2. eterlan

    eterlan

    Joined:
    Sep 29, 2018
    Posts:
    177
    I guess it's a bad question..
    I use the generic approach, and got hybrid and pure two approaches. Just put it here for anyone who might interested.
    Any suggestions would be welcome.:)

    Code (CSharp):
    1.     public class FindMaximumSystem : ComponentSystem
    2.     {
    3.         protected override void OnUpdate()
    4.         {
    5.         }
    6.  
    7.         public NativeList<int> FindMaximum<T>()
    8.             where T : struct, IBufferElementData
    9.         {
    10.             return SortInt<T>();
    11.         }
    12.  
    13.         private NativeList<int> SortInt<T>()
    14.             where T : struct, IBufferElementData
    15.         {
    16.             var output = new NativeList<int>(8, Allocator.TempJob);
    17.  
    18.             Entities.ForEach((DynamicBuffer<T> b0) =>
    19.             {
    20.                 var largestIndex = 0;
    21.                 var buffer       = b0.Reinterpret<float>().AsNativeArray();
    22.                 var largest      = buffer[0];
    23.  
    24.                 for (var currIndex = 0; currIndex < b0.Length; currIndex++)
    25.                 {
    26.                     var current = buffer[currIndex];
    27.                     var larger  = current > largest;
    28.                     largestIndex = math.select(largestIndex, currIndex, larger);
    29.                 }
    30.  
    31.                 output.Add(largestIndex);
    32.             });
    33.             return output;
    34.         }
    35.         // @Todo Should I just let a length parameter in to avoid some efforts?
    36.         public NativeArray<int> FindMaximum<T>(out JobHandle handle)
    37.             where T : struct, IBufferElementData
    38.         {
    39.             var query  = EntityManager.CreateEntityQuery(typeof(T));
    40.             var entities = query.ToEntityArray(Allocator.TempJob);
    41.             var entity = entities[0];
    42.             entities.Dispose();
    43.  
    44.             var length = EntityManager.GetBuffer<T>(entity).Length;
    45.             var output = new NativeArray<int>(length, Allocator.TempJob);
    46.             var job = new Sort<T> {Output = output};
    47.             handle = job.Schedule(query);
    48.             return output;
    49.         }
    50.  
    51.         private struct Sort<T> : IJobForEachWithEntity_EB<T> where T : struct, IBufferElementData
    52.         {
    53.             public NativeArray<int> Output;
    54.  
    55.             public void Execute(Entity entity, int index, DynamicBuffer<T> b0)
    56.             {
    57.                 var largestIndex = 0;
    58.                 var buffer       = b0.Reinterpret<float>().AsNativeArray();
    59.                 var length       = b0.Length;
    60.                 var largest      = buffer[0];
    61.  
    62.                 for (var currIndex = 0; currIndex < length; currIndex++)
    63.                 {
    64.                     var tendency = buffer[currIndex];
    65.                     var larger   = tendency > largest;
    66.                     largestIndex = math.select(largestIndex, currIndex, larger);
    67.                 }
    68.  
    69.                 Output[index] = largestIndex;
    70.             }
    71.         }