forked from Shardstone/trail-into-darkness
123 lines
3.7 KiB
C#
123 lines
3.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace Jovian.InGameLogging {
|
|
public sealed class GameLogStore : IGameLogStore {
|
|
private readonly LogEntry[] buffer;
|
|
private readonly HashSet<LogChannel> disabledChannels = new();
|
|
private int head;
|
|
private int count;
|
|
|
|
public int Count => count;
|
|
public int Capacity => buffer.Length;
|
|
|
|
public event Action<LogEntry> OnEntryAdded;
|
|
public event Action OnCleared;
|
|
|
|
public GameLogStore(int capacity = 500) {
|
|
buffer = new LogEntry[capacity];
|
|
head = 0;
|
|
count = 0;
|
|
}
|
|
|
|
public void Add(LogChannel channel, string message) {
|
|
if(disabledChannels.Contains(channel)) {
|
|
return;
|
|
}
|
|
var entry = new LogEntry(message, channel, Time.time);
|
|
buffer[head] = entry;
|
|
head = (head + 1) % buffer.Length;
|
|
if(count < buffer.Length) {
|
|
count++;
|
|
}
|
|
OnEntryAdded?.Invoke(entry);
|
|
}
|
|
|
|
public void EnableChannel(LogChannel channel) {
|
|
disabledChannels.Remove(channel);
|
|
}
|
|
|
|
public void DisableChannel(LogChannel channel) {
|
|
disabledChannels.Add(channel);
|
|
}
|
|
|
|
public bool IsChannelEnabled(LogChannel channel) {
|
|
return !disabledChannels.Contains(channel);
|
|
}
|
|
|
|
public void Clear() {
|
|
head = 0;
|
|
count = 0;
|
|
OnCleared?.Invoke();
|
|
}
|
|
|
|
public void Clear(LogChannel channel) {
|
|
var kept = new List<LogEntry>(count);
|
|
var entries = GetEntries();
|
|
for(var i = 0; i < entries.Length; i++) {
|
|
if(entries[i].channel != channel) {
|
|
kept.Add(entries[i]);
|
|
}
|
|
}
|
|
|
|
head = 0;
|
|
count = 0;
|
|
for(int i = 0; i < kept.Count; i++) {
|
|
buffer[i] = kept[i];
|
|
count++;
|
|
}
|
|
head = count % buffer.Length;
|
|
OnCleared?.Invoke();
|
|
}
|
|
|
|
public ReadOnlySpan<LogEntry> GetEntries() {
|
|
if(count < buffer.Length) {
|
|
return new ReadOnlySpan<LogEntry>(buffer, 0, count);
|
|
}
|
|
var result = new LogEntry[count];
|
|
var start = head;
|
|
for(var i = 0; i < count; i++) {
|
|
result[i] = buffer[(start + i) % buffer.Length];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public int GetEntries(LogChannel channel, List<LogEntry> results) {
|
|
results.Clear();
|
|
var entries = GetEntries();
|
|
for(var i = 0; i < entries.Length; i++) {
|
|
if(entries[i].channel == channel) {
|
|
results.Add(entries[i]);
|
|
}
|
|
}
|
|
return results.Count;
|
|
}
|
|
|
|
public GameLogSaveData GetSaveData() {
|
|
var entries = GetEntries();
|
|
var list = new List<LogEntry>(entries.Length);
|
|
foreach(var t in entries) {
|
|
list.Add(t);
|
|
}
|
|
return new GameLogSaveData(list);
|
|
}
|
|
|
|
public void RestoreFromSaveData(GameLogSaveData data) {
|
|
head = 0;
|
|
count = 0;
|
|
if(data?.entries == null) {
|
|
OnCleared?.Invoke();
|
|
return;
|
|
}
|
|
var startIndex = Math.Max(0, data.entries.Count - buffer.Length);
|
|
for(var i = startIndex; i < data.entries.Count; i++) {
|
|
buffer[count] = data.entries[i];
|
|
count++;
|
|
}
|
|
head = count % buffer.Length;
|
|
OnCleared?.Invoke();
|
|
}
|
|
}
|
|
}
|