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

Question Questions around EntityCommandBuffer.SetBuffer and dynamic buffer sync points

Discussion in 'Entity Component System' started by bilalakil, Aug 18, 2022.

  1. bilalakil

    bilalakil

    Joined:
    Jan 28, 2018
    Posts:
    68
    Two questions:

    1. How are you supposed to use
    EntityCommandBuffer.SetBuffer
    ? There's only a default constructor on a
    DynamicBuffer
    and otherwise I'm not seeing a way to create a "temporary local buffer" to pass into that function. On the other hand, if you modify (e.g. clear, which the ECB doesn't have a function to simulate) a real buffer, then there's no need to call
    SetBuffer
    at all because those changes will be applied directly?

    2. The docs about sync points don't suggest that dynamic buffer modifications could trigger a sync point. Confirming that this is the case?

    3. If Q2 is confirmed, then what's the point of using
    EntityCommandBuffer.SetBuffer
    at all? I suppose there are the "fringe benefits" of replay-ability, and I guess it's needed if you want to set a buffer on an entity that's being created in an ECB, but then per Q1 I wouldn't know how to actually use
    EntityCommandBuffer.SetBuffer
    in that instance.
     
  2. bilalakil

    bilalakil

    Joined:
    Jan 28, 2018
    Posts:
    68
    Pertaining to Q1: Ok I think I misunderstood what
    SetBuffer
    actually does and assumed too much meaning from its name. Turns out you don't pass a buffer into it, rather it gives you a (new?) buffer for a given entity, which you can then use the other ECB commands to fill in.

    I found this snippet in a markdown file in Entities source:

    Code (CSharp):
    1. // SetBuffer is like AddBuffer, but safety checks will throw an exception at playback if
    2. // the entity doesn't already have a MyElement buffer.
    3. DynamicBuffer<MyElement> otherBuf = ecb.SetBuffer<MyElement>(otherEntity);
    4.  
    5. // Records a MyElement value to append to the buffer. Throws an exception at
    6. // playback if the entity doesn't already have a MyElement buffer.
    7. ecb.AppendToBuffer<MyElement>(otherEntity, new MyElement { Value = 12 });
    Need to find out what happens if a buffer already exists on that entity - will it be overwritten with a new one, or returned as is?
     
  3. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,983
    AddBuffer will add or overwrite. SetBuffer will overwrite or throw if a buffer isn't already there. AppendToBuffer is like SetBuffer but instead of overwriting, it appends a single element.
     
    Occuros and bilalakil like this.
  4. bilalakil

    bilalakil

    Joined:
    Jan 28, 2018
    Posts:
    68
    Code (CSharp):
    1.                 {
    2.                     var b = mgr.GetBuffer<RewardChoiceBufferData>(self._singletonEnt);
    3.                     UnityEngine.Debug.Log($"{b.Length}");
    4.                 }
    5.                 {
    6.                     var cb = new EntityCommandBuffer(Allocator.Temp);
    7.                     var b = cb.SetBuffer<RewardChoiceBufferData>(self._singletonEnt);
    8.                     cb.AppendToBuffer(self._singletonEnt, new RewardChoiceBufferData());
    9.                     cb.AppendToBuffer(self._singletonEnt, new RewardChoiceBufferData());
    10.                     cb.AppendToBuffer(self._singletonEnt, new RewardChoiceBufferData());
    11.                     cb.Playback(state.EntityManager);
    12.                 }
    13.                 {
    14.                     var b = mgr.GetBuffer<RewardChoiceBufferData>(self._singletonEnt);
    15.                     UnityEngine.Debug.Log($"{b.Length}");
    16.                 }
    17.                 {
    18.                     var cb = new EntityCommandBuffer(Allocator.Temp);
    19.                     var b = cb.SetBuffer<RewardChoiceBufferData>(self._singletonEnt);
    20.                     cb.AppendToBuffer(self._singletonEnt, new RewardChoiceBufferData());
    21.                     cb.AppendToBuffer(self._singletonEnt, new RewardChoiceBufferData());
    22.                     cb.Playback(state.EntityManager);
    23.                 }
    24.                 {
    25.                     var b = mgr.GetBuffer<RewardChoiceBufferData>(self._singletonEnt);
    26.                     UnityEngine.Debug.Log($"{b.Length}");
    27.                 }
    Log shows 0 -> 3 -> 2, so
    SetBuffer
    overrides, and Q1 is now answered!

    AddBuffer
    exhibits the same behaviour, which leads to question what the difference between the two (noting this on the
    AddBuffer
    docs
    : "Will throw an error ... if the entity doesn't have a DynamicBuffer<T> component storing elements of type T").
     
  5. bilalakil

    bilalakil

    Joined:
    Jan 28, 2018
    Posts:
    68
    Thanks @DreamingImLatios , didn't see your response before I posted that.

    However, the docs suggest your comment about
    AddBuffer
    adding or overwriting is wrong - although I've not tested. See the last sentence in my above post. Maybe the docs are wrong? Or my interpretation of either is wrong :p
     
  6. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,983
    I think those docs are wrong.
     
  7. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,574
    It looks like indeed doc is wrong.
    DynamicBuffer is added, when is missing.
    Can you guys use report button on the doc, to correct the information.