Currently stumped with “Compilation was requested for method…” warning. It’s annoying because it pauses the editor when playing right after compilation. I usually solve this using RegisterGenericJobType, but now it’s not working. Maybe I miss something so I need a new set of eyes. This is the whole warning that stops the editor:
Compilation was requested for method `BovineLabs.Event.Jobs.JobEvent+JobEventProducer`2[[Game.BaseLabelingSystem`3+ReaderJob[[Game.WorkerReachabilityLabel, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null],
[Game.WorkerReachabilityLabelingStrategy, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null],
[Game.MarkWorkerReachabilityLabelAsDirty, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]],
Game.CoreGlue, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null],
[Game.MarkWorkerReachabilityLabelAsDirty, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]],
BovineLabs.Event, Version=0.0.0.0, Culture=neutral,
PublicKeyToken=null::Execute(BovineLabs.Event.Jobs.JobEvent+JobEventProducer`2[[Game.BaseLabelingSystem`3+ReaderJob[[Game.WorkerReachabilityLabel, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null],
[Game.WorkerReachabilityLabelingStrategy, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null],
[Game.MarkWorkerReachabilityLabelAsDirty, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], Game.CoreGlue, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null],
[Game.MarkWorkerReachabilityLabelAsDirty, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]&, BovineLabs.Event,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.IntPtr, mscorlib,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.IntPtr, mscorlib,Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089|Unity.Jobs.LowLevel.Unsafe.JobRanges&, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral,
PublicKeyToken=null|System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)` but it is not a known
Burst entry point. This may be because the [BurstCompile] method is defined in a generic class, and the generic class is not
instantiated with concrete types anywhere in your code.
The code are the following. I omitted most of it for brevity. I only added the important stuff. This is the base system class:
public abstract partial class EventReaderSystem<TJob, TData> : JobSystemBase
where TJob : struct, IJobEvent<TData>
where TData : unmanaged {
private GameEventSystem? eventSystem;
protected override void OnCreate() {
this.eventSystem = this.World.GetOrCreateSystemManaged<GameEventSystem>();
}
protected override JobHandle OnUpdate(JobHandle inputDeps) {
TJob job = PrepareJob();
JobHandle handle = job.Schedule<TJob, TData>(this.eventSystem, inputDeps);
...
return handle;
}
protected abstract TJob PrepareJob();
}
This is another generic system class that is a child class of EventReaderSystem:
public abstract partial class BaseLabelingSystem<TLabel, TLabelingStrategy, TMarkDirtyEvent> :
EventReaderSystem<BaseLabelingSystem<TLabel, TLabelingStrategy, TMarkDirtyEvent>.ReaderJob, TMarkDirtyEvent>
where TLabel : unmanaged, IComponentData, ITileLabel
where TLabelingStrategy : unmanaged, ITileLabelingStrategy
where TMarkDirtyEvent : unmanaged {
private GameEventSystem? eventSystem;
private FloodFiller<TLabel, TLabelingStrategy> floodFiller;
private NativeCounter dirtyCounter;
protected override void OnCreate() {
base.OnCreate();
this.eventSystem = GetOrCreateSystemManaged<GameEventSystem>();
this.floodFiller =
new FloodFiller<TLabel, TLabelingStrategy>(PROCESS_COUNT_PER_FRAME, Allocator.Persistent);
this.dirtyCounter = new NativeCounter(Allocator.Persistent);
}
protected override void OnDestroy() {
base.OnDestroy();
this.floodFiller.Dispose();
this.dirtyCounter.Dispose();
}
protected override ReaderJob PrepareJob() {
return new ReaderJob() {
dirtyCounter = this.dirtyCounter
};
}
protected override JobHandle OnUpdate(JobHandle inputDeps) {
JobHandle handle = base.OnUpdate(inputDeps);
UpdateFloodFillerJob job = new() {
allTiles = GetComponentLookup<Tile>(),
allLabels = GetComponentLookup<TLabel>(),
strategy = PrepareStrategy(),
floodFiller = this.floodFiller
};
handle = job.Schedule(inputDeps);
return handle;
}
protected abstract TLabelingStrategy PrepareStrategy();
[BurstCompile]
public struct UpdateFloodFillerJob : IJob {
...
}
[BurstCompile]
public struct ReaderJob : IJobEvent<TMarkDirtyEvent> {
...
}
}
A concrete implementation of BaseLabelingSystem is done like this:
public partial class WorkerReachabilityLabelingSystem : BaseLabelingSystem<WorkerReachabilityLabel,
WorkerReachabilityLabelingStrategy, MarkWorkerReachabilityLabelAsDirty> {
private MultipleGrid2dSystem? gridSystem;
protected override void OnCreate() {
base.OnCreate();
this.gridSystem = GetOrCreateSystemManaged<MultipleGrid2dSystem>();
}
protected override WorkerReachabilityLabelingStrategy PrepareStrategy() {
return new WorkerReachabilityLabelingStrategy() {
grid = this.gridSystem.GridWrapper,
allTiles = GetComponentLookup<Tile>()
};
}
}
The code where the warning is issued is the JobEventProducer.Execute() here. JobEvent.Schedule() is the one called when scheduling jobs of type IJobEvent. (I’m using an old version of BovineLabs Event system).
[JobProducerType(typeof(JobEvent.JobEventProducer<,>))]
public interface IJobEvent<T> {
void Execute(T parameter);
}
public static class JobEvent {
public static JobHandle Schedule<TJob, T>(this TJob jobData, EventSystemBase eventSystem,
JobHandle dependsOn = default)
where TJob : struct, IJobEvent<T>
where T : unmanaged {
return ScheduleInternal<TJob, T>(jobData, eventSystem, dependsOn, false);
}
private static unsafe JobHandle ScheduleInternal<TJob, T>(this TJob jobData, EventSystemBase eventSystem,
JobHandle dependsOn, bool isParallel)
where TJob : struct, IJobEvent<T>
where T : unmanaged {
dependsOn = eventSystem.GetEventReaders<T>(dependsOn, out IReadOnlyList<NativeEventStream.Reader> events);
for (int i = 0; i < events.Count; i++) {
NativeEventStream.Reader reader = events[i];
JobEventProducer<TJob, T> fullData = new JobEventProducer<TJob, T> {
Reader = reader, JobData = jobData, IsParallel = isParallel
};
#if UNITY_2020_2_OR_NEWER
const ScheduleMode scheduleMode = ScheduleMode.Parallel;
#else
const ScheduleMode scheduleMode = ScheduleMode.Batched;
#endif
JobsUtility.JobScheduleParameters scheduleParams = new JobsUtility.JobScheduleParameters(
UnsafeUtility.AddressOf(ref fullData),
isParallel ? JobEventProducer<TJob, T>.InitializeParallel() :
JobEventProducer<TJob, T>.InitializeSingle(), dependsOn, scheduleMode);
dependsOn = isParallel ? JobsUtility.ScheduleParallelFor(ref scheduleParams, reader.ForEachCount, 1) :
JobsUtility.Schedule(ref scheduleParams);
}
eventSystem.AddJobHandleForConsumer<T>(dependsOn);
return dependsOn;
}
public struct JobEventProducer<TJob, T>
where TJob : struct, IJobEvent<T>
where T : unmanaged {
...
private delegate void ExecuteJobFunction(ref JobEventProducer<TJob, T> fullData, IntPtr additionalPtr,
IntPtr bufferRangePatchData, ref JobRanges ranges, int jobIndex);
public static IntPtr InitializeSingle() {
...
}
public static void Execute(ref JobEventProducer<TJob, T> fullData, IntPtr additionalPtr,
IntPtr bufferRangePatchData, ref JobRanges ranges, int jobIndex) {
while (true) {
int begin = 0;
int end = fullData.Reader.ForEachCount;
// If we are running the job in parallel, steal some work.
if (fullData.IsParallel) {
if (!JobsUtility.GetWorkStealingRange(ref ranges, jobIndex, out begin, out end)) {
return;
}
}
for (int i = begin; i < end; i++) {
int count = fullData.Reader.BeginForEachIndex(i);
for (int j = 0; j < count; j++) {
T e = fullData.Reader.Read<T>();
fullData.JobData.Execute(e);
}
fullData.Reader.EndForEachIndex();
}
if (!fullData.IsParallel) {
break;
}
}
}
}
}
I only see two relevant generic jobs:
- BaseLabelingSystem.UpdateFloodFillerJob
- BaseLabelingSystem.ReaderJob
So in my AssemblyInfo, I have this:
[assembly: RegisterGenericJobType(typeof(BaseLabelingSystem<WorkerReachabilityLabel, WorkerReachabilityLabelingStrategy, MarkWorkerReachabilityLabelAsDirty>.ReaderJob))]
[assembly: RegisterGenericJobType(typeof(BaseLabelingSystem<WorkerReachabilityLabel, WorkerReachabilityLabelingStrategy, MarkWorkerReachabilityLabelAsDirty>.UpdateFloodFillerJob))]
From here, I don’t know what else to add in AssemblyInfo. There are no generic components and RegisterGenericSystemType only works with struct systems.
Any ideas?