#Question about Firefighters example project - HeatSystem.cs and [EntityIndexInQuery]

1 messages ยท Page 1 of 1 (latest)

tawny stirrup
#

Hi ๐Ÿ‘‹

I am working through the DOTS bootcamp videos and in Day 3 there is a
DynamicBuffer<Heat> HeatBuffer
We use it to store the values in a way that we can easily get access to neighbour Entities by means of calculation. But then we use it inside a job:

[WithAll(typeof(GroundCell))]
[BurstCompile]
public partial struct GroundCellUpdate : IJobEntity
{
    public float ElapsedTime;
    public Config Config;
    [ReadOnly] public DynamicBuffer<Heat> HeatBuffer;
    public float MinY;
    public float MaxY;

    public void Execute(ref LocalTransform trans, ref URPMaterialPropertyBaseColor color, [EntityIndexInQuery] int entityIdx)
    {
        var heat = HeatBuffer[entityIdx].Value;

        ...
        color.Value = math.lerp(Config.MinHeatColor, Config.MaxHeatColor, heat);

        entityIdx++;
    }
}

Now as far as I understand Queries returns Entities in no particular order. So how does the [EntityIndexInQuery] int entityIdx matches the index of the var heat = HeatBuffer[entityIdx].Value; ?

Here is the code that calls the job:

    DynamicBuffer<Heat> heatBuffer, Config config)
{
    var minY = -(config.GroundCellYScale / 2);
    var groundCellUpdateJob = new GroundCellUpdate
    {
        Config = config,
        HeatBuffer = heatBuffer,
        ElapsedTime = (float)SystemAPI.Time.ElapsedTime,
        MinY = minY,
        MaxY = minY + config.GroundCellYScale,
    };

    return groundCellUpdateJob.Schedule(dependency);
}```

I might have missed something that was said previously about it ๐Ÿ˜…  But maybe someone can explain this to me - how can we be sure that the query index matches the HeatBuffer index ?
willow garnet
#

it does have an order and thats exactly what the attribute is for when going parallel, to give you the index of an entity in an identical non parallel query

#

of course it doesnt work if there are changes to the entities in between (add/remove etc)

tawny stirrup
willow garnet
#

determinism tools are a very useful feature of the ECS framework ๐Ÿ™‚

still anvil
bleak bone
#

I agree, seeing a DynamicBuffer passed to an IJobEntity as a job struct field rather than an Execute() parameter feels pretty sketchy, even if it's technically correct. DynamicBuffer is best thought of a transient, on-the-stack object with a very limited lifespan, while working with the buffer contents of a single entity between structural changes.

...though any attempt to make a structural change (& invalidate the DynamicBuffer) would block until the job completed anyway. So, maybe it's fine as-is?

willow garnet
#

the advantage of the given approach is that you can dynamically change the query without having to add/remove components, plus it doesnt eat up chunk space this way

i didnt look at the tutorial code tho so i dont know if thats reasonable, though this approach doesnt seem problematic to me as-is

still anvil
#

Also if I'd be passing something which I use as a list I think its a bit less confusing to pass it as a NativeList instead of a dynamicbuffer (i.e. just doing .AsList before), so that its less confusing and less tied to the ECS types

willow garnet
#

I would've done that too (AsArray I guess you mean). Though I like removing abstractions/indirections if I don't need them, so I wouldn't go out of my way to change this code (and if it's a common thing in a project I may even prefer it).

willow garnet
bleak bone
#

EntityIndexInQuery works with enableable components (at least, it is expected to. If it doesn't, please let me know!). However, note the comment in the API docs:

This is generally way more expensive than ChunkIndexInQuery and EntityIndexInChunk, as it needs to schedule a EntityQuery.CalculateBaseEntityIndexArrayAsync job
Basically we run a separate prepass job to run a prefix-sum operation on the query's chunks, so that the job that requests [EntityIndexInQuery] gets the correct values.

#

And of course if you do things like enable/disable components in the same job that's asking for EntityIndexInQuery, ymmv

willow garnet
#

ah, I kind of expected that not to work because its expensive to calculate; my bad and thanks for the correction!