296 lines
8.1 KiB
C#
296 lines
8.1 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Threading.Tasks;
|
|
using UnityEngine;
|
|
using Object = UnityEngine.Object;
|
|
|
|
#if UNITY_EDITOR
|
|
using System.Reflection;
|
|
using Needle.Engine.Utils;
|
|
using UnityEditor;
|
|
#endif
|
|
|
|
namespace Needle.Engine
|
|
{
|
|
[Flags]
|
|
internal enum TracingScenario
|
|
{
|
|
Any = 0,
|
|
Types = 1 << 0,
|
|
NetworkRequests = 1 << 1,
|
|
ComponentGeneration = 1 << 2,
|
|
ColorSpaces = 1 << 3,
|
|
FileExport = 1 << 4,
|
|
EditorSync = 1 << 5,
|
|
Samples = 1 << 6,
|
|
/// <summary>
|
|
/// E.g. Tools package or BuildPipeline package logs
|
|
/// </summary>
|
|
Tools = 1 << 7,
|
|
AuthenticationState = 1 << 8,
|
|
IPC = 1 << 9,
|
|
WebProject = 1 << 10,
|
|
}
|
|
|
|
internal static class OptionOverrides
|
|
{
|
|
public static bool OverrideNodeJSVersion
|
|
{
|
|
#if UNITY_EDITOR
|
|
get => SessionState.GetBool("NEEDLE_ENGINE_OVERRIDE_NODEJS", false);
|
|
set => SessionState.SetBool("NEEDLE_ENGINE_OVERRIDE_NODEJS", value);
|
|
#else
|
|
get => false;
|
|
#endif
|
|
}
|
|
public static string NodeJSVersion
|
|
{
|
|
#if UNITY_EDITOR
|
|
get => SessionState.GetString("NEEDLE_ENGINE_OVERRIDE_VALUE_NODEJS", "v14").Trim();
|
|
set => SessionState.SetString("NEEDLE_ENGINE_OVERRIDE_VALUE_NODEJS", value);
|
|
#else
|
|
get => "";
|
|
#endif
|
|
}
|
|
|
|
public static bool OverrideLicenseType
|
|
{
|
|
#if UNITY_EDITOR
|
|
get => SessionState.GetBool("NEEDLE_ENGINE_OVERRIDE_LICENSE_TYPE", false);
|
|
set => SessionState.SetBool("NEEDLE_ENGINE_OVERRIDE_LICENSE_TYPE", value);
|
|
#else
|
|
get => false;
|
|
#endif
|
|
}
|
|
|
|
public static string LicenseType
|
|
{
|
|
#if UNITY_EDITOR
|
|
get => SessionState.GetString("NEEDLE_ENGINE_OVERRIDE_VALUE_LICENSE_TYPE", "free").Trim();
|
|
set
|
|
{
|
|
SessionState.SetString("NEEDLE_ENGINE_OVERRIDE_VALUE_LICENSE_TYPE", value);
|
|
#pragma warning disable CS4014
|
|
LicenseCheck.QueryLicense(false);
|
|
#pragma warning restore CS4014
|
|
}
|
|
#else
|
|
get => "";
|
|
#endif
|
|
}
|
|
}
|
|
|
|
internal static class NeedleDebug
|
|
{
|
|
internal static bool DeveloperMode
|
|
{
|
|
#if UNITY_EDITOR
|
|
get {
|
|
if (!UnityThreads.IsMainThread()) return false;
|
|
return SessionState.GetBool("NEEDLE_ENGINE_DEVELOPER_MODE", false);
|
|
}
|
|
set => SessionState.SetBool("NEEDLE_ENGINE_DEVELOPER_MODE", value);
|
|
#else
|
|
get => false;
|
|
set { }
|
|
#endif
|
|
}
|
|
|
|
private static string LogFilePath => Application.dataPath + "/../Logs/Needle.log";
|
|
private static string LogFilePathPrev => Application.dataPath + "/../Logs/Needle-prev.log";
|
|
private static StreamWriter LogFileStream { get; set; }
|
|
|
|
#if UNITY_EDITOR
|
|
[InitializeOnLoadMethod]
|
|
private static void Init()
|
|
{
|
|
if (!SessionState.GetBool("NEEDLE_ENGINE_LOG_TO_FILE", false))
|
|
{
|
|
SessionState.SetBool("NEEDLE_ENGINE_LOG_TO_FILE", true);
|
|
if (File.Exists(LogFilePath))
|
|
{
|
|
File.Copy(LogFilePath, LogFilePathPrev, true);
|
|
File.Delete(LogFilePath);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
private static void WriteLogToFile(TracingScenario scenario, object obj, Object context = null)
|
|
{
|
|
#if UNITY_EDITOR
|
|
try
|
|
{
|
|
switch (scenario)
|
|
{
|
|
case TracingScenario.Any:
|
|
case TracingScenario.Samples:
|
|
case TracingScenario.Tools:
|
|
case TracingScenario.AuthenticationState:
|
|
case TracingScenario.IPC:
|
|
case TracingScenario.WebProject:
|
|
LogFileStream ??= new StreamWriter(LogFilePath, true);
|
|
var dt = DateTime.Now;
|
|
var str = dt.ToString("yyyy-MM-dd HH:mm:ss") + " - " + scenario.ToString();
|
|
if(context) str += " (" + context.name + ")";
|
|
str += ": " + obj;
|
|
LogFileStream.WriteLine(str);
|
|
LogFileStream.Flush();
|
|
break;
|
|
}
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
if(DeveloperMode) Debug.LogError("Failed to write log to file: " + e);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#if HAS_HIDE_IN_CALLSTACKS
|
|
[HideInCallstack]
|
|
#endif
|
|
public static void Log(TracingScenario scenario, object obj, Object context = null)
|
|
{
|
|
WriteLogToFile(scenario, obj, context);
|
|
if (IsEnabled(scenario)) Debug.Log(obj, context);
|
|
}
|
|
#if HAS_HIDE_IN_CALLSTACKS
|
|
[HideInCallstack]
|
|
#endif
|
|
public static void Log(TracingScenario scenario, Func<object> obj, Object context = null)
|
|
{
|
|
WriteLogToFile(scenario, obj, context);
|
|
if (IsEnabled(scenario)) Debug.Log(obj.Invoke(), context);
|
|
}
|
|
#if HAS_HIDE_IN_CALLSTACKS
|
|
[HideInCallstack]
|
|
#endif
|
|
public static async void LogAsync(TracingScenario scenario, Func<Task<object>> obj, Object context = null)
|
|
{
|
|
WriteLogToFile(scenario, obj, context);
|
|
if (IsEnabled(scenario)) Debug.Log(await obj.Invoke(), context);
|
|
}
|
|
|
|
#if HAS_HIDE_IN_CALLSTACKS
|
|
[HideInCallstack]
|
|
#endif
|
|
public static void LogWarning(TracingScenario scenario, object obj, Object context = null)
|
|
{
|
|
WriteLogToFile(scenario, obj, context);
|
|
if (IsEnabled(scenario)) Debug.LogWarning(obj, context);
|
|
}
|
|
|
|
#if HAS_HIDE_IN_CALLSTACKS
|
|
[HideInCallstack]
|
|
#endif
|
|
public static void LogError(TracingScenario scenario, object obj, Object context = null)
|
|
{
|
|
WriteLogToFile(scenario, obj, context);
|
|
if (IsEnabled(scenario)) Debug.LogError(obj, context);
|
|
}
|
|
|
|
#if HAS_HIDE_IN_CALLSTACKS
|
|
[HideInCallstack]
|
|
#endif
|
|
public static void LogException(TracingScenario scenario, Exception e, Object context = null)
|
|
{
|
|
WriteLogToFile(scenario, e, context);
|
|
if (IsEnabled(scenario)) Debug.LogException(e, context);
|
|
}
|
|
|
|
public static bool IsEnabled(TracingScenario scenario)
|
|
{
|
|
if (scenario == TracingScenario.Any) return true;
|
|
return currentTracingScenarios.HasFlag(scenario);
|
|
}
|
|
|
|
// We cache it to not access EditorPrefs every time we need it
|
|
private static int cachedTracingScenario = -1;
|
|
|
|
private static TracingScenario currentTracingScenarios
|
|
{
|
|
get
|
|
{
|
|
if (cachedTracingScenario != -1)
|
|
return (TracingScenario)cachedTracingScenario;
|
|
#if UNITY_EDITOR
|
|
if(UnityThreads.IsMainThread())
|
|
cachedTracingScenario = EditorPrefs.GetInt("NeedleTracingScenario", 0);
|
|
else cachedTracingScenario = 0;
|
|
#else
|
|
cachedTracingScenario = 0;
|
|
#endif
|
|
return (TracingScenario)cachedTracingScenario;
|
|
}
|
|
set
|
|
{
|
|
if (cachedTracingScenario == (int)value) return;
|
|
cachedTracingScenario = (int)value;
|
|
#if UNITY_EDITOR
|
|
EditorPrefs.SetInt("NeedleTracingScenario", (int)value);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
private class TracingScenarioEditor : EditorWindow
|
|
{
|
|
[MenuItem("Needle Engine/Internal/Tracing Scenarios", false, 50)]
|
|
private static void Open()
|
|
{
|
|
var window = GetWindow<TracingScenarioEditor>();
|
|
if (window == null) window = CreateInstance<TracingScenarioEditor>();
|
|
window.Show();
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
titleContent = new GUIContent("Tracing Scenarios");
|
|
}
|
|
|
|
private readonly string[] tracingScenarioTypes = Enum.GetNames(typeof(TracingScenario));
|
|
private readonly Array tracingScenarioValues = Enum.GetValues(typeof(TracingScenario));
|
|
private PropertyInfo[] optionOverrideFields;
|
|
|
|
private void OnGUI()
|
|
{
|
|
var newValue = 0;
|
|
GUILayout.Label("Logging", EditorStyles.boldLabel);
|
|
for (var i = 0; i < tracingScenarioTypes.Length; i++)
|
|
{
|
|
var val = (TracingScenario)tracingScenarioValues.GetValue(i);
|
|
if ((int)val == 0) continue;
|
|
var isFlagEnabled =
|
|
currentTracingScenarios.HasFlag((TracingScenario)tracingScenarioValues.GetValue(i));
|
|
var enabled = EditorGUILayout.ToggleLeft(ObjectNames.NicifyVariableName(tracingScenarioValues.GetValue(i).ToString()),
|
|
isFlagEnabled);
|
|
newValue |= enabled ? (int)tracingScenarioValues.GetValue(i) : 0;
|
|
}
|
|
currentTracingScenarios = (TracingScenario)newValue;
|
|
EditorGUILayout.Space();
|
|
|
|
if (DeveloperMode)
|
|
{
|
|
GUILayout.Label("Overrides", EditorStyles.boldLabel);
|
|
optionOverrideFields ??= typeof(OptionOverrides).GetProperties(BindingFlags.Static | BindingFlags.Public);
|
|
foreach (var field in optionOverrideFields)
|
|
{
|
|
if (field.PropertyType == typeof(bool))
|
|
{
|
|
var val = (bool)field.GetValue(null);
|
|
var enabled = EditorGUILayout.ToggleLeft(ObjectNames.NicifyVariableName(field.Name), val);
|
|
field.SetValue(null, enabled);
|
|
}
|
|
else if (field.PropertyType == typeof(string))
|
|
{
|
|
var val = (string)field.GetValue(null);
|
|
var enabled = EditorGUILayout.DelayedTextField(ObjectNames.NicifyVariableName(field.Name), val);
|
|
field.SetValue(null, enabled);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
} |