Having a headache transferring my project from OOP to ECS.
I have a lot of entities. I named their archetype “Chunk” since they’re representing a piece of the game’s world.
Each of the Chunks contains a DynamicBuffer which I use to contain a number of Entitty structs.
I created an IJobEntity struct that should process the Chunks, which involves both reading and writing to Chunk’s DynamicBuffers, e.g. swapping elements of a buffer, while iterating over them.
This processing job worked just fine as long as it was running on a single Chunk.
Then I attempted to make a Chunk interchange DynamicBuffer elements with another one via the aformentioned job and when I called EntityManager.GetBuffer I got this:
InvalidOperationException: The BufferTypeHandle<MyBufferElement> has been declared as [ReadOnly] in the job, but you are writing to it.
I haven’t explicitly declared anything as [ReadOnly].
Could anyone please explain to me what exactly I am doing wrong here? I read somewhere that a job can only access data from its own struct, but despite that I could read other entities’ data via EntityManager without any issues, so I’m kinda clueless about how exactly these access restrictions work. Chunks never interchange DynamicBuffer elements with chunks that are processed at the same time with ScheduleParallel (see the uploaded image).
And, more importantly, could anyone suggest me a way to implement the behaviour I described above, a way to interchage elements between DynamicBuffers of different entities? It is vital that it should be made while iterating through atoms, so creating a list of swap operations and performing them later is not an option.
If I understand correctly you want random access to DynamicBuffer/Components? You should use a ComponentLookup or BufferLookup for that: [Look up arbitrary data | Entities | 1.0.16
O](Look up arbitrary data | Entities | 1.0.16)therwise why not just include the DynamicBuffer in the Execute signature and you will get the buffer for the entity you are iterating over?
Thanks, I’ll take a look and reply to this topis as soon as I can. This seems to be the answer I was looking for.
Once again, it works just fine as long as I’m working with DynamicBuffer of the Chunk I’m executing the job on. But I need to access DynamicBuffers of other neighbouring Chunks. How would I include other entity’s ComponentData in the Execute method? I thought it’s only possible to reference the data of the current entity of the query, may be I’m missing something?
I tried using BufferLookup as you suggested and it worked exactly as I wanted. Since Entities 1.0 is pretty fresh, I had to use 0.51’s BufferFromEntity instead, but I believe they play the same role.
Thanks again for your help, now pixels of my “powder toy”-ish simulation flow from one chunk to another without problems and I have cleaner code without unnecessary EntityManager involvement.
I’m now struggling with parallel writing into those buffers and figuring out how to migrate my singletons to 1.0, but those are questions for other threads.