// The pipeline control function for build tasks that runs on the separate build thread public void Build(bool rebuild) { Busy = true; ShouldStop = false; _isCleaning = false; Stopwatch timer = Stopwatch.StartNew(); bool success = false; try { Engine.Logger.BuildStart(rebuild, Engine.IsRelease); // Reset the item enumerator to the beginning _itemEnumerator = Project.Items.GetEnumerator(); _itemIndex = 0; // Ensure that the intermediate, output, and temp directories exist if (!Directory.Exists(Project.Paths.IntermediateRoot)) { Directory.CreateDirectory(Project.Paths.IntermediateRoot); } if (!Directory.Exists(Project.Paths.OutputRoot)) { Directory.CreateDirectory(Project.Paths.OutputRoot); } if (Directory.Exists(TempFilePath)) { Directory.Delete(TempFilePath, true); } Directory.CreateDirectory(TempFilePath); // Launch the build tasks foreach (var task in _tasks) { task.Start(rebuild); } // Wait for the tasks to complete foreach (var task in _tasks) { task.Join(); } // Clean up the temp files Directory.Delete(TempFilePath, true); // Check for exit request before moving on if (ShouldStop) { return; } // Clean up, lots of temp items probably hanging around at this point GC.Collect(); // Fail out if any items failed if (_tasks.Any(task => task.Results.FailCount > 0)) { Engine.Logger.EngineError("One or more items failed to build, skipping content output step."); return; } // Check if the output settings have changed bool outChanged = CheckOutputChanged(); // Test if we can skip output, otherwise report if (_tasks.All(task => task.Results.PassCount == task.Results.SkipCount)) { if (!outChanged) { Engine.Logger.EngineInfo($"Skipping content output step, no items were rebuilt.", true); success = true; return; } else { Engine.Logger.EngineInfo($"No items were rebuilt, but the output settings have changed.", true); } } Engine.Logger.BuildContinue(timer.Elapsed); // Create the output process and build the metadata var outProc = new PackingProcess(this, _tasks); if (!outProc.BuildContentPack()) { return; } // One last exit check before starting the output process if (ShouldStop) { return; } // Perform the final output steps (will check for cancellation) success = outProc.ProcessOutput(outChanged); } finally { Busy = false; Engine.Logger.BuildEnd(success, timer.Elapsed, ShouldStop); } }