mirror of
https://github.com/tiennm99/zfoo.git
synced 2026-05-20 03:26:57 +00:00
perf[protocol]: 使用模板生成协议
This commit is contained in:
@@ -128,7 +128,9 @@ public abstract class GenerateProtocolFile {
|
||||
if (generateLanguages.contains(CodeLanguage.Lua)) {
|
||||
GenerateLuaUtils.init(generateOperation);
|
||||
GenerateLuaUtils.createProtocolManager(allSortedGenerateProtocols);
|
||||
allSortedGenerateProtocols.forEach(it -> GenerateLuaUtils.createLuaProtocolFile((ProtocolRegistration) it));
|
||||
for (var protocolRegistration : allSortedGenerateProtocols) {
|
||||
GenerateLuaUtils.createLuaProtocolFile((ProtocolRegistration) protocolRegistration);
|
||||
}
|
||||
}
|
||||
|
||||
// 生成GdScript协议
|
||||
|
||||
@@ -17,9 +17,9 @@ import com.zfoo.protocol.generate.GenerateOperation;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolDocument;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolPath;
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.registration.IProtocolRegistration;
|
||||
import com.zfoo.protocol.registration.ProtocolRegistration;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.reflect.*;
|
||||
import com.zfoo.protocol.util.ClassUtils;
|
||||
import com.zfoo.protocol.util.FileUtils;
|
||||
@@ -28,8 +28,10 @@ import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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 {
|
||||
var list = List.of("lua/Buffer/ByteBuffer.lua", "lua/Buffer/Long.lua");
|
||||
|
||||
for (var fileName : list) {
|
||||
var fileInputStream = ClassUtils.getFileFromClassPath(fileName);
|
||||
var createFile = new File(StringUtils.format("{}/{}", protocolOutputRootPath, StringUtils.substringAfterFirst(fileName, "lua/")));
|
||||
@@ -87,110 +88,71 @@ public abstract class GenerateLuaUtils {
|
||||
}
|
||||
|
||||
// 生成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")));
|
||||
luaBuilder.append(protocolManagerStr);
|
||||
|
||||
luaBuilder.append("function initProtocol()").append(LS);
|
||||
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());
|
||||
protocolBuilder.append(TAB).append(StringUtils.format("protocols[{}] = {}", protocolId, name)).append(LS);
|
||||
}
|
||||
protocolManagerTemplate = StringUtils.format(protocolManagerTemplate, "{}", "{}", fieldBuilder.toString().trim(), protocolBuilder.toString().trim());
|
||||
FileUtils.writeStringToFile(new File(StringUtils.format("{}/{}", protocolOutputRootPath, "ProtocolManager.lua")), protocolManagerTemplate);
|
||||
}
|
||||
|
||||
public static void createLuaProtocolFile(ProtocolRegistration registration) {
|
||||
public static void createLuaProtocolFile(ProtocolRegistration registration) throws IOException {
|
||||
// 初始化index
|
||||
GenerateProtocolFile.index.set(0);
|
||||
|
||||
var protocolId = registration.protocolId();
|
||||
var registrationConstructor = registration.getConstructor();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
|
||||
var protocolClazzName = registrationConstructor.getDeclaringClass().getSimpleName();
|
||||
var protocolTemplate = StringUtils.bytesToString(IOUtils.toByteArray(ClassUtils.getFileFromClassPath("lua/ProtocolTemplate.lua")));
|
||||
|
||||
var luaBuilder = new StringBuilder();
|
||||
|
||||
// document
|
||||
luaBuilder.append(documentTitle(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);
|
||||
var docTitle = docTitle(registration);
|
||||
var valueOfMethod = valueOfMethod(registration);
|
||||
var writePacket = writePacket(registration);
|
||||
var readPacket = readPacket(registration);
|
||||
|
||||
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"
|
||||
, protocolOutputRootPath
|
||||
, GenerateProtocolPath.getCapitalizeProtocolPath(protocolId)
|
||||
, protocolClazzName);
|
||||
FileUtils.writeStringToFile(new File(protocolOutputPath), luaBuilder.toString());
|
||||
, protocolOutputRootPath, GenerateProtocolPath.getCapitalizeProtocolPath(protocolId), protocolClazzName);
|
||||
FileUtils.writeStringToFile(new File(protocolOutputPath), protocolTemplate);
|
||||
}
|
||||
|
||||
private static String documentTitle(ProtocolRegistration registration) {
|
||||
private static String docTitle(ProtocolRegistration registration) {
|
||||
var protocolId = registration.protocolId();
|
||||
var registrationConstructor = registration.getConstructor();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var luaBuilder = new StringBuilder();
|
||||
|
||||
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
|
||||
var docTitle = protocolDocument.getKey();
|
||||
|
||||
if (StringUtils.isNotBlank(docTitle)) {
|
||||
Arrays.stream(docTitle.split(LS)).forEach(it -> luaBuilder.append(docToLuaDoc(it)).append(LS));
|
||||
luaBuilder.append(LS);
|
||||
}
|
||||
|
||||
return luaBuilder.toString();
|
||||
}
|
||||
|
||||
private static String newFunction(ProtocolRegistration registration) {
|
||||
short protocolId = registration.getId();
|
||||
private static Pair<String, String> valueOfMethod(ProtocolRegistration registration) {
|
||||
var protocolId = registration.getId();
|
||||
var fields = registration.getFields();
|
||||
var protocolClazzName = registration.getConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
|
||||
var docFieldMap = protocolDocument.getValue();
|
||||
|
||||
var valueOfParams = StringUtils.joinWith(", ", Arrays.stream(fields).map(it -> it.getName()).collect(Collectors.toList()).toArray());
|
||||
var luaBuilder = new StringBuilder();
|
||||
|
||||
luaBuilder.append(StringUtils.format("local {} = {}", protocolClazzName)).append(LS + LS);
|
||||
|
||||
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++) {
|
||||
for (var i = 0; i < fields.length; i++) {
|
||||
var field = fields[i];
|
||||
var propertyName = field.getName();
|
||||
|
||||
@@ -201,92 +163,42 @@ public abstract class GenerateLuaUtils {
|
||||
}
|
||||
|
||||
if (i == fields.length - 1) {
|
||||
luaBuilder.append(TAB + TAB)
|
||||
.append(StringUtils.format("{} = {}", propertyName, propertyName));
|
||||
luaBuilder.append(TAB + TAB).append(StringUtils.format("{} = {}", propertyName, propertyName));
|
||||
} else {
|
||||
luaBuilder.append(TAB + TAB)
|
||||
.append(StringUtils.format("{} = {},", propertyName, propertyName));
|
||||
luaBuilder.append(TAB + TAB).append(StringUtils.format("{} = {},", propertyName, propertyName));
|
||||
}
|
||||
|
||||
// 生成类型的注释
|
||||
luaBuilder.append(" -- ").append(field.getGenericType().getTypeName()).append(LS);
|
||||
}
|
||||
luaBuilder.append(TAB).append("}").append(LS);
|
||||
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();
|
||||
return new Pair<>(valueOfParams, 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) {
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var protocolClazzName = registration.getConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
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++) {
|
||||
var field = fields[i];
|
||||
var fieldRegistration = fieldRegistrations[i];
|
||||
|
||||
luaSerializer(fieldRegistration.serializer()).writeObject(luaBuilder, "packet." + field.getName(), 1, field, fieldRegistration);
|
||||
}
|
||||
|
||||
luaBuilder.append("end").append(LS).append(LS);
|
||||
return luaBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
private static String readPacket(ProtocolRegistration registration) {
|
||||
Field[] fields = registration.getFields();
|
||||
IFieldRegistration[] fieldRegistrations = registration.getFieldRegistrations();
|
||||
var protocolClazzName = registration.getConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
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);
|
||||
|
||||
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var luaBuilder = new StringBuilder();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
IFieldRegistration fieldRegistration = fieldRegistrations[i];
|
||||
|
||||
String readObject = luaSerializer(fieldRegistration.serializer()).readObject(jsBuilder, 1, field, fieldRegistration);
|
||||
jsBuilder.append(TAB).append(StringUtils.format("packet.{} = {}", field.getName(), readObject)).append(LS);
|
||||
var field = fields[i];
|
||||
var fieldRegistration = fieldRegistrations[i];
|
||||
var readObject = luaSerializer(fieldRegistration.serializer()).readObject(luaBuilder, 1, field, fieldRegistration);
|
||||
luaBuilder.append(TAB).append(StringUtils.format("packet.{} = {}", field.getName(), readObject)).append(LS);
|
||||
}
|
||||
|
||||
jsBuilder.append(TAB).append("return packet").append(LS);
|
||||
|
||||
jsBuilder.append("end").append(LS);
|
||||
|
||||
return jsBuilder.toString();
|
||||
return luaBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
private static String docToLuaDoc(String doc) {
|
||||
return doc.replaceFirst("//", "--");
|
||||
}
|
||||
|
||||
+7
@@ -32,3 +32,10 @@ function ProtocolManager.read(buffer)
|
||||
return ProtocolManager.getProtocol(protocolId):read(buffer)
|
||||
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 {}
|
||||
@@ -13,7 +13,7 @@ namespace csharp
|
||||
|
||||
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();
|
||||
buffer.WriteBytes(complexObjectBytes);
|
||||
var packet = ProtocolManager.Read(buffer);
|
||||
@@ -187,4 +187,4 @@ namespace csharp
|
||||
throw new Exception("a is not equals b");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -1,6 +1,7 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using Spring.Util;
|
||||
using XLua;
|
||||
|
||||
namespace Test.Editor.LuaTest
|
||||
@@ -18,7 +19,7 @@ namespace Test.Editor.LuaTest
|
||||
var luaEnv = new LuaEnv();
|
||||
var luaDebugBuilder = new StringBuilder();
|
||||
// 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("dbg.tcpListen('localhost', 9966)").Append(FileUtils.LS);
|
||||
// luaDebugBuilder.Append("dbg.waitIDE()").Append(FileUtils.LS);
|
||||
@@ -27,8 +28,8 @@ namespace Test.Editor.LuaTest
|
||||
|
||||
luaEnv.AddLoader(CustomLoader);
|
||||
|
||||
var luaProtocolTestStr = File.ReadAllText(TEST_PATH + "LuaProtocolTest.lua");
|
||||
luaEnv.DoString(luaProtocolTestStr, "LuaProtocolTest");
|
||||
var luaProtocolTestStr = File.ReadAllText(TEST_PATH + "main.lua");
|
||||
luaEnv.DoString(luaProtocolTestStr, "main");
|
||||
|
||||
LuaFunction byteBufferTestFunction = luaEnv.Global.Get<LuaFunction>("byteBufferTest");
|
||||
byteBufferTestFunction.Call();
|
||||
@@ -44,4 +45,4 @@ namespace Test.Editor.LuaTest
|
||||
return File.ReadAllBytes(TEST_PATH + filepath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user