private void Run() { _isRunning = true; #if DEBUG Started?.Invoke(this, EventArgs.Empty); #endif while (!_terminated) { long elapsedMilliseconds = Interlocked.Exchange(ref _uiElapsedMilliseconds, 0); // Perform a simulation tick if (elapsedMilliseconds > 0) { IMap map = _mapProvider.Current(); _actors.SimulationUpdate(map); } _gate.WaitOne(); } _isRunning = false; #if DEBUG Stopped?.Invoke(this, EventArgs.Empty); #endif }
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 }