#Scheduling IJobEntity inside of a public static method breaks CodeGen

1 messages · Page 1 of 1 (latest)

twin mulch
#

This error happens during runtime. I have helper methods that schedule jobs.

Exception: This method should have been replaced by source gen.
Collapse.Actor.Engine.StallExecutor.Update (Collapse.Actor.Engine.ActorEngineOrchestratorSystem orchestrator, Unity.Jobs.JobHandle inputDeps) (at Assets/Collapse/Script/Actor/Engine/Behavior/Stall/Stall.cs:20)
Collapse.Actor.Engine.ActorEngineOrchestratorSystem.OnUpdate () (at Assets/Collapse/Script/Actor/Engine/ActorEngineOrchestrator.cs:31)
Unity.Entities.SystemBase.Update () (at ./Library/PackageCache/com.unity.entities@1.0.0-pre.15/Unity.Entities/SystemBase.cs:428)
Unity.Entities.ComponentSystemGroup.UpdateAllSystems () (at ./Library/PackageCache/com.unity.entities@1.0.0-pre.15/Unity.Entities/ComponentSystemGroup.cs:670)
UnityEngine.Debug:LogException(Exception)
Unity.Debug:LogException(Exception) (at ./Library/PackageCache/com.unity.entities@1.0.0-pre.15/Unity.Entities/Stubs/Unity/Debug.cs:19)
Unity.Entities.ComponentSystemGroup:UpdateAllSystems() (at ./Library/PackageCache/com.unity.entities@1.0.0-pre.15/Unity.Entities/ComponentSystemGroup.cs:675)
Unity.Entities.ComponentSystemGroup:OnUpdate() (at ./Library/PackageCache/com.unity.entities@1.0.0-pre.15/Unity.Entities/ComponentSystemGroup.cs:634)
Unity.Entities.SystemBase:Update() (at ./Library/PackageCache/com.unity.entities@1.0.0-pre.15/Unity.Entities/SystemBase.cs:416)
Unity.Entities.ComponentSystemGroup:UpdateAllSystems() (at ./Library/PackageCache/com.unity.entities@1.0.0-pre.15/Unity.Entities/ComponentSystemGroup.cs:670)
Unity.Entities.ComponentSystemGroup:OnUpdate() (at ./Library/PackageCache/com.unity.entities@1.0.0-pre.15/Unity.Entities/ComponentSystemGroup.cs:628)
Unity.Entities.SystemBase:Update() (at ./Library/PackageCache/com.unity.entities@1.0.0-pre.15/Unity.Entities/SystemBase.cs:416)
Unity.Entities.DummyDelegateWrapper:TriggerUpdate() (at ./Library/PackageCache/com.unity.entities@1.0.0-pre.15/Unity.Entities/ScriptBehaviourUpdateOrder.cs:526)
#

Here's how I schedule it

 public static class StallExecutor
    {
        public static JobHandle Update(ActorEngineOrchestratorSystem orchestrator, JobHandle inputDeps)
        {
            var ecb = orchestrator.BeginUsingCommandBuffer();
            return new StallCancelJob
            {
                ECB = ecb
            }.Schedule(inputDeps);
        }
    }
lusty plover
#

It can't be static since the code-gen doesn't see this as something it needs to add to the calling system

#

It basically has the same limitations as calls to SystemAPI

twin mulch
#

Ok, so make it non-static, make it partial as well?

lusty plover
twin mulch
#

Gotcha

#

So should i do new StallExecutor().Update(...)?

lusty plover
#

I think that should work

#

Not 100% sure though

twin mulch
#

let me try real quick

lusty plover
#

Is there a reason you aren't just creating the job struct directly in the system?

#

(I'm guessing it's the specific usage of an ECB here)

twin mulch
#

It's just for encapsulation purposes

#

All the jobs are scheduled in one orchestrator system

#

But it's up to each job module to host the jobs and scheduling code

#

Hmm, making it an instance method didn't work

lusty plover
#

It throws the same error?

twin mulch
#

yep

#

I'm going to try doing AggressiveInlining

#

see if that tricks the codegen

#

LMAO that just moved the exception stack trace to complaining about the Orchestrator system

#

I really don't want to move all the scheduling code into one big system, but it needs to be scheduled at once

lusty plover
twin mulch
#

Ah, I see. Good catch

lusty plover
#

If you want to ignore code generation in this case you can make these jobs IJobChunk instead of IJobEntity

#

It's more boilerplate though

twin mulch
#

I'm just going to move the scheduling code into helper instance methods inside the orcehstrator system, and use #region to make it less cluttered

#

Would that still work?

lusty plover
#

Yes, but you'd need to manually manage (i.e. update) your ComponentTypeHandles

twin mulch
#

I actualyl use ComponentLookup

lusty plover
#

Actually, it seems that was also replaced by code generation

#

Let me check if I can work around it

twin mulch
#

It's sorta okay, moving the scheduling code into helper instance methods got past the exception. Now I have to do the same to. 30 other jobs 🥲

#

But please lmk if you find a workaround

lusty plover
#

Out of interest, why do you need to schedule them in the same system? Shared resources?

twin mulch
#

Both to reduce the latency of systems just existing, and to enforce order of execution of certain jobs

#

jobs that span multiple domains. For example, StatCompare jobs must go after StatOperation

#

It's too confusing if I put them into multiple systems and add a bunch of UpdateBefore and UpdateAfter

#

If I do it in one place, the execution order/parallelism becomes much clearer

#

Right now the execution looks like this

protected override void OnUpdate()
        {
            var start = Dependency;

            var decisionMakerPath = JobHandleExt.CombineDependencies(
                Stall(start),
                Wait(start),
                DecisionMakerExecutor.Update(this, start),
                DecisionMakerRestartExecutor.Update(this, start),
                DecisionMakerStopSystem.Update(this, start)
            ); ;

            var positionPath = JobHandleExt.CombineDependencies(
                FaceExecutor.Update(this, start),
                FaceAtExecutor.Update(this, start),
                FaceConstantlyExecutor.Update(this, start),
                MoveGroundFreeExecutor.Update(this, start),
                PositionExecutor.Update(this, start)
            );

            var partPath = JobHandleExt.CombineDependencies(
                DiplomacyExecutor.Update(this, start),
                ProximityExecutor.Update(this, start)
            );
            partPath = SearchExecutor.Update(this, partPath);
            partPath = ProximityCountExecutor.Update(this, partPath);
            partPath = JobHandleExt.CombineDependencies(
                StatOperationExecutor.Update(this, partPath),
                TraitToggleExecutor.Update(this, partPath)
            );
            partPath = StatExecutor.Update(this, partPath);
            partPath = JobHandleExt.CombineDependencies(
                StatCompareExecutor.Update(this, partPath),
                TraitMatchExecutor.Update(this, partPath)
            );
            partPath = PartRepositoryClearExecutor.Update(this, partPath);

            Dependency = JobHandleExt.CombineDependencies(
                decisionMakerPath,
                positionPath,
                partPath
            );

            ECBS.AddJobHandleForProducer(Dependency);

            ConstantPrintExecutor.Update(this);
            PrintExecutor.Update(this);
        }
#

Wait and Stall have already been replaced

lusty plover
#

Alright, I don't have any job dependencies that are this complex. I just try to put the entire logic into a single job and schedule that

#

Using IJobChunk should work though, as the Schedule method doesn't use code generation, but like I mentioned it's more boiler plate

#

You'll basically need to (in part) rewrite all your jobs

#

So probably not worth it

twin mulch
#

I only have 30 jobs. Not much rewriting, just copy and pasting

#

but thanks for your help!

lusty plover
#

Depending on which ComponentTypeHandles were code-generated before it can be a bit of extra code adding those. If all 30 jobs share similar handles it's not too much of a hassle

#

(Especially now that SystemAPI.GetComponentTypeHandle exists)

dull turtle
#

Is there some kind of constraint on where I can define and from where I can call IJobEntity jobs?

I have this exception when calling Run on a job called from a static function in some helper class:
Exception: This method should have been replaced by source gen.