175 lines
6.6 KiB
C#
175 lines
6.6 KiB
C#
using System.IO;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using Sirenix.OdinInspector;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
#if UNITY_EDITOR
|
|
using Sirenix.OdinInspector.Editor;
|
|
|
|
namespace SLSUtilities.General
|
|
{
|
|
public class DictionaryCodeGeneratorWindow : OdinEditorWindow
|
|
{
|
|
// 临时持有目标字典的引用
|
|
private SerializedDictionary<string, string> _targetDict;
|
|
|
|
[Title("代码生成设置")]
|
|
[LabelText("类名")]
|
|
public string ClassName = "AttributeKeys";
|
|
|
|
[LabelText("命名空间")]
|
|
public string NamespaceName = "Cielonos.Generated";
|
|
|
|
[FolderPath, LabelText("保存路径")]
|
|
public string SavePath = "Assets/Scripts/Generated";
|
|
|
|
// 静态打开方法
|
|
public static void Open(SerializedDictionary<string, string> targetDict,
|
|
string className, string nameSpaceName, string savePath = "Assets/Scripts/Generated")
|
|
{
|
|
var window = GetWindow<DictionaryCodeGeneratorWindow>();
|
|
window.titleContent = new GUIContent("常量生成器");
|
|
window._targetDict = targetDict;
|
|
window.ClassName = className; // 设置默认类名
|
|
window.NamespaceName = nameSpaceName; // 设置默认命名空间
|
|
window.SavePath = savePath; // 设置默认保存路径
|
|
window.Show();
|
|
}
|
|
|
|
[Button("生成代码 (Generate)", ButtonSizes.Large), PropertyOrder(10)]
|
|
[GUIColor(0.4f, 0.8f, 0.4f)]
|
|
public void Generate()
|
|
{
|
|
if (_targetDict == null)
|
|
{
|
|
Debug.LogError("字典引用丢失,请重新打开窗口。");
|
|
return;
|
|
}
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
// 1. 生成头部
|
|
sb.AppendLine("// ========================================================");
|
|
sb.AppendLine($"// Auto-generated from SerializedDictionary: {ClassName}");
|
|
sb.AppendLine("// ========================================================");
|
|
sb.AppendLine("");
|
|
|
|
if (!string.IsNullOrEmpty(NamespaceName))
|
|
{
|
|
sb.AppendLine($"namespace {NamespaceName}");
|
|
sb.AppendLine("{");
|
|
}
|
|
|
|
string indent = string.IsNullOrEmpty(NamespaceName) ? "" : " ";
|
|
sb.AppendLine($"{indent}public static class {ClassName}");
|
|
sb.AppendLine($"{indent}{{");
|
|
|
|
// 2. 遍历字典内容
|
|
// SerializedDictionary 实现了 IEnumerable<KeyValuePair<string, string>>
|
|
foreach (var kvp in _targetDict)
|
|
{
|
|
string key = kvp.Key;
|
|
string desc = kvp.Value;
|
|
|
|
// 简单的变量名过滤 (只保留字母数字下划线)
|
|
string varName = Regex.Replace(key, "[^a-zA-Z0-9_]", "");
|
|
|
|
// 修正:变量名不能以数字开头
|
|
if (varName.Length > 0 && char.IsDigit(varName[0]))
|
|
varName = "_" + varName;
|
|
|
|
if (string.IsNullOrEmpty(varName)) continue;
|
|
|
|
// 添加注释
|
|
if (!string.IsNullOrEmpty(desc))
|
|
{
|
|
sb.AppendLine($"{indent} /// <summary> {desc.Replace("\n", " ")} </summary>");
|
|
}
|
|
|
|
// 添加常量定义
|
|
sb.AppendLine($"{indent} public const string {varName} = \"{key}\";");
|
|
}
|
|
|
|
sb.AppendLine($"{indent}}}");
|
|
if (!string.IsNullOrEmpty(NamespaceName)) sb.AppendLine("}");
|
|
|
|
// 3. 写入文件
|
|
if (!Directory.Exists(SavePath)) Directory.CreateDirectory(SavePath);
|
|
string fullPath = Path.Combine(SavePath, $"{ClassName}.cs");
|
|
|
|
File.WriteAllText(fullPath, sb.ToString(), Encoding.UTF8);
|
|
AssetDatabase.Refresh();
|
|
|
|
ShowNotification(new GUIContent("生成成功!"));
|
|
Debug.Log($"[CodeGenerator] 文件已生成: {fullPath}");
|
|
}
|
|
|
|
[Button("反向同步 (Sync from Script)", ButtonSizes.Large), PropertyOrder(11)]
|
|
[GUIColor(0.4f, 0.6f, 0.8f)]
|
|
public void SyncFromScript()
|
|
{
|
|
if (_targetDict == null)
|
|
{
|
|
Debug.LogError("字典引用丢失,请重新打开窗口。");
|
|
return;
|
|
}
|
|
|
|
string fullPath = Path.Combine(SavePath, $"{ClassName}.cs");
|
|
if (!File.Exists(fullPath))
|
|
{
|
|
Debug.LogError($"[CodeGenerator] 找不到文件: {fullPath}");
|
|
return;
|
|
}
|
|
|
|
string[] lines = File.ReadAllLines(fullPath, Encoding.UTF8);
|
|
var newEntries = new System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<string, string>>();
|
|
string currentSummary = "";
|
|
|
|
Regex summaryRegex = new Regex(@"///\s*<summary>\s*(.*?)\s*</summary>");
|
|
Regex constRegex = new Regex(@"public\s+const\s+string\s+\w+\s*=\s*""([^""]+)""\s*;");
|
|
|
|
foreach (var line in lines)
|
|
{
|
|
string trimmed = line.Trim();
|
|
|
|
Match sumMatch = summaryRegex.Match(trimmed);
|
|
if (sumMatch.Success)
|
|
{
|
|
currentSummary = sumMatch.Groups[1].Value;
|
|
continue;
|
|
}
|
|
|
|
Match constMatch = constRegex.Match(trimmed);
|
|
if (constMatch.Success)
|
|
{
|
|
string key = constMatch.Groups[1].Value;
|
|
newEntries.Add(new System.Collections.Generic.KeyValuePair<string, string>(key, currentSummary));
|
|
currentSummary = ""; // 匹配完毕后清空,准备匹配下一个
|
|
}
|
|
}
|
|
|
|
if (newEntries.Count > 0)
|
|
{
|
|
_targetDict.Clear();
|
|
|
|
foreach (var kvp in newEntries)
|
|
{
|
|
if (!_targetDict.ContainsKey(kvp.Key))
|
|
{
|
|
_targetDict.Add(kvp.Key, kvp.Value);
|
|
}
|
|
}
|
|
|
|
ShowNotification(new GUIContent("反向同步成功!"));
|
|
Debug.Log($"[CodeGenerator] 从 {fullPath} 成功同步了 {newEntries.Count} 个属性到字典中。由于直接修改了内存数据,请记得手动保存包含该字典的资源文件。");
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning($"[CodeGenerator] 在 {fullPath} 中没有找到任何常量定义。");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif |