| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using Dalamud.Game.Command;
- using HuntBuddy.Attributes;
- namespace HuntBuddy
- {
- public class PluginCommandManager<THost> : IDisposable
- {
- private readonly CommandManager _commandManager;
- private readonly (string, CommandInfo)[] _pluginCommands;
- private readonly THost _host;
- public PluginCommandManager(THost host, CommandManager commandManager)
- {
- this._commandManager = commandManager;
- this._host = host;
- this._pluginCommands = host!.GetType().GetMethods(BindingFlags.NonPublic | BindingFlags.Public |
- BindingFlags.Static | BindingFlags.Instance)
- .Where(method => method.GetCustomAttribute<CommandAttribute>() != null)
- .SelectMany(GetCommandInfoTuple)
- .ToArray();
- AddCommandHandlers();
- }
- // http://codebetter.com/patricksmacchia/2008/11/19/an-easy-and-efficient-way-to-improve-net-code-performances/
- // Benchmarking this myself gave similar results, so I'm doing this to somewhat counteract using reflection to access command attributes.
- // I like the convenience of attributes, but in principle it's a bit slower to use them as opposed to just initializing CommandInfos directly.
- // It's usually sub-1 millisecond anyways, though. It probably doesn't matter at all.
- private void AddCommandHandlers()
- {
- for (var i = 0; i < this._pluginCommands.Length; i++)
- {
- var (command, commandInfo) = this._pluginCommands[i];
- this._commandManager.AddHandler(command, commandInfo);
- }
- }
- private void RemoveCommandHandlers()
- {
- for (var i = 0; i < this._pluginCommands.Length; i++)
- {
- var (command, _) = this._pluginCommands[i];
- this._commandManager.RemoveHandler(command);
- }
- }
- private IEnumerable<(string, CommandInfo)> GetCommandInfoTuple(MethodInfo method)
- {
- var handlerDelegate = (CommandInfo.HandlerDelegate)Delegate.CreateDelegate(typeof(CommandInfo.HandlerDelegate), this._host, method);
- var command = handlerDelegate.Method.GetCustomAttribute<CommandAttribute>();
- var aliases = handlerDelegate.Method.GetCustomAttribute<AliasesAttribute>();
- var helpMessage = handlerDelegate.Method.GetCustomAttribute<HelpMessageAttribute>();
- var doNotShowInHelp = handlerDelegate.Method.GetCustomAttribute<DoNotShowInHelpAttribute>();
- var commandInfo = new CommandInfo(handlerDelegate)
- {
- HelpMessage = helpMessage?.HelpMessage ?? string.Empty,
- ShowInHelp = doNotShowInHelp == null,
- };
- // Create list of tuples that will be filled with one tuple per alias, in addition to the base command tuple.
- var commandInfoTuples = new List<(string, CommandInfo)> { (command!.Command, commandInfo) };
- if (aliases != null)
- {
- // ReSharper disable once LoopCanBeConvertedToQuery
- for (var i = 0; i < aliases.Aliases.Length; i++)
- {
- commandInfoTuples.Add((aliases.Aliases[i], commandInfo));
- }
- }
- return commandInfoTuples;
- }
- public void Dispose()
- {
- RemoveCommandHandlers();
- GC.SuppressFinalize(this);
- }
- }
- }
|