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?
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.
Well… this compiles (not sure if it works at runtime)… and it looks really strange because readonly is not readonly.
Declare the buffer in the aspect as readonly (even if it’s not!)
public readonly partial struct MyAspect : IAspect
{
public readonly DynamicBuffer<float> MyBuf; // readonly makes compiler happy
}
[BurstCompile]
public partial struct MyJob : IJobEntity
{
[BurstCompile]
public void Execute(MyAspect aspect)
{
// you can't do aspect.MyBuf[0] = 123.456f;
// but you can do this...
var myBufRw = aspect.MyBuf;
myBufRw[0] = 123.456f;
// or you can do this....
aspect.MyBuf.ElementAt(0) = 123.456f;
}
}
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.
@VergilUa @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: Examples of using DynamicBuffer in Aspects? . 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.”
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.
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.
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.