using System; using System.Collections.Generic; using System.Threading; using UnityEngine; namespace Jovian.Logger { public static class LoggerUtility { private static LoggerSettings loggerSettings; private static bool setByFrameCount = true; private static int frameCount; private static bool isLoaded; private static readonly int mainThreadId = Thread.CurrentThread.ManagedThreadId; /// /// Returns true if the current code is executing on the main Unity thread. /// public static bool IsMainThread => Thread.CurrentThread.ManagedThreadId == mainThreadId; /// /// Callback to post formatted log messages. /// public static Action<(JovianLogType, LogCategory, string)> FormattedLogCallback { get; set; } /// /// Callback for watch-mode logs that update in place instead of creating new entries. /// Parameters: (watchKey, value, logCategory) /// public static Action<(string key, string value, LogCategory category)> WatchCallback { get; set; } /// /// Callback when a watch key is removed. /// public static Action UnwatchCallback { get; set; } /// /// If enabled it will show either the Unity's Time.frameCount or the custom frame count set by the user. This is a global setting. /// public static int FrameCount { get { if(setByFrameCount) { try { frameCount = Time.frameCount; } catch(UnityException) { // Time.frameCount can only be called from the main thread. // Return last known value when called from a background thread. } } return frameCount; } set { frameCount = value; setByFrameCount = false; } } public static LoggerSettings LoadCustomLoggerSettings() { try { if(isLoaded) { return loggerSettings; } loggerSettings = Resources.Load("logger-settings"); isLoaded = true; return loggerSettings; } catch { //Debug.Log($"[Exception] LoggerSettings could not be loaded."); } return null; } /// /// Toggle the frame counting feature to be included with the logs on/off /// /// public static void ToggleFrameCount(bool enable) { IsFrameCountEnabled = enable; } /// /// Enable/Disable logging globally /// /// public static void ToggleLogging(bool enable) { loggerSettings.enableGlobalLogging = enable; } /// /// Check if the frame count feature is enabled /// public static bool IsFrameCountEnabled { get; private set; } /// /// Load settings preemptively to avoid asynchronous loading for unity assets. /// public static void PreloadLoggerSettings() { try { LoadCustomLoggerSettings(); } catch(Exception e) { Debug.Log($"[Exception] LoggerSettings could not be loaded. {e}"); } } /// /// Adds a custom filter programmatically. Useful for setting up remote filters /// /// Required set of log categories /// The log level, default being level 4, Exception(in unity it is the base log level) /// A list of classes that should be watched, default null /// If all preexisting filters should be first removed public static void AddFilter(LogCategory logCategory, JovianLogType jovianLogLevel = JovianLogType.Spam, List callerNames = null, bool clearAll = false) { var filter = new Filters() { jovianLogType = jovianLogLevel, logCategory = logCategory, callerNames = callerNames }; var loggerSettings = LoadCustomLoggerSettings(); if(clearAll) { loggerSettings.globalFilters = new Filters[1]; loggerSettings.globalFilters[0] = filter; InternalLogger.LoadSettings(); return; } var filters = new Filters[loggerSettings.globalFilters.Length + 1]; for(var i = 0; i < loggerSettings.globalFilters.Length; i++) { filters[i] = loggerSettings.globalFilters[i]; } filters[^1] = filter; loggerSettings.globalFilters = filters; InternalLogger.LoadSettings(); } public static void ReloadLoggerSettings() { InternalLogger.LoadSettings(); } public static UnityEngine.LogType GetLogType(JovianLogType jovianLogType) { return jovianLogType switch { JovianLogType.Info => UnityEngine.LogType.Log, JovianLogType.Warning => UnityEngine.LogType.Warning, JovianLogType.Error => UnityEngine.LogType.Error, JovianLogType.Assert => UnityEngine.LogType.Assert, JovianLogType.Exception => UnityEngine.LogType.Exception, JovianLogType.Spam => UnityEngine.LogType.Log, _ => UnityEngine.LogType.Log }; } } }