示例#1
0
        // For convenience, this call has all of the parameters as the main call, except the jobIdToUnPauseWhenDone parameter, which is set automatically
        // This method is really "Start a new job, and if it does not complete immediately, pause the calling job, and register that it will be un-paused when the new job completes"
        public uint StartJobAndPause
        (
            IEnumerator job,
            OnJobCompletionHandler completionHandler     = null,
            OnJobCancellationHandler cancellationHandler = null,
            string jobName            = "",
            List <uint> dependentJobs = null,
            float timeoutTime         = Single.MaxValue,
            int maxExecutionsPerFrame = Int32.MaxValue,
            bool canSkipFrames        = false,
            bool startImmediately     = false
        )
        {
            if (CurrentlyRunningJobId == UInt32.MaxValue)
            {
                throw new Exception("JobManager:  Call to StartJobAndPause received from code that is not a job");
            }

            var id = StartJob(job, completionHandler, cancellationHandler, jobName, dependentJobs,
                              timeoutTime, maxExecutionsPerFrame, canSkipFrames, startImmediately, CurrentlyRunningJobId);

            if (RegisteredJobs.ContainsKey(id)) // If the job has not already finished
            {
                PauseJob(CurrentlyRunningJobId);
            }

            return(id);
        }
示例#2
0
        public uint StartJob
        (
            IEnumerator job,
            OnJobCompletionHandler completionHandler     = null,
            OnJobCancellationHandler cancellationHandler = null,
            string jobName              = "",
            List <uint> dependentJobs   = null,
            float timeoutTime           = Single.MaxValue,
            int maxExecutionsPerFrame   = Int32.MaxValue,
            bool canSkipFrames          = false,
            bool startImmediately       = false, // Note that if startImmediately is set to true, the time budgeting for the current frame might be thrown off
            uint jobIdToUnPauseWhenDone = UInt32.MaxValue
        )
        {
            uint id = NextUid++;

            if (jobName.Equals(""))
            {
                jobName = "(unnamed)";
            }

            RegisteredJobs[id] = new Job();  // Add to the list of registered jobs PRIOR to launching the coroutine, since the job might finish immediately

            var jobEntry = RegisteredJobs[id];

            jobEntry.Coroutine              = null;
            jobEntry.JobCompletionHandler   = completionHandler;
            jobEntry.JobCancellationHandler = cancellationHandler;
            jobEntry.Name = jobName;
            if (dependentJobs == null)
            {
                jobEntry.DependentJobs = new List <uint>( ); // This is because we can't pass a non-null default item as a function parameter above if the item is a reference
            }
            else
            {
                // This rule (dependent jobs must have been registered prior to the dependee) prevents circularity
                if (dependentJobs.Any(jobId => jobId >= id))
                {
                    throw new Exception("JobManager:  Error starting job \"" + jobName + "\"; invalid dependent job ID (must be a job that has already been started)");
                }

                jobEntry.DependentJobs = dependentJobs;

                // For all the dependent jobs, ensure they can't skip frames (that could cause a lockup)
                foreach (var jobId in dependentJobs)
                {
                    if (RegisteredJobs.ContainsKey(jobId))
                    {
                        RegisteredJobs[jobId].CanSkipFrames = false;
                    }
                }
            }
            jobEntry.TimeoutTimeInTicks     = (timeoutTime > 1e20f ? Int64.MaxValue : Stopwatch.Frequency * (long)timeoutTime);
            jobEntry.MaxExecutionsPerFrame  = maxExecutionsPerFrame;
            jobEntry.CanSkipFrames          = canSkipFrames;
            jobEntry.JobIdToUnPauseWhenDone = jobIdToUnPauseWhenDone;

            jobEntry.State        = JobState.Running;
            jobEntry.FinishJobNow = false;

            var coroutine = StartCoroutine(RunJob(id, job, startImmediately));

            // Now that we have a reference to the coroutine, we can save it in the dictionary.  However the job may have ran
            // and immediately finished by the time we get here, so in that case the registered item has already been removed.
            if (RegisteredJobs.ContainsKey(id))
            {
                RegisteredJobs[id].Coroutine = coroutine;
            }

            return(id);
        }