WuhuIslandTesting/Library/PackageCache/com.unity.scriptablebuildpipeline@1.21.5/Editor/Utilities/TaskCachingUtility.cs
2025-01-07 02:06:59 +01:00

126 lines
4.8 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.Build.Pipeline.Interfaces;
using UnityEngine;
namespace UnityEditor.Build.Pipeline.Utilities
{
internal static class TaskCachingUtility
{
public class WorkItem<T>
{
public T Context;
public int Index;
public CacheEntry entry;
public string StatusText;
public WorkItem(T context, string statusText = "")
{
this.Context = context;
this.StatusText = statusText;
}
}
public interface IRunCachedCallbacks<T>
{
/// <summary>
/// Creates a cache entry for the specified work item.
/// </summary>
/// <param name="item">The work item.</param>
/// <returns>Returns the created entry.</returns>
CacheEntry CreateCacheEntry(WorkItem<T> item);
/// <summary>
/// Process the uncached work item.
/// </summary>
/// <param name="item">The work item.</param>
void ProcessUncached(WorkItem<T> item);
/// <summary>
/// Process the cached work item.
/// </summary>
/// <param name="item">The work item.</param>
/// <param name="info">The cached information for the work item.</param>
void ProcessCached(WorkItem<T> item, CachedInfo info);
/// <summary>
/// Post processes the work item.
/// </summary>
/// <param name="item">The work item.</param>
void PostProcess(WorkItem<T> item);
/// <summary>
/// Creates cached information for the specified work item.
/// </summary>
/// <param name="item">The work item.</param>
/// <returns>Returns the cached information created.</returns>
CachedInfo CreateCachedInfo(WorkItem<T> item);
}
public static ReturnCode RunCachedOperation<T>(IBuildCache cache, IBuildLogger log, IProgressTracker tracker, List<WorkItem<T>> workItems,
IRunCachedCallbacks<T> cbs
)
{
using (log.ScopedStep(LogLevel.Info, "RunCachedOperation"))
{
List<CacheEntry> cacheEntries = null;
List<WorkItem<T>> nonCachedItems = workItems;
var cachedItems = new List<WorkItem<T>>();
for (int i = 0; i < workItems.Count; i++)
{
workItems[i].Index = i;
}
IList<CachedInfo> cachedInfo = null;
if (cache != null)
{
using (log.ScopedStep(LogLevel.Info, "Creating Cache Entries"))
for (int i = 0; i < workItems.Count; i++)
{
workItems[i].entry = cbs.CreateCacheEntry(workItems[i]);
}
cacheEntries = workItems.Select(i => i.entry).ToList();
using (log.ScopedStep(LogLevel.Info, "Load Cached Data"))
cache.LoadCachedData(cacheEntries, out cachedInfo);
cachedItems = workItems.Where(x => cachedInfo[x.Index] != null).ToList();
nonCachedItems = workItems.Where(x => cachedInfo[x.Index] == null).ToList();
}
using (log.ScopedStep(LogLevel.Info, "Process Entries"))
foreach (WorkItem<T> item in nonCachedItems)
{
if (!tracker.UpdateInfoUnchecked(item.StatusText))
return ReturnCode.Canceled;
cbs.ProcessUncached(item);
}
using (log.ScopedStep(LogLevel.Info, "Process Cached Entries"))
foreach (WorkItem<T> item in cachedItems)
cbs.ProcessCached(item, cachedInfo[item.Index]);
foreach (WorkItem<T> item in workItems)
cbs.PostProcess(item);
if (cache != null)
{
List<CachedInfo> uncachedInfo;
using (log.ScopedStep(LogLevel.Info, "Saving to Cache"))
{
using (log.ScopedStep(LogLevel.Info, "Creating Cached Infos"))
uncachedInfo = nonCachedItems.Select((item) => cbs.CreateCachedInfo(item)).ToList();
cache.SaveCachedData(uncachedInfo);
}
}
log.AddEntrySafe(LogLevel.Info, $"Total Entries: {workItems.Count}, Processed: {nonCachedItems.Count}, Cached: {cachedItems.Count}");
return ReturnCode.Success;
}
}
}
}