using UnityEngine; using System; using System.IO; using System.Collections.Generic; using System.Diagnostics; namespace UnityEngine.ProBuilder { /// /// Describes the various states of chatty-ness. /// [Flags] enum LogLevel { None = 0x0, Error = 0x1, Warning = 0x2, Info = 0x4, Default = Error | Warning, All = 0xFF } /// /// Where the pb_Log writes to (default is Unity Console). /// /// /// If logging to a File, the pb_Log.outputFile must be set. /// You may log to one or multiple output sources. /// [Flags] enum LogOutput { None = 0x0, Console = 0x1, File = 0x2, } /// /// Debug log replacement. /// /// /// IMPORTANT - pb_LogEditor initializes this class from the Editor side (so preferences can be accessed)! /// static class Log { public const string k_ProBuilderLogFileName = "ProBuilderLog.txt"; // Retain a stack of previous log levels. static Stack s_logStack = new Stack(); // Current log level. static LogLevel s_LogLevel = LogLevel.All; // Where to write log strings. static LogOutput s_Output = LogOutput.Console; // Path to the log file. static string s_LogFilePath = k_ProBuilderLogFileName; /// /// Push the current log level in the stack. See also PopLogLevel. /// /// public static void PushLogLevel(LogLevel level) { s_logStack.Push(s_LogLevel); s_LogLevel = level; } /// /// Pop the current log level in the stack. See also PushLogLevel. /// public static void PopLogLevel() { s_LogLevel = s_logStack.Pop(); } /// /// Set the log level without modifying the stack. /// /// public static void SetLogLevel(LogLevel level) { s_LogLevel = level; } /// /// Set the output destination for logs. /// If output is file, make sure to also set the log file path (otherwise it defaults to ProBuilderLog.txt in project directory). /// /// public static void SetOutput(LogOutput output) { s_Output = output; } /// /// Set the path of the log file that pb_Log writes messages to. /// /// public static void SetLogFile(string path) { s_LogFilePath = path; } /// /// Output a debug message. /// /// These should not be committed to trunk. /// /// [Conditional("DEBUG")] public static void Debug(T value) { Debug(value.ToString()); } /// /// Output a debug message. /// /// /// These should not be committed to trunk. /// /// [Conditional("DEBUG")] public static void Debug(string message) { DoPrint(message, LogType.Log); } [Conditional("DEBUG")] public static void Debug(string format, params object[] values) { Debug(string.Format(format, values)); } /// /// Output an informational message. /// /// /// public static void Info(string format, params object[] values) { Info(string.Format(format, values)); } public static void Info(string message) { if ((s_LogLevel & LogLevel.Info) > 0) DoPrint(message, LogType.Log); } /// /// Output a warning message. /// /// /// public static void Warning(string format, params object[] values) { Warning(string.Format(format, values)); } public static void Warning(string message) { if ((s_LogLevel & LogLevel.Warning) > 0) DoPrint(message, LogType.Warning); } /// /// Output an error message. /// /// /// public static void Error(string format, params object[] values) { Error(string.Format(format, values)); } public static void Error(string message) { if ((s_LogLevel & LogLevel.Error) > 0) DoPrint(message, LogType.Error); } /// /// ConsolePro3 specific functionality - update a single log continuously. /// /// /// /// /// [Conditional("CONSOLE_PRO_ENABLED")] internal static void Watch(T key, K value) { UnityEngine.Debug.Log(string.Format("{0} : {1}\nCPAPI:{{\"cmd\":\"Watch\" \"name\":\"{0}\"}}", key.ToString(), value.ToString())); } static void DoPrint(string message, LogType type) { if ((s_Output & LogOutput.Console) > 0) PrintToConsole(message, type); if ((s_Output & LogOutput.File) > 0) PrintToFile(message, s_LogFilePath); } /// /// Print a message to a file. /// /// /// static void PrintToFile(string message, string path) { if (string.IsNullOrEmpty(path)) return; string full_path = Path.GetFullPath(path); if (string.IsNullOrEmpty(full_path)) { Log.PrintToConsole("m_LogFilePath bad: " + full_path); return; } if (!File.Exists(full_path)) { string directory = Path.GetDirectoryName(full_path); if (string.IsNullOrEmpty(directory)) { Log.PrintToConsole("m_LogFilePath bad: " + full_path); return; } Directory.CreateDirectory(directory); using (StreamWriter sw = File.CreateText(full_path)) { sw.WriteLine(message); } } else { using (StreamWriter sw = File.AppendText(full_path)) { // sw.WriteLine(); sw.WriteLine(message); } } } /// /// Delete the log file if it exists. /// public static void ClearLogFile() { if (File.Exists(s_LogFilePath)) File.Delete(s_LogFilePath); } /// /// Print a message to the Unity console. /// /// /// static void PrintToConsole(string message, LogType type = LogType.Log) { if (type == LogType.Log) UnityEngine.Debug.Log(message); else if (type == LogType.Warning) UnityEngine.Debug.LogWarning(message); else if (type == LogType.Error) UnityEngine.Debug.LogError(message); else if (type == LogType.Assert) #if UNITY_5_3_OR_NEWER UnityEngine.Debug.LogAssertion(message); #else UnityEngine.Debug.LogError(message); #endif else UnityEngine.Debug.Log(message); } internal static void NotNull(T obj, string message) { if (obj == null) throw new ArgumentNullException(message); } } }