static void ResolveInvokeTarget(VarPool varManager, TypeFinder typeFinder, ProtocolInfo info, out Type type, out object targetObj, out object[] args, out Type[] argTypes, out BindingFlags bind) { type = null; targetObj = null; bind = new BindingFlags(); if (info.VarAddress == null) { type = typeFinder.GetType(info.TypeFullName); if (type == null) { throw new InformationException(string.Format(CultureInfo.CurrentCulture, ResourcesLocal.Instance.UnknownTypeInfoFormat, info.TypeFullName)); } bind.IsStatic = true; } else { VarAndType varAndType = varManager.GetVarAndType(info.VarAddress); targetObj = varAndType.Core; if (targetObj == null) { throw new InformationException(ResourcesLocal.Instance.NullObjectOperation); } type = varAndType.Type; } ResolveArgs(varManager, info.Arguments, out args, out argTypes); }
internal static ReturnInfo Execute(Action <Action> invokeCore, VarPool varManager, TypeFinder typeFinder, ProtocolInfo info) { IAsyncInvoke invoke = new AsyncExecute(invokeCore); if (info.ProtocolType == ProtocolType.Operation) { invoke = new SyncExecute(invokeCore); var executeCheck = varManager.Add(false); var args = new List <object>(info.Arguments); args.Insert(0, executeCheck); info = new ProtocolInfo(info.ProtocolType, info.OperationTypeInfo, info.VarAddress, info.TypeFullName, info.Operation, args.ToArray()); try { return(Execute(invoke, varManager, typeFinder, info)); } finally { varManager.Remove(executeCheck); } } else { return(Execute(invoke, varManager, typeFinder, info)); } }
static InformationException MakeNotFoundException(ProtocolInfo info, Type findStartType, Type[] argTypes, bool isObjectArrayArg, int nameMatchCount, bool isAmbiguousArgs) { if (isAmbiguousArgs) { throw new InformationException(string.Format(CultureInfo.CurrentCulture, ResourcesLocal.Instance.ErrorManyFoundInvokeFormat, findStartType.Name, info.Operation, MakeErrorInvokeArgInfo(argTypes))); } else if (nameMatchCount == 0) { return(new InformationException(string.Format(CultureInfo.CurrentCulture, ResourcesLocal.Instance.ErrorNotFoundInvokeFormat, findStartType.Name, info.Operation, MakeErrorInvokeArgInfo(argTypes)))); } else { if (isObjectArrayArg) { return(new InformationException(string.Format(CultureInfo.CurrentCulture, ResourcesLocal.Instance.ErrorArgumentInvokeFormatForObjectArray, findStartType.Name, info.Operation, MakeErrorInvokeArgInfo(argTypes)))); } else { return(new InformationException(string.Format(CultureInfo.CurrentCulture, ResourcesLocal.Instance.ErrorArgumentInvokeFormat, findStartType.Name, info.Operation, MakeErrorInvokeArgInfo(argTypes)))); } } }
static ReturnInfo GetValue(VarPool varManager, ProtocolInfo info) { if (info.Arguments.Length != 0) { throw new InternalException(); } return(new ReturnInfo(varManager.GetVarAndType(info.VarAddress).Core)); }
public ReturnInfo Execute(ProtocolInfo info) { try { return(FriendlyInvoker.Execute(_invoke, _pool, _typeFinder, info)); } catch (Exception e) { return(new ReturnInfo(new ExceptionInfo(e))); } }
static ReturnInfo SetValue(VarPool varManager, ProtocolInfo info) { if (info.Arguments.Length != 1) { throw new InternalException(); } object[] args; ResolveArgs(varManager, info.Arguments, out args); varManager.SetObject(info.VarAddress, args[0]); return(new ReturnInfo()); }
static ReturnInfo ExecuteField(IAsyncInvoke async, VarPool varManager, ProtocolInfo info, object obj, object[] args, FieldInfo field) { if (args.Length == 0) { VarAddress getVar = varManager.Add(null); KeepAlive(varManager, info.Arguments, getVar); async.Execute(delegate { ReturnInfo retInfo = new ReturnInfo(); try { varManager.SetObject(getVar, field.GetValue(obj)); } catch (Exception e) { retInfo = new ReturnInfo(new ExceptionInfo(e)); } varManager.SetObject((VarAddress)info.Arguments[0], retInfo); FreeKeepAlive(varManager, info.Arguments, getVar); }); return(new ReturnInfo(getVar)); } else if (args.Length == 1) { KeepAlive(varManager, info.Arguments, null); async.Execute(delegate { ReturnInfo retInfo = new ReturnInfo(); try { field.SetValue(obj, args[0]); } catch (Exception e) { retInfo = new ReturnInfo(new ExceptionInfo(e)); } varManager.SetObject((VarAddress)info.Arguments[0], retInfo); FreeKeepAlive(varManager, info.Arguments, null); }); return(new ReturnInfo()); } throw new InternalException(); }
static ReturnInfo VarInitialize(VarPool varManager, ProtocolInfo info) { //arguments count is 1. if (info.Arguments.Length != 1) { throw new InternalException(); } object[] args; ResolveArgs(varManager, info.Arguments, out args); //entry variable. return(new ReturnInfo(varManager.Add(args[0]))); }
static ReturnInfo GetElements(VarPool varManager, ProtocolInfo info) { object obj = varManager.GetVarAndType(info.VarAddress).Core; IEnumerable enumerable = obj as IEnumerable; if (enumerable == null) { throw new InformationException(ResourcesLocal.Instance.HasNotEnumerable); } List <VarAddress> list = new List <VarAddress>(); foreach (object element in enumerable) { list.Add(varManager.Add(element)); } return(new ReturnInfo(list.ToArray())); }
static ReturnInfo ExecuteMethodOrProperty(IAsyncInvoke async, VarPool varManager, ProtocolInfo info, object obj, object[] args, MethodInfo method) { VarAddress handle = null; if (method.ReturnParameter.ParameterType != typeof(void)) { handle = varManager.Add(null); } KeepAlive(varManager, info.Arguments, handle); async.Execute(delegate { ReturnInfo retInfo = new ReturnInfo(); try { object retObj = method.Invoke(obj, args); if (method.ReturnParameter.ParameterType != typeof(void)) { varManager.SetObject(handle, retObj); } List <object> retArgsTmp = new List <object>(); retArgsTmp.Add(null); retArgsTmp.AddRange(args); ReflectArgsAfterInvoke(varManager, info.Arguments, retArgsTmp.ToArray()); } catch (Exception e) { retInfo = new ReturnInfo(new ExceptionInfo(e)); } varManager.SetObject((VarAddress)info.Arguments[0], retInfo); FreeKeepAlive(varManager, info.Arguments, handle); }); return(new ReturnInfo(handle)); }
internal static ReturnInfo Execute(IAsyncInvoke async, VarPool varManager, TypeFinder typeFinder, ProtocolInfo info) { switch (info.ProtocolType) { case ProtocolType.AsyncResultVarInitialize: case ProtocolType.VarInitialize: return(VarInitialize(varManager, info)); case ProtocolType.VarNew: return(VarNew(async, varManager, typeFinder, info)); case ProtocolType.BinOff: return(BinOff(varManager, info)); case ProtocolType.GetValue: return(GetValue(varManager, info)); case ProtocolType.SetValue: return(SetValue(varManager, info)); case ProtocolType.GetElements: return(GetElements(varManager, info)); case ProtocolType.Operation: case ProtocolType.AsyncOperation: return(AsyncOperation(async, varManager, typeFinder, info)); case ProtocolType.IsEmptyVar: return(IsEmptyVar(varManager, info)); default: throw new InternalException(); } }
static ReturnInfo AsyncOperation(IAsyncInvoke async, VarPool varManager, TypeFinder typeFinder, ProtocolInfo info) { Type type; object obj; object[] args; Type[] argTypesOri; BindingFlags bind; ResolveInvokeTarget(varManager, typeFinder, info, out type, out obj, out args, out argTypesOri, out bind); List <object> argTmp = new List <object>(args); argTmp.RemoveAt(0); args = argTmp.ToArray(); List <Type> argTypeTmp = new List <Type>(argTypesOri); argTypeTmp.RemoveAt(0); argTypesOri = argTypeTmp.ToArray(); if (info.OperationTypeInfo != null) { type = typeFinder.GetType(info.OperationTypeInfo.Target); if (type == null) { throw new InformationException(string.Format(CultureInfo.CurrentCulture, ResourcesLocal.Instance.UnknownTypeInfoFormat, info.OperationTypeInfo.Target)); } } string operation = OptimizeOperationName(type, info.Operation, args.Length); Type findStartType = type; Type[] argTypes = GetArgTypes(typeFinder, info.OperationTypeInfo, argTypesOri); //find operation. bool isObjectArrayArg = false; int nameMatchCount = 0; bool first = true; bool isAmbiguousArgs = false; while (!isAmbiguousArgs && type != null) { if (!first) { type = type.BaseType(); if (type == null) { break; } } first = false; FieldInfo field = FindField(type, bind, operation, args, ref isObjectArrayArg, ref nameMatchCount); if (field != null) { return(ExecuteField(async, varManager, info, obj, args, field)); } PropertyInfo property = FindProperty(type, bind, operation, args, ref isObjectArrayArg, ref nameMatchCount); if (property != null) { return(ExecuteProperty(async, varManager, info, obj, args, property)); } MethodInfo method = FindMethodOrProperty(info.OperationTypeInfo != null, type, bind, operation, argTypes, ref isObjectArrayArg, ref nameMatchCount, ref isAmbiguousArgs); if (method != null) { return(ExecuteMethodOrProperty(async, varManager, info, obj, args, method)); } } throw MakeNotFoundException(info, findStartType, argTypes, isObjectArrayArg, nameMatchCount, isAmbiguousArgs); }
static ReturnInfo BinOff(VarPool varManager, ProtocolInfo info) { varManager.Remove(info.VarAddress); return(new ReturnInfo()); }
/// <summary> /// create object. /// </summary> static ReturnInfo VarNew(IAsyncInvoke async, VarPool varManager, TypeFinder typeFinder, ProtocolInfo info) { Type type = typeFinder.GetType(info.TypeFullName); if (type == null) { throw new InformationException(string.Format(CultureInfo.CurrentCulture, ResourcesLocal.Instance.UnknownTypeInfoFormat, info.TypeFullName)); } object[] args; Type[] argTypesOri; ResolveArgs(varManager, info.Arguments, out args, out argTypesOri); Type[] argTypes = GetArgTypes(typeFinder, info.OperationTypeInfo, argTypesOri); //value type. if (argTypes.Length == 0 && type.IsValueType()) { return(new ReturnInfo(varManager.Add(Activator.CreateInstance(type)))); } //resolve overload. ConstructorInfo[] constructorInfos = type.GetConstructors(); List <ConstructorInfo> constructorList = new List <ConstructorInfo>(); bool isObjectArrayArg = false; for (int i = 0; i < constructorInfos.Length; i++) { ParameterInfo[] paramInfos = constructorInfos[i].GetParameters(); bool isPerfect; bool isObjectArrayArgTmp; if (IsMatchParameter(info.OperationTypeInfo != null, argTypes, paramInfos, out isPerfect, out isObjectArrayArgTmp)) { if (isPerfect) { constructorList.Clear(); constructorList.Add(constructorInfos[i]); break; } constructorList.Add(constructorInfos[i]); } if (isObjectArrayArgTmp) { isObjectArrayArg = true; } } //not found. if (constructorList.Count == 0) { if (isObjectArrayArg) { throw new InformationException(string.Format(CultureInfo.CurrentCulture, ResourcesLocal.Instance.ErrorNotFoundConstractorFormatForObjectArray, type.Name, MakeErrorInvokeArgInfo(argTypes))); } else { throw new InformationException(string.Format(CultureInfo.CurrentCulture, ResourcesLocal.Instance.ErrorNotFoundConstractorFormat, type.Name, MakeErrorInvokeArgInfo(argTypes))); } } if (constructorList.Count != 1) { //can't resolve overload. throw new InformationException(string.Format(CultureInfo.CurrentCulture, ResourcesLocal.Instance.ErrorManyFoundConstractorFormat, type.Name, MakeErrorInvokeArgInfo(argTypes))); } //create. bool isCreated = false;//TODO object instance = null; async.Execute(() => { instance = constructorList[0].Invoke(args); isCreated = true; }); while (!isCreated) { Thread.Sleep(0); } //resolve ref, out. ReflectArgsAfterInvoke(varManager, info.Arguments, args); //entry object. return(new ReturnInfo(varManager.Add(instance))); }
static ReturnInfo IsEmptyVar(VarPool varManager, ProtocolInfo info) { return(new ReturnInfo(varManager.IsEmptyVar((VarAddress)info.Arguments[0]))); }