Even More Modifiers  1.0.0.0
A mod for rolling various bonus stats on items
AutoDelegationAttribute.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Reflection;
5 using Loot.Api.Core;
6 using Loot.Api.Delegators;
7 
8 namespace Loot.Api.Attributes
9 {
17  [AttributeUsage(AttributeTargets.Method)]
18  public sealed class AutoDelegation : Attribute
19  {
20  private readonly IEnumerable<string> _delegationTypes;
21 
22  public IEnumerable<string> DelegationTypes => new List<string>(_delegationTypes);
23 
24  public AutoDelegation(params string[] types)
25  {
26  _delegationTypes = new List<string>(GetTargetNames(types));
27  }
28 
29  public AutoDelegation(params DelegationTarget[] targets)
30  {
31  _delegationTypes = new List<string>(
32  GetTargetNames(targets
33  .Select(target => Enum.GetName(typeof(DelegationTarget), target))));
34  }
35 
36  private IEnumerable<string> GetTargetNames(IEnumerable<string> names)
37  => names.Select(GetFilteredName);
38 
39  private string GetFilteredName(string name)
40  {
41  if (name.StartsWith("On")) name = name.Substring(2);
42  if (!name.EndsWith("Event")) name = $"{name}Event";
43  return name;
44  }
45 
46  public void Attach(ModifierDelegatorPlayer delegatorPlayer, MethodInfo method, ModifierEffect effect)
47  {
48  foreach (string type in _delegationTypes)
49  {
50  EventInfo evt = delegatorPlayer.GetType().GetEvent(type, BindingFlags.Instance | BindingFlags.Public);
51  if (evt != null)
52  {
53  try
54  {
55  Delegate handler = Delegate.CreateDelegate(evt.EventHandlerType, effect, method);
56  evt.AddEventHandler(delegatorPlayer, handler);
57  }
58  catch (Exception e)
59  {
60  Loot.Logger.Error("An error just occurred. Please share this error log with the mod author.", e);
61  }
62  }
63  }
64  }
65 
66  public void Detach(ModifierDelegatorPlayer delegatorPlayer, MethodInfo method, ModifierEffect effect)
67  {
68  foreach (string type in _delegationTypes)
69  {
70  EventInfo evt = delegatorPlayer.GetType().GetEvent(type, BindingFlags.Instance | BindingFlags.Public);
71  if (evt != null)
72  {
73  try
74  {
75  Delegate handler = Delegate.CreateDelegate(evt.EventHandlerType, effect, method);
76  evt.RemoveEventHandler(delegatorPlayer, handler);
77  }
78  catch (Exception e)
79  {
80  Loot.Logger.Error("An error just occurred. Please share this error log with the mod author.", e);
81  }
82  }
83  }
84  }
85 
86  // TODO I forgot why I added this
87  //public bool IsMethodCompatibleWithDelegate<T>(MethodInfo method) where T : class
88  //{
89  // Type delegateType = typeof(T);
90  // MethodInfo delegateSignature = delegateType.GetMethod("Invoke");
91 
92  // bool parametersEqual = delegateSignature
93  // .GetParameters()
94  // .Select(x => x.ParameterType)
95  // .SequenceEqual(method.GetParameters()
96  // .Select(x => x.ParameterType));
97 
98  // return delegateSignature.ReturnType == method.ReturnType &&
99  // parametersEqual;
100  //}
101  }
102 }
This attribute may be used to skip usage of AttachDelegations and DetachDelegations Which is a cumber...
A ModifierEffect signifies the effect of a modifier on a player It should house the implementation...
void Detach(ModifierDelegatorPlayer delegatorPlayer, MethodInfo method, ModifierEffect effect)
readonly IEnumerable< string > _delegationTypes
void Attach(ModifierDelegatorPlayer delegatorPlayer, MethodInfo method, ModifierEffect effect)
DelegationTarget
Defines a target that can be used in conjunction with AutoDelegation for identifying the target event...
Holds player-entity data and handles it
AutoDelegation(params DelegationTarget[] targets)