Code cleanup, documentation

This commit is contained in:
r00telement
2022-01-09 23:07:50 +00:00
parent c8abfcdb05
commit 5f07ee691d
14 changed files with 176 additions and 41 deletions

View File

@@ -319,7 +319,7 @@ namespace PlayerTags.GameInterface.ContextMenus
ContextMenuOpenedDelegate contextMenuOpenedDelegate = ContextMenuOpened;
if (m_CurrentSelectedItem is OpenSubContextMenuItem openSubContextMenuItem)
{
contextMenuOpenedDelegate = openSubContextMenuItem.OpenedAction;
contextMenuOpenedDelegate = openSubContextMenuItem.Opened;
}
// Read the context menu items from the game, then allow subscribers to modify them
@@ -442,7 +442,7 @@ namespace PlayerTags.GameInterface.ContextMenus
objectName = GameInterfaceHelper.ReadSeString((IntPtr)agentContext->ObjectName.StringPtr);
}
gameObjectContext = new GameObjectContext(agentContext->ObjectId, agentContext->ObjectContentIdLower, objectName, agentContext->ObjectWorldId);
gameObjectContext = new GameObjectContext(agentContext->GameObjectId, agentContext->GameObjectContentIdLower, objectName, agentContext->GameObjectWorldId);
}
var contextMenuOpenedArgs = new ContextMenuOpenedArgs(addon, agent, parentAddonName, initialContextMenuItems)

View File

@@ -3,18 +3,35 @@ using System;
namespace PlayerTags.GameInterface.ContextMenus
{
/// <summary>
/// An item in a context menu.
/// </summary>
public abstract class ContextMenuItem
{
/// <summary>
/// The name of the item.
/// </summary>
public SeString Name { get; set; }
/// <summary>
/// Whether the item is enabled. When enabled, an item is selectable.
/// </summary>
public bool IsEnabled { get; set; } = true;
public bool HasPreviousArrow { get; set; } = false;
public bool HasNextArrow { get; set; } = false;
/// <summary>
/// The indicator of the item.
/// </summary>
public ContextMenuItemIndicator Indicator { get; set; } = ContextMenuItemIndicator.None;
/// <summary>
/// The agent of the item.
/// </summary>
internal IntPtr Agent { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="ContextMenuItem"/> class.
/// </summary>
/// <param name="name">The name of the item.</param>
public ContextMenuItem(SeString name)
{
Name = name;

View File

@@ -0,0 +1,21 @@
namespace PlayerTags.GameInterface.ContextMenus
{
/// <summary>
/// An indicator displayed on a context menu item.
/// </summary>
public enum ContextMenuItemIndicator
{
/// <summary>
/// The item has no indicator.
/// </summary>
None,
/// <summary>
/// The item has a previous indicator.
/// </summary>
Previous,
/// <summary>
/// The item has a next indicator.
/// </summary>
Next
}
}

View File

@@ -65,7 +65,7 @@ namespace PlayerTags.GameInterface.ContextMenus
}
}
public int HasPreviousArrowFlagsIndex
public int HasPreviousIndicatorFlagsIndex
{
get
{
@@ -78,7 +78,7 @@ namespace PlayerTags.GameInterface.ContextMenus
}
}
public int HasNextArrowFlagsIndex
public int HasNextIndicatorFlagsIndex
{
get
{
@@ -254,25 +254,34 @@ namespace PlayerTags.GameInterface.ContextMenus
}
byte action = *(actions + contextMenuItemAtkValueBaseIndex);
// Get the has previous arrow flag
var hasPreviousArrowFlagsAtkValue = &m_AtkValues[HasPreviousArrowFlagsIndex];
var hasPreviousArrow = HasFlag(hasPreviousArrowFlagsAtkValue->UInt, contextMenuItemIndex);
// Get the has previous indicator flag
var hasPreviousIndicatorFlagsAtkValue = &m_AtkValues[HasPreviousIndicatorFlagsIndex];
var hasPreviousIndicator = HasFlag(hasPreviousIndicatorFlagsAtkValue->UInt, contextMenuItemIndex);
// Get the has next arrow flag
var hasNextArrowFlagsAtkValue = &m_AtkValues[HasNextArrowFlagsIndex];
var hasNextArrow = HasFlag(hasNextArrowFlagsAtkValue->UInt, contextMenuItemIndex);
// Get the has next indicator flag
var hasNextIndicatorlagsAtkValue = &m_AtkValues[HasNextIndicatorFlagsIndex];
var hasNextIndicator = HasFlag(hasNextIndicatorlagsAtkValue->UInt, contextMenuItemIndex);
ContextMenuItemIndicator indicator = ContextMenuItemIndicator.None;
if (hasPreviousIndicator)
{
indicator = ContextMenuItemIndicator.Previous;
}
else if (hasNextIndicator)
{
indicator = ContextMenuItemIndicator.Next;
}
var gameContextMenuItem = new GameContextMenuItem(name, action)
{
Agent = m_Agent,
IsEnabled = isEnabled,
HasPreviousArrow = hasPreviousArrow,
HasNextArrow = hasNextArrow
Indicator = indicator
};
gameContextMenuItems.Add(gameContextMenuItem);
PluginLog.Debug($"Read Name={gameContextMenuItem.Name} Action={gameContextMenuItem.Action} IsEnabled={gameContextMenuItem.IsEnabled} HasPreviousArrow={gameContextMenuItem.HasPreviousArrow} HasNextArrow={gameContextMenuItem.HasNextArrow}");
PluginLog.Debug($"Read Name={gameContextMenuItem.Name} Action={gameContextMenuItem.ItemSelectedAction} IsEnabled={gameContextMenuItem.IsEnabled} Indicator={gameContextMenuItem.Indicator}");
}
return gameContextMenuItems.ToArray();
@@ -327,12 +336,12 @@ namespace PlayerTags.GameInterface.ContextMenus
contextMenuItemCountAtkValue->UInt = (uint)contextMenuOpenedArgs.ContextMenuItems.Count();
// Clear the previous arrow flags
var hasPreviousArrowAtkValue = &m_AtkValues[HasPreviousArrowFlagsIndex];
hasPreviousArrowAtkValue->UInt = 0;
var hasPreviousIndicatorAtkValue = &m_AtkValues[HasPreviousIndicatorFlagsIndex];
hasPreviousIndicatorAtkValue->UInt = 0;
// Clear the next arrow flags
var subContextMenusFlagsAtkValue = &m_AtkValues[HasNextArrowFlagsIndex];
subContextMenusFlagsAtkValue->UInt = 0;
var hasNextIndiactorFlagsAtkValue = &m_AtkValues[HasNextIndicatorFlagsIndex];
hasNextIndiactorFlagsAtkValue->UInt = 0;
for (int contextMenuItemIndex = 0; contextMenuItemIndex < contextMenuOpenedArgs.ContextMenuItems.Count(); ++contextMenuItemIndex)
{
@@ -357,7 +366,7 @@ namespace PlayerTags.GameInterface.ContextMenus
byte action = 0;
if (contextMenuItem is GameContextMenuItem gameContextMenuItem)
{
action = gameContextMenuItem.Action;
action = gameContextMenuItem.ItemSelectedAction;
}
else if (contextMenuItem is CustomContextMenuItem customContextMenuItem)
{
@@ -393,10 +402,16 @@ namespace PlayerTags.GameInterface.ContextMenus
}
*(actions + FirstContextMenuItemIndex + contextMenuItemIndex) = action;
SetFlag(ref hasPreviousArrowAtkValue->UInt, contextMenuItemIndex, contextMenuItem.HasPreviousArrow);
SetFlag(ref subContextMenusFlagsAtkValue->UInt, contextMenuItemIndex, contextMenuItem.HasNextArrow);
if (contextMenuItem.Indicator == ContextMenuItemIndicator.Previous)
{
SetFlag(ref hasPreviousIndicatorAtkValue->UInt, contextMenuItemIndex, true);
}
else if (contextMenuItem.Indicator == ContextMenuItemIndicator.Next)
{
SetFlag(ref hasNextIndiactorFlagsAtkValue->UInt, contextMenuItemIndex, true);
}
PluginLog.Debug($"Write Name={contextMenuItem.Name} Action={action} IsEnabled={contextMenuItem.IsEnabled} HasPreviousArrow={contextMenuItem.HasPreviousArrow} HasNextArrow={contextMenuItem.HasNextArrow}");
PluginLog.Debug($"Write Name={contextMenuItem.Name} Action={action} IsEnabled={contextMenuItem.IsEnabled} Indicator={contextMenuItem.Indicator}");
}
Print();

View File

@@ -2,10 +2,21 @@
namespace PlayerTags.GameInterface.ContextMenus
{
/// <summary>
/// An item in a context menu with a user defined action.
/// </summary>
public class CustomContextMenuItem : ContextMenuItem
{
/// <summary>
/// The action that will be called when the item is selected.
/// </summary>
public CustomContextMenuItemSelectedDelegate ItemSelected { get; }
/// <summary>
/// Initializes a new instance of the <see cref="CustomContextMenuItem"/> class.
/// </summary>
/// <param name="name">The name of the item.</param>
/// <param name="itemSelected">The action that will be called when the item is selected.</param>
internal CustomContextMenuItem(SeString name, CustomContextMenuItemSelectedDelegate itemSelected)
: base(name)
{

View File

@@ -1,7 +1,7 @@
namespace PlayerTags.GameInterface.ContextMenus
{
/// <summary>
/// Provides data for <see cref="CustomContextMenuItemSelectedDelegate"/> events.
/// Provides data for <see cref="CustomContextMenuItemSelectedDelegate"/> methods.
/// </summary>
public class CustomContextMenuItemSelectedArgs
{
@@ -15,6 +15,11 @@
/// </summary>
public CustomContextMenuItem SelectedItem { get; init; }
/// <summary>
/// Initializes a new instance of the <see cref="CustomContextMenuItemSelectedArgs"/> class.
/// </summary>
/// <param name="contextMenuOpenedArgs">The currently opened context menu.</param>
/// <param name="selectedItem">The selected item within the currently opened context menu.</param>
public CustomContextMenuItemSelectedArgs(ContextMenuOpenedArgs contextMenuOpenedArgs, CustomContextMenuItem selectedItem)
{
ContextMenuOpenedArgs = contextMenuOpenedArgs;

View File

@@ -1,4 +1,8 @@
namespace PlayerTags.GameInterface.ContextMenus
{
/// <summary>
/// Represents the method that handles when a <see cref="CustomContextMenuItem"/> is selected.
/// </summary>
/// <param name="args">The data associated with the selected <see cref="CustomContextMenuItem"/>.</param>
public delegate void CustomContextMenuItemSelectedDelegate(CustomContextMenuItemSelectedArgs args);
}

View File

@@ -16,9 +16,9 @@ namespace FFXIVClientStructs.FFXIV.Client.UI.Agent
[FieldOffset(0xD08)] public byte* SubContextMenuTitle;
[FieldOffset(0xD18)] public unsafe AgentContextItemData* ItemData;
[FieldOffset(0xE08)] public Utf8String ObjectName;
[FieldOffset(0xEE0)] public uint ObjectContentIdLower;
[FieldOffset(0xEF0)] public uint ObjectId;
[FieldOffset(0xF00)] public ushort ObjectWorldId;
[FieldOffset(0xEE0)] public uint GameObjectContentIdLower;
[FieldOffset(0xEF0)] public uint GameObjectId;
[FieldOffset(0xF00)] public ushort GameObjectWorldId;
[FieldOffset(0x1740)] public bool IsSubContextMenu;
}
}

View File

@@ -1,16 +1,26 @@
using Dalamud.Game.Text.SeStringHandling;
using System;
namespace PlayerTags.GameInterface.ContextMenus
{
/// <summary>
/// An item in a context menu that with a specific game action.
/// </summary>
public class GameContextMenuItem : ContextMenuItem
{
public byte Action { get; }
/// <summary>
/// The game action that will be handled when the item is selected.
/// </summary>
public byte ItemSelectedAction { get; }
public GameContextMenuItem(SeString name, byte action)
/// <summary>
/// Initializes a new instance of the <see cref="GameContextMenuItem"/> class.
/// </summary>
/// <param name="name">The name of the item.</param>
/// <param name="itemSelectedAction">The game action that will be handled when the item is selected.</param>
public GameContextMenuItem(SeString name, byte itemSelectedAction)
: base(name)
{
Action = action;
ItemSelectedAction = itemSelectedAction;
}
}
}

View File

@@ -2,20 +2,42 @@
namespace PlayerTags.GameInterface.ContextMenus
{
/// <summary>
/// Provides game object context to a context menu.
/// </summary>
public class GameObjectContext
{
/// <summary>
/// The id of the game object.
/// </summary>
public uint Id { get; }
public uint ContentIdLower { get; }
/// <summary>
/// The lower content id of the game object.
/// </summary>
public uint LowerContentId { get; }
/// <summary>
/// The name of the game object.
/// </summary>
public SeString? Name { get; }
/// <summary>
/// The world id of the game object.
/// </summary>
public ushort WorldId { get; }
public GameObjectContext(uint id, uint contentIdLower, SeString name, ushort worldId)
/// <summary>
/// Initializes a new instance of the <see cref="GameObjectContext"/> class.
/// </summary>
/// <param name="id">The id of the game object.</param>
/// <param name="lowerContentId">The lower content id of the game object.</param>
/// <param name="name">The name of the game object.</param>
/// <param name="worldId">The world id of the game object.</param>
public GameObjectContext(uint id, uint lowerContentId, SeString name, ushort worldId)
{
Id = id;
ContentIdLower = contentIdLower;
LowerContentId = lowerContentId;
Name = name;
WorldId = worldId;
}

View File

@@ -1,13 +1,31 @@
namespace PlayerTags.GameInterface.ContextMenus
{
/// <summary>
/// Provides item context to a context menu.
/// </summary>
public class ItemContext
{
/// <summary>
/// The id of the item.
/// </summary>
public uint Id { get; }
/// <summary>
/// The count of the item in the stack.
/// </summary>
public uint Count { get; }
/// <summary>
/// Whether the item is high quality.
/// </summary>
public bool IsHighQuality { get; }
/// <summary>
/// Initializes a new instance of the <see cref="ItemContext"/> class.
/// </summary>
/// <param name="id">The id of the item.</param>
/// <param name="count">The count of the item in the stack.</param>
/// <param name="isHighQuality">Whether the item is high quality.</param>
public ItemContext(uint id, uint count, bool isHighQuality)
{
Id = id;

View File

@@ -2,15 +2,26 @@
namespace PlayerTags.GameInterface.ContextMenus
{
/// <summary>
/// An item in a context menu that can open a sub context menu.
/// </summary>
public class OpenSubContextMenuItem : ContextMenuItem
{
public ContextMenuOpenedDelegate OpenedAction { get; set; }
/// <summary>
/// The action that will be called when the item is selected.
/// </summary>
public ContextMenuOpenedDelegate Opened { get; set; }
internal OpenSubContextMenuItem(SeString name, ContextMenuOpenedDelegate openedAction)
/// <summary>
/// Initializes a new instance of the <see cref="OpenSubContextMenuItem"/> class.
/// </summary>
/// <param name="name">The name of the item.</param>
/// <param name="opened">The action that will be called when the item is selected.</param>
internal OpenSubContextMenuItem(SeString name, ContextMenuOpenedDelegate opened)
: base(name)
{
OpenedAction = openedAction;
HasNextArrow = true;
Opened = opened;
Indicator = ContextMenuItemIndicator.Next;
}
}
}

View File

@@ -121,6 +121,7 @@ namespace PlayerTags.GameInterface
}
IMemorySpace.Free((void*)ptr, size);
ptr = IntPtr.Zero;
}
}
}

View File

@@ -7,7 +7,7 @@ using System.Reflection;
namespace PlayerTags
{
/// <summary>
/// Generates names based on an existing list of words.
/// Generates names based on existing lists of words.
/// </summary>
public static class RandomNameGenerator
{
@@ -94,7 +94,7 @@ namespace PlayerTags
}
/// <summary>
/// Gets a deterministic hash code for the given string/
/// Gets a deterministic hash code for the given string.
/// </summary>
/// <param name="str">The string to hash.</param>
/// <returns>A deterministic hash code.</returns>