Is there any way to RequireNoneForUpdate?

Wondering if there is a way to do RequireNoneForUpdate in a system?

I could always add a dummy component to some entity then delete that entity, but I would need to create a new type or every instance or sling it onto another entity with a type that I care about.
It’s also sorta defeats the purpose.

The use case is a system that only ever runs the once to do some initialization.

Just put EntityQuery with None to RequireForUpdate.

Before posting I did try this:

var query = new EntityQueryDescBuilder();
query.AddNone(typeof(ClientID));
query.FinalizeQuery();
RequireForUpdate(EntityManager.CreateEntityQuery(query));

But got some strange errors, so I just assumed I misunderstood the purpose of this API.

After actually reading the manual here https://docs.unity3d.com/Packages/com.unity.entities@0.50/manual/ecs_entity_query.html
I tried this:

var query = new EntityQueryDesc
{
    None = new ComponentType[] { typeof(ClientID) }
};
RequireForUpdate(GetEntityQuery(query));

Which runs without errors but doesn’t do what I need.

After looking into the source code, I’m not actually sure it’s possible…

In class SystemState it has the follow method which checks if a system can run

internal bool ShouldRunSystem()
{
    if (AlwaysUpdateSystem)
        return true;

    ref var required = ref RequiredEntityQueries;

    if (required.Length > 0)
    {
        for (int i = 0; i != required.Length; i++)
        {
            EntityQuery query = required[i];
            if (query.IsEmptyIgnoreFilter)
                return false;
        }

        return true;
    }
...

Here it requires that the EntityQuery must match some entities to pass.
What I’m looking for is that is matches no entities.

@eizenhorn I believe your suggestion would only check that there is at least one entity that does not have the component.

If you use default bootstrap then there always will be entities (world time for example). But anyway, if you want use your system only once for data initialisation you can just mark system as always update, in OnUpdate check your condition (there is no entities with component you interested in) and the disable that system (Enabled property)

1 Like

Doh, dunno why I didn’t think of the Enabled property!

It would be great if RequireForUpdate honored the state of Enableable components in an EntityQuery. Setting a system as disabled means managing the state of a bunch of init systems when you want to init again, unless I’m missing something?

You really don’t want this as it would require a sync point.

Enable states can be changed in a job therefore you would need to complete all jobs in the chain that could possibly edit the enable state before you can determine if the system should run on main thread.

1 Like

Thanks for clarifying the context. So from your experience, is there a best standard workflow for initializing data after baking? I have been mulling a couple of strategies:

  • Accept the one-time structural change of removing a “RequiresInit” tag, or something similar, from an entity that requires initialization.
  • Disable the init system after first run; fetch it via handle later should it need to be reenabled (restarting, respawning, instantiating new entities that need init, etc).
  • Something else?