Barotrauma Client Doc
TaskPool.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6 
7 namespace Barotrauma
8 {
9  public static class TaskPool
10  {
11  const int MaxTasks = 5000;
12 
13  private struct TaskAction
14  {
15  public string Name;
16  public Task Task;
17  public Action<Task, object> OnCompletion;
18  public object UserData;
19  }
20 
21  private static readonly List<TaskAction> taskActions = new List<TaskAction>();
22 
23  public static void ListTasks()
24  {
25  lock (taskActions)
26  {
27  DebugConsole.NewMessage($"Task count: {taskActions.Count}");
28  for (int i = 0; i < taskActions.Count; i++)
29  {
30  DebugConsole.NewMessage($" -{i}: {taskActions[i].Name}, {taskActions[i].Task.Status}");
31  }
32  }
33  }
34 
35  public static bool IsTaskRunning(string name)
36  {
37  lock (taskActions)
38  {
39  return taskActions.Any(t => t.Name == name);
40  }
41  }
42 
43  private static void AddInternal(string name, Task task, Action<Task, object> onCompletion, object userdata, bool addIfFound = true)
44  {
45  lock (taskActions)
46  {
47  if (!addIfFound)
48  {
49  if (taskActions.Any(t => t.Name == name)) { return; }
50  }
51  if (taskActions.Count >= MaxTasks)
52  {
53  throw new Exception(
54  "Too many tasks in the TaskPool:\n" + string.Join('\n', taskActions.Select(ta => ta.Name))
55  );
56  }
57  taskActions.Add(new TaskAction() { Name = name, Task = task, OnCompletion = onCompletion, UserData = userdata });
58  DebugConsole.Log($"New task: {name} ({taskActions.Count}/{MaxTasks})");
59  }
60  }
61 
62  public static void Add(string name, Task task, Action<Task> onCompletion)
63  {
64  AddInternal(name, task, (Task t, object obj) => { onCompletion?.Invoke(t); }, null);
65  }
66  public static void AddIfNotFound(string name, Task task, Action<Task> onCompletion)
67  {
68  AddInternal(name, task, (Task t, object obj) => { onCompletion?.Invoke(t); }, null, addIfFound: false);
69  }
70 
71  public static void Add<U>(string name, Task task, U userdata, Action<Task, U> onCompletion) where U : class
72  {
73  AddInternal(name, task, (Task t, object obj) => { onCompletion?.Invoke(t, (U)obj); }, userdata);
74  }
75 
76  public static void Update()
77  {
78  lock (taskActions)
79  {
80  for (int i = 0; i < taskActions.Count; i++)
81  {
82  if (taskActions[i].Task.IsCompleted)
83  {
84  taskActions[i].OnCompletion?.Invoke(taskActions[i].Task, taskActions[i].UserData);
85  DebugConsole.Log($"Task {taskActions[i].Name} completed ({taskActions.Count-1}/{MaxTasks})");
86  taskActions.RemoveAt(i);
87  i--;
88  }
89  }
90  }
91  }
92 
93  public static void PrintTaskExceptions(Task task, string msg)
94  {
95  DebugConsole.ThrowError(msg);
96  foreach (Exception e in task.Exception.InnerExceptions)
97  {
98  DebugConsole.ThrowError(e.Message + "\n" + e.StackTrace.CleanupStackTrace());
99  }
100  }
101  }
102 }