#if UNITY_EDITOR || DEVELOPMENT_BUILD
#define DEVELOPMENT
#endif
using FishNet.Documenting;
using System;
using System.Runtime.CompilerServices;
using System.Text;
using FishNet.Managing.Timing;
using UnityEngine;
namespace FishNet.Managing.Logging
{
///
/// Configuration ScriptableObject specifying which data to log. Used in conjuction with NetworkManager.
///
[CreateAssetMenu(fileName = "New LevelLoggingConfiguration", menuName = "FishNet/Logging/Level Logging Configuration")]
public class LevelLoggingConfiguration : LoggingConfiguration
{
#region Serialized.
///
/// True to add localtick to logs.
///
[Tooltip("True to add localtick to logs.")]
[SerializeField]
private bool _addLocalTick;
///
/// True to add timestamps to logs.
///
[Tooltip("True to add timestamps to logs.")]
[SerializeField]
private bool _addTimestamps = true;
///
/// True to add timestamps when in editor. False to only include timestamps in builds.
///
[Tooltip("True to add timestamps when in editor. False to only include timestamps in builds.")]
[SerializeField]
private bool _enableTimestampsInEditor;
///
/// Type of logging to use for development builds and editor.
///
[Tooltip("Type of logging to use for development builds and editor.")]
[SerializeField]
private LoggingType _developmentLogging = LoggingType.Common;
///
/// Type of logging to use for GUI builds.
///
[Tooltip("Type of logging to use for GUI builds.")]
[SerializeField]
private LoggingType _guiLogging = LoggingType.Warning;
///
/// Type of logging to use for headless builds.
///
[Tooltip("Type of logging to use for headless builds.")]
[SerializeField]
private LoggingType _headlessLogging = LoggingType.Error;
#endregion
#region Private.
///
/// True when initialized.
///
private bool _initialized;
///
/// Highest type which can be logged.
///
private LoggingType _highestLoggingType = LoggingType.Off;
///
/// Sequential stringbuilder for performance.
///
private static StringBuilder _stringBuilder = new();
#endregion
[APIExclude]
public void LoggingConstructor(bool loggingEnabled, LoggingType development, LoggingType gui, LoggingType headless)
{
base.IsEnabled = loggingEnabled;
_developmentLogging = development;
_guiLogging = gui;
_headlessLogging = headless;
}
///
/// Initializes script for use.
///
///
public override void InitializeOnce()
{
byte currentHighest = (byte)LoggingType.Off;
#if UNITY_SERVER
currentHighest = Math.Max(currentHighest, (byte)_headlessLogging);
#elif DEVELOPMENT
currentHighest = Math.Max(currentHighest, (byte)_developmentLogging);
#else
currentHighest = Math.Max(currentHighest, (byte)_guiLogging);
#endif
_highestLoggingType = (LoggingType)currentHighest;
_initialized = true;
}
///
/// True if can log for loggingType.
///
/// Type of logging being filtered.
///
public override bool CanLog(LoggingType loggingType)
{
if (!base.IsEnabled)
return false;
if (!_initialized)
{
#if DEVELOPMENT
if (Application.isPlaying)
NetworkManagerExtensions.LogError("CanLog called before being initialized.");
else
return true;
#endif
return false;
}
return ((byte)loggingType <= (byte)_highestLoggingType);
}
///
/// Logs a common value if can log.
///
public override void Log(string value)
{
if (CanLog(LoggingType.Common))
Debug.Log(AddSettingsToLog(value));
}
///
/// Logs a warning value if can log.
///
public override void LogWarning(string value)
{
if (CanLog(LoggingType.Warning))
Debug.LogWarning(AddSettingsToLog(value));
}
///
/// Logs an error value if can log.
///
public override void LogError(string value)
{
if (CanLog(LoggingType.Error))
{
Debug.LogError(AddSettingsToLog(value));
}
}
///
/// Clones this logging configuration.
///
///
public override LoggingConfiguration Clone()
{
LevelLoggingConfiguration copy = ScriptableObject.CreateInstance();
copy.LoggingConstructor(base.IsEnabled, _developmentLogging, _guiLogging, _headlessLogging);
copy._addTimestamps = _addTimestamps;
copy._addLocalTick = _addLocalTick;
copy._enableTimestampsInEditor = _enableTimestampsInEditor;
return copy;
}
///
/// Adds onto logging message if settings are enabled to.
///
private string AddSettingsToLog(string value)
{
_stringBuilder.Clear();
if (_addTimestamps && (!Application.isEditor || _enableTimestampsInEditor))
_stringBuilder.Append($"[{DateTime.Now:yyyy.MM.dd HH:mm:ss}] ");
if (_addLocalTick)
{
TimeManager tm = InstanceFinder.TimeManager;
uint tick = (tm == null) ? TimeManager.UNSET_TICK : tm.LocalTick;
_stringBuilder.Append($"LocalTick [{tick}] ");
}
//If anything was added onto string builder then add value, and set value to string builder.
if (_stringBuilder.Length > 0)
{
_stringBuilder.Append(value);
value = _stringBuilder.ToString();
}
return value;
}
}
}