Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / props / weapon / WeaponManager.cs
@小李xl 小李xl on 24 Aug 2022 4 KB 架构调整
  1. using System.Reflection;
  2. using System;
  3. using System.Collections.Generic;
  4. using Godot;
  5.  
  6. /// <summary>
  7. /// 武器管理类, 负责武器注册和创建
  8. /// </summary>
  9. public static class WeaponManager
  10. {
  11. private static Dictionary<string, Func<Weapon>> registerData = new Dictionary<string, Func<Weapon>>();
  12.  
  13. /// <summary>
  14. /// 从一个指定的程序集中扫描并注册武器对象
  15. /// </summary>
  16. /// <param name="assembly">数据集</param>
  17. public static void RegisterWeaponFromAssembly(Assembly assembly)
  18. {
  19. var types = assembly.GetTypes();
  20. foreach (var type in types)
  21. {
  22. //注册类
  23. Attribute[] attribute = Attribute.GetCustomAttributes(type, typeof(RegisterWeapon), false);
  24. if (attribute != null && attribute.Length > 0)
  25. {
  26. if (!typeof(Weapon).IsAssignableFrom(type))
  27. {
  28. throw new Exception($"注册武器类'{type.FullName}'没有继承类'Weapon'!");
  29. }
  30. var atts = (RegisterWeapon[])attribute;
  31. foreach (var att in atts)
  32. {
  33. //注册类
  34. if (att.AttributeType == null) //没有指定属性类型
  35. {
  36. RegisterWeapon(att.Id, () =>
  37. {
  38. return Activator.CreateInstance(type, att.Id, new WeaponAttribute()) as Weapon;
  39. });
  40. }
  41. else
  42. {
  43. if (!typeof(WeaponAttribute).IsAssignableFrom(att.AttributeType))
  44. {
  45. throw new Exception($"注册武器类'{type.FullName}'标注的特性中参数'AttributeType'类型没有继承'WeaponAttribute'!");
  46. }
  47. RegisterWeapon(att.Id, () =>
  48. {
  49. return Activator.CreateInstance(type, att.Id, Activator.CreateInstance(att.AttributeType)) as Weapon;
  50. });
  51. }
  52. }
  53. }
  54.  
  55. //注册函数
  56. MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
  57. foreach (var method in methods)
  58. {
  59. Attribute mAttribute;
  60. //
  61. if ((mAttribute = Attribute.GetCustomAttribute(method, typeof(RegisterWeaponFunction), false)) != null)
  62. {
  63. if (!typeof(Weapon).IsAssignableFrom(method.ReturnType)) //返回值类型不是 Weapon
  64. {
  65. throw new Exception($"注册武器函数'{method.DeclaringType.FullName}.{method.Name}'返回值类型不为'Weapon'!");
  66. }
  67. var args = method.GetParameters();
  68. if (args == null || args.Length != 1 || args[0].ParameterType != typeof(string)) //参数类型不正确
  69. {
  70. throw new Exception($"注册武器函数'{method.DeclaringType.FullName}.{method.Name}'参数不满足(string id)类型");
  71. }
  72. var att = (RegisterWeaponFunction)mAttribute;
  73. //注册函数
  74. RegisterWeapon(att.Id, () =>
  75. {
  76. return method.Invoke(null, new object[] { att.Id }) as Weapon;
  77. });
  78. }
  79. }
  80. }
  81. }
  82.  
  83. /// <summary>
  84. /// 注册当个武器对象
  85. /// </summary>
  86. /// <param name="id">武器唯一id, 该id不能重复</param>
  87. /// <param name="callBack">获取武器时的回调函数, 函数返回武器对象</param>
  88. public static void RegisterWeapon(string id, Func<Weapon> callBack)
  89. {
  90. if (registerData.ContainsKey(id))
  91. {
  92. throw new Exception($"武器id: '{id} 已经被注册!'");
  93. }
  94. registerData.Add(id, callBack);
  95. }
  96.  
  97. /// <summary>
  98. /// 根据武器唯一id获取
  99. /// </summary>
  100. /// <param name="id">武器id</param>
  101. public static Weapon GetGun(string id)
  102. {
  103. if (registerData.TryGetValue(id, out var callback))
  104. {
  105. return callback();
  106. }
  107. throw new Exception($"当前武器'{id}未被注册'");
  108. }
  109.  
  110. /// <summary>
  111. /// 根据武器唯一id获取
  112. /// </summary>
  113. /// <param name="id">武器id</param>
  114. public static T GetGun<T>(string id) where T : Weapon
  115. {
  116. return (T)GetGun(id);
  117. }
  118. }