// SPDX-FileCopyrightText: 2023 Unity Technologies and the glTFast authors // SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; using UnityEngine; namespace GLTFast.Logging { /// /// Logger that stores/collects all messages. /// [Serializable] public class CollectingLogger : ICodeLogger { List m_Items; /// public void Error(LogCode code, params string[] messages) { if (m_Items == null) { m_Items = new List(); } m_Items.Add(new LogItem(LogType.Error, code, messages)); } /// public void Warning(LogCode code, params string[] messages) { if (m_Items == null) { m_Items = new List(); } m_Items.Add(new LogItem(LogType.Warning, code, messages)); } /// public void Info(LogCode code, params string[] messages) { if (m_Items == null) { m_Items = new List(); } m_Items.Add(new LogItem(LogType.Log, code, messages)); } /// public void Log(LogType logType, LogCode code, params string[] messages) { if (m_Items == null) { m_Items = new List(); } m_Items.Add(new LogItem(logType, code, messages)); } /// public void Error(string message) { if (m_Items == null) { m_Items = new List(); } m_Items.Add(new LogItem(LogType.Error, LogCode.None, message)); } /// public void Warning(string message) { if (m_Items == null) { m_Items = new List(); } m_Items.Add(new LogItem(LogType.Warning, LogCode.None, message)); } /// public void Info(string message) { if (m_Items == null) { m_Items = new List(); } m_Items.Add(new LogItem(LogType.Log, LogCode.None, message)); } /// /// Logs all collected messages to the console. /// public void LogAll() { if (m_Items != null) { foreach (var item in m_Items) { item.Log(); } } } /// /// Number of log items in /// public int Count => m_Items?.Count ?? 0; /// /// Items that were logged /// public IEnumerable Items => m_Items?.AsReadOnly(); } /// /// Encapsulates a single log message. /// [Serializable] public class LogItem { /// /// The severeness type of the log message. /// public LogType Type => type; /// /// Message code /// public LogCode Code => code; /// /// Additional, optional message parts /// public string[] Messages => messages; [SerializeField] LogType type; [SerializeField] LogCode code; [SerializeField] string[] messages; /// /// Default constructor /// /// The severeness type of the log message /// Message code /// Additional, optional message parts public LogItem(LogType type, LogCode code, params string[] messages) { this.type = type; this.code = code; this.messages = messages; } /// /// Logs the message to the console /// public void Log() { Debug.LogFormat(Type, LogOption.NoStacktrace, null, LogMessages.GetFullMessage(Code, Messages)); } /// /// Returns the full log message /// /// Log message public override string ToString() { return LogMessages.GetFullMessage(Code, Messages); } /// public override int GetHashCode() { #if NET_STANDARD var hash = new HashCode(); hash.Add(Type); hash.Add(Code); if (Messages != null) { foreach (var id in Messages) { hash.Add(id); } } return hash.ToHashCode(); #else var hash = 17; hash = hash * 31 + Type.GetHashCode(); hash = hash * 31 + Code.GetHashCode(); if (Messages != null) { hash = hash * 31 + Messages.Length; foreach (var message in Messages) { hash = hash * 31 + message.GetHashCode(); } } return hash; #endif } /// public override bool Equals(object obj) { //Check for null and compare run-time types. if (obj == null || GetType() != obj.GetType()) { return false; } return Equals((LogItem)obj); } bool Equals(LogItem other) { if (Type != other.Type || Code != other.Code) return false; if (Messages == null ^ other.Messages == null) return false; return Messages == null || AreEqual(Messages, other.Messages); } static bool AreEqual(IReadOnlyList a, IReadOnlyList b) { if (a.Count == b.Count) { for (var i = 0; i < a.Count; i++) { if (!a[i].Equals(b[i])) return false; } return true; } return false; } } }