Set up notifier infrastructure

This commit is contained in:
ackwell 2024-01-19 02:09:43 +11:00
parent 8c763d5379
commit 5c15a3a4ff
3 changed files with 90 additions and 0 deletions

View file

@ -0,0 +1,52 @@
using Dalamud.Interface.Internal.Notifications;
using OtterGui.Classes;
namespace Penumbra.Import.Models;
public record class IoNotifier
{
/// <summary> Notification subclass so that we have a distinct type to filter by. </summary>
private class LegallyDistinctNotification : Notification
{
public LegallyDistinctNotification(string content, NotificationType type): base(content, type)
{}
}
private readonly DateTime _startTime = DateTime.UtcNow;
private string _context = "";
/// <summary> Create a new notifier with the specified context appended to any other context already present. </summary>
public IoNotifier WithContext(string context)
=> this with { _context = $"{_context}{context}: "};
/// <summary> Send a warning with any current context to notification channels. </summary>
public void Warning(string content)
=> SendNotification(content, NotificationType.Warning);
/// <summary> Get the current warnings for this notifier. </summary>
/// <remarks> This does not currently filter to notifications with the current notifier's context - it will return all IO notifications from all notifiers. </remarks>
public IEnumerable<string> GetWarnings()
=> GetFilteredNotifications(NotificationType.Warning);
/// <summary> Create an exception with any current context. </summary>
[StackTraceHidden]
public Exception Exception(string message)
=> Exception<Exception>(message);
/// <summary> Create an exception of the provided type with any current context. </summary>
[StackTraceHidden]
public TException Exception<TException>(string message)
where TException : Exception, new()
=> (TException)Activator.CreateInstance(typeof(TException), $"{_context}{message}")!;
private void SendNotification(string message, NotificationType type)
=> Penumbra.Messager.AddMessage(
new LegallyDistinctNotification($"{_context}{message}", type),
true, false, true, false
);
private IEnumerable<string> GetFilteredNotifications(NotificationType type)
=> Penumbra.Messager
.Where(p => p.Key >= _startTime && p.Value is LegallyDistinctNotification && p.Value.NotificationType == type)
.Select(p => p.Value.PrintMessage);
}

View file

@ -25,6 +25,7 @@ public partial class ModEditWindow
private bool _dirty;
public bool PendingIo { get; private set; }
public List<Exception> IoExceptions { get; private set; } = [];
public List<string> IoWarnings { get; private set; } = [];
public MdlTab(ModEditWindow edit, byte[] bytes, string path)
{

View file

@ -63,6 +63,7 @@ public partial class ModEditWindow
DrawExport(tab, childSize, disabled);
DrawIoExceptions(tab);
DrawIoWarnings(tab);
}
private void DrawImport(MdlTab tab, Vector2 size, bool _1)
@ -148,7 +149,43 @@ public partial class ModEditWindow
using var exceptionNode = ImRaii.TreeNode(message);
if (exceptionNode)
{
ImGui.Dummy(new Vector2(ImGui.GetStyle().IndentSpacing, 0));
ImGui.SameLine();
ImGuiUtil.TextWrapped(exception.ToString());
}
}
}
private static void DrawIoWarnings(MdlTab tab)
{
if (tab.IoWarnings.Count == 0)
return;
var size = new Vector2(ImGui.GetContentRegionAvail().X, 0);
using var frame = ImRaii.FramedGroup("Warnings", size, headerPreIcon: FontAwesomeIcon.ExclamationCircle, borderColor: 0xFF40FFFF);
var spaceAvail = ImGui.GetContentRegionAvail().X - ImGui.GetStyle().ItemSpacing.X - 100;
foreach (var (warning, index) in tab.IoWarnings.WithIndex())
{
using var id = ImRaii.PushId(index);
var textSize = ImGui.CalcTextSize(warning).X;
if (textSize <= spaceAvail)
{
ImRaii.TreeNode(warning, ImGuiTreeNodeFlags.Leaf).Dispose();
continue;
}
var firstLine = warning[..(int)Math.Floor(warning.Length * (spaceAvail / textSize))] + "...";
using var warningNode = ImRaii.TreeNode(firstLine);
if (warningNode)
{
ImGui.Dummy(new Vector2(ImGui.GetStyle().IndentSpacing, 0));
ImGui.SameLine();
ImGuiUtil.TextWrapped(warning.ToString());
}
}
}