upm_guru_kcp/Editor/Proto2CSEditor.cs

248 lines
8.8 KiB
C#
Raw Normal View History

2023-08-30 05:50:21 +00:00
//
// Proto2CSEditor.cs
//
// Author:
// JasonXuDeveloper <jasonxudeveloper@gmail.com>
//
// Copyright (c) 2020 JEngine
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System.IO;
using Google.Protobuf.Reflection;
using ProtoBuf.Reflection;
using UnityEditor;
using UnityEngine;
namespace Guru
{
internal class Proto2CSEditor : EditorWindow
{
private static Proto2CSEditor win;
//[MenuItem("Tools/Protobuf/Show Generate Window")]
//public static void ShowCSGenerateWindow()
//{
// int index = Application.dataPath.LastIndexOf('/');
// var proto_dir = $"{Application.dataPath.Substring(0, index)}/ServerProtos";
// win = GetWindow<Proto2CSEditor>("Proto2CS Generator");
// win.folder = EditorUtility.OpenFolderPanel("Please select proto files directory",
// proto_dir, "");
// win.minSize = new Vector2(500, 500);
// win.Show();
//}
[MenuItem("Tools/Protobuf/Generate All")]
public static void GenerateAllProtos()
{
int index = Application.dataPath.LastIndexOf('/');
var proto_dir = $"{Application.dataPath.Substring(0, index)}/ServerProtos";
var file_list = GetAllProtoFiles(proto_dir);
2023-08-31 03:12:35 +00:00
var dest_folder = proto_dir;// $"{Application.dataPath}/../Assets/Scripts/NetworkGen";
2023-08-30 05:50:21 +00:00
if (Directory.Exists(dest_folder))
{
Directory.Delete(dest_folder, true);
// Just in case the system has output_folder still locked for deletion
while (Directory.Exists(dest_folder))
{
System.Threading.Thread.Sleep(10);
}
}
Directory.CreateDirectory(dest_folder);
Generate(proto_dir, file_list, dest_folder);
}
[MenuItem("Tools/Protobuf/View Proto Files")]
private static void ViewDataPath()
{
int index = Application.dataPath.LastIndexOf('/');
var proto_dir = $"{Application.dataPath.Substring(0, index)}/ServerProtos";
if (!Directory.Exists(proto_dir))
{
Directory.CreateDirectory(proto_dir);
}
EditorUtility.OpenWithDefaultApp(proto_dir);
}
[SerializeField] protected string[] _fileList = new string[0];
protected string folder;
protected SerializedObject _serializedObject;
protected SerializedProperty _fileListProperty;
protected void OnEnable()
{
//使用当前类初始化
_serializedObject = new SerializedObject(this);
//获取当前类中可序列话的属性
_fileListProperty = _serializedObject.FindProperty("_fileList");
}
protected void OnGUI()
{
//绘制标题
GUILayout.Space(10);
GUIStyle textStyle = new GUIStyle();
textStyle.fontSize = 24;
textStyle.normal.textColor = Color.white;
textStyle.alignment = TextAnchor.MiddleCenter;
GUILayout.Label("Proto文件转CS文件", textStyle);
textStyle.fontSize = 18;
GUILayout.Label("Proto file to CS file", textStyle);
GUILayout.Space(10);
/*
*
*/
GUILayout.Label("Proto file folder Proto文件路径");
GUILayout.BeginHorizontal();
EditorGUI.BeginDisabledGroup(true);
folder = EditorGUILayout.TextField(folder);
EditorGUI.EndDisabledGroup();
GUILayout.Space(10);
if (GUILayout.Button("Select Path 选择路径", GUILayout.ExpandWidth(false)))
{
int index = Application.dataPath.LastIndexOf('/');
var proto_dir = $"{Application.dataPath.Substring(0, index)}/ServerProtos";
folder = EditorUtility.OpenFolderPanel("Select proto files source 请选择proto文件路径", proto_dir, "");
}
GUILayout.EndHorizontal();
/*
*
*/
GUILayout.Space(10);
GUILayout.Label("Files to convert 需转换文件");
//更新
_serializedObject.Update();
//开始检查是否有修改
EditorGUI.BeginChangeCheck();
//显示属性
EditorGUILayout.PropertyField(_fileListProperty, true);
//结束检查是否有修改
if (EditorGUI.EndChangeCheck())
{
//提交修改
_serializedObject.ApplyModifiedProperties();
}
/*
*
*/
GUILayout.Space(50);
if (GUILayout.Button("Match all files from folder 从文件夹中匹配全部文件"))
{
_fileList = GetAllProtoFiles(folder);
_serializedObject.Update();
}
GUILayout.Space(10);
if (GUILayout.Button("Generate 生成"))
{
var dest_folder = $"{Application.dataPath}/Gen/Network";
//Generate(folder, _fileList, dest_folder);
}
}
private static string[] GetAllProtoFiles(string path)
{
if (string.IsNullOrEmpty(path))
{
Debug.LogError($"Folder path is empty!");
return null;
}
var file_list = Directory.GetFiles(path, "*.proto", SearchOption.AllDirectories);
var file_name_list = new string[file_list.Length];
for (int i = 0; i < file_list.Length; i++)
{
file_name_list[i] = Path.GetFileName(file_list[i]);
}
return file_name_list;
}
private static void Generate(string inpath, string[] inprotos, string outpath)
{
if (!Directory.Exists(outpath))
{
Directory.CreateDirectory(outpath);
}
var set = new FileDescriptorSet();
set.AddImportPath(inpath);
foreach (var inproto in inprotos)
{
var s = inproto;
if (!inproto.Contains(".proto"))
{
s += ".proto";
}
set.Add(s, true);
}
set.Process();
var errors = set.GetErrors();
CSharpCodeGenerator.ClearTypeNames();
var files = CSharpCodeGenerator.Default.Generate(set);
foreach (var file in files)
{
CSharpCodeGenerator.ClearTypeNames();
var full_file_name = file.Name;
int index = full_file_name.LastIndexOf('.');
var file_name = index > 0 ? full_file_name.Substring(0, index) : full_file_name;
file_name = file_name.ToLower();
var dest_filename = $"{NameNormalizer.AutoCapitalize(file_name)}.cs";
//var path = Path.Combine(outpath, file.Name);
var path = Path.Combine(outpath, dest_filename);
File.WriteAllText(path, file.Text);
Debug.Log($"Generated cs file for {full_file_name.Replace(".cs", ".proto")} successfully to: {path}");
}
EditorUtility.DisplayDialog("Complete",
"Proto文件已转CS详细请看控制台输出" +
"\n" +
"Proto files has been convert into CS files, please go to console and view details",
"Close window");
if (win != null)
{
win.Close();
}
AssetDatabase.Refresh();
}
}
}