/// <summary> /// 分析绑定方法 /// </summary> /// <param name="invocation"></param> /// <param name="components"></param> protected virtual void AnalysisBindingEvents(InvocationExpression invocation, List <ComponentItem> components) { var component = components.Find(x => invocation.Arguments.Count > 1 && invocation.Arguments.First().ToString().Contains("m_" + x.name)); if (component != null) { var source = invocation.Arguments.ToArray()[1].ToString().Replace("\"", ""); var info = component.eventItems.Find(x => x.bindingSource == source); var arg0 = invocation.Arguments.First().ToString(); var targetName = arg0.Substring(arg0.IndexOf(".") + 1); Type infoType = GetTypeClamp(component.componentType, targetName); if (info == null) { info = new BindingEvent(); info.bindingSource = source; info.bindingTarget = targetName; info.bindingTargetType.Update(infoType); component.eventItems.Add(info); } info.bindingTargetType.Update(infoType); if (invocation.Arguments.Count() > 2) { info.type = BindingType.WithTarget;//3个参数 } else { info.type = BindingType.Normal;//2个参数 } } }
/// <summary> /// 本地事件关联 /// </summary> protected virtual void LocalEventInvocations(string name, BindingEvent bindingInfo, bool bindingAble) { var node = bindingAble ? InitComponentsNode : AwakeNode; var invocations = node.Body.Descendants.OfType <InvocationExpression>(); var targetName = "m_" + name; var invocation = invocations.Where(x => x.Target.ToString().Contains(targetName) && x.Arguments.FirstOrDefault().ToString() == bindingInfo.bindingSource).FirstOrDefault(); var eventName = bindingInfo.bindingTarget;//如onClick if (invocation == null && !string.IsNullOrEmpty(eventName) && !string.IsNullOrEmpty(bindingInfo.bindingSource)) { invocation = new InvocationExpression(); invocation.Target = new MemberReferenceExpression(new MemberReferenceExpression(new IdentifierExpression("m_" + name), eventName, new AstType[0]), "AddListener", new AstType[0]); invocation.Arguments.Add(new IdentifierExpression(bindingInfo.bindingSource)); node.Body.Add(invocation); CompleteMethod(bindingInfo); } }
/// <summary> /// 分析本地方法 /// </summary> /// <param name="invocation"></param> /// <param name="components"></param> protected virtual void AnalysisLoaclInvocation(InvocationExpression invocation, List <ComponentItem> components) { var component = components.Find(x => invocation.Target.ToString().Contains("m_" + x.name)); if (component != null) { string bindingSource = invocation.Arguments.First().ToString(); var info = component.eventItems.Find(x => invocation.Target.ToString().Contains("m_" + component.name + "." + x.bindingTarget) && x.type == BindingType.NoBinding && x.bindingSource == bindingSource); if (info == null) { var express = invocation.Target as MemberReferenceExpression; var target = (express.Target as MemberReferenceExpression).MemberNameToken.Name; Type infoType = GetTypeClamp(component.componentType, target); info = new BindingEvent(); info.type = BindingType.NoBinding; info.bindingSource = bindingSource; info.bindingTarget = target; info.bindingTargetType.Update(infoType); component.eventItems.Add(info); } } }
private void AnalysisBindingEvents(string componentName, string targetName, string sourceName, ComponentItem[] components) { for (int i = 0; i < components.Length; i++) { var component = components[i]; if (component.name == componentName) { Type infoType = GenCodeUtil.GetTypeClamp(component.componentType, targetName); var info = component.eventItems.Find(x => x.bindingSource == sourceName); if (info == null) { info = new BindingEvent(); component.eventItems.Add(info); } info.bindingSource = sourceName; info.bindingTarget = targetName; info.bindingTargetType.Update(infoType); info.type = BindingType.Simple; } } }
/// <summary> /// 事件绑定信息解析 /// </summary> /// <param name="invocation"></param> /// <param name="components"></param> private static void AnalysisBindingEvents(string invocation, ComponentItem[] components) { var arguments = invocation.Replace(" ", "").Split(','); var arg0s = arguments[0].Split('.'); for (int i = 0; i < components.Length; i++) { var component = components[i]; var targetName = arg0s[2]; var sourceName = arguments[1].Replace(keyword_address, ""); if (component.name == arg0s[1]) { Type infoType = GenCodeUtil.GetTypeClamp(component.componentType, targetName); var info = component.eventItems.Find(x => x.bindingSource == sourceName); if (info == null) { info = new BindingEvent(); component.eventItems.Add(info); } info.bindingSource = sourceName; info.bindingTarget = targetName; info.bindingTargetType.Update(infoType); if (arguments.Length > 2) { info.type = BindingType.Full;//3个参数 } else { info.type = BindingType.Simple;//2个参数 } } } }
/// <summary> /// 完善本地绑定的方法 /// </summary> /// <param name="item"></param> protected void CompleteMethod(BindingEvent item) { var funcNode = classNode.Descendants.OfType <MethodDeclaration>().Where(x => x.Name == item.bindingSource).FirstOrDefault(); if (funcNode == null) { UnityEngine.Debug.Assert(item.bindingTargetType.type != null, item.bindingSource + ":" + item.bindingTarget); var parameter = item.bindingTargetType.type.GetMethod("AddListener").GetParameters()[0]; List <ParameterDeclaration> arguments = new List <ParameterDeclaration>(); var parameters = parameter.ParameterType.GetGenericArguments(); int count = 0; var oldType = typeof(PanelBase).Assembly.GetType(classNode.Name); System.Reflection.MethodInfo oldMethod = null; if (oldType != null) { oldMethod = oldType.GetMethod(item.bindingSource, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic); } System.Reflection.ParameterInfo[] oldParamters = null; if (oldMethod != null) { if (parameters.Count() == 0) { return; } else { oldParamters = oldMethod.GetParameters(); } } bool sameFunc = parameters.Length > 0; for (int i = 0; i < parameters.Length; i++) { var para = parameters[i]; if (oldParamters != null) { var oldParam = oldParamters[i]; if (oldParam.ParameterType.FullName != para.FullName) { sameFunc = false; } } else { sameFunc = false; } ParameterDeclaration argument = new ParameterDeclaration(new BridgeUI.NRefactory.CSharp.PrimitiveType(para.FullName), "arg" + count++); arguments.Add(argument); } if (!sameFunc) { funcNode = new MethodDeclaration(); funcNode.Name = item.bindingSource; funcNode.Modifiers |= Modifiers.Protected; funcNode.ReturnType = new BridgeUI.NRefactory.CSharp.PrimitiveType("void"); funcNode.Parameters.AddRange(arguments); funcNode.Body = new BlockStatement(); classNode.AddChild(funcNode, Roles.TypeMemberRole); } } }
/// <summary> /// 远端关联事件 /// </summary> /// <param name="name"></param> /// <param name="bindingInfo"></param> protected virtual void BindingEventInvocations(string name, Type componentType, BindingEvent bindingInfo) { var invocations = PropBindingsNode.Body.Descendants.OfType <InvocationExpression>(); var arg0_name = "m_" + name + "." + bindingInfo.bindingTarget; //绑定目标 var arg1_name = string.Format("\"{0}\"", bindingInfo.bindingSource); //绑定源 var may_invocations = invocations.Where( x => x.Target.ToString().Contains("Binder") && x.Arguments.Count > 0 && x.Arguments.First().ToString() == arg0_name && x.Arguments.ToArray().Length > 1 && x.Arguments.ToArray()[1].ToString() == arg1_name); InvocationExpression invocation = null; if (may_invocations != null) { //两个参数 if (bindingInfo.type == BindingType.Normal) { invocation = may_invocations.Where(x => x.Arguments.Count() == 2).FirstOrDefault(); } //三个参数 else if (bindingInfo.type == BindingType.WithTarget) { invocation = may_invocations.Where(x => x.Arguments.ToArray().Length > 2 && x.Arguments.ToArray()[2].ToString() == "m_" + name).FirstOrDefault(); } } if (invocation == null) { var methodName = "RegistEvent"; UnityEngine.Debug.Assert(bindingInfo.bindingTargetType.type != null, bindingInfo.bindingSource + ";" + bindingInfo.bindingTarget + " type Null"); ///从UnityEvent和UnityEvent<T>派生 if (bindingInfo.bindingTargetType.type.BaseType.IsGenericType) { var arguments = bindingInfo.bindingTargetType.type.BaseType.GetGenericArguments().Select(x => x.FullName).ToList(); if (bindingInfo.type == BindingType.WithTarget) { arguments.Add(componentType.FullName); } methodName = "RegistEvent<" + string.Join(",", arguments.ToArray()) + ">"; } if (!string.IsNullOrEmpty(methodName)) { invocation = new InvocationExpression(); invocation.Target = new MemberReferenceExpression(new IdentifierExpression("Binder"), methodName, new AstType[0]); invocation.Arguments.Add(new IdentifierExpression(arg0_name)); invocation.Arguments.Add(new PrimitiveExpression(bindingInfo.bindingSource)); if (bindingInfo.type == BindingType.WithTarget) { invocation.Arguments.Add(new IdentifierExpression("m_" + name)); } PropBindingsNode.Body.Add(invocation); } } }
/// <summary> /// 远端关联事件 /// </summary> /// <param name="name"></param> /// <param name="bindingInfo"></param> protected virtual void BindingEventInvocations(string name, Type componentType, BindingEvent bindingInfo) { var invocations = PropBindingsNode.Body.Descendants.OfType <InvocationExpression>(); var arg0_name = "m_" + name + "." + bindingInfo.bindingTarget; var arg1_name = string.Format("\"{0}\"", bindingInfo.bindingSource); var invocation = invocations.Where( x => x.Target.ToString().Contains("Binder") && x.Arguments.Count > 0 && x.Arguments.First().ToString() == arg0_name && x.Arguments.ToArray()[1].ToString() == arg1_name).FirstOrDefault(); if (invocation == null) { var methodName = "RegistEvent"; if (typeof(UnityEngine.Events.UnityEvent).IsAssignableFrom(bindingInfo.bindingTargetType.type)) { methodName = string.Format("RegistEvent<{0}>", componentType.FullName); } if (!string.IsNullOrEmpty(methodName)) { invocation = new InvocationExpression(); invocation.Target = new MemberReferenceExpression(new IdentifierExpression("Binder"), methodName, new AstType[0]); invocation.Arguments.Add(new IdentifierExpression(arg0_name)); invocation.Arguments.Add(new PrimitiveExpression(bindingInfo.bindingSource)); invocation.Arguments.Add(new IdentifierExpression("m_" + name)); PropBindingsNode.Body.Add(invocation); } } }
/// <summary> /// PanelAction类型 /// </summary> /// <param name="component"></param> /// <param name="eventItem"></param> /// <returns></returns> private Type GetPanelActionType(ComponentItem component, BindingEvent eventItem) { var type = eventItem.bindingTargetType.type; if (type != null) { Type typevalue = type; if (type.BaseType.IsGenericType) { var argumentList = new List <Type>(type.BaseType.GetGenericArguments()); Type[] arguments = null; switch (eventItem.type) { case BindingType.Simple: arguments = argumentList.ToArray(); break; case BindingType.Full: argumentList.Add(component.componentType); arguments = argumentList.ToArray(); break; default: break; } if (arguments.Length == 1) { typevalue = typeof(Binding.PanelAction <>).MakeGenericType(arguments); } else if (arguments.Length == 2) { typevalue = typeof(Binding.PanelAction <,>).MakeGenericType(arguments); } else if (arguments.Length == 3) { typevalue = typeof(Binding.PanelAction <, ,>).MakeGenericType(arguments); } else if (arguments.Length == 4) { typevalue = typeof(Binding.PanelAction <, , ,>).MakeGenericType(arguments); } } else { if (eventItem.type == BindingType.Simple) { typevalue = typeof(Binding.PanelAction); } else { typevalue = typeof(Binding.PanelAction <>).MakeGenericType(component.componentType); } } return(typevalue); } else { return(null); } }