#Building EntityQueries from SystemAPI inside an ISystem doesn't seem to work?

1 messages · Page 1 of 1 (latest)

velvet cape
#

Hi there,

I'm trying to set a value from a system, as I'm still beginning with ECS.
I don't understand why this doesn't work:


[BurstCompile]
struct ChickenMovementJob : IJobChunk
{
    public ComponentTypeHandle<AgentBody> AgentBodyTypeHandle;
   // public float DeltaTime;

    [BurstCompile]
    public void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
    {
        AgentBody t;
        NativeArray<AgentBody> agents = chunk.GetNativeArray(ref AgentBodyTypeHandle);

        var enumerator = new ChunkEntityEnumerator(useEnabledMask, chunkEnabledMask, chunk.Count);
        while (enumerator.NextEntityIndex(out var i))
        {
            t = agents[i];

            t.Destination = new float3(30, 0, 0);
            t.IsStopped = false;

            agents[i] = t;
        }
    }
}

[BurstCompile]
public partial struct ChickenMovementSystem : ISystem
{
    private EntityQuery getChickenQuery;

    [BurstCompile]
    public void OnCreate(ref SystemState state)
    {
        SystemAPIQueryBuilder queryBuilder = SystemAPI.QueryBuilder(); // error points HERE
        queryBuilder = queryBuilder.WithAll<ChickenComponent>();
        queryBuilder = queryBuilder.WithAllRW<AgentBody>();
        getChickenQuery = queryBuilder.Build();

    }

    [BurstCompile]
    public void OnUpdate(ref SystemState state)
    {
        var chickenMovementJob = new ChickenMovementJob();

        chickenMovementJob.AgentBodyTypeHandle =
            state.GetComponentTypeHandle<AgentBody>(isReadOnly: false);

        state.Dependency = chickenMovementJob.ScheduleParallel(getChickenQuery, state.Dependency);
    }
}```

I get this error :

InvalidOperationException: No suitable code replacement generated, this is either due to generators failing, or lack of support in your current context
#

Note, I can achieve this with "Query" but I wanted to get the "AgentBod"ies of the entities that also have "ChickenComponent"

#

I don't chain the query just in order to have the error's line

#

AgentBody and ChickenComponent are IComponentData structs

#

Any ideas what I do wrong ?

shut tendon
#

you need to use SystemAPI.QueryBuilder explicitly

#

it's a codegen

#

using it directly not going to work

#

storing it in a field or variable is not supported

velvet cape
#

x)

shut tendon
#

EntityQueryBuilder is a different type

#

shouldn't be confused with anything returned by SystemAPI

velvet cape
#

[BurstCompile]
struct ChickenMovementJob : IJobChunk
{
    public ComponentTypeHandle<AgentBody> AgentBodyTypeHandle;
   // public float DeltaTime;

    [BurstCompile]
    public void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
    {
        AgentBody t;
        NativeArray<AgentBody> agents = chunk.GetNativeArray(ref AgentBodyTypeHandle);

        var enumerator = new ChunkEntityEnumerator(useEnabledMask, chunkEnabledMask, chunk.Count);
        while (enumerator.NextEntityIndex(out var i))
        {
            t = agents[i];

            t.Destination = new float3(30, 0, 0);
            t.IsStopped = false;

            agents[i] = t;
        }
    }
}


[BurstCompile]
public partial struct ChickenMovementSystem : ISystem
{
    private EntityQuery getChickenQuery;

    [BurstCompile]
    public void OnCreate(ref SystemState state)
    {
        EntityQueryBuilder queryBuilder = new EntityQueryBuilder(Allocator.Temp);
        queryBuilder = queryBuilder.WithAll<ChickenComponent>();
        queryBuilder = queryBuilder.WithAllRW<AgentBody>();
        getChickenQuery = queryBuilder.Build(ref state);

    }

    [BurstCompile]
    public void OnUpdate(ref SystemState state)
    {
        var chickenMovementJob = new ChickenMovementJob();

        chickenMovementJob.AgentBodyTypeHandle =
            state.GetComponentTypeHandle<AgentBody>(isReadOnly: false);

     //   chickenMovementJob.DeltaTime = state.World.Time.DeltaTime;

        state.Dependency = chickenMovementJob.ScheduleParallel(getChickenQuery, state.Dependency);

    }

}```

Works 🙂
shut tendon
#

fun fact btw

#

you can use SystemAPI instead

#

inside OnUpdate

#

it will be generated into what you have rn

#

same for any type handles

velvet cape
#

It creates what's needed in OnCreate ?

shut tendon
#

it creates fields for all of it

#

and etc

#

so all SystemAPI calls as of now can be called inside OnUpdate

#

and it will be generated into the most efficient code

#

even more efficient than you have rn (due to type handle)

#

and same with IJobChunk vs IJobEntity

#

IJE still generates into IJC, but codegens does some additional optimizations on top

velvet cape
#

thanks a lot; so the better version:

[BurstCompile]
public partial struct ChickenMovementJob : IJobEntity
{
    [BurstCompile]
    public void Execute(ref AgentBody agentBody)
    {
        agentBody.Destination = new float3(30, 0, 0);
        agentBody.IsStopped = false;
    }
}


[BurstCompile]
public partial struct ChickenMovementSystem : ISystem
{
    [BurstCompile]
    public void OnUpdate(ref SystemState state)
    {
        var chickenMovementJob = new ChickenMovementJob();

        state.Dependency = chickenMovementJob.ScheduleParallel(
            SystemAPI.QueryBuilder()
                .WithAll<ChickenComponent>()
                .WithAllRW<AgentBody>()
                .Build(), state.Dependency);
    }

}
#

alright I understand a lot better of those methods work ^^

#

thanks again 🙂

shut tendon
#

codegen has utilites for that

#

just add attribute on job struct [WithAll(typeof(CharacterComponent))]

#

and use ScheduleParallel() overload

#

without parameters and return

#

generated code will equal to your current implementation

velvet cape
#

[BurstCompile]
public partial struct ChickenMovementJob : IJobEntity
{
    [BurstCompile]
    public void Execute(ref AgentBody agentBody)
    {
        agentBody.Destination = new float3(30, 0, 0);
        agentBody.IsStopped = false;
    }
}


[BurstCompile]
[WithAll(typeof(ChickenComponent), typeof(AgentBody))]
public partial struct ChickenMovementSystem : ISystem
{
    [BurstCompile]
    public void OnUpdate(ref SystemState state)
    {
        state.Dependency = new ChickenMovementJob().ScheduleParallel(state.Dependency);
    }
}
shut tendon
#

no need for dependency overload

#

just (); will do the same thing

#

and you applied WithAll attribute on wrong struct

#

it needs to be on job

#

not on system

velvet cape
#
[BurstCompile]
[WithAll(typeof(ChickenComponent), typeof(AgentBody))]
public partial struct ChickenMovementJob : IJobEntity
{
    [BurstCompile]
    public void Execute(ref AgentBody agentBody)
    {
        agentBody.Destination = new float3(30, 0, 0);
        agentBody.IsStopped = false;
    }
}


//(edit) [BurstCompile]
public partial struct ChickenMovementSystem : ISystem
{
    [BurstCompile]
    public void OnUpdate(ref SystemState state) =>
        new ChickenMovementJob().ScheduleParallel();

}

indeed, less lines x)

shut tendon
#

=> not sure if that's supported

#

but maybe they fixed that

#

last time I checked it wasn't

#

but it was early 1.0

velvet cape
#

it works on editor

shut tendon
#

if it works, then should be fine

velvet cape
#

2022.3.6f1, Entities 1.0.11

shut tendon
#

typeof(AgentBody)

#

also

#

you don't need that

#

query generated automatically resolves everything inside Execute paramters

#

also avoid adding BurstCompile attribute on system struct

#

it makes ilpp run additional processing on each type that has this attribute

#

while ISystem has it's own scan

#

you only need to specify it on OnCreate/OnUpdate/OnDestroy

#

but I'd argue you only want it on OnUpdate, to reduce compilation time

velvet cape
#

ok; but still useful for the jobentity struct ?

shut tendon
#

and you always should burst jobs