/// <summary> /// Process all the ChunkOperations currently in the queue. /// Everything is asynchronous and should load (at best) by grouping everything into lists before saving/loading. /// This also handles chunk unloading when it is no longer needed by ChunkOperations AND ChunkLoaders. /// <a href="http://www.stevevermeulen.com/index.php/2017/09/using-async-await-in-unity3d-2017/"> /// See for more info on async + Unity. /// </a> /// </summary> private async Task ProcessOperations() { isProcessingOperations = true; List <Vector3Int> chunksUsed = new List <Vector3Int>(); // If there are any elements in the queue of operations while (chunkOperations.Any()) { // Get the first operation and execute it IChunkOperation operation = chunkOperations.Dequeue(); // Execute the task, and wait for it to return await operation.Execute(this); // Keep track of all the chunks that were used by the operations chunksUsed = chunksUsed.Union(operation.ChunkPositions).ToList(); } if (chunksUsed.Count > 0) { // Unload all chunks that were used and are no longer needed await UnloadChunks(GetChunksToUnloadFromPositions(chunksUsed), worldInfo); } isProcessingOperations = false; }
/// <summary> /// Add the given operation to the ChunkOperations Queue. /// </summary> /// <param name="operation">The operation to add</param> /// <returns>Returns the ExecuteTask to await for</returns> private Task AddChunkOperation(IChunkOperation operation) { chunkOperations.Enqueue(operation); // Return the task so the original caller can await it // see implementation in the corresponding IChunkOperation's Execute() method. return(operation.ExecuteCompletionSource.Task); }