2025-09-25 19:04:05 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
|
using Convention;
|
2025-10-08 12:06:37 +08:00
|
|
|
|
using UnityEngine;
|
2025-09-25 19:04:05 +08:00
|
|
|
|
|
|
|
|
|
|
namespace Demo.Editor
|
|
|
|
|
|
{
|
|
|
|
|
|
public static class ProjectCreateHelper
|
|
|
|
|
|
{
|
2025-10-18 18:22:27 +08:00
|
|
|
|
private static string GetTypename(Type type)
|
|
|
|
|
|
{
|
|
|
|
|
|
string result = type.Name;
|
|
|
|
|
|
if (result.Contains('`'))
|
|
|
|
|
|
return result[..result.LastIndexOf('`')];
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-25 19:04:05 +08:00
|
|
|
|
private static void WritePythonStyleFunction(StreamWriter stream, string name, IEnumerable<string> paramList, string description)
|
|
|
|
|
|
{
|
|
|
|
|
|
stream.Write($"def {name}({string.Join(',', paramList)}):\n");
|
|
|
|
|
|
stream.Write($"'''\n{description}\n'''\n...\n\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static void WriteCPPClassBase(StreamWriter stream, Type currentType)
|
2025-10-18 18:22:27 +08:00
|
|
|
|
{
|
|
|
|
|
|
string currentTypeName = GetTypename(currentType);
|
|
|
|
|
|
string baseTypeName = GetTypename(currentType.BaseType);
|
|
|
|
|
|
if (currentType == typeof(ScriptableObject))
|
|
|
|
|
|
{
|
2025-10-08 12:06:37 +08:00
|
|
|
|
// <20><><EFBFBD>ƹ<EFBFBD><C6B9>ߺ<EFBFBD>
|
2025-10-18 18:22:27 +08:00
|
|
|
|
stream.WriteLine("#define __build_in_pragma #");
|
|
|
|
|
|
stream.WriteLine("#define __build_in_to_text(x) #x");
|
2025-10-14 22:57:48 +08:00
|
|
|
|
stream.WriteLine("#define this");
|
2025-10-18 18:22:27 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ඨ<EFBFBD><E0B6A8><EFBFBD><EFBFBD>ʶ<EFBFBD><CAB6>
|
|
|
|
|
|
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
2025-10-08 00:35:50 +08:00
|
|
|
|
{
|
|
|
|
|
|
foreach (var type in asm.GetTypes())
|
|
|
|
|
|
{
|
|
|
|
|
|
// Functions
|
|
|
|
|
|
if (typeof(ScriptableObject).IsAssignableFrom(type))
|
|
|
|
|
|
{
|
2025-10-18 18:22:27 +08:00
|
|
|
|
string typeName = GetTypename(type);
|
|
|
|
|
|
stream.WriteLine($"#define {typeName} \"{typeName}\"");
|
2025-10-08 00:35:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-08 12:06:37 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD>Mathf
|
|
|
|
|
|
foreach (var method in typeof(Mathf).GetMethods())
|
2025-10-18 18:22:27 +08:00
|
|
|
|
{
|
2025-10-08 12:06:37 +08:00
|
|
|
|
stream.WriteLine($"#define {method.Name}({string.Join(',', from param in method.GetParameters() select param.Name)})");
|
2025-10-18 18:22:27 +08:00
|
|
|
|
}
|
2025-10-14 22:57:48 +08:00
|
|
|
|
foreach (var curveType in Enum.GetNames(typeof(MathExtension.EaseCurveType)))
|
|
|
|
|
|
{
|
|
|
|
|
|
stream.WriteLine($"#define {curveType}");
|
2025-10-18 18:22:27 +08:00
|
|
|
|
}
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>RScript<70>ؼ<EFBFBD><D8BC><EFBFBD>
|
|
|
|
|
|
{
|
|
|
|
|
|
stream.Write(@"
|
2025-10-08 12:06:37 +08:00
|
|
|
|
/*
|
|
|
|
|
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǩ
|
|
|
|
|
|
*/
|
|
|
|
|
|
");
|
2025-10-18 18:22:27 +08:00
|
|
|
|
stream.Write($"#define label(label_name) __build_in_pragma define label_name\n\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
{
|
|
|
|
|
|
stream.Write(@"
|
2025-10-08 12:06:37 +08:00
|
|
|
|
/*
|
2025-10-18 18:22:27 +08:00
|
|
|
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD>prΪ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>label<EFBFBD><EFBFBD>
|
2025-10-08 12:06:37 +08:00
|
|
|
|
*/
|
|
|
|
|
|
");
|
2025-10-18 18:22:27 +08:00
|
|
|
|
stream.Write($"#define goto(pr,label_name)\n\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
{
|
|
|
|
|
|
stream.Write(@"
|
2025-10-08 12:06:37 +08:00
|
|
|
|
/*
|
2025-10-18 18:22:27 +08:00
|
|
|
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD>prΪ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>ε<EFBFBD><EFBFBD><EFBFBD>goto<EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD>, ջģʽ
|
2025-10-08 12:06:37 +08:00
|
|
|
|
*/
|
|
|
|
|
|
");
|
2025-10-18 18:22:27 +08:00
|
|
|
|
stream.Write($"#define back(pr)\n\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
{
|
|
|
|
|
|
stream.Write(@"
|
|
|
|
|
|
/*
|
|
|
|
|
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD>prΪ<EFBFBD><EFBFBD>ʱ<EFBFBD>˳<EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>
|
|
|
|
|
|
*/
|
|
|
|
|
|
");
|
|
|
|
|
|
stream.Write($"#define break(pr)\n\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
{
|
|
|
|
|
|
stream.Write(@"
|
|
|
|
|
|
/*
|
|
|
|
|
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ佫<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD>Ҫʹ<EFBFBD><EFBFBD>goto<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*/
|
|
|
|
|
|
");
|
|
|
|
|
|
stream.Write($"#define namespace(name)\n\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
stream.WriteLine($"struct {currentTypeName}");
|
|
|
|
|
|
stream.WriteLine("{");
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
stream.Write($"#include \"{baseTypeName}.helper.h\"\n\n");
|
|
|
|
|
|
stream.WriteLine($"struct {currentTypeName}:public {baseTypeName}");
|
|
|
|
|
|
stream.WriteLine("{");
|
2025-10-05 20:18:48 +08:00
|
|
|
|
}
|
2025-10-07 01:45:52 +08:00
|
|
|
|
}
|
2025-09-25 19:04:05 +08:00
|
|
|
|
|
|
|
|
|
|
private static void WriteCPPStyleFunction(StreamWriter stream, string name, IEnumerable<string> paramList, string description)
|
|
|
|
|
|
{
|
2025-10-08 00:35:50 +08:00
|
|
|
|
if (name == nameof(ScriptableObject.LoadSubScript))
|
|
|
|
|
|
{
|
2025-10-05 20:18:48 +08:00
|
|
|
|
stream.Write("/*\n" + description + "\n*/\n");
|
|
|
|
|
|
stream.Write($"#define {name}({string.Join(',', paramList)}) __build_in_pragma include {paramList.ToArray()[1]}\n\n");
|
|
|
|
|
|
//stream.Write($"#define {name}({string.Join(',', paramList)})\n\n");
|
2025-10-08 00:35:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
stream.Write("/*\n" + description + "\n*/\n");
|
|
|
|
|
|
stream.Write($"#define {name}({string.Join(',', paramList)}) \n\n");
|
|
|
|
|
|
}
|
2025-09-25 19:04:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-18 18:22:27 +08:00
|
|
|
|
private static void WriteCPPClassEnd(StreamWriter stream, Type currentType)
|
|
|
|
|
|
{
|
|
|
|
|
|
stream.WriteLine("};");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static void CreateHelperFiles(string dir, ProjectDefaultFileStyle style = ProjectDefaultFileStyle.CPP)
|
2025-09-25 19:04:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
var toolDir = new ToolFile(dir);
|
|
|
|
|
|
if (toolDir.IsDir() == false)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new InvalidOperationException("Not a directory");
|
|
|
|
|
|
}
|
|
|
|
|
|
toolDir.MustExistsPath();
|
|
|
|
|
|
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var type in asm.GetTypes())
|
|
|
|
|
|
{
|
2025-10-07 15:45:12 +08:00
|
|
|
|
// Functions
|
|
|
|
|
|
if (typeof(ScriptableObject).IsAssignableFrom(type))
|
2025-09-25 19:04:05 +08:00
|
|
|
|
{
|
2025-10-07 15:45:12 +08:00
|
|
|
|
var scriptCalls = (from info in type.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
|
|
|
|
|
|
where info is MethodInfo
|
|
|
|
|
|
where info.GetCustomAttribute<ScriptableCallAttribute>(false) != null
|
|
|
|
|
|
select info as MethodInfo).ToList();
|
2025-10-18 18:22:27 +08:00
|
|
|
|
var typeName = GetTypename(type);
|
|
|
|
|
|
string fileHeader = $"{typeName}.helper" + style switch
|
2025-10-07 15:45:12 +08:00
|
|
|
|
{
|
|
|
|
|
|
ProjectDefaultFileStyle.PY => ",py",
|
|
|
|
|
|
_ => ".h"
|
|
|
|
|
|
};
|
|
|
|
|
|
using var fs = File.AppendText((toolDir | fileHeader).GetFullPath());
|
2025-09-25 19:04:05 +08:00
|
|
|
|
switch (style)
|
|
|
|
|
|
{
|
2025-10-07 15:45:12 +08:00
|
|
|
|
case ProjectDefaultFileStyle.CPP:
|
|
|
|
|
|
WriteCPPClassBase(fs, type);
|
|
|
|
|
|
break;
|
2025-09-25 19:04:05 +08:00
|
|
|
|
case ProjectDefaultFileStyle.PY:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2025-10-07 15:45:12 +08:00
|
|
|
|
foreach (var methodInfo in scriptCalls)
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = methodInfo.GetCustomAttribute<ScriptableCallAttribute>(false);
|
|
|
|
|
|
switch (style)
|
|
|
|
|
|
{
|
|
|
|
|
|
case ProjectDefaultFileStyle.PY:
|
|
|
|
|
|
WritePythonStyleFunction(fs, methodInfo.Name, from param in methodInfo.GetParameters() select param.Name, data.Description);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
WriteCPPStyleFunction(fs, methodInfo.Name, from param in methodInfo.GetParameters() select param.Name, data.Description);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2025-10-18 18:22:27 +08:00
|
|
|
|
}
|
|
|
|
|
|
switch (style)
|
|
|
|
|
|
{
|
|
|
|
|
|
case ProjectDefaultFileStyle.CPP:
|
|
|
|
|
|
WriteCPPClassEnd(fs, type);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ProjectDefaultFileStyle.PY:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-07 15:45:12 +08:00
|
|
|
|
// Enums
|
|
|
|
|
|
if (typeof(Enum).IsAssignableFrom(type)&& type.GetCustomAttribute<ScriptableCallAttribute>(false) != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
// TODO
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-25 19:04:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|