perf[protocol]: 使用模板生成协议

This commit is contained in:
jaysunxiao committed 2022-05-18 18:35:12 +08:00
1 parent 5eb2530eae
commit d4ded2dd19
15 files changed
+97 -142

No files matched your search

@@ -128,7 +128,9 @@ public abstract class GenerateProtocolFile {
if (generateLanguages.contains(CodeLanguage.Lua)) { if (generateLanguages.contains(CodeLanguage.Lua)) {
GenerateLuaUtils.init(generateOperation); GenerateLuaUtils.init(generateOperation);
GenerateLuaUtils.createProtocolManager(allSortedGenerateProtocols); GenerateLuaUtils.createProtocolManager(allSortedGenerateProtocols);
allSortedGenerateProtocols.forEach(it -> GenerateLuaUtils.createLuaProtocolFile((ProtocolRegistration) it)); for (var protocolRegistration : allSortedGenerateProtocols) {
GenerateLuaUtils.createLuaProtocolFile((ProtocolRegistration) protocolRegistration);
}
} }
// 生成GdScript协议 // 生成GdScript协议
@@ -17,9 +17,9 @@ import com.zfoo.protocol.generate.GenerateOperation;
import com.zfoo.protocol.generate.GenerateProtocolDocument; import com.zfoo.protocol.generate.GenerateProtocolDocument;
import com.zfoo.protocol.generate.GenerateProtocolFile; import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.generate.GenerateProtocolPath; import com.zfoo.protocol.generate.GenerateProtocolPath;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.registration.IProtocolRegistration; import com.zfoo.protocol.registration.IProtocolRegistration;
import com.zfoo.protocol.registration.ProtocolRegistration; import com.zfoo.protocol.registration.ProtocolRegistration;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.serializer.reflect.*; import com.zfoo.protocol.serializer.reflect.*;
import com.zfoo.protocol.util.ClassUtils; import com.zfoo.protocol.util.ClassUtils;
import com.zfoo.protocol.util.FileUtils; import com.zfoo.protocol.util.FileUtils;
@@ -28,8 +28,10 @@ import com.zfoo.protocol.util.StringUtils;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field; import java.util.Arrays;
import java.util.*; import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static com.zfoo.protocol.util.FileUtils.LS; import static com.zfoo.protocol.util.FileUtils.LS;
@@ -79,7 +81,6 @@ public abstract class GenerateLuaUtils {
public static void createProtocolManager(List<IProtocolRegistration> protocolList) throws IOException { public static void createProtocolManager(List<IProtocolRegistration> protocolList) throws IOException {
var list = List.of("lua/Buffer/ByteBuffer.lua", "lua/Buffer/Long.lua"); var list = List.of("lua/Buffer/ByteBuffer.lua", "lua/Buffer/Long.lua");
for (var fileName : list) { for (var fileName : list) {
var fileInputStream = ClassUtils.getFileFromClassPath(fileName); var fileInputStream = ClassUtils.getFileFromClassPath(fileName);
var createFile = new File(StringUtils.format("{}/{}", protocolOutputRootPath, StringUtils.substringAfterFirst(fileName, "lua/"))); var createFile = new File(StringUtils.format("{}/{}", protocolOutputRootPath, StringUtils.substringAfterFirst(fileName, "lua/")));
@@ -87,110 +88,71 @@ public abstract class GenerateLuaUtils {
} }
// 生成Protocol.lua文件 // 生成Protocol.lua文件
var luaBuilder = new StringBuilder(); var protocolManagerTemplate = StringUtils.bytesToString(IOUtils.toByteArray(ClassUtils.getFileFromClassPath("lua/ProtocolManagerTemplate.lua")));
var fieldBuilder = new StringBuilder();
var protocolBuilder = new StringBuilder();
for (var protocol : protocolList) {
var protocolId = protocol.protocolId();
var name = protocol.protocolConstructor().getDeclaringClass().getSimpleName();
var path = GenerateProtocolPath.getCapitalizeProtocolPath(protocolId);
if (StringUtils.isBlank(path)) {
fieldBuilder.append(TAB).append(StringUtils.format("local {} = require(\"LuaProtocol.{}\")", name, name)).append(LS);
} else {
fieldBuilder.append(TAB).append(StringUtils.format("local {} = require(\"LuaProtocol.{}.{}\")"
, name, path.replaceAll(StringUtils.SLASH, StringUtils.PERIOD), name)).append(LS);
}
var protocolManagerStr = StringUtils.bytesToString(IOUtils.toByteArray(ClassUtils.getFileFromClassPath("lua/ProtocolManager.lua"))); protocolBuilder.append(TAB).append(StringUtils.format("protocols[{}] = {}", protocolId, name)).append(LS);
luaBuilder.append(protocolManagerStr); }
protocolManagerTemplate = StringUtils.format(protocolManagerTemplate, "{}", "{}", fieldBuilder.toString().trim(), protocolBuilder.toString().trim());
luaBuilder.append("function initProtocol()").append(LS); FileUtils.writeStringToFile(new File(StringUtils.format("{}/{}", protocolOutputRootPath, "ProtocolManager.lua")), protocolManagerTemplate);
protocolList.stream()
.filter(it -> Objects.nonNull(it))
.forEach(it -> {
var name = it.protocolConstructor().getDeclaringClass().getSimpleName();
var path = GenerateProtocolPath.getCapitalizeProtocolPath(it.protocolId());
if (StringUtils.isBlank(path)) {
luaBuilder.append(TAB).append(StringUtils.format("local {} = require(\"LuaProtocol.{}\")", name, name)).append(LS);
} else {
luaBuilder.append(TAB).append(StringUtils.format("local {} = require(\"LuaProtocol.{}.{}\")"
, name, path.replaceAll(StringUtils.SLASH, StringUtils.PERIOD), name)).append(LS);
}
});
protocolList.stream().filter(it -> Objects.nonNull(it))
.forEach(it -> luaBuilder.append(TAB).append(StringUtils.format("protocols[{}] = {}", it.protocolId(), it.protocolConstructor().getDeclaringClass().getSimpleName())).append(LS));
luaBuilder.append("end").append(LS + LS);
luaBuilder.append("ProtocolManager.initProtocol = initProtocol").append(LS);
luaBuilder.append("return ProtocolManager").append(LS);
FileUtils.writeStringToFile(new File(StringUtils.format("{}/{}", protocolOutputRootPath, "ProtocolManager.lua")), luaBuilder.toString());
} }
public static void createLuaProtocolFile(ProtocolRegistration registration) { public static void createLuaProtocolFile(ProtocolRegistration registration) throws IOException {
// 初始化index // 初始化index
GenerateProtocolFile.index.set(0); GenerateProtocolFile.index.set(0);
var protocolId = registration.protocolId(); var protocolId = registration.protocolId();
var registrationConstructor = registration.getConstructor(); var registrationConstructor = registration.getConstructor();
var fieldRegistrations = registration.getFieldRegistrations();
var protocolClazzName = registrationConstructor.getDeclaringClass().getSimpleName(); var protocolClazzName = registrationConstructor.getDeclaringClass().getSimpleName();
var protocolTemplate = StringUtils.bytesToString(IOUtils.toByteArray(ClassUtils.getFileFromClassPath("lua/ProtocolTemplate.lua")));
var luaBuilder = new StringBuilder(); var docTitle = docTitle(registration);
var valueOfMethod = valueOfMethod(registration);
// document var writePacket = writePacket(registration);
luaBuilder.append(documentTitle(registration)); var readPacket = readPacket(registration);
// new object
luaBuilder.append(newFunction(registration));
// protocolId method
luaBuilder.append(protocolIdFunction(registration));
// writeObject method
luaBuilder.append(writePacket(registration));
// readObject method
luaBuilder.append(readPacket(registration)).append(LS);
luaBuilder.append(StringUtils.format("return {}", protocolClazzName)).append(LS);
protocolTemplate = StringUtils.format(protocolTemplate, docTitle, protocolClazzName, "{}", protocolClazzName
, valueOfMethod.getKey().trim(), valueOfMethod.getValue().trim(), protocolClazzName, protocolId
, protocolClazzName, writePacket.trim(), protocolClazzName, protocolClazzName, readPacket.trim(), protocolClazzName);
var protocolOutputPath = StringUtils.format("{}/{}/{}.lua" var protocolOutputPath = StringUtils.format("{}/{}/{}.lua"
, protocolOutputRootPath , protocolOutputRootPath, GenerateProtocolPath.getCapitalizeProtocolPath(protocolId), protocolClazzName);
, GenerateProtocolPath.getCapitalizeProtocolPath(protocolId) FileUtils.writeStringToFile(new File(protocolOutputPath), protocolTemplate);
, protocolClazzName);
FileUtils.writeStringToFile(new File(protocolOutputPath), luaBuilder.toString());
} }
private static String documentTitle(ProtocolRegistration registration) { private static String docTitle(ProtocolRegistration registration) {
var protocolId = registration.protocolId(); var protocolId = registration.protocolId();
var registrationConstructor = registration.getConstructor();
var fieldRegistrations = registration.getFieldRegistrations();
var luaBuilder = new StringBuilder(); var luaBuilder = new StringBuilder();
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId); var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
var docTitle = protocolDocument.getKey(); var docTitle = protocolDocument.getKey();
if (StringUtils.isNotBlank(docTitle)) { if (StringUtils.isNotBlank(docTitle)) {
Arrays.stream(docTitle.split(LS)).forEach(it -> luaBuilder.append(docToLuaDoc(it)).append(LS)); Arrays.stream(docTitle.split(LS)).forEach(it -> luaBuilder.append(docToLuaDoc(it)).append(LS));
luaBuilder.append(LS);
} }
return luaBuilder.toString(); return luaBuilder.toString();
} }
private static String newFunction(ProtocolRegistration registration) { private static Pair<String, String> valueOfMethod(ProtocolRegistration registration) {
short protocolId = registration.getId(); var protocolId = registration.getId();
var fields = registration.getFields(); var fields = registration.getFields();
var protocolClazzName = registration.getConstructor().getDeclaringClass().getSimpleName();
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId); var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
var docFieldMap = protocolDocument.getValue(); var docFieldMap = protocolDocument.getValue();
var valueOfParams = StringUtils.joinWith(", ", Arrays.stream(fields).map(it -> it.getName()).collect(Collectors.toList()).toArray());
var luaBuilder = new StringBuilder(); var luaBuilder = new StringBuilder();
luaBuilder.append(StringUtils.format("local {} = {}", protocolClazzName)).append(LS + LS); for (var i = 0; i < fields.length; i++) {
luaBuilder.append(StringUtils.format("function {}:new(", protocolClazzName));
luaBuilder.append(StringUtils.joinWith(", ", Arrays.stream(fields).map(it -> it.getName()).collect(Collectors.toList()).toArray()))
.append(")")
.append(LS);
luaBuilder.append(TAB).append("local obj = {").append(LS);
for (int i = 0; i < fields.length; i++) {
var field = fields[i]; var field = fields[i];
var propertyName = field.getName(); var propertyName = field.getName();
@@ -201,92 +163,42 @@ public abstract class GenerateLuaUtils {
} }
if (i == fields.length - 1) { if (i == fields.length - 1) {
luaBuilder.append(TAB + TAB) luaBuilder.append(TAB + TAB).append(StringUtils.format("{} = {}", propertyName, propertyName));
.append(StringUtils.format("{} = {}", propertyName, propertyName));
} else { } else {
luaBuilder.append(TAB + TAB) luaBuilder.append(TAB + TAB).append(StringUtils.format("{} = {},", propertyName, propertyName));
.append(StringUtils.format("{} = {},", propertyName, propertyName));
} }
// 生成类型的注释 // 生成类型的注释
luaBuilder.append(" -- ").append(field.getGenericType().getTypeName()).append(LS); luaBuilder.append(" -- ").append(field.getGenericType().getTypeName()).append(LS);
} }
luaBuilder.append(TAB).append("}").append(LS); return new Pair<>(valueOfParams, luaBuilder.toString());
luaBuilder.append(TAB).append("setmetatable(obj, self)").append(LS);
luaBuilder.append(TAB).append("self.__index = self").append(LS);
luaBuilder.append(TAB).append("return obj").append(LS);
luaBuilder.append("end").append(LS).append(LS);
return luaBuilder.toString();
} }
private static String protocolIdFunction(ProtocolRegistration registration) {
short protocolId = registration.getId();
var protocolClazzName = registration.getConstructor().getDeclaringClass().getSimpleName();
var luaBuilder = new StringBuilder();
luaBuilder.append(StringUtils.format("function {}:protocolId()", protocolClazzName)).append(LS);
luaBuilder.append(TAB).append(StringUtils.format("return {}", protocolId)).append(LS);
luaBuilder.append("end").append(LS).append(LS);
return luaBuilder.toString();
}
private static String writePacket(ProtocolRegistration registration) { private static String writePacket(ProtocolRegistration registration) {
var fields = registration.getFields(); var fields = registration.getFields();
var fieldRegistrations = registration.getFieldRegistrations(); var fieldRegistrations = registration.getFieldRegistrations();
var protocolClazzName = registration.getConstructor().getDeclaringClass().getSimpleName();
var luaBuilder = new StringBuilder(); var luaBuilder = new StringBuilder();
luaBuilder.append(StringUtils.format("function {}:write(buffer, packet)", protocolClazzName)).append(LS);
luaBuilder.append(TAB).append("if buffer:writePacketFlag(packet) then").append(LS);
luaBuilder.append(TAB + TAB).append("return").append(LS);
luaBuilder.append(TAB).append("end").append(LS);
for (var i = 0; i < fields.length; i++) { for (var i = 0; i < fields.length; i++) {
var field = fields[i]; var field = fields[i];
var fieldRegistration = fieldRegistrations[i]; var fieldRegistration = fieldRegistrations[i];
luaSerializer(fieldRegistration.serializer()).writeObject(luaBuilder, "packet." + field.getName(), 1, field, fieldRegistration); luaSerializer(fieldRegistration.serializer()).writeObject(luaBuilder, "packet." + field.getName(), 1, field, fieldRegistration);
} }
luaBuilder.append("end").append(LS).append(LS);
return luaBuilder.toString(); return luaBuilder.toString();
} }
private static String readPacket(ProtocolRegistration registration) { private static String readPacket(ProtocolRegistration registration) {
Field[] fields = registration.getFields(); var fields = registration.getFields();
IFieldRegistration[] fieldRegistrations = registration.getFieldRegistrations(); var fieldRegistrations = registration.getFieldRegistrations();
var protocolClazzName = registration.getConstructor().getDeclaringClass().getSimpleName(); var luaBuilder = new StringBuilder();
var jsBuilder = new StringBuilder();
jsBuilder.append(StringUtils.format("function {}:read(buffer)", protocolClazzName)).append(LS);
jsBuilder.append(TAB).append("if not(buffer:readBoolean()) then").append(LS);
jsBuilder.append(TAB + TAB).append("return nil").append(LS);
jsBuilder.append(TAB).append("end").append(LS);
jsBuilder.append(TAB).append(StringUtils.format("local packet = {}:new()", protocolClazzName)).append(LS);
for (int i = 0; i < fields.length; i++) { for (int i = 0; i < fields.length; i++) {
Field field = fields[i]; var field = fields[i];
IFieldRegistration fieldRegistration = fieldRegistrations[i]; var fieldRegistration = fieldRegistrations[i];
var readObject = luaSerializer(fieldRegistration.serializer()).readObject(luaBuilder, 1, field, fieldRegistration);
String readObject = luaSerializer(fieldRegistration.serializer()).readObject(jsBuilder, 1, field, fieldRegistration); luaBuilder.append(TAB).append(StringUtils.format("packet.{} = {}", field.getName(), readObject)).append(LS);
jsBuilder.append(TAB).append(StringUtils.format("packet.{} = {}", field.getName(), readObject)).append(LS);
} }
return luaBuilder.toString();
jsBuilder.append(TAB).append("return packet").append(LS);
jsBuilder.append("end").append(LS);
return jsBuilder.toString();
} }
private static String docToLuaDoc(String doc) { private static String docToLuaDoc(String doc) {
return doc.replaceFirst("//", "--"); return doc.replaceFirst("//", "--");
} }
@@ -32,3 +32,10 @@ function ProtocolManager.read(buffer)
return ProtocolManager.getProtocol(protocolId):read(buffer) return ProtocolManager.getProtocol(protocolId):read(buffer)
end end
function initProtocol()
{}
{}
end
ProtocolManager.initProtocol = initProtocol
return ProtocolManager
@@ -0,0 +1,33 @@
{}
local {} = {}
function {}:new({})
local obj = {
{}
}
setmetatable(obj, self)
self.__index = self
return obj
end
function {}:protocolId()
return {}
end
function {}:write(buffer, packet)
if buffer:writePacketFlag(packet) then
return
end
{}
end
function {}:read(buffer)
if not(buffer:readBoolean()) then
return nil
end
local packet = {}:new()
{}
return packet
end
return {}
+1 -1
View File
@@ -13,7 +13,7 @@ namespace csharp
ProtocolManager.InitProtocol(); ProtocolManager.InitProtocol();
// 获取复杂对象的字节流 // 获取复杂对象的字节流
var complexObjectBytes = File.ReadAllBytes("C:\\zfoo\\protocol\\src\\test\\resources\\ComplexObject.bytes"); var complexObjectBytes = File.ReadAllBytes("../resources/ComplexObject.bytes");
var buffer = ByteBuffer.ValueOf(); var buffer = ByteBuffer.ValueOf();
buffer.WriteBytes(complexObjectBytes); buffer.WriteBytes(complexObjectBytes);
var packet = ProtocolManager.Read(buffer); var packet = ProtocolManager.Read(buffer);
@@ -1,6 +1,7 @@
using System.IO; using System.IO;
using System.Text; using System.Text;
using NUnit.Framework; using NUnit.Framework;
using Spring.Util;
using XLua; using XLua;
namespace Test.Editor.LuaTest namespace Test.Editor.LuaTest
@@ -18,7 +19,7 @@ namespace Test.Editor.LuaTest
var luaEnv = new LuaEnv(); var luaEnv = new LuaEnv();
var luaDebugBuilder = new StringBuilder(); var luaDebugBuilder = new StringBuilder();
// Rider的断点调试 // Rider的断点调试
// luaDebugBuilder.Append("package.cpath = package.cpath .. ';C:/Users/jm/AppData/Roaming/JetBrains/Rider2020.1/plugins/intellij-emmylua/classes/debugger/emmy/windows/x64/?.dll'").Append(FileUtils.LS); // luaDebugBuilder.Append("package.cpath = package.cpath .. ';C:/Users/jaysunxiao/AppData/Roaming/JetBrains/Rider2021.1/plugins/EmmyLua/classes/debugger/emmy/windows/x64/?.dll'").Append(FileUtils.LS);
// luaDebugBuilder.Append("local dbg = require('emmy_core')").Append(FileUtils.LS); // luaDebugBuilder.Append("local dbg = require('emmy_core')").Append(FileUtils.LS);
// luaDebugBuilder.Append("dbg.tcpListen('localhost', 9966)").Append(FileUtils.LS); // luaDebugBuilder.Append("dbg.tcpListen('localhost', 9966)").Append(FileUtils.LS);
// luaDebugBuilder.Append("dbg.waitIDE()").Append(FileUtils.LS); // luaDebugBuilder.Append("dbg.waitIDE()").Append(FileUtils.LS);
@@ -27,8 +28,8 @@ namespace Test.Editor.LuaTest
luaEnv.AddLoader(CustomLoader); luaEnv.AddLoader(CustomLoader);
var luaProtocolTestStr = File.ReadAllText(TEST_PATH + "LuaProtocolTest.lua"); var luaProtocolTestStr = File.ReadAllText(TEST_PATH + "main.lua");
luaEnv.DoString(luaProtocolTestStr, "LuaProtocolTest"); luaEnv.DoString(luaProtocolTestStr, "main");
LuaFunction byteBufferTestFunction = luaEnv.Global.Get<LuaFunction>("byteBufferTest"); LuaFunction byteBufferTestFunction = luaEnv.Global.Get<LuaFunction>("byteBufferTest");
byteBufferTestFunction.Call(); byteBufferTestFunction.Call();