You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
5.2 KiB

  1. //----------------------------------------------------------------------------
  2. // Copyright (C) 2004-2017 by EMGU Corporation. All rights reserved.
  3. //----------------------------------------------------------------------------
  4. using System;
  5. using System.Reflection;
  6. using Emgu.Util;
  7. using Emgu.Util.TypeEnum;
  8. using Emgu.CV.Reflection;
  9. namespace Emgu.CV.UI
  10. {
  11. /// <summary>
  12. /// An operation contains the MethodInfo and the methods parameters. It provides a way to invoke a specific method with the specific parameters.
  13. /// </summary>
  14. public class Operation: ICodeGenerable
  15. {
  16. private MethodInfo _mi;
  17. private Object[] _parameters;
  18. /// <summary>
  19. /// The MethodInfo
  20. /// </summary>
  21. public MethodInfo Method
  22. {
  23. get { return _mi; }
  24. set { _mi = value; }
  25. }
  26. /// <summary>
  27. /// The parameters for this method
  28. /// </summary>
  29. public Object[] Parameters
  30. {
  31. get { return _parameters; }
  32. set { _parameters = value; }
  33. }
  34. /// <summary>
  35. /// Craete an operation using the specific method and parameters
  36. /// </summary>
  37. /// <param name="mi">The method info</param>
  38. /// <param name="parameters">The parameters for this method</param>
  39. public Operation(MethodInfo mi, Object[] parameters)
  40. {
  41. _mi = mi;
  42. _parameters = parameters;
  43. }
  44. /// <summary>
  45. /// Call the specific method with the specific parameters on the provided <paramref name="instance"/>
  46. /// </summary>
  47. /// <param name="instance">The instance to call the method</param>
  48. /// <returns></returns>
  49. public Object InvokeMethod(Object instance)
  50. {
  51. if (!_mi.ContainsGenericParameters)
  52. return _mi.DeclaringType.InvokeMember(_mi.Name, BindingFlags.InvokeMethod, null, instance, _parameters);
  53. #region get the generic types
  54. Type[] types = new Type[_mi.GetGenericArguments().Length];
  55. for (int i = 0; i < types.Length; i++)
  56. {
  57. types[i] = (_parameters[i] as GenericParameter).SelectedType;
  58. }
  59. #endregion
  60. #region get the non-generic parameters
  61. Object[] param = new object[_parameters.Length - types.Length];
  62. Array.Copy(_parameters, types.Length, param, 0, param.Length);
  63. #endregion
  64. return _mi.MakeGenericMethod(types).Invoke(instance, param); //m.DeclaringType.InvokeMember(m.Name, BindingFlags.InvokeMethod, null, instance, param);
  65. }
  66. /// <summary>
  67. /// Represent this operation as a string
  68. /// </summary>
  69. /// <returns></returns>
  70. public override string ToString()
  71. {
  72. return String.Format(
  73. System.Globalization.CultureInfo.CurrentCulture,
  74. "{0}({1})",
  75. Method.Name,
  76. String.Join(", ", System.Array.ConvertAll<Object, String>(Parameters, System.Convert.ToString)));
  77. }
  78. /// <summary>
  79. /// Represent this operation as code
  80. /// </summary>
  81. /// <returns></returns>
  82. public String ToCode(ProgrammingLanguage language)
  83. {
  84. Type[] genericArguments = _mi.GetGenericArguments();
  85. Object[] genericParameters = new object[genericArguments.Length];
  86. Object[] nonGenericParameters = new object[_parameters.Length - genericParameters.Length];
  87. Array.Copy(_parameters, genericParameters, genericParameters.Length);
  88. Array.Copy(_parameters, genericParameters.Length, nonGenericParameters, 0, nonGenericParameters.Length);
  89. String genericArgString =
  90. genericArguments.Length > 0 ?
  91. String.Join(",", Array.ConvertAll<Object, String>(genericParameters,
  92. delegate(Object t)
  93. {
  94. return (t as GenericParameter).SelectedType.Name;
  95. }))
  96. : string.Empty;
  97. String res = String.Empty;
  98. switch (language)
  99. {
  100. case ProgrammingLanguage.CSharp:
  101. if (genericArguments.Length > 0)
  102. genericArgString = String.Format("<{0}>", genericArgString);
  103. res = String.Format("{0}.{1}{2}({3})",
  104. "{instance}",
  105. Method.Name,
  106. genericArgString,
  107. String.Join(", ", System.Array.ConvertAll<Object, String>(nonGenericParameters, delegate(Object p) { return ParameterToCode(p, language); })));
  108. break;
  109. case ProgrammingLanguage.CPlusPlus:
  110. if (genericArguments.Length > 0)
  111. genericArgString = String.Format("<{0}>", genericArgString);
  112. res = String.Format("{0}->{1}{2}({3})",
  113. "{instance}",
  114. Method.Name,
  115. genericArgString,
  116. String.Join(", ", System.Array.ConvertAll<Object, String>(nonGenericParameters, delegate(Object p) { return ParameterToCode(p, language); })));
  117. break;
  118. }
  119. return res;
  120. }
  121. private static String ParameterToCode(Object parameter, ProgrammingLanguage language)
  122. {
  123. ICodeGenerable gen = parameter as ICodeGenerable;
  124. return gen == null ? Convert.ToString(parameter) :
  125. gen.ToCode(language);
  126. }
  127. }
  128. }