#Lookup dependencies.

1 messages · Page 1 of 1 (latest)

turbid cedar
#

Say I have health system that where an entity has health, and a dynamic buffer for changing health. Now any system can supposedly damage an entity by adding to that buffer. This has been working so far until I made a parallel job that does this by accessing a buffer lookup (with parallel safety disabled because each entity was only iterated once), where I'm getting an error of an unassigned dependency.

InvalidOperationException: The previously scheduled job ArcJob writes to the BufferLookup<HealthChangeBuffer> ArcJob.ObjectHealth. You must call JobHandle.Complete() on the job ArcJob, before you can read from the BufferLookup<HealthChangeBuffer> safely.

I've gotten this error before and I usually fixed it by adding the component type to the query, and adding state.dependency as a dependency. However, I have no clue how to go about this with a buffer lookup. The buffer component type is listed in the query but that doesn't seem to apply to the lookup itself. What am I missing?

#

Full code, some trivial stuff has been replaced with comment

[UpdateInGroup(typeof(PredictedFixedStepSimulationSystemGroup)), UpdateBefore(typeof(ProjectileAgeSystem))
/*, UpdateBefore(typeof(HealthChangeSystem)) Not in same system group and thus invalid.*/]
partial struct ArcSystem : ISystem
{
    private EntityQuery _arcQuery;
    private EntityQuery _objectQuery;

        //Creating this variable instead of calling SystemAPI.GetBufferLookup on update changed nothing.
    private BufferLookup<HealthChangeBuffer> _healthLookup;

    [BurstCompile]
    public void OnCreate(ref SystemState state)
    {
        _arcQuery = SystemAPI.QueryBuilder().WithAll<LocalTransform, ArcData, Simulate>().Build();
        _objectQuery = SystemAPI.QueryBuilder().WithAll<LocalTransform, HealthChangeBuffer, Simulate>().Build();
        _healthLookup = SystemAPI.GetBufferLookup<HealthChangeBuffer>(false);
        state.Require<ArcLinkGraphicData>();
    }

    [BurstCompile]
    public void OnUpdate(ref SystemState state)
    {
        //Graphics stuff

        _healthLookup.Update(ref state);
        NativeList<LocalTransform> arcTransforms = _arcQuery.ToComponentDataListAsync<LocalTransform>(stuff);
        NativeList<ArcData> arcData = _arcQuery.ToComponentDataListAsync<ArcData>(stuff);
        NativeList<LocalTransform> objectTransforms = _objectQuery.ToComponentDataListAsync<LocalTransform>(stuff);
        NativeList<Entity> objectEntities = _objectQuery.ToEntityListAsync(stuff);
        JobHandle dependency = state.Dependency.CombineWith(depA, depB, depC, depD);
        dependency = new ArcJob {
            //Set the lists
            ObjectHealth = _healthLookup,
        }.Schedule(objectTransforms, 16, dependency);
        //dispose lists
        state.Dependency = dependency;
    }
}

[BurstCompile]
public struct ArcJob : IJobParallelForDefer
{
    //The data lists
    [WriteOnly, NativeDisableParallelForRestriction] public BufferLookup<HealthChangeBuffer> ObjectHealth;
    public void Execute(int objectIndex)
    {
        //A bunch of conditions and stuff
        objectHealth.Add(stuff);
    }
}
open totem
#

that trivial stuff is kind of important

#

what is stuff

#

state.Dependency in, out depA?

turbid cedar
#

I'll add some extra context + uncomment

open totem
#

Tbh this looks like it's coming from another system

#

Where you are accessing health buffer on main thread

#

But yeah I just wanted to check stuff to make sure the input dependency wasn't being lost

turbid cedar
#

Clyde says that the code wasn't sent :/

#

Hoping for the best 🙏

#
public static JobHandle CombineWith(this JobHandle a, JobHandle b, JobHandle c, JobHandle d, JobHandle e)
{
    return JobHandle.CombineDependencies(a, b, JobHandle.CombineDependencies(c, d, e));
}
turbid cedar
#

Do system dependencies wait for jobs?

open totem
#

Yeah you probably just need to complete dependency

#

If you're using it on main thread

turbid cedar
#

aaahhhk

#

kk thxz

dusty swift
#

like it changes nothing, but makes the code a bit more readable

#

If the HealthChangeBuffer is on the entity you're looping over, why aren't you just using an IJobEntity?

turbid cedar
turbid cedar
#

In hindsight, I could have just used IJobEntity for the larger query and looked up the smaller

dusty swift
turbid cedar
#

well, cut out really

dusty swift
#

You should really learn how job entity works, otherwise you lose out on a lot of code cleanness and performance

turbid cedar
#

I already use IJobEntity, just not for this.