Skip to content
Snippets Groups Projects
Commit 21dccdae authored by Chang, Ryan's avatar Chang, Ryan
Browse files

Improvements to threading

parent 73e2fc7c
No related branches found
No related tags found
No related merge requests found
......@@ -41,18 +41,29 @@ public class TerrainGenerator : MonoBehaviour
[Tooltip("How tall the terrain is. May be changed to allow for higher terrains.")]
public float terrainHeight = 600;
[Tooltip("What percentage of threads available should we use?")]
public float threadsUsage = 0.7f;
public int MaxThreads => Mathf.FloorToInt(Environment.ProcessorCount * threadsUsage);
[Header("Autogenerated values")]
[Tooltip("Which terrain grid are we on right now?")]
public Vector2Int currentGridPosition;
[Tooltip("Array of terrains to reuse.")]
public Terrain[] terrains = new Terrain[9];
[Tooltip("Dictionary of previously loaded terrains.")]
public Dictionary<Vector2Int, TerrainData> previouslyLoaded = new();
public Queue<TerrainGenThread> threadsToRun = new();
public Queue<TerrainGenThread> queuedThreads = new();
public ConcurrentBag<TerrainGenThread> completedGenerators = new();
public int threadsCount = 0;
[Header("Stats")]
public int runningThreads = 0;
/// <summary>
/// Apply the terrain that was generated by genThread.
......@@ -78,24 +89,29 @@ public class TerrainGenerator : MonoBehaviour
if (!previouslyLoaded.ContainsKey(gridPos) || forceRefresh)
{
TerrainData data = Instantiate(Resources.Load<TerrainData>("Template"));
TerrainGenThread genThread = new(this, data, crawlPos, gridPos);
TerrainGenThread tGenThread = new(this, data, crawlPos, gridPos);
previouslyLoaded[gridPos] = data;
threadsCount++;
if (threadsCount >= Environment.ProcessorCount)
if (runningThreads >= MaxThreads)
{
threadsToRun.Enqueue(genThread);
// Too many threads.
queuedThreads.Enqueue(tGenThread);
}
else
{
ThreadStart starter = new(genThread.Generate);
Thread thread = new(starter);
previouslyLoaded[gridPos] = data;
thread.Start();
StartThread(tGenThread);
}
}
}
private void StartThread(TerrainGenThread tGenThread)
{
runningThreads++;
ThreadStart starter = new(tGenThread.Generate);
Thread thread = new(starter);
thread.Start();
}
public virtual void GenerateSurronding(Vector2 initCrawlPos, bool forceRefresh = false)
{
int count = 0;
......@@ -113,6 +129,7 @@ public class TerrainGenerator : MonoBehaviour
private void Update()
{
// Check for refresh.
if (refresh)
{
refresh = false;
......@@ -123,10 +140,33 @@ public class TerrainGenerator : MonoBehaviour
GenerateSurronding(crawlStartPosition, true);
}
if (completedGenerators.TryTake(out TerrainGenThread tGenThread))
// Check for queued threads.
if (queuedThreads.TryDequeue(out TerrainGenThread queuedThread)
&& runningThreads < MaxThreads)
{
ApplyGeneratedTerrain(tGenThread);
threadsCount--;
StartThread(queuedThread);
}
// Check for completed generators.
if (completedGenerators.TryTake(out TerrainGenThread completedThread))
{
ApplyGeneratedTerrain(completedThread);
runningThreads--;
}
}
/// <summary>
/// Gets the square distance between two points.
/// If A is located at (0,0) and B is located at (5,-10),
/// the distance would be 5+10=15.
/// </summary>
/// <param name="a">A position on the grid.</param>
/// <param name="b">Another position.</param>
/// <returns></returns>
public int SquareDistance(Vector2Int a, Vector2Int b)
{
Vector2Int diff = b - a;
return Mathf.Abs(diff.x) + Mathf.Abs(diff.y);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment