using System; using System.Collections.Generic; using UnityEditor; namespace Ubisoft.Hotel.PackageManager.Editor { internal class BuildBatch { internal enum EWhenOnDone { AllStepsDone, OnPostprocessDone }; private EWhenOnDone WhenOnDone { get; set; } private Queue Queue { get; } private int StepsPerformedCount { get; set; } private int AllStepCount { get; set; } internal bool IsPerforming { get; private set; } internal bool IsDone { get; private set; } private Action OnStepPerformed { get; set; } /// /// Constructor for a build batch which is able to perform a sequence of BuildStep objects, each responsible for carrying out a /// single step of the build pipeline. /// /// Callback to call when a step is performed. internal BuildBatch(Action onStepPerformed) { Queue = new Queue(); OnStepPerformed = onStepPerformed; Reset(); } internal void Reset() { Queue.Clear(); IsPerforming = false; IsDone = false; StepsPerformedCount = 0; } internal void EnqueueStep(BuildStep step) { Queue.Enqueue(step); } internal void Perform(EWhenOnDone whenOnDone) { WhenOnDone = whenOnDone; IsPerforming = true; IsDone = false; StepsPerformedCount = 0; AllStepCount = Queue.Count; int count = 0; string msg = ""; foreach (BuildStep step in Queue) { if (count > 0) { msg += ", "; } msg += step.Name; count++; } PackageManager.Log($"BuildBatch: Performing batch {msg} ({AllStepCount})..."); if (AllStepCount == 0) { OnDone(); } else { // Run the job right away so it will also work in -quit batch mode Update(); } } private bool CanShowProgressBar() { return false; //return !Application.isBatchMode; } private void UpdateProgressBar() { if (CanShowProgressBar() && Queue.Count > 0) { BuildStep step = Queue.Peek(); if (EditorUtility.DisplayCancelableProgressBar("Building batch...", $"Performing {step.Name} ({StepsPerformedCount}/{AllStepCount}) ...", StepsPerformedCount / AllStepCount)) { throw new Exception("BuildBatchCancelled"); } } } internal void Update() { if (IsPerforming) { if (Queue.Count > 0) { BuildStep step = Queue.Peek(); if (step.IsPerforming) { step.Update(); } else if (!step.IsDone) { StepsPerformedCount++; OnStepPerformed?.Invoke(step); PackageManagerMain.Instance.PackageManager.BuildBatch_TicksAtStepBegin = DateTime.Now.Ticks; PackageManager.Log($"BuildBatch: Performing step {StepsPerformedCount}/{AllStepCount} ({step.Name})..."); UpdateProgressBar(); step.Perform(); } if (step.IsDone) { _ = Queue.Dequeue(); IsPerforming = Queue.Count > 0; if (!IsPerforming && WhenOnDone == EWhenOnDone.AllStepsDone) { OnDone(); } } } } } internal void OnPostprocessBuild() { if (WhenOnDone == EWhenOnDone.OnPostprocessDone) { OnDone(); } } internal void OnAborted() { Finish("BuildBatch: batch was aborted!"); } internal void OnDone() { Finish("BuildBatch: batch is done!"); } private void Finish(string msg) { IsDone = true; PackageManager packageManager = PackageManagerMain.Instance.PackageManager; packageManager.BuildBatch_AddTimeDetail("Finish"); PackageManager.Log($"{msg} in {packageManager.BuildBatch_TimeSpentAsString}"); PackageManager.Log("BuildBatch: " + packageManager.BuildBatch_FormatTimeDetail()); if (CanShowProgressBar()) { EditorUtility.ClearProgressBar(); } } } }