Open Search
    JobInterface Class Reference

    #include <job.h>

    Inheritance diagram for JobInterface:

    Detailed Description

    A job is a threaded entity that can be enqueued or added to a group. A JobRef is similar to a ThreadRef but all jobs on the same queue (JobQueueRef) share a set of worker threads whereas each ThreadRef has its own private thread.

    Once a job has been enqueued it will be executed as soon as a worker thread of the specified queue is available. In general jobs must be independent of each other. The order and timing of the execution as well as the chosen worker thread are completely up to the job system. It keeps the worker threads as busy as possible until a queue is (temporarily) empty.

    One way to create a job is to inherit from JobInterface/JobInterfaceTemplate and to implement operator (), for example

    class MyJob : public JobInterfaceTemplate<MyJob>
    {
    public:
    Result<void> operator ()()
    {
    ... your code goes here ...
    }
    };

    A job is reference counted. A typical application might involve creating a job with Create() (or NewObj) and enqueueing it. Your job will automatically be deleted once it is not referenced anymore. The same applies to jobs that are added to a group.

    Instead of creating an object that is derived from JobInterface you may also enqueue a lambda expression which can have the advantage of writing code that is easier to manage because the parallelized tasks appear in sequential order in the source code.

    if (doSomethingThatTakesAWhile)
    {
    []()
    {
    ... your parallel code goes here ...
    }
    JobRef & Enqueue(JobQueueInterface *queue=JOBQUEUE_CURRENT)
    Definition: job.h:1369
    #define iferr_return
    Definition: resultbase.h:1521

    Jobs are not allowed to sleep at all. They may only wait for jobs or groups they have created and enqueued (otherwise this would easily dead-lock). See Wait() or GetResult() for more details.

    Note
    By default the job system assumes that all jobs of a group share the same dependencies (because they operate on the same data) and single jobs share dependencies when they use the same code (again because they likely use the same data). Furthermore jobs enqueued to the main thread queue are assumed to have a UI dependency by default. For the unlikely case of requiring custom dependencies const JobDependencyGroupInterface* GetDependencyGroup() const can be implemented by your jobs to return a shared dependency group.
    class AJobWithCustomDependencies : public JobInterfaceTemplate<AJobWithCustomDependencies>
    {
    public:
    Result<void> operator ()() { ... }
    const JobDependencyGroupInterface* GetDependencyGroup() const { return g_mySharedDependencies; }
    };

    Public Member Functions

    JOBOPTIONFLAGS GetJobOptions () const
     
    const CharGetName () const
     
     JobInterface (const JobInterfaceJumpTablePOD &jmpTable)
     
     ~JobInterface () override
     
     JobInterface (JobInterface &&src)
     
    JobInterfaceoperator= (JobInterface &&src)
     
    Bool Wait (TimeValue timeout=TIMEVALUE_INFINITE, WAITMODE mode=WAITMODE::DEFAULT) const
     
    Result< void > GetResult (TimeValue timeout=TIMEVALUE_INFINITE, WAITMODE mode=WAITMODE::DEFAULT) const
     
    Result< void > MoveResult (TimeValue timeout=TIMEVALUE_INFINITE, WAITMODE mode=WAITMODE::DEFAULT)
     
    void Cancel ()
     
    Bool IsCancelled () const
     
    void CancelAndWait (WAITMODE mode=WAITMODE::DEFAULT)
     
    JobInterfaceEnqueue (JobQueueInterface *queue=JOBQUEUE_CURRENT)
     
    Result< void > AddSubJob (JobInterface *subJob)
     
    template<typename JOB >
    Result< void > AddSubJob (ResultMemT< JOB * > subJob)
     
    template<typename JOBREF >
    Result< void > AddSubJob (ResultMemT< JOBREF > &&subJob)
     
    template<typename GROUP >
    Result< void > AddSubGroup (GROUP *subGroup)
     
    template<typename GROUP >
    Result< void > AddSubGroup (ResultMemT< GROUP * > subGroup)
     
    template<typename GROUP >
    Result< void > AddSubGroup (ResultMemT< GROUP > subGroup)
     
    JobGroupInterfaceGetJobGroup () const
     
    ObservableFinishedBase< JobInterfaceObservableFinished ()
     
    ObservableCancelledBase< JobInterfaceObservableCancelled ()
     
    Result< void > Then (JobInterface *next, JobQueueInterface *queue=JOBQUEUE_CURRENT)
     
    String ToString (const FormatStatement *formatStatement=nullptr) const
     

    Static Public Member Functions

    template<JOBCANCELLATION B = JOBCANCELLATION::AUTOMATIC, typename FN , typename... ARGS>
    static ResultMemT< JobInterface * > Create (FN &&src, ARGS &&... args)
     
    static Int GetCurrentWorkerThreadIndex ()
     
    static Int GetCurrentThreadCount ()
     
    static Bool IsCurrentJobCancelled (const JobInterface *optionalJob=nullptr)
     
    static JobStatusInterfaceGetCurrentJob ()
     

    Private Member Functions

     MAXON_DISALLOW_COPY_AND_ASSIGN (JobInterface)
     

    Static Private Member Functions

    template<typename IMPLEMENTATION >
    static IMPLEMENTATION & GetWorker (const JobInterface *job)
     
    template<typename IMPLEMENTATION , Bool USE_VIRTUAL_DESTRUCTOR>
    static void * DestructWorker (const JobInterface *self)
     
    template<typename IMPLEMENTATION >
    static const ErrorInterfaceRunWorker (const JobInterface *job)
     
    template<typename T >
    static const JobDependencyGroupInterface * GetWorkerDependencyGroupImpl (const JobInterface *job, std::false_type *)
     
    template<typename T >
    static const JobDependencyGroupInterface * GetWorkerDependencyGroupImpl (const JobInterface *job, std::true_type *)
     
    template<typename IMPLEMENTATION >
    static const JobDependencyGroupInterface * GetWorkerDependencyGroup (const JobInterface *job)
     
    template<typename IMPLEMENTATION >
    static void * GetWorkerOptions (const JobInterface *self, Int selector, void *param)
     
    static CoreJobGroup & GetCoreJobGroup (JobGroupInterface *group)
     
    template<JOBCANCELLATION B, typename FN , typename... ARGS>
    static ResultPtr< JobInterfaceCreateJob (FN &&src, ARGS &&... args)
     

    Friends

    class StrongRefHandler
     
    template<typename >
    struct ObservableFinishedBase
     
    template<typename >
    struct ObservableCancelledBase
     
    class JobStatusInterface
     
    class JobGroupInterface
     
    template<typename >
    class StaticJobGroupInterface
     
    class TimerInterface
     
    template<typename FN >
    auto ExecuteOnMainThread (FN &&fn, WAITMODE waitMode, TimeValue wait) -> decltype(fn())