Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Creating a job from an interface

Discussion in 'Entity Component System' started by crener, Nov 5, 2020.

  1. crener

    crener

    Joined:
    Aug 29, 2015
    Posts:
    27
    I've written a system that has a lot of jobs and variances in jobs that mean there could potentially be many types of jobs created in a given situation to help with this I made a big ExtractJob extension method which correctly determines and initialises the correct job and returns it. Now that was fine which writing unit test cause I could use
    .Execute()
    to run it on the test thread.

    Now in my stupidity I actually wanted to Schedule a Job and realised that because structs are a value type and I return and interface I can't actually ever schedule a job without manually creating giant duplicated blocks of code all over the place because I rely on returning an interface which can't be scheduled because C# doesn't have a way to restrict an interface to a Job.

    Example:
    Code (CSharp):
    1. public IAwesomeJob : IJob
    2. {
    3.     float Data {get; set;}
    4. }
    5.  
    6. public interface IJobProvider
    7. {
    8.     // great but because of the interface useless in the job system as it can't be scheduled
    9.     IAwesomeJob Job {get;}
    10. }
    Has anyone had a similar issue and what was the solution?
     
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,983
    This isn't directly addressing the problem but moreso attacking the issue from a different angle:
    https://github.com/Dreaming381/BurstGenericsTest

    In this example, a method returns a generic configuration struct which has nested job types of the various possible jobs. It then uses a specialized scheduling method to create the actual job struct from the config data and schedule it or run it. (In the repo I only implemented Run() but scheduling works too.)

    An additional benefit to this approach is that it avoids boxing the value type to an interface, so you don't have GC and everything can stay on the stack. This is one of my real-world use cases:
    Config: https://github.com/Dreaming381/lsss...hysics/Utilities/Queries/Physics.FindPairs.cs
    Jobs: https://github.com/Dreaming381/lsss...Physics/Internal/Queries/FindPairsInternal.cs
     
  3. crener

    crener

    Joined:
    Aug 29, 2015
    Posts:
    27
    Hmm that's interesting and defiantly useful for future reference but I don't think it fixes my issue (directly).

    I've had the weekend to think about it and I'm fundamentally trying to fight the language because the way that interfaces are setup in C# means that there can never be a guarantee that an interface implementation is a struct. If your curious this is the bit of code that is causing the issue because it returns the interface. I don't think that generics would help either as that would mean I need to know the type beforehand.

    That generics example did give me an idea though. In my case I'm basically just wrapping a switch statement to create a struct given a single enum value (more or less) so I should be able to make a 'dynamic' job of sorts which changes code paths part way through execution based on the enum value. It won't give the 100% best performance because there is still a bunch of statements to check before calculating the actual value can begin but it should be enough to start using the job system more while I think of a better solution...
     
    Last edited: Nov 9, 2020
  4. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,983
    The reason you are struggling so much is because what you are doing has the fundamental issue of boxing structs and generating GC. Returning an interface that is a struct boxes it. I would really encourage you to rethink your design.

    Probably the simplest remedy would be to return a struct containing all possible job types with only the necessary one implemented, and expose scheduling methods which schedule the correct job internally.
     
    Nyanpas likes this.