public void SetContext(TypeDeclaration classNode, GenCodeRule rule) { this.classNode = classNode; this.rule = rule; _initComponentNode = null; _propBindingsNode = null; }
private static void LoadUICoder(GameObject prefab, GenCodeRule rule, Action <UICoder> onLoadCoder) { //加载已经存在的脚本 LoadOldScript(prefab, coder => { //添加命名空间和引用 CompleteNameSpace(coder.tree, rule); //添加类 CompleteClass(coder.tree, coder.className, rule); onLoadCoder.Invoke(coder); }); }
/// <summary> /// 分析代码的的组件信息 /// </summary> /// <param name="component"></param> /// <param name="components"></param> public static void AnalysisComponent(MonoBehaviour component, List <ComponentItem> components, GenCodeRule rule) { var type = component.GetType(); rule.nameSpace = type.Namespace; var propertys = type.GetProperties(BindingFlags.GetProperty | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (var prop in propertys) { var support = typeof(UnityEngine.MonoBehaviour).IsAssignableFrom(prop.PropertyType) || typeof(ScriptableObject).IsAssignableFrom(prop.PropertyType) || prop.PropertyType == typeof(GameObject); if (support) { var compItem = components.Find(x => "m_" + x.name == prop.Name || x.name == prop.Name); if (compItem == null) { compItem = new ComponentItem(); compItem.name = prop.Name.Replace("m_", ""); components.Add(compItem); } var value = prop.GetValue(component, new object[0]); if (value != null) { if (prop.PropertyType == typeof(GameObject)) { compItem.target = value as GameObject; compItem.components = SortComponent(compItem.target); var types = Array.ConvertAll(compItem.components, x => x.type); compItem.componentID = Array.IndexOf(types, typeof(GameObject)); } else if (typeof(ScriptableObject).IsAssignableFrom(prop.PropertyType)) { compItem.UpdateAsScriptObject(value as ScriptableObject); } else { compItem.target = (value as MonoBehaviour).gameObject; compItem.components = SortComponent(compItem.target); var types = Array.ConvertAll(compItem.components, x => x.type); compItem.componentID = Array.IndexOf(types, value.GetType()); } } } } ViewCoder coder = new ViewCoder(); coder.AnalysisBinding(component, components.ToArray(), rule); }
/// <summary> /// 创建代码 /// </summary> /// <param name="go"></param> /// <param name="components"></param> /// <param name="rule"></param> public static void UpdateBindingScripts(GameObject go, List <ComponentItem> components, GenCodeRule rule) { Action <ViewCoder> onLoad = (uiCoder) => { var baseType = GenCodeUtil.supportBaseTypes[rule.baseTypeIndex]; var needAdd = FilterExisField(baseType, components); uiCoder.parentClassName = supportBaseTypes[rule.baseTypeIndex]; uiCoder.componentItems = needAdd; uiCoder.CompileSave(); UnityEditor.EditorApplication.delayCall += AssetDatabase.Refresh; }; LoadBindingScriptAsnyc(go, components, onLoad); }
/// <summary> /// 分析组件的绑定信息 /// </summary> /// <param name="component"></param> /// <param name="components"></param> private static void AnalysisBindings(MonoBehaviour component, List <ComponentItem> components, GenCodeRule rule) { var script = MonoScript.FromMonoBehaviour(component).text; var tree = new CSharpParser().Parse(script); var classNode = tree.Descendants.OfType <TypeDeclaration>().Where(x => x.Name == component.GetType().Name).FirstOrDefault(); componentCoder.SetContext(classNode, rule); componentCoder.AnalysisBinding(components); }
/// <summary> /// 完善方法内容 /// </summary> /// <param name="classNode"></param> /// <param name="components"></param> private static void BindingInfoMethods(TypeDeclaration classNode, ComponentItem[] components, GenCodeRule rule) { componentCoder.SetContext(classNode, rule); foreach (var component in components) { componentCoder.CompleteCode(component, rule.bindingAble); } }
/// <summary> /// 完善命名空间 /// </summary> /// <param name="tree"></param> /// <param name="rule"></param> private static void CompleteNameSpace(ICSharpCode.NRefactory.CSharp.SyntaxTree tree, GenCodeRule rule) { string[] usingDeclarations = { "BridgeUI", "UnityEngine", "UnityEngine.UI", "System.Collections", "System.Collections.Generic", }; foreach (var item in usingDeclarations) { if (tree.Descendants.OfType <UsingDeclaration>().Where(x => x.Namespace == item).Count() == 0) { tree.AddChild <AstNode>(new UsingDeclaration(item), Roles.Root); } } }
/// <summary> /// 完善类名 /// </summary> /// <param name="tree"></param> /// <param name="prefab"></param> /// <param name="rule"></param> /// <returns></returns> private static TypeDeclaration CompleteClass(ICSharpCode.NRefactory.CSharp.SyntaxTree tree, string className, GenCodeRule rule) { TypeDeclaration classNode = null; if (tree.Descendants.OfType <TypeDeclaration>().Where(x => x.Name == className).Count() == 0) { classNode = new TypeDeclaration(); classNode.Name = className; classNode.Modifiers |= Modifiers.Public; var comment = new Comment("<summary>", CommentType.Documentation); tree.AddChild(comment, Roles.Comment); comment = new Comment("[代码说明信息]", CommentType.Documentation); tree.AddChild(comment, Roles.Comment); comment = new Comment("<summary>", CommentType.Documentation); tree.AddChild(comment, Roles.Comment); tree.AddChild(classNode, Roles.TypeMemberRole); } classNode = tree.Descendants.OfType <TypeDeclaration>().Where(x => x.Name == className).First(); var baseType = GenCodeUtil.supportBaseTypes[rule.baseTypeIndex]; var basePanels = LoadAllBasePanels(); var bs = classNode.BaseTypes.Where(x => Array.Find(basePanels, y => y.Contains(x.ToString())) != null).FirstOrDefault(); if (bs != null) { classNode.BaseTypes.Remove(bs); } classNode.BaseTypes.Add(new SimpleType(baseType)); return(classNode); }
/// <summary> /// 创建代码 /// </summary> /// <param name="go"></param> /// <param name="components"></param> /// <param name="rule"></param> public static void CreateScript(GameObject go, List <ComponentItem> components, GenCodeRule rule) { Action <UICoder> onLoad = (uiCoder) => { var baseType = GenCodeUtil.supportBaseTypes[rule.baseTypeIndex]; var needAdd = FilterExisField(baseType, components); var tree = uiCoder.tree; var className = uiCoder.className; var classNode = tree.Descendants.OfType <TypeDeclaration>().Where(x => x.Name == className).First(); CreateMemberFields(classNode, needAdd); BindingInfoMethods(classNode, needAdd, rule); SortClassMembers(classNode); var prefabPath = AssetDatabase.GetAssetPath(go); var folder = prefabPath.Remove(prefabPath.LastIndexOf("/")); var scriptPath = string.Format("{0}/{1}.cs", folder, uiCoder.className); System.IO.File.WriteAllText(scriptPath, uiCoder.Compile()); var type = typeof(BridgeUI.PanelBase).Assembly.GetType(className); if (type != null) { if (go.GetComponent(type) == null) { go.AddComponent(type); } } EditorApplication.delayCall += () => { AssetDatabase.Refresh(); }; }; GenCodeUtil.LoadUICoder(go, rule, onLoad); }
/// <summary> /// 分析代码的的组件信息 /// </summary> /// <param name="component"></param> /// <param name="components"></param> public static void AnalysisComponent(MonoBehaviour component, List <ComponentItem> components, GenCodeRule rule) { var fields = component.GetType().GetFields(BindingFlags.GetField | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); fields = (from field in fields let atts = field.GetCustomAttributes(false) from att in atts where att is SerializeField select field).ToArray(); foreach (var field in fields) { if (typeof(UnityEngine.MonoBehaviour).IsAssignableFrom(field.FieldType) || typeof(ScriptableObject).IsAssignableFrom(field.FieldType)) { var compItem = components.Find(x => "m_" + x.name == field.Name || x.name == field.Name); if (compItem == null) { compItem = new ComponentItem(); compItem.name = field.Name.Replace("m_", ""); components.Add(compItem); } var value = field.GetValue(component); if (value != null) { if (field.FieldType == typeof(GameObject)) { compItem.target = value as GameObject; compItem.components = SortComponent(compItem.target); compItem.componentID = Array.IndexOf(compItem.components, typeof(GameObject)); } else if (typeof(ScriptableObject).IsAssignableFrom(field.FieldType)) { compItem.UpdateAsScriptObject(value as ScriptableObject); } else { compItem.target = (value as MonoBehaviour).gameObject; compItem.components = SortComponent(compItem.target); compItem.componentID = Array.IndexOf(Array.ConvertAll(compItem.components, x => x.type), value.GetType()); } } } } AnalysisBindings(component, components, rule); }
/// <summary> /// 分析组件的绑定信息 /// </summary> /// <param name="component"></param> /// <param name="components"></param> private static void AnalysisBindings(MonoBehaviour component, List <ComponentItem> components, GenCodeRule rule) { var script = MonoScript.FromMonoBehaviour(component).text; var tree = new CSharpParser().Parse(script); var classNode = tree.Descendants.OfType <TypeDeclaration>().Where(x => x.Name == component.GetType().Name).FirstOrDefault(); var baseType = classNode.BaseTypes.FirstOrDefault(); rule.baseTypeIndex = Array.IndexOf(GenCodeUtil.supportBaseTypes, baseType.ToString()); componentCoder.SetContext(classNode, rule); componentCoder.AnalysisBinding(components); }
/// <summary> /// 创建代码 /// </summary> /// <param name="go"></param> /// <param name="components"></param> /// <param name="rule"></param> public static void CreateViewScript(GameObject go, List <ComponentItem> components, GenCodeRule rule) { Action <UICoder> onLoad = (uiCoder) => { var baseType = GenCodeUtil.supportBaseTypes[rule.baseTypeIndex]; var needAdd = FilterExisField(baseType, components); var tree = uiCoder.tree; var className = uiCoder.className; var classNode = tree.Descendants.OfType <TypeDeclaration>().Where(x => x.Name == className).First(); var type = typeof(BridgeUI.PanelBase).Assembly.GetType(className); CreateMemberFields(classNode, needAdd); BindingInfoMethods(classNode, needAdd, rule); SortClassMembers(classNode); var prefabPath = AssetDatabase.GetAssetPath(go); Component script = null; if (type != null) { script = go.GetComponent(type); } var scriptPath = ""; if (script != null) { var vScript = MonoScript.FromMonoBehaviour(script as MonoBehaviour); if (vScript.name == go.name) { scriptPath = AssetDatabase.GetAssetPath(vScript); } else { scriptPath = AssetDatabase.GetAssetPath(go).Replace(".prefab", ".cs"); } } else { var folder = prefabPath.Remove(prefabPath.LastIndexOf("/")); scriptPath = string.Format("{0}/{1}.cs", folder, uiCoder.className); } var scriptValue = uiCoder.Compile(); System.IO.File.WriteAllText(scriptPath, scriptValue, System.Text.Encoding.UTF8); AssetDatabase.Refresh(); EditorApplication.delayCall += () => { if (type != null) { script = go.GetComponent(type); if (script == null) { go.AddComponent(type); } if (rule.onGenerated != null) { rule.onGenerated.Invoke(script); } EditorApplication.update = null; } AssetDatabase.Refresh(); }; }; GenCodeUtil.LoadViewScriptCoder(go, rule, onLoad); }
/// <summary> /// 更新View 和 ViewModel的脚本 /// </summary> /// <param name="go"></param> /// <param name="components"></param> /// <param name="rule"></param> public static void UpdateScripts(GameObject go, List <ComponentItem> components, GenCodeRule rule) { rule.onGenerated = (viewScript) => { if (viewScript is PanelBase) { var viewScriptPath = AssetDatabase.GetAssetPath(viewScript); //!!!ViewModelScript需要放置到ViewScript下 var vmScriptTempPath = viewScriptPath.Replace(".cs", "_ViewModel.cs"); var viewModelScript = AssetDatabase.LoadAssetAtPath <MonoScript>(vmScriptTempPath); var viewModel = (viewScript as PanelBase).ViewModel; if (viewModelScript != null) { GenCodeUtil.UpdateViewModelScript(viewModelScript, components); } else { var vscript = MonoScript.FromMonoBehaviour(viewScript as PanelBase); string scriptPath = null; if (vscript.name == go.name) { scriptPath = AssetDatabase.GetAssetPath(vscript).Replace(".cs", "_ViewModel.cs"); } else { scriptPath = AssetDatabase.GetAssetPath(go).Replace(".prefab", "_ViewModel.cs"); } CreateNewViewModelScript(go.name + "_ViewModel", scriptPath, components); } } }; GenCodeUtil.CreateViewScript(go, components, rule); }
public void AnalysisBinding(MonoBehaviour component, ComponentItem[] componentItems, GenCodeRule rule) { var fullViewName = Setting.defultNameSpace + "." + component.gameObject.name + "_Internal"; var bindingType = typeof(BridgeUI.Binding.BindingViewBase).Assembly.GetType(fullViewName); rule.baseTypeIndex = Array.IndexOf(GenCodeUtil.supportBaseTypes, bindingType.BaseType.ToString()); SwitchExecuter(bindingType); executer.AnalysisBinding(component.gameObject, componentItems); }
/// <summary> /// 更新View 和 ViewModel的脚本 /// </summary> /// <param name="go"></param> /// <param name="components"></param> /// <param name="rule"></param> public static void UpdateScripts(GameObject go, List <ComponentItem> components, GenCodeRule rule) { rule.onGenerated = (viewScript) => { if (viewScript is PanelBase) { var viewModel = (viewScript as PanelBase).ViewModel; if (viewModel) { GenCodeUtil.UpdateViewModelScript(viewModel, components); } } }; GenCodeUtil.CreateViewScript(go, components, rule); }
/// <summary> /// 更新View 和 ViewModel的脚本 /// </summary> /// <param name="go"></param> /// <param name="components"></param> /// <param name="rule"></param> public static void UpdateScripts(GameObject go, List <ComponentItem> components, GenCodeRule rule) { rule.onGenerated = (viewScript) => { if (viewScript is PanelBase) { var viewModel = (viewScript as PanelBase).ViewModel; if (viewModel is Binding.ViewModel && viewModel.GetType() != typeof(Binding.ViewModel)) { GenCodeUtil.UpdateViewModelScript(viewModel as Binding.ViewModel, components); } else if (viewModel is Binding.ViewModelContainer) { GenCodeUtil.UpdateViewModelScript((viewModel as Binding.ViewModelContainer).instence, components); } } }; GenCodeUtil.CreateViewScript(go, components, rule); }