namespace VRTK.Prefabs.Helpers.SceneConsole
{
using UnityEngine;
using UnityEngine.UI;
using System;
using Malimbe.PropertySerializationAttribute;
using Malimbe.XmlDocumentationAttribute;
using Zinnia.Data.Attribute;
///
/// The public interface into the SceneConsole Prefab.
///
public class SceneConsoleFacade : MonoBehaviour
{
#region Console Settings
///
/// The size of the font the log text is displayed in.
///
[Serialized]
[field: Header("Console Settings"), DocumentedByXml]
public int FontSize { get; set; } = 10;
///
/// The of the text for an info log message.
///
[Serialized]
[field: DocumentedByXml]
public Color InfoMessage { get; set; } = Color.black;
///
/// The of the text for an assertion log message.
///
[Serialized]
[field: DocumentedByXml]
public Color AssertMessage { get; set; } = Color.black;
///
/// The of the text for a warning log message.
///
[Serialized]
[field: DocumentedByXml]
public Color WarningMessage { get; set; } = Color.yellow;
///
/// The of the text for an error log message.
///
[Serialized]
[field: DocumentedByXml]
public Color ErrorMessage { get; set; } = Color.red;
///
/// The of the text for an exception log message.
///
[Serialized]
[field: DocumentedByXml]
public Color ExceptionMessage { get; set; } = Color.red;
///
/// Determines whether to collapse same messages into one message in the log.
///
[Serialized]
[field: DocumentedByXml]
public bool CollapseLog { get; set; }
#endregion
#region Reference Settings
///
/// The console scrollable area.
///
[Serialized]
[field: Header("Reference Settings"), DocumentedByXml, Restricted]
public ScrollRect ScrollWindow { get; protected set; }
///
/// The output content .
///
[Serialized]
[field: DocumentedByXml, Restricted]
public RectTransform ConsoleRect { get; protected set; }
///
/// The element to output the console to.
///
[Serialized]
[field: DocumentedByXml, Restricted]
public Text ConsoleOutput { get; protected set; }
#endregion
///
/// The character to use for the line ending.
///
protected const string newline = "\n";
///
/// The specified line buffer.
///
protected const int lineBuffer = 50;
///
/// The current line buffer in use.
///
protected int currentBuffer;
///
/// The last log message.
///
protected string lastMessage;
///
/// Clears the current log view of all messages
///
public virtual void ClearLog()
{
if (ConsoleOutput != null)
{
ConsoleOutput.text = "";
}
currentBuffer = 0;
lastMessage = "";
}
protected virtual void OnEnable()
{
Application.logMessageReceived += HandleLog;
}
protected virtual void OnDisable()
{
Application.logMessageReceived -= HandleLog;
if (ConsoleRect != null)
{
ConsoleRect.sizeDelta = Vector2.zero;
}
}
///
/// Gets a rich text styled message for the given .
///
/// The message to style.
/// The of the message.
/// A rich text styled message.
protected virtual string GetMessage(string message, LogType type)
{
Color color;
switch (type)
{
case LogType.Error:
color = ErrorMessage;
break;
case LogType.Assert:
color = AssertMessage;
break;
case LogType.Warning:
color = WarningMessage;
break;
case LogType.Log:
color = InfoMessage;
break;
case LogType.Exception:
color = ExceptionMessage;
break;
default:
throw new ArgumentOutOfRangeException(nameof(type), type, null);
}
string hexadecimalColorString = ColorUtility.ToHtmlStringRGBA(color);
return $"{message}{newline}";
}
///
/// Digests the current Unity log stream and outputs it to the provided
///
/// The message from the log stream.
/// The stacktrace data from the log stream
/// The type of the given log message.
protected virtual void HandleLog(string message, string stackTrace, LogType type)
{
if (ConsoleOutput == null || ScrollWindow == null || ConsoleRect == null)
{
return;
}
string logOutput = GetMessage(message, type);
string consoleOutputText = ConsoleOutput.text;
if (currentBuffer >= lineBuffer)
{
const int halfLineBuffer = lineBuffer / 2;
int lookupIndex = 0;
int skippedLineCount = 0;
while (skippedLineCount < halfLineBuffer && lookupIndex < consoleOutputText.Length)
{
int newlineIndex = consoleOutputText.IndexOf(newline, lookupIndex, StringComparison.Ordinal);
if (newlineIndex == -1)
{
break;
}
lookupIndex = newlineIndex + 1;
skippedLineCount++;
}
if (lookupIndex < consoleOutputText.Length)
{
consoleOutputText = consoleOutputText.Substring(lookupIndex);
}
currentBuffer = halfLineBuffer;
}
if (!CollapseLog || lastMessage != logOutput)
{
consoleOutputText += logOutput;
lastMessage = logOutput;
}
ConsoleOutput.text = consoleOutputText;
ConsoleOutput.fontSize = FontSize;
ConsoleRect.sizeDelta = new Vector2(ConsoleOutput.preferredWidth, ConsoleOutput.preferredHeight);
ScrollWindow.verticalNormalizedPosition = 0;
currentBuffer++;
}
}
}