using System; using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine; namespace NBF { public static class CfgEditorUtil { [MenuItem("构建/配置表/生成脚本")] public static void CreateScriptableObject() { EditorUtils.GetOrCreateAsset(ConfigAssets.SavePath); GenConfigScripts(); AssetDatabase.Refresh(); } [MenuItem("构建/配置表/导表")] public static void BuildExcel() { ExcelToJsonWindow.GenConfig(false); AssetDatabase.Refresh(); } // [MenuItem("构建/配置表/读取")] // public static void Read() // { // var assets = EditorUtils.GetOrCreateAsset(ConfigAssets.SavePath); // // var path = Path.Combine(Application.dataPath, "Resources/config", "Input.json"); // var json = File.ReadAllText(path); // // JsonUtility.FromJsonOverwrite(json, assets); // EditorUtility.SetDirty(assets); // AssetDatabase.SaveAssets(); // 保存更改 // AssetDatabase.Refresh(); // } // [MenuItem("构建/配置表/转json")] // public static void GenJson() // { // CfgAssets cfgAssets = AssetDatabase.LoadAssetAtPath("Assets/Resources/config/CfgAssets.asset"); // var json = JsonUtility.ToJson(cfgAssets); // File.WriteAllText(Path.Combine(Application.dataPath, "Resources/config", "Input.json"), json); // // CfgAssets cfgAssets = Resources.Load("config/CfgAssets"); // } #region 生成脚本 private static string GenPath = "Scripts/Configs/Gen"; private static string TempPath = "Scripts/Configs/Editor/ConfigWarpTemplate"; public static void GenConfigScripts() { if (!Directory.Exists($"{Application.dataPath}/{GenPath}")) { return; } var types = Reflection.GetAllNonAbstractDerivedTypes(); Dictionary tableNameAttributes = new Dictionary(); foreach (var type in types) { tableNameAttributes[type] = type.Name; } // var canGen = CanGen(tableNameAttributes); // // if (!canGen) return; GenParse(tableNameAttributes); GenWarp(tableNameAttributes); // GenBinder(tableNameAttributes); AssetDatabase.Refresh(); } private static bool CanGen(Dictionary tableNameAttributes) { // return true; string filePath = Path.Combine(Application.dataPath, $"{GenPath}/Warps"); if (!Directory.Exists(filePath)) return true; var files = Directory.GetFiles(filePath); List allFileName = new List(); foreach (var file in files) { if (Path.GetExtension(file).ToLower() == ".meta") continue; var fileName = Path.GetFileNameWithoutExtension(file); allFileName.Add(fileName.Replace("Warp", "")); } if (allFileName.Count != tableNameAttributes.Count) return true; foreach (var type in tableNameAttributes.Keys) { if (!allFileName.Contains(type.Name)) return true; } return false; } private static void GenWarp(Dictionary tableNameAttributes) { // 为何使用生成式,不使用static静态泛型 ? 生成式扩展更强且不会破坏原类的集成结构,父类也不用是泛型类 //否则比如 BaseConfig 类型来使用。集成结构会受很大限制,反而没有生成式来的灵活 string filePath = Path.Combine(Application.dataPath, TempPath); if (File.Exists(filePath)) { // 读取文本内容 string fileContent = File.ReadAllText(filePath); var rootPath = $"{Application.dataPath}/{GenPath}/Warps"; if (!Directory.Exists(rootPath)) { return; } if (!Directory.Exists(rootPath)) { Directory.CreateDirectory(rootPath); } foreach (var type in tableNameAttributes.Keys) { var content = fileContent.Replace("##NAME##", type.Name); File.WriteAllText($"{rootPath}/{type.Name}Warp.cs", content); } } else { Debug.LogError("生成代码模板不存在,请检查"); } } private static void GenParse(Dictionary tableNameAttributes) { if (!Directory.Exists($"{Application.dataPath}/{GenPath}")) { return; } CodeWriter codeWriter = new CodeWriter(); codeWriter.Writeln("/**本脚本为自动生成,每次生成会覆盖!请勿手动修改**/"); codeWriter.Writeln(); codeWriter.Writeln("using System;"); codeWriter.Writeln("using System.Collections.Generic;"); codeWriter.Writeln("using System.Reflection;"); codeWriter.Writeln("using Newtonsoft.Json.Linq;"); codeWriter.Writeln("using UnityEngine;"); codeWriter.Writeln(); codeWriter.Writeln("namespace NBF"); codeWriter.StartBlock(); codeWriter.Writeln("public partial class ConfigAssets"); codeWriter.StartBlock(); foreach (var type in tableNameAttributes.Keys) { // codeWriter.Writeln($"[HideInInspector] public List<{type.Name}> {type.Name}Arr;"); codeWriter.Writeln($"public List<{type.Name}> {type.Name}Arr;"); } codeWriter.Writeln(); codeWriter.Writeln("public void Parse(JToken[] arr, Type type)"); codeWriter.StartBlock(); codeWriter.Writeln("var tableNameAttribute = type.GetCustomAttribute();"); codeWriter.Writeln("if (tableNameAttribute == null) return;"); foreach (var type in tableNameAttributes.Keys) { codeWriter.Writeln($"if (type == typeof({type.Name}))"); codeWriter.StartBlock(); codeWriter.Writeln($"{type.Name}Arr = ParseLine<{type.Name}>(arr, tableNameAttribute);"); codeWriter.EndBlock(); codeWriter.Writeln(); } codeWriter.EndBlock(); codeWriter.Writeln(); codeWriter.Writeln("public void AssociationContexts()"); codeWriter.StartBlock(); foreach (var type in tableNameAttributes.Keys) { codeWriter.Writeln($"new ConfigContext<{type.Name}>().Association({type.Name}Arr);"); } codeWriter.EndBlock(); codeWriter.EndBlock(); codeWriter.EndBlock(); codeWriter.Save($"{Application.dataPath}/{GenPath}/ConfigAssets.Gen.cs"); } private static void WriterCreateParse(CodeWriter codeWriter, Type type) { codeWriter.Writeln($"if (type == typeof({type.Name}))"); codeWriter.StartBlock(); codeWriter.Writeln($"return CreateParseTableTask<{type.Name}>();"); codeWriter.EndBlock(); codeWriter.Writeln(); } #endregion } }