#[BUG] WithAny doesn't add dependencies to system

1 messages · Page 1 of 1 (latest)

fringe vector
#

Changed my query from WithAll to WithAny and instantly ran into safety violations.

            query = new EntityQueryBuilder(Allocator.Temp)
                .WithAny<InitializeEntity, InitializeSubSceneEntity>()
                .WithAll<NavMeshSurface>()
                .WithAllRW<WorldReference>()
                .Build(ref state);```
A quick break point in AddReaderWritersToLists and can clearly see it's not not adding the WithAny components
(Note they are IEnableable, probably related)
@rigid nest because I think I've pinged you about query stuff before.
#
InvalidOperationException: The previously scheduled job NavMeshInitializeSystem:NewSurfaceJob reads from the ComponentTypeHandle<BovineLabs.Core.LifeCycle.InitializeEntity> NewSurfaceJob.safety. You are trying to schedule a new job InitializeEntitySystem:MarkInitializedJob, which writes to the same ComponentTypeHandle<BovineLabs.Core.LifeCycle.InitializeEntity> (via MarkInitializedJob.JobData.__TypeHandle.__BovineLabs_Core_LifeCycle_InitializeEntity_RW_ComponentTypeHandle). To guarantee safety, you must include NavMeshInitializeSystem:NewSurfaceJob as a dependency of the newly scheduled job.```
#

causing me access violations

#

because I have a job that i change the enable state of this component EnabledRefRW<InitializeEntity>

#

yeah it only uses components from CalculateRequiredComponentsFromQuery

fringe vector
#

OK so I wrote myself a patch
I had some surprising trouble fixing this in the actual create entity query part so instead I just patched the AddReaderWritersToLists method like so:
-edit- git history overwritten, read below for update

#

hopefully I haven't overlooked something, but it seemed the safest way for a local patch as it touched the least

fringe vector
#

I've just woken up and realised my patch only needs to add ienableable from any because if you actually accessed the any component you would have a type handle which would have added the dependency

#

It's just entity query filtering doesn't actually need a type handle so it's never added

fringe vector
#

Because I'm about to override the git history so above link will be invalid, just in case anyone reads this what I previously did was

            for (var i = 0; i < _QueryData->ArchetypeQueryCount; i++)
            {
                for (var j = 0; j < _QueryData->ArchetypeQueries[i].AnyCount; j++)
                {
                    var type = _QueryData->ArchetypeQueries[i].Any[j];

                    if (type.IsZeroSized && !type.IsEnableable)
                    {
                        continue;
                    }

                    var accessMode = (ComponentType.AccessMode)this._QueryData->ArchetypeQueries[i].AnyAccessMode[j];
                    switch (accessMode)
                    {
                        case ComponentType.AccessMode.ReadOnly:
                            anyAdded |= CalculateReaderWriterDependency.AddReaderTypeIndex(type, ref reading, ref writing);
                            break;
                        case ComponentType.AccessMode.ReadWrite:
                            anyAdded |= CalculateReaderWriterDependency.AddWriterTypeIndex(type, ref reading, ref writing);
                            break;
                    }
                }
            }```
#

but i'm simplying it down to just this

            for (var i = 0; i < _QueryData->ArchetypeQueryCount; i++)
            {
                for (var j = 0; j < _QueryData->ArchetypeQueries[i].AnyCount; j++)
                {
                    if (!_QueryData->ArchetypeQueries[i].Any[j].IsEnableable)
                    {
                        continue;
                    }

                    anyAdded |= CalculateReaderWriterDependency.AddReaderTypeIndex(_QueryData->ArchetypeQueries[i].Any[j], ref reading, ref writing);
                }
            }```
rigid nest
#

To make sure I understand the problem: you have a query in a system using WithAny<A,B>() where either/both of the types are IEnableable. The types are only used to limit the query results, and are not explicitly read or written by the system or any of its jobs (otherwise, the system would have to create a TypeHandle for them, and they'd be registered as read/write types on those grounds). However, evaluating the query implicitly reads the enabled bits for the Any types, and since the system hadn't registered the type, you get a safety error about earlier jobs that write to the enableable types which may still be running. Is that correct?

fringe vector
#

Yep that sums it up

rigid nest
#

Excellent. This should be the last of these gaps then; WithDisabled and WithAll are already handled because they actually require the underlying types, WithPresent and WithAbsent ignore enabled bits by definition, and WithNone was fixed after your previous report. Thanks!

rigid nest
#

I'm currently making the fix in EntityQueryManager.InitializeReaderWriter() (where the query's list of reader/writer types are first allocated and populated at query creation time), not in AddReaderWritersToLists (where the query's types are added to a system). Is there a reason I'm not seeing to prefer the latter over the former?

fringe vector
#

The later was just my final hack fix, it definitely didn't feel like the right place

#

I just failed in my first attempt as I tried to modify required components but then realised these aren't actually required so wasn't sure how to correctly handle them being optional