chore: warnings pass

This commit is contained in:
goat 2022-10-29 15:19:52 +02:00
parent 505e37fd28
commit b093323acc
No known key found for this signature in database
GPG key ID: 49E2AA8C6A76498B
49 changed files with 352 additions and 254 deletions

View file

@ -21,36 +21,6 @@ namespace Dalamud.Configuration
this.configDirectory.Create(); this.configDirectory.Create();
} }
/// <summary>
/// Serializes a plugin configuration object.
/// </summary>
/// <param name="config">The configuration object.</param>
/// <returns>A string representing the serialized configuration object.</returns>
internal static string SerializeConfig(object? config)
{
return JsonConvert.SerializeObject(config, Formatting.Indented, new JsonSerializerSettings
{
TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple,
TypeNameHandling = TypeNameHandling.Objects,
});
}
/// <summary>
/// Deserializes a plugin configuration from a string.
/// </summary>
/// <param name="data">The serialized configuration.</param>
/// <returns>The configuration object, or null.</returns>
internal static IPluginConfiguration? DeserializeConfig(string data)
{
return JsonConvert.DeserializeObject<IPluginConfiguration>(
data,
new JsonSerializerSettings
{
TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple,
TypeNameHandling = TypeNameHandling.Objects,
});
}
/// <summary> /// <summary>
/// Save/Load plugin configuration. /// Save/Load plugin configuration.
/// NOTE: Save/Load are still using Type information for now, /// NOTE: Save/Load are still using Type information for now,
@ -145,6 +115,36 @@ namespace Dalamud.Configuration
/// <returns>FileInfo of the config file.</returns> /// <returns>FileInfo of the config file.</returns>
public FileInfo GetConfigFile(string pluginName) => new(Path.Combine(this.configDirectory.FullName, $"{pluginName}.json")); public FileInfo GetConfigFile(string pluginName) => new(Path.Combine(this.configDirectory.FullName, $"{pluginName}.json"));
/// <summary>
/// Serializes a plugin configuration object.
/// </summary>
/// <param name="config">The configuration object.</param>
/// <returns>A string representing the serialized configuration object.</returns>
internal static string SerializeConfig(object? config)
{
return JsonConvert.SerializeObject(config, Formatting.Indented, new JsonSerializerSettings
{
TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple,
TypeNameHandling = TypeNameHandling.Objects,
});
}
/// <summary>
/// Deserializes a plugin configuration from a string.
/// </summary>
/// <param name="data">The serialized configuration.</param>
/// <returns>The configuration object, or null.</returns>
internal static IPluginConfiguration? DeserializeConfig(string data)
{
return JsonConvert.DeserializeObject<IPluginConfiguration>(
data,
new JsonSerializerSettings
{
TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple,
TypeNameHandling = TypeNameHandling.Objects,
});
}
private DirectoryInfo GetDirectoryPath(string pluginName) => new(Path.Combine(this.configDirectory.FullName, pluginName)); private DirectoryInfo GetDirectoryPath(string pluginName) => new(Path.Combine(this.configDirectory.FullName, pluginName));
} }
} }

View file

@ -4,6 +4,7 @@ using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dalamud.Configuration.Internal; using Dalamud.Configuration.Internal;
using Dalamud.Game; using Dalamud.Game;
using Dalamud.Game.Gui.Internal; using Dalamud.Game.Gui.Internal;

View file

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using JetBrains.Annotations; using JetBrains.Annotations;
namespace Dalamud.Game namespace Dalamud.Game

View file

@ -35,11 +35,6 @@ namespace Dalamud.Game.ClientState
private bool lastConditionNone = true; private bool lastConditionNone = true;
private bool lastFramePvP = false; private bool lastFramePvP = false;
/// <summary>
/// Gets client state address resolver.
/// </summary>
internal ClientStateAddressResolver AddressResolver => this.address;
[ServiceManager.ServiceConstructor] [ServiceManager.ServiceConstructor]
private ClientState(SigScanner sigScanner, DalamudStartInfo startInfo) private ClientState(SigScanner sigScanner, DalamudStartInfo startInfo)
{ {
@ -127,6 +122,11 @@ namespace Dalamud.Game.ClientState
/// </summary> /// </summary>
public bool IsPvPExcludingDen { get; private set; } public bool IsPvPExcludingDen { get; private set; }
/// <summary>
/// Gets client state address resolver.
/// </summary>
internal ClientStateAddressResolver AddressResolver => this.address;
/// <summary> /// <summary>
/// Dispose of managed and unmanaged resources. /// Dispose of managed and unmanaged resources.
/// </summary> /// </summary>

View file

@ -149,6 +149,12 @@ namespace Dalamud.Game.Command
return this.commandMap.Remove(command); return this.commandMap.Remove(command);
} }
/// <inheritdoc/>
void IDisposable.Dispose()
{
this.chatGui.CheckMessageHandled -= this.OnCheckMessageHandled;
}
private void OnCheckMessageHandled(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled) private void OnCheckMessageHandled(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled)
{ {
if (type == XivChatType.ErrorMessage && senderId == 0) if (type == XivChatType.ErrorMessage && senderId == 0)
@ -173,10 +179,5 @@ namespace Dalamud.Game.Command
} }
} }
} }
public void Dispose()
{
this.chatGui.CheckMessageHandled -= this.OnCheckMessageHandled;
}
} }
} }

View file

@ -168,7 +168,6 @@ namespace Dalamud.Game
/// <summary> /// <summary>
/// Run given function right away if this function has been called from game's Framework.Update thread, or otherwise run on next Framework.Update call. /// Run given function right away if this function has been called from game's Framework.Update thread, or otherwise run on next Framework.Update call.
/// </summary> /// </summary>
/// <typeparam name="T">Return type.</typeparam>
/// <param name="func">Function to call.</param> /// <param name="func">Function to call.</param>
/// <returns>Task representing the pending or already completed function.</returns> /// <returns>Task representing the pending or already completed function.</returns>
public Task RunOnFrameworkThread(Func<Task> func) => public Task RunOnFrameworkThread(Func<Task> func) =>
@ -287,7 +286,6 @@ namespace Dalamud.Game
/// <summary> /// <summary>
/// Run given function in upcoming Framework.Tick call. /// Run given function in upcoming Framework.Tick call.
/// </summary> /// </summary>
/// <typeparam name="T">Return type.</typeparam>
/// <param name="func">Function to call.</param> /// <param name="func">Function to call.</param>
/// <param name="delay">Wait for given timespan before calling this function.</param> /// <param name="delay">Wait for given timespan before calling this function.</param>
/// <param name="delayTicks">Count given number of Framework.Tick calls before calling this function. This takes precedence over delay parameter.</param> /// <param name="delayTicks">Count given number of Framework.Tick calls before calling this function. This takes precedence over delay parameter.</param>

View file

@ -177,12 +177,6 @@ namespace Dalamud.Game.Gui.FlyText
} }
} }
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction(GameGui gameGui)
{
this.createFlyTextHook.Enable();
}
private static byte[] Terminate(byte[] source) private static byte[] Terminate(byte[] source)
{ {
var terminated = new byte[source.Length + 1]; var terminated = new byte[source.Length + 1];
@ -192,6 +186,12 @@ namespace Dalamud.Game.Gui.FlyText
return terminated; return terminated;
} }
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction(GameGui gameGui)
{
this.createFlyTextHook.Enable();
}
private IntPtr CreateFlyTextDetour( private IntPtr CreateFlyTextDetour(
IntPtr addonFlyText, IntPtr addonFlyText,
FlyTextKind kind, FlyTextKind kind,

View file

@ -85,7 +85,7 @@ namespace Dalamud.Game.Gui.FlyText
/// Serif Val1 with all caps condensed font EXP with Text2 in sans-serif as subtitle. /// Serif Val1 with all caps condensed font EXP with Text2 in sans-serif as subtitle.
/// </summary> /// </summary>
Exp = 14, Exp = 14,
/// <summary> /// <summary>
/// Serif Val1 with all caps condensed font ISLAND EXP with Text2 in sans-serif as subtitle. /// Serif Val1 with all caps condensed font ISLAND EXP with Text2 in sans-serif as subtitle.
/// </summary> /// </summary>

View file

@ -406,25 +406,6 @@ namespace Dalamud.Game.Gui
return IntPtr.Zero; return IntPtr.Zero;
} }
/// <summary>
/// Set the current background music.
/// </summary>
/// <param name="bgmKey">The background music key.</param>
public void SetBgm(ushort bgmKey) => this.setGlobalBgmHook.Original(bgmKey, 0, 0, 0, 0, 0);
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction()
{
this.setGlobalBgmHook.Enable();
this.handleItemHoverHook.Enable();
this.handleItemOutHook.Enable();
this.handleImmHook.Enable();
this.toggleUiHideHook.Enable();
this.handleActionHoverHook.Enable();
this.handleActionOutHook.Enable();
this.utf8StringFromSequenceHook.Enable();
}
/// <summary> /// <summary>
/// Disables the hooks and submodules of this module. /// Disables the hooks and submodules of this module.
/// </summary> /// </summary>
@ -440,6 +421,12 @@ namespace Dalamud.Game.Gui
this.utf8StringFromSequenceHook.Dispose(); this.utf8StringFromSequenceHook.Dispose();
} }
/// <summary>
/// Set the current background music.
/// </summary>
/// <param name="bgmKey">The background music key.</param>
public void SetBgm(ushort bgmKey) => this.setGlobalBgmHook.Original(bgmKey, 0, 0, 0, 0, 0);
/// <summary> /// <summary>
/// Reset the stored "UI hide" state. /// Reset the stored "UI hide" state.
/// </summary> /// </summary>
@ -448,6 +435,19 @@ namespace Dalamud.Game.Gui
this.GameUiHidden = false; this.GameUiHidden = false;
} }
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction()
{
this.setGlobalBgmHook.Enable();
this.handleItemHoverHook.Enable();
this.handleItemOutHook.Enable();
this.handleImmHook.Enable();
this.toggleUiHideHook.Enable();
this.handleActionHoverHook.Enable();
this.handleActionOutHook.Enable();
this.utf8StringFromSequenceHook.Enable();
}
private IntPtr HandleSetGlobalBgmDetour(ushort bgmKey, byte a2, uint a3, uint a4, uint a5, byte a6) private IntPtr HandleSetGlobalBgmDetour(ushort bgmKey, byte a2, uint a3, uint a4, uint a5, byte a6)
{ {
var retVal = this.setGlobalBgmHook.Original(bgmKey, a2, a3, a4, a5, a6); var retVal = this.setGlobalBgmHook.Original(bgmKey, a2, a3, a4, a5, a6);

View file

@ -11,6 +11,7 @@ using Dalamud.Interface.Internal;
using Dalamud.Logging.Internal; using Dalamud.Logging.Internal;
using ImGuiNET; using ImGuiNET;
using PInvoke; using PInvoke;
using static Dalamud.NativeFunctions; using static Dalamud.NativeFunctions;
namespace Dalamud.Game.Gui.Internal namespace Dalamud.Game.Gui.Internal
@ -58,64 +59,6 @@ namespace Dalamud.Game.Gui.Internal
Marshal.FreeHGlobal((IntPtr)this.cursorPos); Marshal.FreeHGlobal((IntPtr)this.cursorPos);
} }
private unsafe void LoadCand(IntPtr hWnd)
{
if (hWnd == IntPtr.Zero)
return;
var hIMC = ImmGetContext(hWnd);
if (hIMC == IntPtr.Zero)
return;
var size = ImmGetCandidateListW(hIMC, 0, IntPtr.Zero, 0);
if (size == 0)
return;
var candlistPtr = Marshal.AllocHGlobal((int)size);
size = ImmGetCandidateListW(hIMC, 0, candlistPtr, (uint)size);
var candlist = this.ImmCandNative = Marshal.PtrToStructure<CandidateList>(candlistPtr);
var pageSize = candlist.PageSize;
var candCount = candlist.Count;
if (pageSize > 0 && candCount > 1)
{
var dwOffsets = new int[candCount];
for (var i = 0; i < candCount; i++)
{
dwOffsets[i] = Marshal.ReadInt32(candlistPtr + ((i + 6) * sizeof(int)));
}
var pageStart = candlist.PageStart;
var cand = new string[pageSize];
this.ImmCand.Clear();
for (var i = 0; i < pageSize; i++)
{
var offStart = dwOffsets[i + pageStart];
var offEnd = i + pageStart + 1 < candCount ? dwOffsets[i + pageStart + 1] : size;
var pStrStart = candlistPtr + (int)offStart;
var pStrEnd = candlistPtr + (int)offEnd;
var len = (int)(pStrEnd.ToInt64() - pStrStart.ToInt64());
if (len > 0)
{
var candBytes = new byte[len];
Marshal.Copy(pStrStart, candBytes, 0, len);
var candStr = Encoding.Unicode.GetString(candBytes);
cand[i] = candStr;
this.ImmCand.Add(candStr);
}
}
Marshal.FreeHGlobal(candlistPtr);
}
}
/// <summary> /// <summary>
/// Processes window messages. /// Processes window messages.
/// </summary> /// </summary>
@ -137,13 +80,19 @@ namespace Dalamud.Game.Gui.Internal
{ {
wParam = Marshal.ReadInt32((IntPtr)wParamPtr); wParam = Marshal.ReadInt32((IntPtr)wParamPtr);
} }
catch { } catch
{
// ignored
}
try try
{ {
lParam = Marshal.ReadInt32((IntPtr)lParamPtr); lParam = Marshal.ReadInt32((IntPtr)lParamPtr);
} }
catch { } catch
{
// ignored
}
switch (wmsg) switch (wmsg)
{ {
@ -246,6 +195,64 @@ namespace Dalamud.Game.Gui.Internal
return new Vector2(this.cursorPos->X, this.cursorPos->Y); return new Vector2(this.cursorPos->X, this.cursorPos->Y);
} }
private unsafe void LoadCand(IntPtr hWnd)
{
if (hWnd == IntPtr.Zero)
return;
var hImc = ImmGetContext(hWnd);
if (hImc == IntPtr.Zero)
return;
var size = ImmGetCandidateListW(hImc, 0, IntPtr.Zero, 0);
if (size == 0)
return;
var candlistPtr = Marshal.AllocHGlobal((int)size);
size = ImmGetCandidateListW(hImc, 0, candlistPtr, (uint)size);
var candlist = this.ImmCandNative = Marshal.PtrToStructure<CandidateList>(candlistPtr);
var pageSize = candlist.PageSize;
var candCount = candlist.Count;
if (pageSize > 0 && candCount > 1)
{
var dwOffsets = new int[candCount];
for (var i = 0; i < candCount; i++)
{
dwOffsets[i] = Marshal.ReadInt32(candlistPtr + ((i + 6) * sizeof(int)));
}
var pageStart = candlist.PageStart;
var cand = new string[pageSize];
this.ImmCand.Clear();
for (var i = 0; i < pageSize; i++)
{
var offStart = dwOffsets[i + pageStart];
var offEnd = i + pageStart + 1 < candCount ? dwOffsets[i + pageStart + 1] : size;
var pStrStart = candlistPtr + (int)offStart;
var pStrEnd = candlistPtr + (int)offEnd;
var len = (int)(pStrEnd.ToInt64() - pStrStart.ToInt64());
if (len > 0)
{
var candBytes = new byte[len];
Marshal.Copy(pStrStart, candBytes, 0, len);
var candStr = Encoding.Unicode.GetString(candBytes);
cand[i] = candStr;
this.ImmCand.Add(candStr);
}
}
Marshal.FreeHGlobal(candlistPtr);
}
}
[ServiceManager.CallWhenServicesReady] [ServiceManager.CallWhenServicesReady]
private void ContinueConstruction(InterfaceManager.InterfaceManagerWithScene interfaceManagerWithScene) private void ContinueConstruction(InterfaceManager.InterfaceManagerWithScene interfaceManagerWithScene)
{ {

View file

@ -26,7 +26,7 @@ namespace Dalamud.Game.Gui.PartyFinder
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="PartyFinderGui"/> class. /// Initializes a new instance of the <see cref="PartyFinderGui"/> class.
/// </summary> /// </summary>
/// <param name="tag">Tag.</param> /// <param name="sigScanner">Sig scanner to use.</param>
[ServiceManager.ServiceConstructor] [ServiceManager.ServiceConstructor]
private PartyFinderGui(SigScanner sigScanner) private PartyFinderGui(SigScanner sigScanner)
{ {

View file

@ -32,7 +32,7 @@ namespace Dalamud.Game.Gui.Toast
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ToastGui"/> class. /// Initializes a new instance of the <see cref="ToastGui"/> class.
/// </summary> /// </summary>
/// <param name="tag">Tag.</param> /// <param name="sigScanner">Sig scanner to use.</param>
[ServiceManager.ServiceConstructor] [ServiceManager.ServiceConstructor]
private ToastGui(SigScanner sigScanner) private ToastGui(SigScanner sigScanner)
{ {

View file

@ -3,8 +3,6 @@ using System.Runtime.InteropServices;
using CheapLoc; using CheapLoc;
using Dalamud.Configuration.Internal; using Dalamud.Configuration.Internal;
//using Dalamud.Data;
//using Dalamud.Game.Gui.ContextMenus;
using Dalamud.Game.Text; using Dalamud.Game.Text;
using Dalamud.Game.Text.SeStringHandling; using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads; using Dalamud.Game.Text.SeStringHandling.Payloads;
@ -12,7 +10,6 @@ using Dalamud.Hooking;
using Dalamud.Interface.Internal; using Dalamud.Interface.Internal;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using FFXIVClientStructs.FFXIV.Component.GUI; using FFXIVClientStructs.FFXIV.Component.GUI;
//using Lumina.Excel.GeneratedSheets;
using Serilog; using Serilog;
using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType; using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType;
@ -142,7 +139,7 @@ namespace Dalamud.Game.Internal
return; return;
} }
if (!configuration.DoButtonsSystemMenu || !interfaceManager.IsDispatchingEvents) if (!this.configuration.DoButtonsSystemMenu || !interfaceManager.IsDispatchingEvents)
{ {
this.hookAgentHudOpenSystemMenu.Original(thisPtr, atkValueArgs, menuSize); this.hookAgentHudOpenSystemMenu.Original(thisPtr, atkValueArgs, menuSize);
return; return;

View file

@ -457,6 +457,7 @@ namespace Dalamud.Game.Text.SeStringHandling
/// <summary> /// <summary>
/// The Island Sanctuary icon. /// The Island Sanctuary icon.
/// </summary>
IslandSanctuary = 116, IslandSanctuary = 116,
} }
} }

View file

@ -15,8 +15,12 @@ namespace Dalamud.Hooking
/// <typeparam name="T">Delegate type to represents a function prototype. This must be the same prototype as original function do.</typeparam> /// <typeparam name="T">Delegate type to represents a function prototype. This must be the same prototype as original function do.</typeparam>
public class Hook<T> : IDisposable, IDalamudHook where T : Delegate public class Hook<T> : IDisposable, IDalamudHook where T : Delegate
{ {
#pragma warning disable SA1310
// ReSharper disable once InconsistentNaming
private const ulong IMAGE_ORDINAL_FLAG64 = 0x8000000000000000; private const ulong IMAGE_ORDINAL_FLAG64 = 0x8000000000000000;
// ReSharper disable once InconsistentNaming
private const uint IMAGE_ORDINAL_FLAG32 = 0x80000000; private const uint IMAGE_ORDINAL_FLAG32 = 0x80000000;
#pragma warning restore SA1310
private readonly IntPtr address; private readonly IntPtr address;

View file

@ -2,6 +2,7 @@ using System;
using System.ComponentModel; using System.ComponentModel;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Dalamud.Memory; using Dalamud.Memory;
namespace Dalamud.Hooking.Internal namespace Dalamud.Hooking.Internal
@ -96,8 +97,7 @@ namespace Dalamud.Hooking.Internal
{ {
lock (HookManager.HookEnableSyncRoot) lock (HookManager.HookEnableSyncRoot)
{ {
if (!NativeFunctions.VirtualProtect(this.Address, (UIntPtr)Marshal.SizeOf<IntPtr>(), if (!NativeFunctions.VirtualProtect(this.Address, (UIntPtr)Marshal.SizeOf<IntPtr>(), MemoryProtection.ExecuteReadWrite, out var oldProtect))
MemoryProtection.ExecuteReadWrite, out var oldProtect))
throw new Win32Exception(Marshal.GetLastWin32Error()); throw new Win32Exception(Marshal.GetLastWin32Error());
Marshal.WriteIntPtr(this.Address, Marshal.GetFunctionPointerForDelegate(this.detourDelegate)); Marshal.WriteIntPtr(this.Address, Marshal.GetFunctionPointerForDelegate(this.detourDelegate));
@ -115,8 +115,7 @@ namespace Dalamud.Hooking.Internal
{ {
lock (HookManager.HookEnableSyncRoot) lock (HookManager.HookEnableSyncRoot)
{ {
if (!NativeFunctions.VirtualProtect(this.Address, (UIntPtr)Marshal.SizeOf<IntPtr>(), if (!NativeFunctions.VirtualProtect(this.Address, (UIntPtr)Marshal.SizeOf<IntPtr>(), MemoryProtection.ExecuteReadWrite, out var oldProtect))
MemoryProtection.ExecuteReadWrite, out var oldProtect))
throw new Win32Exception(Marshal.GetLastWin32Error()); throw new Win32Exception(Marshal.GetLastWin32Error());
Marshal.WriteIntPtr(this.Address, this.pfnOriginal); Marshal.WriteIntPtr(this.Address, this.pfnOriginal);

View file

@ -6,6 +6,10 @@ using Reloaded.Hooks;
namespace Dalamud.Hooking.Internal namespace Dalamud.Hooking.Internal
{ {
/// <summary>
/// Class facilitating hooks via reloaded.
/// </summary>
/// <typeparam name="T">Delegate of the hook.</typeparam>
internal class ReloadedHook<T> : Hook<T> where T : Delegate internal class ReloadedHook<T> : Hook<T> where T : Delegate
{ {
private readonly Reloaded.Hooks.Definitions.IHook<T> hookImpl; private readonly Reloaded.Hooks.Definitions.IHook<T> hookImpl;

View file

@ -9,16 +9,6 @@ namespace Dalamud.Interface.GameFonts
/// </summary> /// </summary>
public class FdtReader public class FdtReader
{ {
private static unsafe T StructureFromByteArray<T> (byte[] data, int offset)
{
var len = Marshal.SizeOf<T>();
if (offset + len > data.Length)
throw new Exception("Data too short");
fixed (byte* ptr = data)
return Marshal.PtrToStructure<T>(new(ptr + offset));
}
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="FdtReader"/> class. /// Initializes a new instance of the <see cref="FdtReader"/> class.
/// </summary> /// </summary>
@ -33,7 +23,7 @@ namespace Dalamud.Interface.GameFonts
this.Glyphs.Add(StructureFromByteArray<FontTableEntry>(data, this.FileHeader.FontTableHeaderOffset + Marshal.SizeOf<FontTableHeader>() + (Marshal.SizeOf<FontTableEntry>() * i))); this.Glyphs.Add(StructureFromByteArray<FontTableEntry>(data, this.FileHeader.FontTableHeaderOffset + Marshal.SizeOf<FontTableHeader>() + (Marshal.SizeOf<FontTableEntry>() * i)));
for (int i = 0, i_ = Math.Min(this.FontHeader.KerningTableEntryCount, this.KerningHeader.Count); i < i_; i++) for (int i = 0, i_ = Math.Min(this.FontHeader.KerningTableEntryCount, this.KerningHeader.Count); i < i_; i++)
this.Distances.Add(StructureFromByteArray<KerningTableEntry>(data, this.FileHeader.KerningTableHeaderOffset+ Marshal.SizeOf<KerningTableHeader>() + (Marshal.SizeOf<KerningTableEntry>() * i))); this.Distances.Add(StructureFromByteArray<KerningTableEntry>(data, this.FileHeader.KerningTableHeaderOffset + Marshal.SizeOf<KerningTableHeader>() + (Marshal.SizeOf<KerningTableEntry>() * i)));
} }
/// <summary> /// <summary>
@ -68,7 +58,7 @@ namespace Dalamud.Interface.GameFonts
/// <returns>Corresponding FontTableEntry, or null if not found.</returns> /// <returns>Corresponding FontTableEntry, or null if not found.</returns>
public FontTableEntry? FindGlyph(int codepoint) public FontTableEntry? FindGlyph(int codepoint)
{ {
var i = this.Glyphs.BinarySearch(new FontTableEntry { CharUtf8 = CodePointToUtf8int32(codepoint) }); var i = this.Glyphs.BinarySearch(new FontTableEntry { CharUtf8 = CodePointToUtf8Int32(codepoint) });
if (i < 0 || i == this.Glyphs.Count) if (i < 0 || i == this.Glyphs.Count)
return null; return null;
return this.Glyphs[i]; return this.Glyphs[i];
@ -95,13 +85,23 @@ namespace Dalamud.Interface.GameFonts
/// <returns>Supposed distance adjustment between given characters.</returns> /// <returns>Supposed distance adjustment between given characters.</returns>
public int GetDistance(int codepoint1, int codepoint2) public int GetDistance(int codepoint1, int codepoint2)
{ {
var i = this.Distances.BinarySearch(new KerningTableEntry { LeftUtf8 = CodePointToUtf8int32(codepoint1), RightUtf8 = CodePointToUtf8int32(codepoint2) }); var i = this.Distances.BinarySearch(new KerningTableEntry { LeftUtf8 = CodePointToUtf8Int32(codepoint1), RightUtf8 = CodePointToUtf8Int32(codepoint2) });
if (i < 0 || i == this.Distances.Count) if (i < 0 || i == this.Distances.Count)
return 0; return 0;
return this.Distances[i].RightOffset; return this.Distances[i].RightOffset;
} }
private static int CodePointToUtf8int32(int codepoint) private static unsafe T StructureFromByteArray<T>(byte[] data, int offset)
{
var len = Marshal.SizeOf<T>();
if (offset + len > data.Length)
throw new Exception("Data too short");
fixed (byte* ptr = data)
return Marshal.PtrToStructure<T>(new(ptr + offset));
}
private static int CodePointToUtf8Int32(int codepoint)
{ {
if (codepoint <= 0x7F) if (codepoint <= 0x7F)
{ {

View file

@ -5,6 +5,7 @@ using System.Numerics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dalamud.Data; using Dalamud.Data;
using Dalamud.Game; using Dalamud.Game;
using Dalamud.Interface.Internal; using Dalamud.Interface.Internal;
@ -12,6 +13,7 @@ using Dalamud.Utility.Timing;
using ImGuiNET; using ImGuiNET;
using Lumina.Data.Files; using Lumina.Data.Files;
using Serilog; using Serilog;
using static Dalamud.Interface.ImGuiHelpers; using static Dalamud.Interface.ImGuiHelpers;
namespace Dalamud.Interface.GameFonts namespace Dalamud.Interface.GameFonts
@ -40,7 +42,9 @@ namespace Dalamud.Interface.GameFonts
private readonly Dictionary<GameFontStyle, int> fontUseCounter = new(); private readonly Dictionary<GameFontStyle, int> fontUseCounter = new();
private readonly Dictionary<GameFontStyle, Dictionary<char, Tuple<int, FdtReader.FontTableEntry>>> glyphRectIds = new(); private readonly Dictionary<GameFontStyle, Dictionary<char, Tuple<int, FdtReader.FontTableEntry>>> glyphRectIds = new();
#pragma warning disable CS0414
private bool isBetweenBuildFontsAndRightAfterImGuiIoFontsBuild = false; private bool isBetweenBuildFontsAndRightAfterImGuiIoFontsBuild = false;
#pragma warning restore CS0414
[ServiceManager.ServiceConstructor] [ServiceManager.ServiceConstructor]
private GameFontManager(DataManager dataManager) private GameFontManager(DataManager dataManager)

View file

@ -1,31 +1,43 @@
using System; using System;
using System.Numerics; using System.Numerics;
using System.Text; using System.Text;
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface; namespace Dalamud.Interface;
/// <summary>
/// Class containing various extensions to ImGui, aiding with building custom widgets.
/// </summary>
public static class ImGuiExtensions public static class ImGuiExtensions
{ {
public static void AddTextClippedEx( /// <summary>
this ImDrawListPtr drawListPtr, Vector2 posMin, Vector2 posMax, string text, Vector2? textSizeIfKnown, /// Draw clipped text.
Vector2 align, Vector4? clipRect) /// </summary>
/// <param name="drawListPtr">Pointer to the draw list.</param>
/// <param name="posMin">Minimum position.</param>
/// <param name="posMax">Maximum position.</param>
/// <param name="text">Text to draw.</param>
/// <param name="textSizeIfKnown">Size of the text, if known.</param>
/// <param name="align">Alignment.</param>
/// <param name="clipRect">Clip rect to use.</param>
public static void AddTextClippedEx(this ImDrawListPtr drawListPtr, Vector2 posMin, Vector2 posMax, string text, Vector2? textSizeIfKnown, Vector2 align, Vector4? clipRect)
{ {
var pos = posMin; var pos = posMin;
var textSize = textSizeIfKnown ?? ImGui.CalcTextSize(text, false, 0); var textSize = textSizeIfKnown ?? ImGui.CalcTextSize(text, false, 0);
var clipMin = clipRect.HasValue ? new Vector2(clipRect.Value.X, clipRect.Value.Y) : posMin; var clipMin = clipRect.HasValue ? new Vector2(clipRect.Value.X, clipRect.Value.Y) : posMin;
var clipMax = clipRect.HasValue ? new Vector2(clipRect.Value.Z, clipRect.Value.W) : posMax; var clipMax = clipRect.HasValue ? new Vector2(clipRect.Value.Z, clipRect.Value.W) : posMax;
var needClipping = (pos.X + textSize.X >= clipMax.X) || (pos.Y + textSize.Y >= clipMax.Y); var needClipping = (pos.X + textSize.X >= clipMax.X) || (pos.Y + textSize.Y >= clipMax.Y);
if (clipRect.HasValue) if (clipRect.HasValue)
needClipping |= (pos.X < clipMin.X) || (pos.Y < clipMin.Y); needClipping |= (pos.X < clipMin.X) || (pos.Y < clipMin.Y);
if (align.X > 0) if (align.X > 0)
{ {
pos.X = Math.Max(pos.X, pos.X + ((posMax.X - pos.X - textSize.X) * align.X)); pos.X = Math.Max(pos.X, pos.X + ((posMax.X - pos.X - textSize.X) * align.X));
} }
if (align.Y > 0) if (align.Y > 0)
{ {
pos.Y = Math.Max(pos.Y, pos.Y + ((posMax.Y - pos.Y - textSize.Y) * align.Y)); pos.Y = Math.Max(pos.Y, pos.Y + ((posMax.Y - pos.Y - textSize.Y) * align.Y));
@ -42,22 +54,32 @@ public static class ImGuiExtensions
} }
} }
/// <summary>
/// Add text to a draw list.
/// </summary>
/// <param name="drawListPtr">Pointer to the draw list.</param>
/// <param name="font">Font to use.</param>
/// <param name="fontSize">Font size.</param>
/// <param name="pos">Position to draw at.</param>
/// <param name="col">Color to use.</param>
/// <param name="textBegin">Text to draw.</param>
/// <param name="cpuFineClipRect">Clip rect to use.</param>
// TODO: This should go into ImDrawList.Manual.cs in ImGui.NET... // TODO: This should go into ImDrawList.Manual.cs in ImGui.NET...
public static unsafe void AddText(this ImDrawListPtr drawListPtr, ImFontPtr font, float fontSize, Vector2 pos, uint col, string textBegin, ref Vector4 cpuFineClipRect) public static unsafe void AddText(this ImDrawListPtr drawListPtr, ImFontPtr font, float fontSize, Vector2 pos, uint col, string textBegin, ref Vector4 cpuFineClipRect)
{ {
var nativeFont = font.NativePtr; var nativeFont = font.NativePtr;
var textBeginByteCount = Encoding.UTF8.GetByteCount(textBegin); var textBeginByteCount = Encoding.UTF8.GetByteCount(textBegin);
var nativeTextBegin = stackalloc byte[textBeginByteCount + 1]; var nativeTextBegin = stackalloc byte[textBeginByteCount + 1];
fixed (char* textBeginPtr = textBegin) fixed (char* textBeginPtr = textBegin)
{ {
var nativeTextBeginOffset = Encoding.UTF8.GetBytes(textBeginPtr, textBegin.Length, nativeTextBegin, textBeginByteCount); var nativeTextBeginOffset = Encoding.UTF8.GetBytes(textBeginPtr, textBegin.Length, nativeTextBegin, textBeginByteCount);
nativeTextBegin[nativeTextBeginOffset] = 0; nativeTextBegin[nativeTextBeginOffset] = 0;
} }
byte* nativeTextEnd = null; byte* nativeTextEnd = null;
var wrapWidth = 0.0f; var wrapWidth = 0.0f;
fixed (Vector4* nativeCpuFineClipRect = &cpuFineClipRect) fixed (Vector4* nativeCpuFineClipRect = &cpuFineClipRect)
{ {
ImGuiNative.ImDrawList_AddText_FontPtr(drawListPtr.NativePtr, nativeFont, fontSize, pos, col, nativeTextBegin, nativeTextEnd, wrapWidth, nativeCpuFineClipRect); ImGuiNative.ImDrawList_AddText_FontPtr(drawListPtr.NativePtr, nativeFont, fontSize, pos, col, nativeTextBegin, nativeTextEnd, wrapWidth, nativeCpuFineClipRect);

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Dalamud.Utility; using Dalamud.Utility;
namespace Dalamud.Interface.ImGuiFileDialog namespace Dalamud.Interface.ImGuiFileDialog

View file

@ -313,7 +313,6 @@ namespace Dalamud.Interface.ImGuiFileDialog
{ {
if (ImGui.BeginChild("##FileDialog_SideBar", size)) if (ImGui.BeginChild("##FileDialog_SideBar", size))
{ {
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + Scaled(5)); ImGui.SetCursorPosY(ImGui.GetCursorPosY() + Scaled(5));
var idx = 0; var idx = 0;
@ -508,6 +507,7 @@ namespace Dalamud.Interface.ImGuiFileDialog
this.pathClicked = this.SelectDirectory(file); this.pathClicked = this.SelectDirectory(file);
return true; return true;
} }
if (this.IsDirectoryMode()) if (this.IsDirectoryMode())
{ {
this.SelectFileName(file); this.SelectFileName(file);

View file

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface.ImGuiFileDialog namespace Dalamud.Interface.ImGuiFileDialog
@ -14,7 +15,9 @@ namespace Dalamud.Interface.ImGuiFileDialog
/// <summary> /// <summary>
/// The flags used to draw the file picker window. /// The flags used to draw the file picker window.
/// </summary> /// </summary>
#pragma warning disable SA1401
public ImGuiWindowFlags WindowFlags; public ImGuiWindowFlags WindowFlags;
#pragma warning restore SA1401
private readonly string title; private readonly string title;
private readonly int selectionCountMax; private readonly int selectionCountMax;

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface.ImGuiFileDialog namespace Dalamud.Interface.ImGuiFileDialog
@ -9,11 +10,13 @@ namespace Dalamud.Interface.ImGuiFileDialog
/// </summary> /// </summary>
public class FileDialogManager public class FileDialogManager
{ {
#pragma warning disable SA1401
/// <summary> Additional quick access items for the side bar.</summary> /// <summary> Additional quick access items for the side bar.</summary>
public readonly List<(string Name, string Path, FontAwesomeIcon Icon, int Position)> CustomSideBarItems = new(); public readonly List<(string Name, string Path, FontAwesomeIcon Icon, int Position)> CustomSideBarItems = new();
/// <summary> Additional flags with which to draw the window. </summary> /// <summary> Additional flags with which to draw the window. </summary>
public ImGuiWindowFlags AddedWindowFlags = ImGuiWindowFlags.None; public ImGuiWindowFlags AddedWindowFlags = ImGuiWindowFlags.None;
#pragma warning restore SA1401
private FileDialog? dialog; private FileDialog? dialog;
private Action<bool, string>? callback; private Action<bool, string>? callback;

View file

@ -28,7 +28,7 @@ namespace Dalamud.Interface
/// <summary> /// <summary>
/// Gets a <see cref="Vector2"/> that is pre-scaled with the <see cref="GlobalScale"/> multiplier. /// Gets a <see cref="Vector2"/> that is pre-scaled with the <see cref="GlobalScale"/> multiplier.
/// </summary> /// </summary>
/// <param name="x">Vector2 X & Y parameter.</param> /// <param name="x">Vector2 X/Y parameter.</param>
/// <returns>A scaled Vector2.</returns> /// <returns>A scaled Vector2.</returns>
public static Vector2 ScaledVector2(float x) => new Vector2(x, x) * GlobalScale; public static Vector2 ScaledVector2(float x) => new Vector2(x, x) * GlobalScale;
@ -381,7 +381,7 @@ namespace Dalamud.Interface
public ushort Height; public ushort Height;
public ushort X; public ushort X;
public ushort Y; public ushort Y;
public uint TextureIndexAndGlyphID; public uint TextureIndexAndGlyphId;
public float GlyphAdvanceX; public float GlyphAdvanceX;
public Vector2 GlyphOffset; public Vector2 GlyphOffset;
public ImFont* Font; public ImFont* Font;
@ -394,15 +394,15 @@ namespace Dalamud.Interface
public int TextureIndex public int TextureIndex
{ {
get => (int)(this.TextureIndexAndGlyphID & TextureIndexMask) >> TextureIndexShift; get => (int)(this.TextureIndexAndGlyphId & TextureIndexMask) >> TextureIndexShift;
set => this.TextureIndexAndGlyphID = (this.TextureIndexAndGlyphID & ~TextureIndexMask) | ((uint)value << TextureIndexShift); set => this.TextureIndexAndGlyphId = (this.TextureIndexAndGlyphId & ~TextureIndexMask) | ((uint)value << TextureIndexShift);
} }
public int GlyphID public int GlyphId
{ {
get => (int)(this.TextureIndexAndGlyphID & GlyphIDMask) >> GlyphIDShift; get => (int)(this.TextureIndexAndGlyphId & GlyphIDMask) >> GlyphIDShift;
set => this.TextureIndexAndGlyphID = (this.TextureIndexAndGlyphID & ~GlyphIDMask) | ((uint)value << GlyphIDShift); set => this.TextureIndexAndGlyphId = (this.TextureIndexAndGlyphId & ~GlyphIDMask) | ((uint)value << GlyphIDShift);
} }
}; }
} }
} }

View file

@ -48,7 +48,7 @@ namespace Dalamud.Interface.Internal
private readonly CreditsWindow creditsWindow; private readonly CreditsWindow creditsWindow;
private readonly DataWindow dataWindow; private readonly DataWindow dataWindow;
private readonly GamepadModeNotifierWindow gamepadModeNotifierWindow; private readonly GamepadModeNotifierWindow gamepadModeNotifierWindow;
private readonly IMEWindow imeWindow; private readonly ImeWindow imeWindow;
private readonly ConsoleWindow consoleWindow; private readonly ConsoleWindow consoleWindow;
private readonly PluginStatWindow pluginStatWindow; private readonly PluginStatWindow pluginStatWindow;
private readonly PluginInstallerWindow pluginWindow; private readonly PluginInstallerWindow pluginWindow;
@ -93,7 +93,7 @@ namespace Dalamud.Interface.Internal
this.creditsWindow = new CreditsWindow() { IsOpen = false }; this.creditsWindow = new CreditsWindow() { IsOpen = false };
this.dataWindow = new DataWindow() { IsOpen = false }; this.dataWindow = new DataWindow() { IsOpen = false };
this.gamepadModeNotifierWindow = new GamepadModeNotifierWindow() { IsOpen = false }; this.gamepadModeNotifierWindow = new GamepadModeNotifierWindow() { IsOpen = false };
this.imeWindow = new IMEWindow() { IsOpen = false }; this.imeWindow = new ImeWindow() { IsOpen = false };
this.consoleWindow = new ConsoleWindow() { IsOpen = configuration.LogOpenAtStartup }; this.consoleWindow = new ConsoleWindow() { IsOpen = configuration.LogOpenAtStartup };
this.pluginStatWindow = new PluginStatWindow() { IsOpen = false }; this.pluginStatWindow = new PluginStatWindow() { IsOpen = false };
this.pluginWindow = new PluginInstallerWindow(pluginImageCache) { IsOpen = false }; this.pluginWindow = new PluginInstallerWindow(pluginImageCache) { IsOpen = false };
@ -231,7 +231,7 @@ namespace Dalamud.Interface.Internal
public void OpenGamepadModeNotifierWindow() => this.gamepadModeNotifierWindow.IsOpen = true; public void OpenGamepadModeNotifierWindow() => this.gamepadModeNotifierWindow.IsOpen = true;
/// <summary> /// <summary>
/// Opens the <see cref="IMEWindow"/>. /// Opens the <see cref="ImeWindow"/>.
/// </summary> /// </summary>
public void OpenImeWindow() => this.imeWindow.IsOpen = true; public void OpenImeWindow() => this.imeWindow.IsOpen = true;
@ -276,7 +276,7 @@ namespace Dalamud.Interface.Internal
public void OpenProfiler() => this.profilerWindow.IsOpen = true; public void OpenProfiler() => this.profilerWindow.IsOpen = true;
/// <summary> /// <summary>
/// Opens the <see cref="BranchSwitcherWindow"/> /// Opens the <see cref="BranchSwitcherWindow"/>.
/// </summary> /// </summary>
public void OpenBranchSwitcher() => this.branchSwitcherWindow.IsOpen = true; public void OpenBranchSwitcher() => this.branchSwitcherWindow.IsOpen = true;
@ -285,7 +285,7 @@ namespace Dalamud.Interface.Internal
#region Close #region Close
/// <summary> /// <summary>
/// Closes the <see cref="IMEWindow"/>. /// Closes the <see cref="ImeWindow"/>.
/// </summary> /// </summary>
public void CloseImeWindow() => this.imeWindow.IsOpen = false; public void CloseImeWindow() => this.imeWindow.IsOpen = false;
@ -342,7 +342,7 @@ namespace Dalamud.Interface.Internal
public void ToggleGamepadModeNotifierWindow() => this.gamepadModeNotifierWindow.Toggle(); public void ToggleGamepadModeNotifierWindow() => this.gamepadModeNotifierWindow.Toggle();
/// <summary> /// <summary>
/// Toggles the <see cref="IMEWindow"/>. /// Toggles the <see cref="ImeWindow"/>.
/// </summary> /// </summary>
public void ToggleIMEWindow() => this.imeWindow.Toggle(); public void ToggleIMEWindow() => this.imeWindow.Toggle();

View file

@ -7,6 +7,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using Dalamud.Configuration.Internal; using Dalamud.Configuration.Internal;
using Dalamud.Game; using Dalamud.Game;
using Dalamud.Game.ClientState.GamePad; using Dalamud.Game.ClientState.GamePad;
@ -100,6 +101,7 @@ namespace Dalamud.Interface.Internal
[UnmanagedFunctionPointer(CallingConvention.ThisCall)] [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate IntPtr ProcessMessageDelegate(IntPtr hWnd, uint msg, ulong wParam, ulong lParam, IntPtr handeled); private delegate IntPtr ProcessMessageDelegate(IntPtr hWnd, uint msg, ulong wParam, ulong lParam, IntPtr handeled);
/// <summary> /// <summary>
/// This event gets called each frame to facilitate ImGui drawing. /// This event gets called each frame to facilitate ImGui drawing.
/// </summary> /// </summary>
@ -1135,7 +1137,7 @@ namespace Dalamud.Interface.Internal
} }
/// <summary> /// <summary>
/// Associated InterfaceManager. /// Gets the associated InterfaceManager.
/// </summary> /// </summary>
public InterfaceManager Manager { get; init; } public InterfaceManager Manager { get; init; }
} }

View file

@ -51,6 +51,7 @@ namespace Dalamud.Interface.Internal.ManagedAsserts
// TODO: Needs to be updated for ImGui 1.88 // TODO: Needs to be updated for ImGui 1.88
return; return;
#pragma warning disable CS0162
if (!AssertsEnabled) if (!AssertsEnabled)
{ {
return; return;
@ -93,6 +94,7 @@ namespace Dalamud.Interface.Internal.ManagedAsserts
ShowAssert(source, $"Mismatched Begin/BeginChild vs End/EndChild calls: did you call End/EndChild too much?\n\ncSnap.WindowStackSize = {cSnap.WindowStackSize}"); ShowAssert(source, $"Mismatched Begin/BeginChild vs End/EndChild calls: did you call End/EndChild too much?\n\ncSnap.WindowStackSize = {cSnap.WindowStackSize}");
} }
} }
#pragma warning restore CS0162
} }
private static void ShowAssert(string source, string message) private static void ShowAssert(string source, string message)

View file

@ -19,7 +19,8 @@ namespace Dalamud.Interface.Internal.Windows
/// </summary> /// </summary>
internal class CreditsWindow : Window, IDisposable internal class CreditsWindow : Window, IDisposable
{ {
private const float CreditFPS = 60.0f; private const float CreditFps = 60.0f;
private const string ThankYouText = "Thank you!";
private const string CreditsTextTempl = @" private const string CreditsTextTempl = @"
Dalamud Dalamud
A FFXIV Plugin Framework A FFXIV Plugin Framework
@ -163,7 +164,6 @@ Contribute at: https://github.com/goatsoft/Dalamud
private string creditsText; private string creditsText;
private GameFontHandle? thankYouFont; private GameFontHandle? thankYouFont;
private const string thankYouText = "Thank you!";
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="CreditsWindow"/> class. /// Initializes a new instance of the <see cref="CreditsWindow"/> class.
@ -265,11 +265,11 @@ Contribute at: https://github.com/goatsoft/Dalamud
if (this.thankYouFont != null) if (this.thankYouFont != null)
{ {
ImGui.PushFont(this.thankYouFont.ImFont); ImGui.PushFont(this.thankYouFont.ImFont);
var thankYouLenX = ImGui.CalcTextSize(thankYouText).X; var thankYouLenX = ImGui.CalcTextSize(ThankYouText).X;
ImGui.Dummy(new Vector2((windowX / 2) - (thankYouLenX / 2), 0f)); ImGui.Dummy(new Vector2((windowX / 2) - (thankYouLenX / 2), 0f));
ImGui.SameLine(); ImGui.SameLine();
ImGui.TextUnformatted(thankYouText); ImGui.TextUnformatted(ThankYouText);
ImGui.PopFont(); ImGui.PopFont();
} }
@ -278,7 +278,7 @@ Contribute at: https://github.com/goatsoft/Dalamud
ImGui.PopStyleVar(); ImGui.PopStyleVar();
if (this.creditsThrottler.Elapsed.TotalMilliseconds > (1000.0f / CreditFPS)) if (this.creditsThrottler.Elapsed.TotalMilliseconds > (1000.0f / CreditFps))
{ {
var curY = ImGui.GetScrollY(); var curY = ImGui.GetScrollY();
var maxY = ImGui.GetScrollMaxY(); var maxY = ImGui.GetScrollMaxY();

View file

@ -10,14 +10,14 @@ namespace Dalamud.Interface.Internal.Windows
/// <summary> /// <summary>
/// A window for displaying IME details. /// A window for displaying IME details.
/// </summary> /// </summary>
internal unsafe class IMEWindow : Window internal unsafe class ImeWindow : Window
{ {
private const int ImePageSize = 9; private const int ImePageSize = 9;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="IMEWindow"/> class. /// Initializes a new instance of the <see cref="ImeWindow"/> class.
/// </summary> /// </summary>
public IMEWindow() public ImeWindow()
: base("Dalamud IME", ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoFocusOnAppearing | ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoBackground) : base("Dalamud IME", ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoFocusOnAppearing | ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoBackground)
{ {
this.Size = new Vector2(100, 200); this.Size = new Vector2(100, 200);
@ -38,8 +38,8 @@ namespace Dalamud.Interface.Internal.Windows
return; return;
} }
//ImGui.Text($"{ime.GetCursorPos()}"); // ImGui.Text($"{ime.GetCursorPos()}");
//ImGui.Text($"{ImGui.GetWindowViewport().WorkSize}"); // ImGui.Text($"{ImGui.GetWindowViewport().WorkSize}");
} }
/// <inheritdoc/> /// <inheritdoc/>

View file

@ -1518,8 +1518,9 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
ImGui.TextWrapped(Locs.PluginBody_Outdated); ImGui.TextWrapped(Locs.PluginBody_Outdated);
ImGui.PopStyleColor(); ImGui.PopStyleColor();
} }
else if (plugin is { IsBanned: true }) // Banned warning else if (plugin is { IsBanned: true })
{ {
// Banned warning
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed); ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
ImGuiHelpers.SafeTextWrapped(plugin.BanReason.IsNullOrEmpty() ImGuiHelpers.SafeTextWrapped(plugin.BanReason.IsNullOrEmpty()
? Locs.PluginBody_Banned ? Locs.PluginBody_Banned
@ -1539,8 +1540,9 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
ImGui.TextWrapped(Locs.PluginBody_Policy); ImGui.TextWrapped(Locs.PluginBody_Policy);
ImGui.PopStyleColor(); ImGui.PopStyleColor();
} }
else if (plugin is { State: PluginState.LoadError or PluginState.DependencyResolutionFailed }) // Load failed warning else if (plugin is { State: PluginState.LoadError or PluginState.DependencyResolutionFailed })
{ {
// Load failed warning
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed); ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
ImGui.TextWrapped(Locs.PluginBody_LoadFailed); ImGui.TextWrapped(Locs.PluginBody_LoadFailed);
ImGui.PopStyleColor(); ImGui.PopStyleColor();
@ -1803,7 +1805,7 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
var configuration = Service<DalamudConfiguration>.Get(); var configuration = Service<DalamudConfiguration>.Get();
var commandManager = Service<CommandManager>.Get(); var commandManager = Service<CommandManager>.Get();
var testingOptIn = var testingOptIn =
configuration.PluginTestingOptIns?.FirstOrDefault(x => x.InternalName == plugin.Manifest.InternalName); configuration.PluginTestingOptIns?.FirstOrDefault(x => x.InternalName == plugin.Manifest.InternalName);
var trouble = false; var trouble = false;
@ -2179,9 +2181,10 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
plugin.ReloadManifest(); plugin.ReloadManifest();
} }
var enableTask = Task.Run(() => plugin.Enable()) var enableTask = Task.Run(plugin.Enable)
.ContinueWith(this.DisplayErrorContinuation, .ContinueWith(
Locs.ErrorModal_EnableFail(plugin.Name)); this.DisplayErrorContinuation,
Locs.ErrorModal_EnableFail(plugin.Name));
enableTask.Wait(); enableTask.Wait();
if (!enableTask.Result) if (!enableTask.Result)
@ -2191,8 +2194,9 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
} }
var loadTask = Task.Run(() => plugin.LoadAsync(PluginLoadReason.Installer)) var loadTask = Task.Run(() => plugin.LoadAsync(PluginLoadReason.Installer))
.ContinueWith(this.DisplayErrorContinuation, .ContinueWith(
Locs.ErrorModal_LoadFail(plugin.Name)); this.DisplayErrorContinuation,
Locs.ErrorModal_LoadFail(plugin.Name));
loadTask.Wait(); loadTask.Wait();
this.enableDisableStatus = OperationStatus.Complete; this.enableDisableStatus = OperationStatus.Complete;
@ -2200,9 +2204,10 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
if (!loadTask.Result) if (!loadTask.Result)
return; return;
notifications.AddNotification(Locs.Notifications_PluginEnabled(plugin.Manifest.Name), notifications.AddNotification(
Locs.Notifications_PluginEnabledTitle, Locs.Notifications_PluginEnabled(plugin.Manifest.Name),
NotificationType.Success); Locs.Notifications_PluginEnabledTitle,
NotificationType.Success);
}); });
if (availableUpdate != default && !availableUpdate.InstalledPlugin.IsDev) if (availableUpdate != default && !availableUpdate.InstalledPlugin.IsDev)
@ -2833,6 +2838,7 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
public static string PluginBody_Plugin3rdPartyRepo(string url) => Loc.Localize("InstallerPlugin3rdPartyRepo", "From custom plugin repository {0}").Format(url); public static string PluginBody_Plugin3rdPartyRepo(string url) => Loc.Localize("InstallerPlugin3rdPartyRepo", "From custom plugin repository {0}").Format(url);
public static string PluginBody_AvailableDevPlugin => Loc.Localize("InstallerDevPlugin", " This plugin is available in one of your repos, please remove it from the devPlugins folder."); public static string PluginBody_AvailableDevPlugin => Loc.Localize("InstallerDevPlugin", " This plugin is available in one of your repos, please remove it from the devPlugins folder.");
public static string PluginBody_Outdated => Loc.Localize("InstallerOutdatedPluginBody ", "This plugin is outdated and incompatible at the moment. Please wait for it to be updated by its author."); public static string PluginBody_Outdated => Loc.Localize("InstallerOutdatedPluginBody ", "This plugin is outdated and incompatible at the moment. Please wait for it to be updated by its author.");
public static string PluginBody_Orphaned => Loc.Localize("InstallerOrphanedPluginBody ", "This plugin's source repository is no longer available. You may need to reinstall it from its repository, or re-add the repository."); public static string PluginBody_Orphaned => Loc.Localize("InstallerOrphanedPluginBody ", "This plugin's source repository is no longer available. You may need to reinstall it from its repository, or re-add the repository.");

View file

@ -188,7 +188,6 @@ namespace Dalamud.Interface.Internal.Windows
ImGui.TableNextColumn(); ImGui.TableNextColumn();
ImGui.Text($"{handlerHistory.Key}"); ImGui.Text($"{handlerHistory.Key}");
ImGui.TableNextColumn(); ImGui.TableNextColumn();
ImGui.Text($"{handlerHistory.Value.Last():F4}ms"); ImGui.Text($"{handlerHistory.Value.Last():F4}ms");

View file

@ -1,7 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Utility.Numerics; using Dalamud.Utility.Numerics;
@ -10,29 +12,30 @@ using ImGuiNET;
namespace Dalamud.Interface.Internal.Windows; namespace Dalamud.Interface.Internal.Windows;
/// <summary>
/// Class used to draw the Dalamud profiler.
/// </summary>
public class ProfilerWindow : Window public class ProfilerWindow : Window
{ {
private double min; private double min;
private double max; private double max;
private List<List<Tuple<double, double>>> occupied = new(); private List<List<Tuple<double, double>>> occupied = new();
public ProfilerWindow() : base("Profiler", forceMainWindow: true) { } /// <summary>
/// Initializes a new instance of the <see cref="ProfilerWindow"/> class.
/// </summary>
public ProfilerWindow()
: base("Profiler", forceMainWindow: true)
{
}
/// <inheritdoc cref="Window.OnOpen"/>
public override void OnOpen() public override void OnOpen()
{ {
this.min = Timings.AllTimings.Keys.Min(x => x.StartTime); this.min = Timings.AllTimings.Keys.Min(x => x.StartTime);
this.max = Timings.AllTimings.Keys.Max(x => x.EndTime); this.max = Timings.AllTimings.Keys.Max(x => x.EndTime);
} }
private class RectInfo
{
internal TimingHandle Timing;
internal Vector2 MinPos;
internal Vector2 MaxPos;
internal Vector4 RectColor;
internal bool Hover;
}
/// <inheritdoc/> /// <inheritdoc/>
public override void Draw() public override void Draw()
{ {
@ -249,4 +252,14 @@ public class ProfilerWindow : Window
ImGui.Text("Max: " + actualMax.ToString("0.000")); ImGui.Text("Max: " + actualMax.ToString("0.000"));
ImGui.Text("Timings: " + Timings.AllTimings.Count); ImGui.Text("Timings: " + Timings.AllTimings.Count);
} }
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Internals")]
private class RectInfo
{
internal TimingHandle Timing;
internal Vector2 MinPos;
internal Vector2 MaxPos;
internal Vector4 RectColor;
internal bool Hover;
}
} }

View file

@ -13,6 +13,7 @@ namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps
/// </summary> /// </summary>
internal class ContextMenuAgingStep : IAgingStep internal class ContextMenuAgingStep : IAgingStep
{ {
/*
private SubStep currentSubStep; private SubStep currentSubStep;
private uint clickedItemId; private uint clickedItemId;
@ -36,6 +37,7 @@ namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps
TestMultiple, TestMultiple,
Finish, Finish,
} }
*/
/// <inheritdoc/> /// <inheritdoc/>
public string Name => "Test Context Menu"; public string Name => "Test Context Menu";
@ -141,13 +143,15 @@ namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps
/// <inheritdoc/> /// <inheritdoc/>
public void CleanUp() public void CleanUp()
{ {
// var contextMenu = Service<ContextMenu>.Get(); /*
// contextMenu.ContextMenuOpened -= this.ContextMenuOnContextMenuOpened; var contextMenu = Service<ContextMenu>.Get();
contextMenu.ContextMenuOpened -= this.ContextMenuOnContextMenuOpened;
this.currentSubStep = SubStep.Start; this.currentSubStep = SubStep.Start;
this.clickedItemId = 0; this.clickedItemId = 0;
this.clickedPlayerName = null; this.clickedPlayerName = null;
this.multipleTriggerOne = this.multipleTriggerTwo = false; this.multipleTriggerOne = this.multipleTriggerTwo = false;
*/
} }
/* /*

View file

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Dalamud.Configuration.Internal; using Dalamud.Configuration.Internal;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Utility; using Dalamud.Utility;
@ -16,9 +17,9 @@ namespace Dalamud.Interface.Style
/// </summary> /// </summary>
public abstract class StyleModel public abstract class StyleModel
{ {
private static int NumPushedStyles = 0; private static int numPushedStyles = 0;
private static int NumPushedColors = 0; private static int numPushedColors = 0;
private static bool HasPushedOnce = false; private static bool hasPushedOnce = false;
/// <summary> /// <summary>
/// Gets or sets the name of the style model. /// Gets or sets the name of the style model.
@ -130,11 +131,11 @@ namespace Dalamud.Interface.Style
/// </summary> /// </summary>
public void Pop() public void Pop()
{ {
if (!HasPushedOnce) if (!hasPushedOnce)
throw new InvalidOperationException("Wasn't pushed at least once."); throw new InvalidOperationException("Wasn't pushed at least once.");
ImGui.PopStyleVar(NumPushedStyles); ImGui.PopStyleVar(numPushedStyles);
ImGui.PopStyleColor(NumPushedColors); ImGui.PopStyleColor(numPushedColors);
} }
/// <summary> /// <summary>
@ -146,8 +147,8 @@ namespace Dalamud.Interface.Style
{ {
ImGui.PushStyleVar(style, arg); ImGui.PushStyleVar(style, arg);
if (!HasPushedOnce) if (!hasPushedOnce)
NumPushedStyles++; numPushedStyles++;
} }
/// <summary> /// <summary>
@ -159,8 +160,8 @@ namespace Dalamud.Interface.Style
{ {
ImGui.PushStyleVar(style, arg); ImGui.PushStyleVar(style, arg);
if (!HasPushedOnce) if (!hasPushedOnce)
NumPushedStyles++; numPushedStyles++;
} }
/// <summary> /// <summary>
@ -172,8 +173,8 @@ namespace Dalamud.Interface.Style
{ {
ImGui.PushStyleColor(color, value); ImGui.PushStyleColor(color, value);
if (!HasPushedOnce) if (!hasPushedOnce)
NumPushedColors++; numPushedColors++;
} }
/// <summary> /// <summary>
@ -181,7 +182,7 @@ namespace Dalamud.Interface.Style
/// </summary> /// </summary>
protected void DonePushing() protected void DonePushing()
{ {
HasPushedOnce = true; hasPushedOnce = true;
} }
} }
} }

View file

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using Dalamud.IoC; using Dalamud.IoC;
using Dalamud.IoC.Internal; using Dalamud.IoC.Internal;
using ImGuiScene; using ImGuiScene;
@ -202,14 +203,6 @@ namespace Dalamud.Interface
/// </summary> /// </summary>
internal Guid Id { get; init; } = Guid.NewGuid(); internal Guid Id { get; init; } = Guid.NewGuid();
/// <summary>
/// Trigger the action associated with this entry.
/// </summary>
internal void Trigger()
{
this.onTriggered();
}
/// <inheritdoc/> /// <inheritdoc/>
public int CompareTo(TitleScreenMenuEntry? other) public int CompareTo(TitleScreenMenuEntry? other)
{ {
@ -235,6 +228,14 @@ namespace Dalamud.Interface
return string.Compare(this.Name, other.Name, StringComparison.InvariantCultureIgnoreCase); return string.Compare(this.Name, other.Name, StringComparison.InvariantCultureIgnoreCase);
return string.Compare(this.Name, other.Name, StringComparison.InvariantCulture); return string.Compare(this.Name, other.Name, StringComparison.InvariantCulture);
} }
/// <summary>
/// Trigger the action associated with this entry.
/// </summary>
internal void Trigger()
{
this.onTriggered();
}
} }
} }
} }

View file

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dalamud.Configuration.Internal; using Dalamud.Configuration.Internal;
using Dalamud.Game; using Dalamud.Game;
using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.ClientState.Conditions;

View file

@ -1815,6 +1815,7 @@ namespace Dalamud
/// <summary> /// <summary>
/// Native dbghelp functions. /// Native dbghelp functions.
/// </summary> /// </summary>
[SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1201:Elements should appear in the correct order", Justification = "Native funcs")]
internal static partial class NativeFunctions internal static partial class NativeFunctions
{ {
/// <summary> /// <summary>

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dalamud.Logging.Internal; using Dalamud.Logging.Internal;
using Dalamud.Support; using Dalamud.Support;
using Dalamud.Utility.Timing; using Dalamud.Utility.Timing;

View file

@ -4,6 +4,7 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dalamud.Configuration.Internal; using Dalamud.Configuration.Internal;
using Dalamud.Game; using Dalamud.Game;
using Dalamud.Game.Gui.Dtr; using Dalamud.Game.Gui.Dtr;

View file

@ -12,9 +12,12 @@ namespace Dalamud.Plugin.Internal.Types;
/// </summary> /// </summary>
internal record LocalPluginManifest : PluginManifest internal record LocalPluginManifest : PluginManifest
{ {
/// <summary>
/// Flag indicating that a plugin was installed from the official repo.
/// </summary>
[JsonIgnore] [JsonIgnore]
public const string FlagMainRepo = "OFFICIAL"; public const string FlagMainRepo = "OFFICIAL";
/// <summary> /// <summary>
/// Gets or sets a value indicating whether the plugin is disabled and should not be loaded. /// Gets or sets a value indicating whether the plugin is disabled and should not be loaded.
/// This value supersedes the ".disabled" file functionality and should not be included in the plugin master. /// This value supersedes the ".disabled" file functionality and should not be included in the plugin master.

View file

@ -137,9 +137,9 @@ internal record PluginManifest
/// <summary> /// <summary>
/// Gets the required Dalamud load step for this plugin to load. Takes precedence over LoadPriority. /// Gets the required Dalamud load step for this plugin to load. Takes precedence over LoadPriority.
/// Valid values are: /// Valid values are:
/// 0. During Framework.Tick, when drawing facilities are available /// 0. During Framework.Tick, when drawing facilities are available.
/// 1. During Framework.Tick /// 1. During Framework.Tick.
/// 2. No requirement /// 2. No requirement.
/// </summary> /// </summary>
[JsonProperty] [JsonProperty]
public int LoadRequiredState { get; init; } public int LoadRequiredState { get; init; }
@ -157,7 +157,7 @@ internal record PluginManifest
public int LoadPriority { get; init; } public int LoadPriority { get; init; }
/// <summary> /// <summary>
/// Gets a value indicating whether the plugin can be unloaded asynchronously. /// Gets a value indicating whether the plugin can be unloaded asynchronously.
/// </summary> /// </summary>
[JsonProperty] [JsonProperty]
public bool CanUnloadAsync { get; init; } public bool CanUnloadAsync { get; init; }

View file

@ -99,7 +99,6 @@ internal class DataShare : IServiceType
cache.UserAssemblyNames.Add(callerName); cache.UserAssemblyNames.Add(callerName);
return true; return true;
} }
/// <summary> /// <summary>
@ -108,7 +107,7 @@ internal class DataShare : IServiceType
/// </summary> /// </summary>
/// <typeparam name="T">The type of the stored data - needs to be a reference type that is shared through Dalamud itself, not loaded by the plugin.</typeparam> /// <typeparam name="T">The type of the stored data - needs to be a reference type that is shared through Dalamud itself, not loaded by the plugin.</typeparam>
/// <param name="tag">The name for the data cache.</param> /// <param name="tag">The name for the data cache.</param>
/// <returns>The requested data</returns> /// <returns>The requested data.</returns>
/// <exception cref="KeyNotFoundException">Thrown if <paramref name="tag"/> is not registered.</exception> /// <exception cref="KeyNotFoundException">Thrown if <paramref name="tag"/> is not registered.</exception>
/// <exception cref="DataCacheTypeMismatchError">Thrown if a cache for <paramref name="tag"/> exists, but contains data of a type not assignable to <typeparamref name="T>"/>.</exception> /// <exception cref="DataCacheTypeMismatchError">Thrown if a cache for <paramref name="tag"/> exists, but contains data of a type not assignable to <typeparamref name="T>"/>.</exception>
/// <exception cref="DataCacheValueNullError">Thrown if the stored data for a cache is null.</exception> /// <exception cref="DataCacheValueNullError">Thrown if the stored data for a cache is null.</exception>

View file

@ -4,6 +4,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dalamud.Configuration.Internal; using Dalamud.Configuration.Internal;
using Dalamud.Game; using Dalamud.Game;
using Dalamud.IoC.Internal; using Dalamud.IoC.Internal;

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dalamud.IoC; using Dalamud.IoC;
using Dalamud.IoC.Internal; using Dalamud.IoC.Internal;
using Dalamud.Utility.Timing; using Dalamud.Utility.Timing;
@ -95,7 +96,7 @@ namespace Dalamud
/// <summary> /// <summary>
/// Attempt to pull the instance out of the service locator. /// Attempt to pull the instance out of the service locator.
/// </summary> /// </summary>
/// <param name="propagateException">Specifies which exceptions to propagate.</param> /// <param name="propagateException">Specifies which exceptions to propagate.</param>
/// <returns>The object if registered, null otherwise.</returns> /// <returns>The object if registered, null otherwise.</returns>
public static T? GetNullable(ExceptionPropagationMode propagateException = ExceptionPropagationMode.PropagateNonUnloaded) public static T? GetNullable(ExceptionPropagationMode propagateException = ExceptionPropagationMode.PropagateNonUnloaded)
{ {

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Security.Cryptography;
namespace Dalamud.Utility namespace Dalamud.Utility
{ {
@ -24,7 +25,7 @@ namespace Dalamud.Utility
/// <returns>The computed hash.</returns> /// <returns>The computed hash.</returns>
internal static string GetSha256Hash(byte[] buffer) internal static string GetSha256Hash(byte[] buffer)
{ {
using var sha = new System.Security.Cryptography.SHA256Managed(); using var sha = SHA256.Create();
var hash = sha.ComputeHash(buffer); var hash = sha.ComputeHash(buffer);
return ByteArrayToString(hash); return ByteArrayToString(hash);
} }

View file

@ -2,15 +2,24 @@ using System.Threading;
namespace Dalamud.Utility.Timing; namespace Dalamud.Utility.Timing;
/// <summary>
/// Class representing a timing event.
/// </summary>
public class TimingEvent public class TimingEvent
{ {
private static long IdCounter = 0;
/// <summary> /// <summary>
/// Id of this timing event. /// Id of this timing event.
/// </summary> /// </summary>
public readonly long Id = Interlocked.Increment(ref IdCounter); #pragma warning disable SA1401
public readonly long Id = Interlocked.Increment(ref idCounter);
#pragma warning restore SA1401
private static long idCounter = 0;
/// <summary>
/// Initializes a new instance of the <see cref="TimingEvent"/> class.
/// </summary>
/// <param name="name">Name of the event.</param>
internal TimingEvent(string name) internal TimingEvent(string name)
{ {
this.Name = name; this.Name = name;

View file

@ -15,7 +15,8 @@ public sealed class TimingHandle : TimingEvent, IDisposable, IComparable<TimingH
/// Initializes a new instance of the <see cref="TimingHandle"/> class. /// Initializes a new instance of the <see cref="TimingHandle"/> class.
/// </summary> /// </summary>
/// <param name="name">The name of this timing.</param> /// <param name="name">The name of this timing.</param>
internal TimingHandle(string name) : base(name) internal TimingHandle(string name)
: base(name)
{ {
this.Stack = Timings.TaskTimingHandles; this.Stack = Timings.TaskTimingHandles;

View file

@ -22,9 +22,12 @@ public static class Timings
/// </summary> /// </summary>
internal static readonly SortedList<TimingHandle, TimingHandle> AllTimings = new(); internal static readonly SortedList<TimingHandle, TimingHandle> AllTimings = new();
/// <summary>
/// List of all timing events.
/// </summary>
internal static readonly List<TimingEvent> Events = new(); internal static readonly List<TimingEvent> Events = new();
private static readonly AsyncLocal<Tuple<int?, List<TimingHandle>>> taskTimingHandleStorage = new(); private static readonly AsyncLocal<Tuple<int?, List<TimingHandle>>> TaskTimingHandleStorage = new();
/// <summary> /// <summary>
/// Gets or sets all active timings of current thread. /// Gets or sets all active timings of current thread.
@ -33,11 +36,11 @@ public static class Timings
{ {
get get
{ {
if (taskTimingHandleStorage.Value == null || taskTimingHandleStorage.Value.Item1 != Task.CurrentId) if (TaskTimingHandleStorage.Value == null || TaskTimingHandleStorage.Value.Item1 != Task.CurrentId)
taskTimingHandleStorage.Value = Tuple.Create<int?, List<TimingHandle>>(Task.CurrentId, new()); TaskTimingHandleStorage.Value = Tuple.Create<int?, List<TimingHandle>>(Task.CurrentId, new());
return taskTimingHandleStorage.Value!.Item2!; return TaskTimingHandleStorage.Value!.Item2!;
} }
set => taskTimingHandleStorage.Value = Tuple.Create(Task.CurrentId, value); set => TaskTimingHandleStorage.Value = Tuple.Create(Task.CurrentId, value);
} }
/// <summary> /// <summary>
@ -115,9 +118,11 @@ public static class Timings
/// <param name="memberName">Name of the calling member.</param> /// <param name="memberName">Name of the calling member.</param>
/// <param name="sourceFilePath">Name of the calling file.</param> /// <param name="sourceFilePath">Name of the calling file.</param>
/// <param name="sourceLineNumber">Name of the calling line number.</param> /// <param name="sourceLineNumber">Name of the calling line number.</param>
/// <returns>Disposable that stops the timing once disposed.</returns> public static void Event(
public static void Event(string name, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", string name,
[CallerLineNumber] int sourceLineNumber = 0) [CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{ {
lock (Events) lock (Events)
{ {