ISystemBase, how do I use it?

I’ve tried this so far:
Code

using Unity.Burst;
using Unity.Collections;
using Unity.Entities;

[assembly: RegisterGenericComponentType(typeof(Edengrall.AI.ReduceSpeed<Food>))]
[assembly: RegisterGenericJobType(typeof(Edengrall.AI.DepleteNeedsSystem<Food>.ExpendJobWith))]
[assembly: RegisterGenericJobType(typeof(Edengrall.AI.DepleteNeedsSystem<Food>.ExpendJobWithout))]
namespace Edengrall.AI {

    public struct ReduceSpeed<T> : IComponentData, AutoSaveIComponentData, IValue<float> where T : struct, IComponentData, AutoSaveIComponentData, IValue<float>, NeedComponent<T> {
        public float Value;
        float IValue<float>.Value { get => Value; set => Value = value; }
    }
    //public static class DepleteNeedsSystemFunctions {
    //    public static void CreateEntityQueries<T>(ref SystemState state, out EntityQuery WithSpeed, out EntityQuery WithoutSpeed) where T : struct, IComponentData, AutoSaveIComponentData, IValue<float>, NeedComponent<T> {
    //    }
    //}
    public struct DepleteNeedsSystem<T> : ISystemBase where T : struct, IComponentData, AutoSaveIComponentData, IValue<float>, NeedComponent<T> {
        private EntityQuery WithSpeed;
        private EntityQuery WithoutSpeed;
        private ExpendJobWith JobExpendJobWith;
        private ExpendJobWithout JobExpendJobWithout;
        public void OnCreate(ref SystemState state) {
            WithSpeed = state.GetEntityQuery(ComponentType.ReadWrite<T>(), ComponentType.Exclude<ReduceSpeed<T>>());
            WithoutSpeed = state.GetEntityQuery(ComponentType.ReadWrite<T>(), ComponentType.ReadOnly<ReduceSpeed<T>>());
            JobExpendJobWith = new ExpendJobWith();
            JobExpendJobWithout = new ExpendJobWithout();
        }
        public struct ExpendJobWith : IJobChunk {
            public ComponentTypeHandle<T> Need;
            [ReadOnly] public ComponentTypeHandle<ReduceSpeed<T>> ReduceSpeed;
            public float Time;
            public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex) {
                var Need = chunk.GetNativeArray(this.Need).Reinterpret<float>();
                var ReduceSpeed = chunk.GetNativeArray(this.ReduceSpeed).Reinterpret<float>();
                for (int i = 0; i < chunk.Count; i++) {
                    if (Need[i] > 0) {
                        Need[i] -= ReduceSpeed[i] * Time;
                        if (Need[i] < 0) {
                            Need[i] = 0;
                        }
                    }
                }
            }
        }
        public struct ExpendJobWithout : IJobChunk {
            public ComponentTypeHandle<T> Need;
            public float Time;
            public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex) {
                var Need = chunk.GetNativeArray(this.Need).Reinterpret<float>();
                for (int i = 0; i < chunk.Count; i++) {
                    if (Need[i] > 0) {
                        Need[i] -= Time;
                        if (Need[i] < 0) {
                            Need[i] = 0;
                        }
                    }
                }
            }
        }

        public void OnDestroy(ref SystemState state) { }

        [BurstCompile]
        public void OnUpdate(ref SystemState state) {
            JobExpendJobWithout.Need = JobExpendJobWith.Need = state.GetComponentTypeHandle<T>();
            JobExpendJobWith.ReduceSpeed = state.GetComponentTypeHandle<ReduceSpeed<T>>();
            state.Dependency = JobExpendJobWith.ScheduleParallel(WithSpeed, JobExpendJobWithout.ScheduleParallel(WithoutSpeed, state.Dependency));
        }
    }
}

Am I doing it wrong? How Wrong? Burst compilation crashed and burned and is now permanently compiling 329/330 functions. I also got this error messasge which might or not might be unrelated:
error

Unexpected exception System.InvalidOperationException: Could not find `burst.initialize` function in library '7FFC1E200000' ---> System.InvalidOperationException: Unable to load function entry `burst.initialize`
  at Burst.Backend.UnmanagedLibrary+WindowsUnmanagedLibrary.GetFunctionByName (System.IntPtr libraryHandle, System.String functionName) [0x00025] in <b2dc5b19d1394c95a1a861711473d7d9>:0
  at Burst.Backend.UnmanagedLibrary.GetFunctionByName (System.IntPtr libraryHandle, System.String functionName) [0x00000] in <b2dc5b19d1394c95a1a861711473d7d9>:0
  at Burst.Compiler.IL.Jit.JitCacheLibraryManager.CallBurstInitializeFunction (System.IntPtr libraryPtr, Burst.Compiler.IL.Jit.GetExternalFunctionPointerDelegate getExternalFunctionPointer) [0x00062] in <f95137a4a8d747bbac814ce8830deb34>:0
   --- End of inner exception stack trace ---
  at Burst.Compiler.IL.Jit.JitCacheLibraryManager.CallBurstInitializeFunction (System.IntPtr libraryPtr, Burst.Compiler.IL.Jit.GetExternalFunctionPointerDelegate getExternalFunctionPointer) [0x000c5] in <f95137a4a8d747bbac814ce8830deb34>:0
  at Burst.Compiler.IL.Jit.JitCacheLibraryManager+<>c__DisplayClass7_2.<TryGetOrLoadLibrary>b__1 () [0x00000] in <f95137a4a8d747bbac814ce8830deb34>:0
  at Burst.Compiler.IL.Jit.JitCacheMethodValue.GetCachedPtrForAssemblies (System.Boolean ensureBurstInitializeHasBeenCalled, System.IntPtr& cachedPtr) [0x0004c] in <f95137a4a8d747bbac814ce8830deb34>:0
  at Burst.Compiler.IL.Jit.JitCompiler.CompileMethods (System.ValueTuple`2[Mono.Cecil.MethodReference,System.String][] methodReferences, Burst.Compiler.IL.Jit.JitOptions jitOptions) [0x002c1] in <f95137a4a8d747bbac814ce8830deb34>:0
  at Burst.Compiler.IL.Jit.JitCompiler.CompileMethod (Mono.Cecil.MethodReference methodReference, System.String methodRefString, Burst.Compiler.IL.Jit.JitOptions jitOptions) [0x0002c] in <f95137a4a8d747bbac814ce8830deb34>:0
  at Burst.Compiler.IL.Jit.JitCompilerService+CompilerThreadContext.Compile (Burst.Compiler.IL.Jit.JitCompilerService+CompileJob job) [0x00464] in <f95137a4a8d747bbac814ce8830deb34>:0

While compiling job: System.Void Unity.Jobs.IJobExtensions/JobStruct`1<FindCloserValue`1/FindCloserValueJob<NPCFaceIcon>>::Execute(T&,System.IntPtr,System.IntPtr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,System.Int32)
at <empty>:line 0

I actually don’t know if it’s a bug or I am doing something completely wrong. Also, shouldn’t there be a [assembly: RegisterGenericSystem(typeof(Edengrall.AI.DepleteNeedsSystem<Food>))]?

AFAIK you can’t have a generic system like that. With managed system that works because you can inherit from it to create the non-generic versions (like FloatSystem : GenericSystem), as struct can’t be inherited then I would assume that this is not supported at all.

1 Like

Besides the ‘generictability’ of the system, it is like that that you use a ISystemBase?
So long I make a ton of versions of it that are not generic, they should work?

Well, it seems you can’t use it yet anyways, accessing it through reflection just gets me “type not registered” error, probably could get away with declaring it before world initialization, but then again it’s too much trouble to use something that is not even ready.
From World.cs

    // TODO: Make methods public once ISystemBase is ready for users
    public static class WorldExtensions
    {
        internal static SystemRef<T> AddSystem<T>(this World self) where T : struct, ISystemBase
        {
            return self.Unmanaged.CreateUnmanagedSystem<T>(self);
        }

        internal static SystemRef<T> GetExistingSystem<T>(this World self) where T : struct, ISystemBase
        {
            return self.Unmanaged.GetExistingUnmanagedSystem<T>();
        }

        internal static SystemRef<T> GetOrCreateSystem<T>(this World self) where T : struct, ISystemBase
        {
            return self.Unmanaged.GetOrCreateUnmanagedSystem<T>(self);
        }

#if !NET_DOTS && !UNITY_DOTSRUNTIME
        internal static SystemHandleUntyped GetOrCreateUnmanagedSystem(this World self, Type unmanagedType)
        {
            return self.Unmanaged.GetOrCreateUnmanagedSystem(self, unmanagedType);
        }
#endif

        internal static void DestroyUnmanagedSystem(this World self, SystemHandleUntyped sysHandle)
        {
            self.Unmanaged.DestroyUnmanagedSystem(sysHandle);
        }
    }
}

Haven’t touched much on ISystemBase, but I would assume that you shouldn’t save state directly on it (i.e. use state.GetEntityQuery inside OnCreate so that it can cache for you, then use state.GetEntityQuery again inside OnUpdate). Again, haven’t touched much, so let me know if you find anything different lol

1 Like

I decided to convert to SystemBase for now, whenever they actually release it I will test again.