// 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;
}
}
}