mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
升级拓展GameEvent,支持基于Interface的方法调用抛出事件,以及自动化根据声明的Interface来生成实现代码。
升级拓展GameEvent,支持基于Interface的方法调用抛出事件,以及自动化根据声明的Interface来生成实现代码。
This commit is contained in:
8
UnityProject/Assets/TEngine/Editor/EventInterface.meta
Normal file
8
UnityProject/Assets/TEngine/Editor/EventInterface.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86094b7c7ca31ab4da174cc7eae14a3c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,199 @@
|
||||
#region Class Documentation
|
||||
/************************************************************************************************************
|
||||
Class Name: EventInterfaceGenerate.cs
|
||||
Type: Editor, Generator, Util, Static
|
||||
Definition:
|
||||
用法,在目录"Assets/GameScripts/HotFix/GameLogic/Event/Interface/"下分组照示例声明Interface 模块待抛出事件的接口。编译后自动生成接口实现抛出的脚本。
|
||||
Example:
|
||||
|
||||
旧版抛出事件方式: GameEvent.Send(RuntimeId.ToRuntimeId("OnMainPlayerCurrencyChange"),CurrencyType.Gold,oldVal,newVal);
|
||||
|
||||
新版抛出事件方式 : GameEvent.Get<IActorLogicEvent>().OnMainPlayerCurrencyChange(CurrencyType.Gold,oldVal,newVal);
|
||||
|
||||
************************************************************************************************************/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using TEngine;
|
||||
using Unity.EditorCoroutines.Editor;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[InitializeOnLoad]
|
||||
public static class EventInterfaceGenerate
|
||||
{
|
||||
public static string NameSpace = @"GameLogic";
|
||||
|
||||
|
||||
public const string EventInterfacePath = "Assets/GameScripts/HotFix/GameLogic/Event/Interface/";
|
||||
|
||||
static EventInterfaceGenerate()
|
||||
{
|
||||
Generate();
|
||||
}
|
||||
|
||||
[MenuItem("TEngine/Generate EventInterface", false, 300)]
|
||||
public static void Generate()
|
||||
{
|
||||
if (EventInterfaceGenerateTag.HadGenerate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EventInterfaceGenerateTag.HadGenerate = true;
|
||||
|
||||
// 加载程序集
|
||||
Assembly assembly = typeof(GameApp).Assembly;
|
||||
|
||||
// 获取程序集中的所有类型
|
||||
Type[] types = assembly.GetTypes();
|
||||
|
||||
// 遍历每个类型
|
||||
foreach (Type type in types)
|
||||
{
|
||||
// 检查类型是否是接口
|
||||
if (!type.IsInterface)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var attribute = type.GetCustomAttributes(typeof(EventInterfaceAttribute), false).FirstOrDefault();
|
||||
|
||||
if (attribute != null)
|
||||
{
|
||||
EventInterfaceAttribute eventInterfaceAttribute = attribute as EventInterfaceAttribute;
|
||||
|
||||
GenAutoBindCode(type, eventInterfaceAttribute);
|
||||
}
|
||||
}
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
Debug.Log("Generate EventInterface Complete");
|
||||
// EditorUtility.DisplayDialog("提示", "代码生成完毕", "OK");
|
||||
|
||||
EditorCoroutineUtility.StartCoroutine(EventInterfaceGenerateTag.Reset(), null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成自动绑定代码
|
||||
/// </summary>
|
||||
private static void GenAutoBindCode(Type interfaceType, EventInterfaceAttribute eventInterfaceAttribute)
|
||||
{
|
||||
string interfaceName = interfaceType.Name;
|
||||
string className = $"{interfaceName}_Gen";
|
||||
string codePath = $"{Application.dataPath}/GameScripts/HotFix/GameLogic/Event/Gen/{eventInterfaceAttribute.EventGroup}";
|
||||
|
||||
if (!Directory.Exists(codePath))
|
||||
{
|
||||
Directory.CreateDirectory(codePath);
|
||||
}
|
||||
|
||||
using (StreamWriter sw = new StreamWriter($"{codePath}/{className}.cs"))
|
||||
{
|
||||
sw.WriteLine(
|
||||
$"//------------------------------------------------------------------------------\n//\t<auto-generated>\n//\t\tThis code was generated by autoBindTool.\n//\t\tChanges to this file may cause incorrect behavior and will be lost if\n//\t\tthe code is regenerated.\n//\t</auto-generated>\n//------------------------------------------------------------------------------");
|
||||
sw.WriteLine("using UnityEngine;");
|
||||
sw.WriteLine("using UnityEngine.UI;");
|
||||
sw.WriteLine("using TEngine;");
|
||||
sw.WriteLine("");
|
||||
|
||||
if (!string.IsNullOrEmpty(NameSpace))
|
||||
{
|
||||
//命名空间
|
||||
sw.WriteLine("namespace " + NameSpace);
|
||||
sw.WriteLine("{");
|
||||
}
|
||||
|
||||
#region EventId生成
|
||||
|
||||
sw.WriteLine($"\tpublic partial class {interfaceName}_Event");
|
||||
sw.WriteLine("\t{");
|
||||
|
||||
// 获取接口中的所有方法
|
||||
MethodInfo[] methods = interfaceType.GetMethods();
|
||||
|
||||
//组件字段
|
||||
foreach (MethodInfo method in methods)
|
||||
{
|
||||
sw.WriteLine($"\t\tpublic static readonly int {method.Name} = RuntimeId.ToRuntimeId(\"{interfaceName}_Event.{method.Name}\");");
|
||||
}
|
||||
|
||||
sw.WriteLine("\t}");
|
||||
sw.WriteLine("");
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
//类名
|
||||
sw.WriteLine($"\t[EventInterfaceImp(EEventGroup.{eventInterfaceAttribute.EventGroup})]");
|
||||
sw.WriteLine($"\tpublic partial class {className} : {interfaceName}");
|
||||
sw.WriteLine("\t{");
|
||||
|
||||
sw.WriteLine("\t\tprivate EventDispatcher _dispatcher;");
|
||||
sw.WriteLine($"\t\tpublic {className}(EventDispatcher dispatcher)");
|
||||
sw.WriteLine("\t\t{");
|
||||
sw.WriteLine($"\t\t\t_dispatcher = dispatcher;");
|
||||
sw.WriteLine("\t\t}");
|
||||
sw.WriteLine("");
|
||||
|
||||
//组件字段
|
||||
foreach (MethodInfo methodInfo in methods)
|
||||
{
|
||||
ParameterInfo[] parameterInfos = methodInfo.GetParameters(); //得到指定方法的参数列表
|
||||
if (parameterInfos.Length <= 0)
|
||||
{
|
||||
sw.WriteLine(
|
||||
$" public void {methodInfo.Name}()\n {{\n _dispatcher.Send({interfaceName}_Event.{methodInfo.Name});\n }}");
|
||||
}
|
||||
else
|
||||
{
|
||||
string paramStr = "";
|
||||
string paramStr2 = "";
|
||||
for (int i = 0; i < parameterInfos.Length; i++)
|
||||
{
|
||||
var parameterInfo = parameterInfos[i];
|
||||
Type type = parameterInfo.ParameterType;
|
||||
string paramName = parameterInfo.Name;
|
||||
if (i == parameterInfos.Length - 1)
|
||||
{
|
||||
paramStr += $"{type.FullName} {paramName}";
|
||||
paramStr2 += $"{paramName}";
|
||||
}
|
||||
else
|
||||
{
|
||||
paramStr += $"{type.FullName} {paramName},";
|
||||
paramStr2 += $"{paramName},";
|
||||
}
|
||||
}
|
||||
|
||||
sw.WriteLine(
|
||||
$" public void {methodInfo.Name}({paramStr})\n {{\n _dispatcher.Send({interfaceName}_Event.{methodInfo.Name},{paramStr2});\n }}");
|
||||
}
|
||||
|
||||
sw.WriteLine("");
|
||||
}
|
||||
|
||||
sw.WriteLine("\t}");
|
||||
|
||||
if (!string.IsNullOrEmpty(NameSpace))
|
||||
{
|
||||
sw.WriteLine("}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class EventInterfaceGenerateTag
|
||||
{
|
||||
public static bool HadGenerate = false;
|
||||
|
||||
public static IEnumerator Reset()
|
||||
{
|
||||
yield return new WaitForSeconds(10f);
|
||||
HadGenerate = false;
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e3af172e88343e4cb49c9e870518ede
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -5,7 +5,9 @@
|
||||
"GUID:24c092aee38482f4e80715eaa8148782",
|
||||
"GUID:e34a5702dd353724aa315fb8011f08c3",
|
||||
"GUID:4d1926c9df5b052469a1c63448b7609a",
|
||||
"GUID:2373f786d14518f44b0f475db77ba4de"
|
||||
"GUID:2373f786d14518f44b0f475db77ba4de",
|
||||
"GUID:6e76b07590314a543b982daed6af2509",
|
||||
"GUID:478a2357cc57436488a56e564b08d223"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
|
@@ -19,10 +19,11 @@ namespace TEngine
|
||||
}
|
||||
|
||||
[System.AttributeUsage(System.AttributeTargets.Interface)]
|
||||
public class EventInterface : Attribute
|
||||
public class EventInterfaceAttribute : Attribute
|
||||
{
|
||||
private EEventGroup _eGroup;
|
||||
public EventInterface(EEventGroup group)
|
||||
public EEventGroup EventGroup => _eGroup;
|
||||
public EventInterfaceAttribute(EEventGroup group)
|
||||
{
|
||||
_eGroup = group;
|
||||
}
|
||||
|
@@ -50,6 +50,21 @@ namespace TEngine
|
||||
_eventEntryMap.Add(typeName, entry);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册wrap的函数。
|
||||
/// </summary>
|
||||
/// <param name="typeName">类型名称。</param>
|
||||
/// <param name="callerWrap">调用接口名。</param>
|
||||
public void RegWrapInterface(string typeName,object callerWrap)
|
||||
{
|
||||
var entry = new EventEntryData();
|
||||
entry.InterfaceWrap = callerWrap;
|
||||
if (typeName != null)
|
||||
{
|
||||
_eventEntryMap.Add(typeName, entry);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分发注册器。
|
||||
|
@@ -12,6 +12,7 @@ namespace TEngine
|
||||
/// </summary>
|
||||
private static readonly EventMgr _eventMgr = new EventMgr();
|
||||
|
||||
public static EventMgr EventMgr => _eventMgr;
|
||||
#region 细分的注册接口
|
||||
|
||||
/// <summary>
|
||||
|
Reference in New Issue
Block a user