Skip to content

Commit

Permalink
2.1.7
Browse files Browse the repository at this point in the history
  • Loading branch information
Critical-Impact committed Dec 30, 2024
1 parent 8b697a9 commit eff15de
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 10 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Removed

## [2.1.7] - 2024-12-30

### Added

- ImGui asserts will be caught and logged

## [2.1.6] - 2024-11-23

### Fixed
Expand Down
7 changes: 6 additions & 1 deletion DalaMock/DI/MockContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,19 @@ private void RegisterMockServices(ContainerBuilder builder)
builder.RegisterInstance(this.dalamudConfiguration);
builder.RegisterType<MockDalamudUi>().SingleInstance();
builder.RegisterType<PluginLoader>().SingleInstance();
builder.RegisterType<AssertHandler>().SingleInstance();
builder.RegisterType<MockFileDialogManager>().As<IFileDialogManager>().SingleInstance();
builder.RegisterInstance(this).SingleInstance();
builder.RegisterInstance(new MockWindowSystem("DalaMock"));
builder.RegisterType<MockMockWindow>().AsSelf().As<Window>().SingleInstance();
builder.RegisterType<MockSettingsWindow>().AsSelf().As<Window>().SingleInstance();
builder.RegisterType<LocalPlayersWindow>().AsSelf().As<Window>().SingleInstance();
builder.RegisterType<LocalPlayerEditWindow>().AsSelf().As<Window>().SingleInstance();
builder.Register<ImGuiScene>(_ => ImGuiScene.CreateWindow()).SingleInstance();
builder.Register<ImGuiScene>(c =>
{
var assertHandler = c.Resolve<AssertHandler>();
return ImGuiScene.CreateWindow(assertHandler);
}).SingleInstance();

builder.Register<GraphicsDevice>(
c =>
Expand Down
2 changes: 1 addition & 1 deletion DalaMock/DalaMock.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Nullable>enable</Nullable>
<LangVersion>12.0</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Version>2.1.6</Version>
<Version>2.1.7</Version>
<PackageProjectUrl>https://github.com/Critical-Impact/DalaMock</PackageProjectUrl>
<RepositoryUrl>https://github.com/Critical-Impact/DalaMock</RepositoryUrl>
<Authors>Critical-Impact</Authors>
Expand Down
123 changes: 123 additions & 0 deletions DalaMock/ImGui/AssertHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
namespace DalaMock.Core.Imgui;

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Mime;
using System.Runtime.InteropServices;
using System.Threading;

using Dalamud.Utility;
using Microsoft.Extensions.Logging;
using Serilog;

/// <summary>
/// Class responsible for registering and handling ImGui asserts.
/// </summary>
public class AssertHandler : IDisposable
{
private readonly ILogger<AssertHandler> logger;
private const int HideThreshold = 20;
private const int HidePrintEvery = 500;

private readonly HashSet<string> ignoredAsserts = [];
private readonly Dictionary<string, uint> assertCounts = new();

// Store callback to avoid it from being GC'd
private readonly AssertCallbackDelegate callback;

/// <summary>
/// Initializes a new instance of the <see cref="AssertHandler"/> class.
/// </summary>
public AssertHandler(ILogger<AssertHandler> logger)
{
this.logger = logger;
this.callback = (expr, file, line) => this.OnImGuiAssert(expr, file, line);
}

private delegate void AssertCallbackDelegate(
[MarshalAs(UnmanagedType.LPStr)] string expr,
[MarshalAs(UnmanagedType.LPStr)] string file,
int line);

/// <summary>
/// Gets or sets a value indicating whether ImGui asserts should be shown to the user.
/// </summary>
public bool ShowAsserts { get; set; }

/// <summary>
/// Gets or sets a value indicating whether we want to hide asserts that occur frequently (= every update)
/// and whether we want to log callstacks.
/// </summary>
public bool EnableVerboseLogging { get; set; }

/// <summary>
/// Register the cimgui assert handler with the native library.
/// </summary>
public void Setup()
{
CustomNativeFunctions.igCustom_SetAssertCallback(this.callback);
}

/// <summary>
/// Unregister the cimgui assert handler with the native library.
/// </summary>
public void Shutdown()
{
CustomNativeFunctions.igCustom_SetAssertCallback(null);
}

/// <inheritdoc/>
public void Dispose()
{
this.Shutdown();
}

private void OnImGuiAssert(string expr, string file, int line)
{
var key = $"{file}:{line}";
if (this.ignoredAsserts.Contains(key))
return;

Lazy<string> stackTrace = new(() => new StackTrace(3).ToString());

if (!this.EnableVerboseLogging)
{
if (this.assertCounts.TryGetValue(key, out var count))
{
this.assertCounts[key] = count + 1;

if (count <= HideThreshold || count % HidePrintEvery == 0)
{
this.logger.LogWarning(
"ImGui assertion failed: {Expr} at {File}:{Line} (repeated {Count} times)",
expr,
file,
line,
count);
}
}
else
{
this.assertCounts[key] = 1;
}
}
else
{
this.logger.LogWarning(
"ImGui assertion failed: {Expr} at {File}:{Line}\n{StackTrace:l}",
expr,
file,
line,
stackTrace.Value);
}
}

private static class CustomNativeFunctions
{
[DllImport("cimgui", CallingConvention = CallingConvention.Cdecl)]
#pragma warning disable SA1300
public static extern void igCustom_SetAssertCallback(AssertCallbackDelegate? callback);
#pragma warning restore SA1300
}
}
22 changes: 15 additions & 7 deletions DalaMock/ImGui/ImGuiScene.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ namespace DalaMock.Core.Imgui;
/// </summary>
public partial class ImGuiScene : IDisposable
{
private readonly AssertHandler assertHandler;

public delegate void BuildUiDelegate();

private readonly Dictionary<Texture, TextureView> autoViewsByTexture = new();
Expand All @@ -41,8 +43,10 @@ public partial class ImGuiScene : IDisposable
/// Creates a new window and a new renderer of the specified type, and initializes ImGUI.
/// </summary>
/// <param name="createInfo">Creation details for the window.</param>
public ImGuiScene(WindowCreateInfo createInfo)
/// <param name="assertHandler"></param>
public ImGuiScene(WindowCreateInfo createInfo, AssertHandler assertHandler)
{
this.assertHandler = assertHandler;
GraphicsDevice graphicsDevice;
Sdl2Window window;
VeldridStartup.CreateWindowAndGraphicsDevice(
Expand All @@ -63,6 +67,7 @@ public ImGuiScene(WindowCreateInfo createInfo)

var context = ImGui.CreateContext();
ImGui.SetCurrentContext(context);
assertHandler.Setup();
ImGui.GetIO().Fonts.AddFontDefault();
ImGui.GetIO().BackendFlags |= ImGuiBackendFlags.RendererHasVtxOffset;
ImGui.GetIO().FontGlobalScale = 1;
Expand All @@ -76,7 +81,9 @@ public ImGuiScene(WindowCreateInfo createInfo)
this.GraphicsDevice.MainSwapchain.Framebuffer.OutputDescription);
this.LoadFont(Path.Combine("Fonts", "FontAwesomeFreeSolid.otf"), 12.0f, 0, new ushort[] { 0xe005, 0xf8ff, 0x00 });
this.SetKeyMappings();
this.SetPerFrameImGuiData(0);
ImGui.NewFrame();
ImGui.EndFrame();
}

/// <summary>
Expand Down Expand Up @@ -106,10 +113,11 @@ public void Dispose()
}

/// <summary>
/// Helper method to create a fullscreen window
/// Helper method to create a fullscreen window.
/// </summary>
/// <param name="assertHandler">The assert handler.</param>
/// <returns>Returns a imguiscene.</returns>
public static ImGuiScene CreateWindow()
public static ImGuiScene CreateWindow(AssertHandler assertHandler)
{
var scene = new ImGuiScene(
new WindowCreateInfo
Expand All @@ -118,9 +126,9 @@ public static ImGuiScene CreateWindow()
WindowInitialState = WindowState.Maximized,
WindowWidth = 500,
WindowHeight = 500,
});
},
assertHandler);
scene.Window.Opacity = 1;

return scene;
}

Expand Down Expand Up @@ -189,7 +197,7 @@ protected virtual void Dispose(bool disposing)
if (disposing)
{
}

this.assertHandler.Dispose();
this.Window.Closed -= this.WindowOnClosed;

this.Window.Close();
Expand Down Expand Up @@ -219,4 +227,4 @@ protected virtual void Dispose(bool disposing)
{
this.Dispose(false);
}
}
}
2 changes: 1 addition & 1 deletion DalaMock/Windows/MockWindowSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ public override void Draw()

base.Draw();
}
}
}

0 comments on commit eff15de

Please sign in to comment.