using System;
using System.Collections.Generic;
namespace BepInEx.Logging
{
///
/// Handles pub-sub event marshalling across all log listeners and sources.
///
public static class Logger
{
///
/// Collection of all log listeners that receive log events.
///
public static ICollection Listeners { get; } = new List();
///
/// Collection of all log source that output log events.
///
public static ICollection Sources { get; } = new LogSourceCollection();
private static readonly ManualLogSource InternalLogSource = CreateLogSource("BepInEx");
internal static void InternalLogEvent(object sender, LogEventArgs eventArgs)
{
foreach (var listener in Listeners)
{
listener?.LogEvent(sender, eventArgs);
}
}
///
/// Logs an entry to the internal logger instance.
///
/// The level of the entry.
/// The data of the entry.
internal static void Log(LogLevel level, object data)
{
InternalLogSource.Log(level, data);
}
internal static void LogFatal(object data) => Log(LogLevel.Fatal, data);
internal static void LogError(object data) => Log(LogLevel.Error, data);
internal static void LogWarning(object data) => Log(LogLevel.Warning, data);
internal static void LogMessage(object data) => Log(LogLevel.Message, data);
internal static void LogInfo(object data) => Log(LogLevel.Info, data);
internal static void LogDebug(object data) => Log(LogLevel.Debug, data);
///
/// Creates a new log source with a name and attaches it to .
///
/// Name of the log source to create.
/// An instance of that allows to write logs.
public static ManualLogSource CreateLogSource(string sourceName)
{
var source = new ManualLogSource(sourceName);
Sources.Add(source);
return source;
}
private class LogSourceCollection : List, ICollection
{
void ICollection.Add(ILogSource item)
{
if (item == null)
throw new ArgumentNullException(nameof(item), "Log sources cannot be null when added to the source list.");
item.LogEvent += InternalLogEvent;
base.Add(item);
}
void ICollection.Clear()
{
foreach (var item in base.ToArray())
{
((ICollection)this).Remove(item);
}
}
bool ICollection.Remove(ILogSource item)
{
if (item == null)
return false;
if (!base.Contains(item))
return false;
item.LogEvent -= InternalLogEvent;
base.Remove(item);
return true;
}
}
}
}