using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using TyphoonFormatCSharp;
using UnityEditor;
using UnityEngine;
using Debug = UnityEngine.Debug;
namespace TyphoonUI
{
public class CodeTool
{
//最大备份数量
public const int MAX_BACK_UP_SIZE = 10;
///
/// 导出所有代码
///
[MenuItem("TyphoonUI/代码导出/导出所有", priority = 5000)]
public static void ExportAll()
{
//备份当前代码目录
BackUpAllCodeScripts();
var guids = AssetDatabase.FindAssets("t:prefab", new[] { "Assets" });
var matches = new HashSet();
foreach (var guid in guids)
{
var path = AssetDatabase.GUIDToAssetPath(guid);
var prefab = AssetDatabase.LoadAssetAtPath(path);
if (prefab != null)
{
var objs = GetUIObjectsInChildren(prefab);
foreach (var element in objs)
{
matches.Add(element);
}
}
}
var sb = new StringBuilder();
var validate = new HashSet();
foreach (var match in matches)
{
var current = PrefabUtility.GetCorrespondingObjectFromSource(match.gameObject);
var corresponding = PrefabUtility.GetCorrespondingObjectFromOriginalSource(match.gameObject);
if (current != null && corresponding != null)
{
//不属于原始节点,跳过
continue;
}
validate.Add(match);
var sourcePath = AssetDatabase.GetAssetPath(match);
sb.AppendLine($"{sourcePath} -> {match.gameObject.GetHierarchyPath()}");
// sb.AppendLine($"[{current}],[{corresponding}]");
}
Debug.Log(sb.ToString());
//检查导出节点是否出现问题
foreach (var element in validate)
{
if (element.HasNullNode())
{
Debug.Log($"{element}存在空节点,已自动处理");
var original = PrefabUtility.GetCorrespondingObjectFromOriginalSource(element);
original.Apply();
EditorUtility.SetDirty(original);
var path = AssetDatabase.GetAssetPath(original);
EditorUtility.SetDirty(AssetDatabase.LoadAssetAtPath(path));
AssetDatabase.SaveAssets();
}
}
//导出所有代码
ExportCode(true, validate.ToArray());
}
///
/// 导出代码(多项导出)
///
public static List ExportCode(bool refreshProj, params UIObject[] objs)
{
var arr = new List();
foreach (var view in objs)
{
arr.Add(new ViewCodeGenerator(view));
view.Apply();
}
//分析导出
foreach (var element in arr)
{
element.Analysis();
//生成成员和初始化方法
element.GenerateMethodInitializeView();
}
//生成类型清单
var classFullNames = new HashSet();
foreach (var generator in arr)
{
classFullNames.Add(generator.GetFullClassName());
}
//补充关联view拓展属性
foreach (var element in arr)
{
element.GenerateViewPropertyField(classFullNames);
}
var result = new List();
//生成代码
foreach (var element in arr)
{
var code = element.GenerateCodeSting();
var savePath = element.GetSavePath();
result.Add(savePath);
TyphoonUIEditor.CreateDirectoryIfNotExist(Path.GetDirectoryName(savePath));
File.WriteAllText(savePath, code);
}
Debug.Log($"生成完毕,共:{result.Count}项");
if (result.Count > 0)
{
AssetDatabase.Refresh();
TyphoonUIEditor.PingObject(result.Last());
FormatCSharp.Format(Paths.ExportCodeFolder, () =>
{
if (refreshProj)
{
AssetDatabase.Refresh();
}
});
}
return result;
}
///
/// 单项导出
///
public static string ExportCode(UIObject obj, bool refreshProj)
{
obj.Apply();
var codeGenerator = new ViewCodeGenerator(obj);
codeGenerator.Analysis();
codeGenerator.GenerateMethodInitializeView();
codeGenerator.GenerateViewPropertyField(new HashSet());
var code = codeGenerator.GenerateCodeSting();
var path = codeGenerator.GetSavePath();
TyphoonUIEditor.CreateDirectoryIfNotExist(Path.GetDirectoryName(path));
Debug.Log($"导出:{path}");
File.WriteAllText(path, code);
if (refreshProj)
{
AssetDatabase.Refresh();
}
return path;
}
///
/// 获取所有子Transform
///
public static List GetTransformInChildren(GameObject parent)
{
List childNodes = new List();
childNodes.Add(parent.transform);
// 获取父节点的所有子节点
foreach (Transform child in parent.transform)
{
// 递归获取子节点的所有子节点
var grandChildNodes = GetTransformInChildren(child.gameObject);
childNodes.AddRange(grandChildNodes);
}
return childNodes;
}
///
/// 获取所有UIObject
///
public static List GetUIObjectsInChildren(GameObject obj)
{
var nodes = GetTransformInChildren(obj);
var hash = new HashSet();
foreach (var node in nodes)
{
var com = node.GetComponent();
if (com != null)
{
hash.Add(com);
}
}
return hash.ToList();
}
//备份所有代码
public static void BackUpAllCodeScripts()
{
if (Directory.Exists(Paths.CodeScriptBackUpFolder))
{
//删除多余的备份文件夹
var info = new DirectoryInfo(Paths.CodeScriptBackUpFolder);
var backups = info.GetDirectories().ToList();
if (backups.Count >= MAX_BACK_UP_SIZE)
{
var deleteCount = backups.Count - MAX_BACK_UP_SIZE + 1;
//删除最早的备份
backups.Sort((a, b) => { return a.CreationTime.CompareTo(b.CreationTime); });
for (int i = 0; i < deleteCount && i < backups.Count; i++)
{
var element = backups[i];
Directory.Delete(element.FullName, true);
}
}
}
var backup = $"{Paths.CodeScriptBackUpFolder}/{DateTime.Now.ToString("yyyyMMdd-HHmmssfff")}";
TyphoonUIEditor.CreateDirectoryIfNotExist(backup);
var from = Paths.ExportCodeFolder;
if (Directory.Exists(from))
{
var info = new DirectoryInfo(from);
var files = info.GetFiles("*", SearchOption.AllDirectories);
foreach (var element in files)
{
var fileFrom = element.FullName;
var fileTo = element.FullName.Replace(info.FullName, backup);
var dir = Path.GetDirectoryName(fileTo);
TyphoonUIEditor.CreateDirectoryIfNotExist(dir);
File.Copy(fileFrom, fileTo, true);
}
}
Debug.Log($"备份{from}-->{backup}");
}
[MenuItem("TyphoonUI/代码导出/查看备份", priority = 5000)]
public static void OpenCodeBackFolder()
{
if (Directory.Exists(Paths.ExportCodeFolder))
{
Process.Start($"explorer", $"\"{Path.GetFullPath(Paths.CodeScriptBackUpFolder)}\"");
}
else
{
Debug.Log("备份目录为空");
}
}
}
}