Search Unity

Question [help] Use DynamicBuffer by Aspect on ECS 1.0

Discussion in 'Entity Component System' started by seojihyuk, Mar 14, 2023.

  1. seojihyuk

    seojihyuk

    Joined:
    Sep 19, 2014
    Posts:
    30
    Hello guys. I've updated to DOTS 1.0 pre 65 recently. So I don't know well about aspect.
    I'm trying to use DynamicBuffer for grid on my game.
    Can't we write DynamicBuffer by method on aspect?
     
    Last edited: Mar 24, 2023
    lclemens likes this.
  2. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    761
    I figured out that you can call myAspect.MyBuf.Add(xxx). But if you try to do myAspect.MyBuf[0] = xxx, then it yells at you saying it's readonly, but if you don't mark the dynamic buffers in the aspect as readonly, then it yells at you. :mad:
     
  3. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    761
    Well... this compiles (not sure if it works at runtime)... and it looks really strange because readonly is not readonly. :confused:

    Declare the buffer in the aspect as readonly (even if it's not!)

    Code (CSharp):
    1.  
    2. public readonly partial struct MyAspect : IAspect
    3. {
    4.     public readonly DynamicBuffer<float> MyBuf; // readonly makes compiler happy
    5. }
    6.  
    7. [BurstCompile]
    8. public partial struct MyJob : IJobEntity
    9. {
    10.     [BurstCompile]
    11.     public void Execute(MyAspect aspect)
    12.     {
    13.         // you can't do aspect.MyBuf[0] = 123.456f;
    14.         // but you can do this...
    15.         var myBufRw = aspect.MyBuf;
    16.         myBufRw[0] = 123.456f;
    17.         // or you can do this....
    18.         aspect.MyBuf.ElementAt(0) = 123.456f;
    19.     }
    20. }
    21.  
     
  4. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Shouldn't passing parameter by ref automatically be picked up by codegen to generate non-readonly variant?

    I haven't used 1.0 aspects yet, but in previous versions it was like that.
     
    lclemens likes this.
  5. Laicasaane

    Laicasaane

    Joined:
    Apr 15, 2015
    Posts:
    365
    From the Aspect document:

    upload_2023-7-9_18-46-12.png
     
    lclemens likes this.
  6. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    761
    @xVergilx @Laicasaane I read the docs for aspects and it really doesn't address DynamicBuffer much other than to say that you can put them in an aspect (without RefRO or RefRW).

    But I know that if you don't declare DynamicBuffer with readonly, visual studio complains: "error CS8340: Instance fields of readonly structs must be readonly." So I'm marking it as readonly and then later I write to it anyway.

    I got the idea for making it readonly (and then treating them as writable anyway) to fix the VS error from this thread: https://forum.unity.com/threads/examples-of-using-dynamicbuffer-in-aspects.1438669/ . Wobbers' theory is: "DynamicBuffers are just pointers to their underlying data which lies somewhere else, so the readonly modifier doesn't really mean anything as far as I know."
     
  7. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Prior to v1.0 sourcegen was detecting what is RO / RW or not based on parameters (in / ref) and attributes.
    So I suspect its the same thing still for the Execute method and fields.
    [ReadOnly] matters per field;

    DynamicBuffers are always RW. Due to their nature. Its a pointer to the block of memory.
    So making aspect that is used to write a readonly makes no sense either.
    Sure its a struct that cannot be changed, but in ECS readonly has a different meaning.
    Don't mix those together however tempting it is.

    Also, try other IDEs other than VS.
    Its hilariously bad nowadays (in performance, analysis, and critical bugs). Check out Rider instead.
     
  8. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    761
    If only Rider wasn't so expensive. In that post that I linked to, the guy said he was getting an error from Rider. So I think either way, we'll get an error without putting readonly in the declaration before DynamicBuffer.
     
    xVergilx likes this.
  9. Laicasaane

    Laicasaane

    Joined:
    Apr 15, 2015
    Posts:
    365
    Because Aspects are "readonly struct". And the rule of the language says: readonly structs must have their members marked as readonly as well. This rule ensures member fields can't change their value.

    And since this is the language rule, no IDE can bypass it.

    This attribute comes from Unity.Collections package, so C# compiler can't associate it with the "readonly" keyword.
     
    xVergilx likes this.