2using System.Collections.Generic;
4using System.Linq.Expressions;
5using System.Reflection;
10 private Func<DramaManager, Dictionary<string, string>,
string[],
bool>
_compiled;
12 private static readonly MethodInfo
_stringIsNullOrEmpty = typeof(
string).GetMethod(
"IsNullOrEmpty",
new Type[1] { typeof(
string) });
14 private static readonly ConstructorInfo
_argumentException = typeof(ArgumentException).GetConstructor(
new Type[1] { typeof(
string) });
35 if (
Method.ContainsGenericParameters)
37 throw new NotSupportedException(
"#drama action cannot contain generic parameters");
41 throw new NotSupportedException(
"#drama action must be static");
43 ParameterInfo[] parameters =
Method.GetParameters();
44 if (parameters.Length < 2 || parameters[0].ParameterType != typeof(
DramaManager) || parameters[1].ParameterType != typeof(Dictionary<string, string>) ||
Method.ReturnType != typeof(
bool))
46 throw new ArgumentException(
"#drama action parameters must start with 'DramaManager dm, Dictionary<string, string>' and returns 'bool'");
51 private Func<DramaManager, Dictionary<string, string>,
string[],
bool>
BuildDelegate()
53 ParameterInfo[] parameters =
Method.GetParameters();
54 ParameterExpression parameterExpression = Expression.Parameter(typeof(
DramaManager),
"dm");
55 ParameterExpression parameterExpression2 = Expression.Parameter(typeof(Dictionary<string, string>),
"line");
56 ParameterExpression parameterExpression3 = Expression.Parameter(typeof(
string[]),
"parameters");
57 List<Expression> list =
new List<Expression> { parameterExpression, parameterExpression2 };
58 if (parameters.Length == 3 && parameters[2].ParameterType == typeof(
string[]))
60 list.Add(parameterExpression3);
62 else if (parameters.Length > 2)
64 for (
int i = 2; i < parameters.Length; i++)
66 ParameterInfo parameter = parameters[i];
68 Expression expr = Expression.Condition(Expression.LessThan(Expression.Constant(num), Expression.ArrayLength(parameterExpression3)), Expression.ArrayIndex(parameterExpression3, Expression.Constant(num)), Expression.Constant(
null, typeof(
string)));
72 return Expression.Lambda<Func<DramaManager, Dictionary<string, string>,
string[],
bool>>(Expression.Call(
null,
Method, list),
new ParameterExpression[3] { parameterExpression, parameterExpression2, parameterExpression3 }).Compile();
77 Type parameterType = parameter.ParameterType;
78 bool isOptional = parameter.IsOptional;
79 object defaultValue = parameter.DefaultValue;
80 string text =
$"required action parameter #{parameter.Position - 2} '{parameter.Name}'";
81 if (parameterType == typeof(
string))
86 ConstantExpression ifTrue = Expression.Constant(defaultValue, typeof(
string));
87 return Expression.Condition(test, ifTrue, expr);
89 string value =
"#drama " + text +
" cannot be empty";
90 UnaryExpression ifTrue2 = Expression.Throw(Expression.New(
_argumentException, Expression.Constant(value)), typeof(
string));
91 return Expression.Condition(test, ifTrue2, expr);
94 if (tryParseMethod ==
null)
96 throw new NotSupportedException(
"#drama type '" + parameterType.Name +
"' does not have a public static TryParse method");
98 ParameterExpression parameterExpression = Expression.Variable(parameterType,
"parsed");
99 Expression test2 = Expression.Call(tryParseMethod, expr, parameterExpression);
100 Expression expression;
103 expression = Expression.Constant(defaultValue, parameterType);
107 string value2 =
"#drama can't parse " + text +
" to type '" + parameterType.Name +
"'";
108 expression = Expression.Throw(Expression.New(
_argumentException, Expression.Constant(value2)), parameterType);
110 ConditionalExpression conditionalExpression = Expression.Condition(Expression.Call(
_stringIsNullOrEmpty, expr), expression, Expression.Condition(test2, parameterExpression, expression));
111 return Expression.Block(
new ParameterExpression[1] { parameterExpression }, conditionalExpression);
118 MethodInfo method = typeof(Enum).GetMethod(
"TryParse", BindingFlags.Static | BindingFlags.Public,
null,
new Type[2]
125 return method.MakeGenericMethod(type);
128 return type.GetMethod(
"TryParse",
new Type[2]
151 ModUtil.LogModError(
"exception while invoking drama action '" +
Method.TryToString() +
"'\n" + ex.Message,
new FileInfo(dm.
path));
152 Debug.LogException(ex);
Func< DramaManager, Dictionary< string, string >, string[], bool > BuildDelegate()
static readonly ConstructorInfo _argumentException
Func< DramaManager, Dictionary< string, string >, string[], bool > _compiled
static readonly MethodInfo _stringIsNullOrEmpty
bool SafeInvoke(DramaManager dm, Dictionary< string, string > line, params string[] parameters)
static MethodInfo GetTryParseMethod(Type type)
static Expression CreateConvertExpression(Expression expr, ParameterInfo parameter)
DramaInvokeDetail(MethodInfo method, string contract=null)