private void StartPathing(IMap map, Job job, IJobFit[] fits) { #if DEBUG Debug.WriteLine("JobManager:StartPathing"); #endif if (fits.Length > _foundRoutes.Length) { _foundRoutes = new Route[fits.Length]; _fitness = new int[fits.Length]; } _pendingRoutes = fits.Length; for (int i = 0; i < fits.Length; i++) { IJobFit fit = fits[i]; Activity activity = job.Activities[0]; ActivityStep step = activity.Steps[0]; ref MapCell location = ref map.GetCell(fit.LocationColumn, fit.LocationRow); ref MapCell target = ref map.GetCell(step.Column, step.Row);
private void Run() { _isRunning = true; #if DEBUG Started?.Invoke(this, EventArgs.Empty); #endif while (!_terminated) { Job?job = GetNextJob(); while (job != default) { IMap map = _mapProvider.Current(); // All the people available to handle the job IJobFit[] fits = _jobFitProvider.GetAvailable(); // Of those, the people who could possibly handle the job // (ie - has the right skill) fits = FilterSuitable(job, fits); if (fits.Length == 0) { // No one available to handle the job // Re-queue it and leave AddJob(job); break; } // Now we calculate the distance to the job for everyone // left, eventually blocking until the pathing is complete. StartPathing(map, job, fits); // Non-path fitness is "suitability" for the job. ie - Those // with higher skills are more fit than those with lower skills. CalculateNonPathFit(job, fits); while (!PathingComplete() && !_terminated) { _gate.WaitOne(); } IJobFit handler = fits[FindJobFit(fits)]; if (handler == default(IJobFit)) { // We couldn't find a handler for this job so we should // put it in the blocked jobs to be re-queued periodically // TODO: create a blocked job queue } else { Job?oldJob = handler.AssignJob(job); if (oldJob != default) { // We assigned them a new job before they started the // old one, so requeue this one AddJob(oldJob); } } if (!_terminated) { ClearFoundRoutes(); job = GetNextJob(); } else { job = default; } } if (!_terminated) { _gate.WaitOne(1000); // Automatically unlock after 1s just in case } } _isRunning = false; #if DEBUG Stopped?.Invoke(this, EventArgs.Empty); #endif }