NAK_CVR_Mods/BetterContentLoading/DownloadManager2/DownloadManager.Queue.cs

80 lines
No EOL
2.4 KiB
C#

using ABI_RC.Core.IO;
namespace NAK.BetterContentLoading;
public partial class DownloadManager2
{
public void QueueDownload(DownloadTask2 newTask2)
{
if (_completedDownloads.TryGetValue(newTask2.Info.DownloadId, out var completedTask))
{
completedTask.AddPlayer(newTask2.PlayerIds.FirstOrDefault());
return;
}
if (TryFindTask(newTask2.Info.DownloadId, out var existingTask))
{
existingTask.AddPlayer(newTask2.PlayerIds.FirstOrDefault());
RecalculatePriority(existingTask);
return;
}
float priority = CalculatePriority(newTask2);
newTask2.CurrentPriority = priority;
lock (_downloadLock)
{
if (_activeDownloads.Count < MaxConcurrentDownloads)
{
StartDownload(newTask2);
return;
}
var lowestPriorityTask = _activeDownloads.Values
.OrderByDescending(t => t.CurrentPriority * (1 + t.Progress / 100f))
.LastOrDefault();
if (lowestPriorityTask != null && priority < lowestPriorityTask.CurrentPriority)
{
PauseDownload(lowestPriorityTask);
StartDownload(newTask2);
}
else
{
_queuedDownloads.Enqueue(newTask2, priority);
}
}
}
private void StartDownload(DownloadTask2 task2)
{
task2.Status = DownloadTaskStatus.Downloading;
_activeDownloads.TryAdd(task2.Info.DownloadId, task2);
Task.Run(() => ProcessDownload(task2));
}
private void PauseDownload(DownloadTask2 task2)
{
task2.Status = DownloadTaskStatus.Queued;
_activeDownloads.TryRemove(task2.Info.DownloadId, out _);
_queuedDownloads.Enqueue(task2, task2.CurrentPriority);
}
private void RecalculatePriority(DownloadTask2 task2)
{
var newPriority = CalculatePriority(task2);
if (Math.Abs(newPriority - task2.CurrentPriority) < float.Epsilon)
return;
task2.CurrentPriority = newPriority;
if (task2.Status == DownloadTaskStatus.Queued || task2.Status == DownloadTaskStatus.Paused)
{
// Re-enqueue with new priority
_queuedDownloads.UpdatePriority(task2, newPriority);
}
}
}