211 lines
8.2 KiB
C#
211 lines
8.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Runtime.CompilerServices;
|
|
using UnityEditor.Build.Content;
|
|
using UnityEditor.Build.Pipeline.Utilities;
|
|
|
|
[assembly: InternalsVisibleTo("Unity.Addressables.Editor.Tests")]
|
|
namespace UnityEditor.Build.Pipeline.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// Describes the level of a log entry
|
|
/// </summary>
|
|
public enum LogLevel
|
|
{
|
|
/// <summary>
|
|
/// The entry is reporting an error.
|
|
/// </summary>
|
|
Error,
|
|
/// <summary>
|
|
/// The entry is reporting an warning.
|
|
/// </summary>
|
|
Warning,
|
|
/// <summary>
|
|
/// The entry is reporting general information.
|
|
/// </summary>
|
|
Info,
|
|
/// <summary>
|
|
/// The entry is reporting verbose information.
|
|
/// </summary>
|
|
Verbose
|
|
}
|
|
|
|
/// <summary>
|
|
/// Interface for monitoring the build process. Several tasks will log details of their progress through this interface.
|
|
/// See the [Build Logging](https://docs.unity3d.com/Packages/com.unity.scriptablebuildpipeline@latest/index.html?subfolder=/manual/BuildLogger.html) documentation for more details.
|
|
/// </summary>
|
|
public interface IBuildLogger : IContextObject
|
|
{
|
|
/// <summary>
|
|
/// Adds details to the active build step
|
|
/// </summary>
|
|
/// <param name="level">The log level of this entry.</param>
|
|
/// <param name="msg">The message to add.</param>
|
|
void AddEntry(LogLevel level, string msg);
|
|
|
|
/// <summary>
|
|
/// Should be called when beginning a build step.
|
|
/// </summary>
|
|
/// <param name="level">The log level of this step.</param>
|
|
/// <param name="stepName">A name associated with the step. It is recommended that this name does not include specific context about the step; dynamic context should be added under the step as an entry.</param>
|
|
/// <param name="subStepsCanBeThreaded">True if within this build step the IBuildLogger will be used on multiple threads.</param>
|
|
void BeginBuildStep(LogLevel level, string stepName, bool subStepsCanBeThreaded);
|
|
|
|
/// <summary>
|
|
/// Ends the build step.
|
|
/// </summary>
|
|
void EndBuildStep();
|
|
}
|
|
internal enum DeferredEventType
|
|
{
|
|
Begin,
|
|
End,
|
|
Info
|
|
}
|
|
|
|
internal struct DeferredEvent
|
|
{
|
|
public LogLevel Level;
|
|
public DeferredEventType Type;
|
|
public double Time;
|
|
public string Name;
|
|
public string Context;
|
|
}
|
|
|
|
internal interface IDeferredBuildLogger
|
|
{
|
|
void HandleDeferredEventStream(IEnumerable<DeferredEvent> events);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Helper class to define a scope with a using statement
|
|
/// </summary>
|
|
public struct ScopedBuildStep : IDisposable
|
|
{
|
|
IBuildLogger m_Logger;
|
|
internal ScopedBuildStep(LogLevel level, string stepName, IBuildLogger logger, bool multiThreaded, string context)
|
|
{
|
|
m_Logger = logger;
|
|
m_Logger?.BeginBuildStep(level, stepName, multiThreaded);
|
|
if (!string.IsNullOrEmpty(context))
|
|
m_Logger?.AddEntrySafe(level, context);
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
void IDisposable.Dispose()
|
|
{
|
|
m_Logger?.EndBuildStep();
|
|
}
|
|
}
|
|
|
|
#if UNITY_2020_2_OR_NEWER || ENABLE_DETAILED_PROFILE_CAPTURING
|
|
internal struct ProfileCaptureScope : IDisposable
|
|
{
|
|
IBuildLogger m_Logger;
|
|
public ProfileCaptureScope(IBuildLogger logger, ProfileCaptureOptions options)
|
|
{
|
|
m_Logger = ScriptableBuildPipeline.useDetailedBuildLog ? logger : null;
|
|
ContentBuildInterface.StartProfileCapture(options);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
ContentBuildProfileEvent[] events = ContentBuildInterface.StopProfileCapture();
|
|
|
|
if (m_Logger == null)
|
|
return;
|
|
|
|
IDeferredBuildLogger dLog = (IDeferredBuildLogger)m_Logger;
|
|
IEnumerable<DeferredEvent> dEvents = events.Select(i =>
|
|
{
|
|
var e = new DeferredEvent();
|
|
e.Level = LogLevel.Verbose;
|
|
BuildLoggerExternsions.ConvertNativeEventName(i.Name, out e.Name, out e.Context);
|
|
e.Time = (double)i.TimeMicroseconds / (double)1000;
|
|
e.Type = BuildLoggerExternsions.ConvertToDeferredType(i.Type);
|
|
return e;
|
|
});
|
|
dLog.HandleDeferredEventStream(dEvents);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// Contains extension methods for the IBuildLogger interface
|
|
/// </summary>
|
|
public static class BuildLoggerExternsions
|
|
{
|
|
/// <summary>
|
|
/// Adds details to the active build step
|
|
/// </summary>
|
|
/// <param name="log">The build log.</param>
|
|
/// <param name="level">The log level of this entry.</param>
|
|
/// <param name="msg">The message to add.</param>
|
|
public static void AddEntrySafe(this IBuildLogger log, LogLevel level, string msg)
|
|
{
|
|
if (log != null)
|
|
{
|
|
log.AddEntry(level, msg);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Begins a new build step and returns an ScopedBuildStep which will end the build step when disposed. It is recommended to use this in conjunction with the using statement.
|
|
/// </summary>
|
|
/// <param name="log">The build log.</param>
|
|
/// <param name="level">The log level of this step.</param>
|
|
/// <param name="stepName">A name associated with the step.</param>
|
|
/// <param name="multiThreaded">True if within this build step the IBuildLogger will be used on multiple threads.</param>
|
|
/// <returns>Returns a ScopedBuildStep that will end the build step when it is disposed.</returns>
|
|
public static ScopedBuildStep ScopedStep(this IBuildLogger log, LogLevel level, string stepName, bool multiThreaded = false)
|
|
{
|
|
return new ScopedBuildStep(level, stepName, log, multiThreaded, null);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Begins a new build step and returns an ScopedBuildStep which will end the build step when disposed. It is recommended to use this in conjunction with the using statement.
|
|
/// </summary>
|
|
/// <param name="log">The build log.</param>
|
|
/// <param name="level">The log level of this step.</param>
|
|
/// <param name="stepName">A name associated with the step.</param>
|
|
/// <param name="context">Adds an entry message the build step. This allows attaching specific context data without changing the stepName.</param>
|
|
/// <returns>Returns a ScopedBuildStep that will end the build step when it is disposed.</returns>
|
|
public static ScopedBuildStep ScopedStep(this IBuildLogger log, LogLevel level, string stepName, string context)
|
|
{
|
|
return new ScopedBuildStep(level, stepName, log, false, context);
|
|
}
|
|
|
|
#if UNITY_2020_2_OR_NEWER || ENABLE_DETAILED_PROFILE_CAPTURING
|
|
internal static DeferredEventType ConvertToDeferredType(ProfileEventType type)
|
|
{
|
|
if (type == ProfileEventType.Begin) return DeferredEventType.Begin;
|
|
if (type == ProfileEventType.End) return DeferredEventType.End;
|
|
if (type == ProfileEventType.Info) return DeferredEventType.Info;
|
|
throw new Exception("Unknown type");
|
|
}
|
|
|
|
const string k_WriteFile = "Write file:";
|
|
const string k_WriteObject = "Write object - ";
|
|
|
|
internal static void ConvertNativeEventName(string nativeName, out string eventName, out string eventContext)
|
|
{
|
|
eventName = nativeName;
|
|
eventContext = "";
|
|
if (nativeName.StartsWith(k_WriteFile, StringComparison.Ordinal))
|
|
{
|
|
eventName = "Write File";
|
|
eventContext = nativeName.Substring(k_WriteFile.Length);
|
|
}
|
|
else if (nativeName.StartsWith(k_WriteObject, StringComparison.Ordinal))
|
|
{
|
|
eventName = "Write Object";
|
|
eventContext = nativeName.Substring(k_WriteObject.Length);
|
|
}
|
|
|
|
if (eventContext.Any(c => c == '"'))
|
|
eventContext = eventContext.Replace("\"", "\\\"");
|
|
}
|
|
#endif
|
|
}
|
|
}
|