mirror of
https://github.com/tiennm99/zfoo.git
synced 2026-08-18 04:28:40 +00:00
ref[cpp]: refactor generate C++ protocol
This commit is contained in:
@@ -13,17 +13,16 @@
|
||||
package com.zfoo.protocol.generate;
|
||||
|
||||
import com.zfoo.protocol.ProtocolManager;
|
||||
import com.zfoo.protocol.collection.CollectionUtils;
|
||||
import com.zfoo.protocol.exception.UnknownException;
|
||||
import com.zfoo.protocol.registration.IProtocolRegistration;
|
||||
import com.zfoo.protocol.registration.ProtocolAnalysis;
|
||||
import com.zfoo.protocol.registration.ProtocolRegistration;
|
||||
import com.zfoo.protocol.serializer.CodeLanguage;
|
||||
import com.zfoo.protocol.serializer.cpp.GenerateCppUtils;
|
||||
import com.zfoo.protocol.serializer.es.GenerateEsUtils;
|
||||
import com.zfoo.protocol.serializer.gdscript.GenerateGdUtils;
|
||||
import com.zfoo.protocol.serializer.go.GenerateGoUtils;
|
||||
import com.zfoo.protocol.serializer.javascript.GenerateJsUtils;
|
||||
import com.zfoo.protocol.serializer.lua.CodeGenerateLua;
|
||||
import com.zfoo.protocol.serializer.python.GeneratePyUtils;
|
||||
import com.zfoo.protocol.serializer.typescript.GenerateTsUtils;
|
||||
import com.zfoo.protocol.util.FileUtils;
|
||||
@@ -32,9 +31,7 @@ import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -80,10 +77,6 @@ public abstract class GenerateProtocolFile {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
generateProtocolFilter = null;
|
||||
index = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* EN: Generate protocol files to various languages
|
||||
@@ -118,6 +111,7 @@ public abstract class GenerateProtocolFile {
|
||||
// 通过协议号,从小到大排序
|
||||
var generateProtocols = allGenerateProtocols.stream()
|
||||
.sorted((a, b) -> a.protocolId() - b.protocolId())
|
||||
.map(it -> (ProtocolRegistration) it)
|
||||
.toList();
|
||||
|
||||
// 解析协议的文档注释
|
||||
@@ -127,13 +121,6 @@ public abstract class GenerateProtocolFile {
|
||||
|
||||
// 生成C++协议
|
||||
var generateLanguages = generateOperation.getGenerateLanguages();
|
||||
if (generateLanguages.contains(CodeLanguage.Cpp)) {
|
||||
GenerateCppUtils.init(generateOperation);
|
||||
GenerateCppUtils.createProtocolManager(generateProtocols);
|
||||
for (var protocolRegistration : generateProtocols) {
|
||||
GenerateCppUtils.createCppProtocolFile((ProtocolRegistration) protocolRegistration);
|
||||
}
|
||||
}
|
||||
|
||||
// 生成Golang协议
|
||||
if (generateLanguages.contains(CodeLanguage.Go)) {
|
||||
@@ -219,4 +206,26 @@ public abstract class GenerateProtocolFile {
|
||||
throw new UnknownException();
|
||||
}
|
||||
|
||||
// 子协议优先生成
|
||||
public static List<ProtocolRegistration> subProtocolFirst(List<ProtocolRegistration> registrations) {
|
||||
var registrations1 = new ArrayList<ProtocolRegistration>(registrations);
|
||||
var subFirstRegistrations = new ArrayList<ProtocolRegistration>();
|
||||
var set = new HashSet<Short>();
|
||||
while (!registrations1.isEmpty()) {
|
||||
for (var i = 0; i < registrations1.size(); i++) {
|
||||
var registration = registrations1.get(i);
|
||||
var protocolId = registration.protocolId();
|
||||
var subProtocols = ProtocolAnalysis.getAllSubProtocolIds(protocolId);
|
||||
subProtocols.removeAll(set);
|
||||
if (CollectionUtils.isEmpty(subProtocols)) {
|
||||
subFirstRegistrations.add(registration);
|
||||
set.add(protocolId);
|
||||
registrations1.remove(registration);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return subFirstRegistrations;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -120,11 +120,11 @@ public abstract class GenerateProtocolNote {
|
||||
return note;
|
||||
}
|
||||
|
||||
public static void initProtocolNote(List<IProtocolRegistration> protocolRegistrations) {
|
||||
public static void initProtocolNote(List<ProtocolRegistration> protocolRegistrations) {
|
||||
AssertionUtils.notNull(protocolNoteMap, "[{}] duplicate initialization", GenerateProtocolNote.class.getSimpleName());
|
||||
|
||||
for (var protocolRegistration : protocolRegistrations) {
|
||||
var protocolClazz = protocolRegistration.protocolConstructor().getDeclaringClass();
|
||||
for (var registration : protocolRegistrations) {
|
||||
var protocolClazz = registration.protocolConstructor().getDeclaringClass();
|
||||
var classNote = StringUtils.EMPTY;
|
||||
var protocolClass = protocolClazz.getDeclaredAnnotation(Note.class);
|
||||
if (protocolClass != null && StringUtils.isNotEmpty(protocolClass.value())) {
|
||||
@@ -132,7 +132,6 @@ public abstract class GenerateProtocolNote {
|
||||
}
|
||||
|
||||
var fieldNoteMap = new HashMap<String, String>();
|
||||
var registration = (ProtocolRegistration) protocolRegistration;
|
||||
for (var field : registration.getFields()) {
|
||||
var noteDescription = field.getDeclaredAnnotation(Note.class);
|
||||
if (noteDescription == null || StringUtils.isEmpty(noteDescription.value())) {
|
||||
@@ -143,7 +142,7 @@ public abstract class GenerateProtocolNote {
|
||||
fieldNoteMap.put(fieldName, StringUtils.trim(fieldNote));
|
||||
}
|
||||
|
||||
protocolNoteMap.put(protocolRegistration.protocolId(), new Pair<>(classNote, fieldNoteMap));
|
||||
protocolNoteMap.put(registration.protocolId(), new Pair<>(classNote, fieldNoteMap));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.zfoo.protocol.collection.CollectionUtils;
|
||||
import com.zfoo.protocol.collection.tree.GeneralTree;
|
||||
import com.zfoo.protocol.collection.tree.TreeNode;
|
||||
import com.zfoo.protocol.registration.IProtocolRegistration;
|
||||
import com.zfoo.protocol.registration.ProtocolRegistration;
|
||||
import com.zfoo.protocol.serializer.CodeLanguage;
|
||||
import com.zfoo.protocol.serializer.enhance.EnhanceObjectProtocolSerializer;
|
||||
import com.zfoo.protocol.util.AssertionUtils;
|
||||
@@ -153,9 +154,9 @@ public abstract class GenerateProtocolPath {
|
||||
*
|
||||
* @param protocolRegistrations 需要解析的路径
|
||||
*/
|
||||
public static void initProtocolPath(List<IProtocolRegistration> protocolRegistrations) {
|
||||
public static void initProtocolPath(List<ProtocolRegistration> protocolRegistrations) {
|
||||
// 将需要生成的协议的路径添加到多叉树中
|
||||
var protocolPathTree = new GeneralTree<IProtocolRegistration>();
|
||||
var protocolPathTree = new GeneralTree<ProtocolRegistration>();
|
||||
protocolRegistrations.forEach(it -> protocolPathTree.addNode(it.protocolConstructor().getDeclaringClass().getCanonicalName(), it));
|
||||
|
||||
var rootTreeNode = protocolPathTree.getRootNode();
|
||||
@@ -187,7 +188,7 @@ public abstract class GenerateProtocolPath {
|
||||
}
|
||||
}
|
||||
|
||||
private static void toProtocolPath(TreeNode<IProtocolRegistration> protocolTreeNode) {
|
||||
private static void toProtocolPath(TreeNode<ProtocolRegistration> protocolTreeNode) {
|
||||
var allChildren = protocolTreeNode.flatTreeNodes()
|
||||
.stream()
|
||||
.filter(it -> it.getData() != null)
|
||||
|
||||
@@ -25,11 +25,10 @@ import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolNote;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolPath;
|
||||
import com.zfoo.protocol.registration.field.*;
|
||||
import com.zfoo.protocol.serializer.cpp.GenerateCppUtils;
|
||||
import com.zfoo.protocol.serializer.cpp.CodeGenerateCpp;
|
||||
import com.zfoo.protocol.serializer.gdscript.GenerateGdUtils;
|
||||
import com.zfoo.protocol.serializer.go.GenerateGoUtils;
|
||||
import com.zfoo.protocol.serializer.javascript.GenerateJsUtils;
|
||||
import com.zfoo.protocol.serializer.lua.CodeGenerateLua;
|
||||
import com.zfoo.protocol.serializer.python.GeneratePyUtils;
|
||||
import com.zfoo.protocol.serializer.reflect.*;
|
||||
import com.zfoo.protocol.serializer.typescript.GenerateTsUtils;
|
||||
@@ -399,8 +398,6 @@ public class ProtocolAnalysis {
|
||||
|
||||
GenerateProtocolNote.clear();
|
||||
GenerateProtocolPath.clear();
|
||||
GenerateProtocolFile.clear();
|
||||
GenerateCppUtils.clear();
|
||||
GenerateGoUtils.clear();
|
||||
GenerateJsUtils.clear();
|
||||
GenerateTsUtils.clear();
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
package com.zfoo.protocol.serializer;
|
||||
|
||||
import com.zfoo.protocol.serializer.cpp.CodeGenerateCpp;
|
||||
import com.zfoo.protocol.serializer.csharp.CodeGenerateCsharp;
|
||||
import com.zfoo.protocol.serializer.lua.CodeGenerateLua;
|
||||
|
||||
@@ -25,7 +26,7 @@ public enum CodeLanguage {
|
||||
*/
|
||||
Enhance(1, null),
|
||||
|
||||
Cpp(1 << 1, null),
|
||||
Cpp(1 << 1, CodeGenerateCpp.class),
|
||||
|
||||
Go(1 << 2, null),
|
||||
|
||||
|
||||
@@ -24,6 +24,9 @@ import java.util.Map;
|
||||
*/
|
||||
public enum CodeTemplatePlaceholder {
|
||||
|
||||
protocol_root_path("${protocol_root_path}"),
|
||||
protocol_imports("${protocol_imports}"),
|
||||
|
||||
protocol_class("${protocol_class}"),
|
||||
|
||||
protocol_registration("${protocol_registration}"),
|
||||
@@ -74,7 +77,7 @@ public enum CodeTemplatePlaceholder {
|
||||
|
||||
for (var codeTemplatePlaceholder : CodeTemplatePlaceholder.values()) {
|
||||
if (formatLine.contains(codeTemplatePlaceholder.placeholder)) {
|
||||
formatLine = formatLine.replace(codeTemplatePlaceholder.placeholder, placeholderMap.get(codeTemplatePlaceholder));
|
||||
formatLine = formatLine.replace(codeTemplatePlaceholder.placeholder, placeholderMap.get(codeTemplatePlaceholder));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.zfoo.protocol.serializer;
|
||||
|
||||
import com.zfoo.protocol.generate.GenerateOperation;
|
||||
import com.zfoo.protocol.registration.IProtocolRegistration;
|
||||
import com.zfoo.protocol.registration.ProtocolRegistration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
@@ -30,16 +30,16 @@ public interface ICodeGenerate {
|
||||
/**
|
||||
* 将一个包下的协议文件生成在一个协议文件里
|
||||
*/
|
||||
void mergerProtocol(List<IProtocolRegistration> registrations) throws IOException;
|
||||
void mergerProtocol(List<ProtocolRegistration> registrations) throws IOException;
|
||||
|
||||
/**
|
||||
* 折叠协议,生成协议文件会和Java源文件保持相同的目录结构
|
||||
*/
|
||||
void foldProtocol(List<IProtocolRegistration> registrations) throws IOException;
|
||||
void foldProtocol(List<ProtocolRegistration> registrations) throws IOException;
|
||||
|
||||
/**
|
||||
* 默认把所有的协议文件放在同一个更目录下,不做任何操作
|
||||
*/
|
||||
void defaultProtocol(List<IProtocolRegistration> registrations) throws IOException;
|
||||
void defaultProtocol(List<ProtocolRegistration> registrations) throws IOException;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,459 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.cpp;
|
||||
|
||||
import com.zfoo.protocol.ProtocolManager;
|
||||
import com.zfoo.protocol.anno.Compatible;
|
||||
import com.zfoo.protocol.generate.GenerateOperation;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolNote;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolPath;
|
||||
import com.zfoo.protocol.registration.ProtocolAnalysis;
|
||||
import com.zfoo.protocol.registration.ProtocolRegistration;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.CodeLanguage;
|
||||
import com.zfoo.protocol.serializer.CodeTemplatePlaceholder;
|
||||
import com.zfoo.protocol.serializer.ICodeGenerate;
|
||||
import com.zfoo.protocol.serializer.enhance.EnhanceObjectProtocolSerializer;
|
||||
import com.zfoo.protocol.serializer.reflect.*;
|
||||
import com.zfoo.protocol.util.ClassUtils;
|
||||
import com.zfoo.protocol.util.FileUtils;
|
||||
import com.zfoo.protocol.util.ReflectionUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
import static com.zfoo.protocol.util.StringUtils.TAB;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public class CodeGenerateCpp implements ICodeGenerate {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CodeGenerateCpp.class);
|
||||
|
||||
// custom configuration
|
||||
public static String protocolOutputRootPath = "zfoocpp";
|
||||
private static String protocolOutputPath = StringUtils.EMPTY;
|
||||
|
||||
private static final Map<ISerializer, ICppSerializer> cppSerializerMap = new HashMap<>();
|
||||
|
||||
public static ICppSerializer cppSerializer(ISerializer serializer) {
|
||||
return cppSerializerMap.get(serializer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(GenerateOperation generateOperation) {
|
||||
protocolOutputPath = FileUtils.joinPath(generateOperation.getProtocolPath(), protocolOutputRootPath);
|
||||
FileUtils.deleteFile(new File(protocolOutputPath));
|
||||
|
||||
cppSerializerMap.put(BooleanSerializer.INSTANCE, new CppBooleanSerializer());
|
||||
cppSerializerMap.put(ByteSerializer.INSTANCE, new CppByteSerializer());
|
||||
cppSerializerMap.put(ShortSerializer.INSTANCE, new CppShortSerializer());
|
||||
cppSerializerMap.put(IntSerializer.INSTANCE, new CppIntSerializer());
|
||||
cppSerializerMap.put(LongSerializer.INSTANCE, new CppLongSerializer());
|
||||
cppSerializerMap.put(FloatSerializer.INSTANCE, new CppFloatSerializer());
|
||||
cppSerializerMap.put(DoubleSerializer.INSTANCE, new CppDoubleSerializer());
|
||||
cppSerializerMap.put(StringSerializer.INSTANCE, new CppStringSerializer());
|
||||
cppSerializerMap.put(ArraySerializer.INSTANCE, new CppArraySerializer());
|
||||
cppSerializerMap.put(ListSerializer.INSTANCE, new CppListSerializer());
|
||||
cppSerializerMap.put(SetSerializer.INSTANCE, new CppSetSerializer());
|
||||
cppSerializerMap.put(MapSerializer.INSTANCE, new CppMapSerializer());
|
||||
cppSerializerMap.put(ObjectProtocolSerializer.INSTANCE, new CppObjectProtocolSerializer());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mergerProtocol(List<ProtocolRegistration> registrations) throws IOException {
|
||||
createTemplateFile(registrations);
|
||||
|
||||
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("cpp/ProtocolManagerTemplate.h");
|
||||
var protocol_imports = new StringBuilder();
|
||||
var protocol_manager_registrations = new StringBuilder();
|
||||
protocol_imports.append(StringUtils.format("#include \"{}/Protocols.h\"", protocolOutputRootPath)).append(LS);
|
||||
for (var registration : registrations) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_class_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
protocol_manager_registrations.append(StringUtils.format("protocols[{}] = new {}Registration();", protocol_id, protocol_class_name)).append(LS);
|
||||
}
|
||||
var placeholderMap = Map.of(CodeTemplatePlaceholder.protocol_imports, protocol_imports.toString()
|
||||
, CodeTemplatePlaceholder.protocol_manager_registrations, protocol_manager_registrations.toString());
|
||||
var formatProtocolManagerTemplate = CodeTemplatePlaceholder.formatTemplate(protocolManagerTemplate, placeholderMap);
|
||||
var protocolManagerFile = new File(StringUtils.format("{}/{}", protocolOutputRootPath, "ProtocolManager.h"));
|
||||
FileUtils.writeStringToFile(protocolManagerFile, formatProtocolManagerTemplate, true);
|
||||
logger.info("Generated C++ protocol manager file:[{}] is in path:[{}]", protocolManagerFile.getName(), protocolManagerFile.getAbsolutePath());
|
||||
|
||||
|
||||
var protocol_class = new StringBuilder();
|
||||
var protocol_registration = new StringBuilder();
|
||||
for (var registration : GenerateProtocolFile.subProtocolFirst(registrations)) {
|
||||
GenerateProtocolFile.index.set(0);
|
||||
var protocol_id = registration.protocolId();
|
||||
|
||||
// protocol
|
||||
protocol_class.append(protocol_class(registration)).append(LS);
|
||||
|
||||
// registration
|
||||
protocol_registration.append(protocol_registration(registration)).append(LS);
|
||||
}
|
||||
|
||||
var protocolTemplate = ClassUtils.getFileFromClassPathToString("cpp/ProtocolsTemplate.h");
|
||||
var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of(
|
||||
CodeTemplatePlaceholder.protocol_root_path, protocolOutputRootPath
|
||||
,CodeTemplatePlaceholder.protocol_class, protocol_class.toString()
|
||||
, CodeTemplatePlaceholder.protocol_registration, protocol_registration.toString()
|
||||
));
|
||||
var outputPath = StringUtils.format("{}/Protocols.h", protocolOutputPath);
|
||||
var file = new File(outputPath);
|
||||
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
|
||||
logger.info("Generated C++ protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void foldProtocol(List<ProtocolRegistration> registrations) throws IOException {
|
||||
createTemplateFile(registrations);
|
||||
|
||||
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("cpp/ProtocolManagerTemplate.h");
|
||||
var protocol_imports = new StringBuilder();
|
||||
var protocol_manager_registrations = new StringBuilder();
|
||||
for (var registration : registrations) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_class_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
protocol_imports.append(StringUtils.format("#include \"{}/{}.h\"", protocolOutputRootPath, GenerateProtocolPath.protocolAbsolutePath(protocol_id, CodeLanguage.Cpp))).append(LS);
|
||||
protocol_manager_registrations.append(StringUtils.format("protocols[{}] = new {}Registration();", protocol_id, protocol_class_name)).append(LS);
|
||||
}
|
||||
var placeholderMap = Map.of(CodeTemplatePlaceholder.protocol_imports, protocol_imports.toString()
|
||||
, CodeTemplatePlaceholder.protocol_manager_registrations, protocol_manager_registrations.toString());
|
||||
var formatProtocolManagerTemplate = CodeTemplatePlaceholder.formatTemplate(protocolManagerTemplate, placeholderMap);
|
||||
var protocolManagerFile = new File(StringUtils.format("{}/{}", protocolOutputRootPath, "ProtocolManager.h"));
|
||||
FileUtils.writeStringToFile(protocolManagerFile, formatProtocolManagerTemplate, true);
|
||||
logger.info("Generated C++ protocol manager file:[{}] is in path:[{}]", protocolManagerFile.getName(), protocolManagerFile.getAbsolutePath());
|
||||
|
||||
|
||||
for (var registration : registrations) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var protocolTemplate = ClassUtils.getFileFromClassPathToString("cpp/ProtocolTemplate.h");
|
||||
var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of(
|
||||
CodeTemplatePlaceholder.protocol_root_path, protocolOutputRootPath
|
||||
,CodeTemplatePlaceholder.protocol_name, protocol_name
|
||||
, CodeTemplatePlaceholder.protocol_imports, protocol_imports_fold(registration)
|
||||
, CodeTemplatePlaceholder.protocol_class, protocol_class(registration)
|
||||
, CodeTemplatePlaceholder.protocol_registration, protocol_registration(registration)
|
||||
));
|
||||
|
||||
var outputPath = StringUtils.format("{}/{}/{}.h", protocolOutputPath, GenerateProtocolPath.protocolPath(protocol_id), protocol_name);
|
||||
var file = new File(outputPath);
|
||||
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
|
||||
logger.info("Generated C++ protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defaultProtocol(List<ProtocolRegistration> registrations) throws IOException {
|
||||
createTemplateFile(registrations);
|
||||
|
||||
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("cpp/ProtocolManagerTemplate.h");
|
||||
var protocol_imports = new StringBuilder();
|
||||
var protocol_manager_registrations = new StringBuilder();
|
||||
for (var registration : registrations) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_class_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
protocol_imports.append(StringUtils.format("#include \"{}/{}.h\"", protocolOutputRootPath, protocol_class_name)).append(LS);
|
||||
protocol_manager_registrations.append(StringUtils.format("protocols[{}] = new {}Registration();", protocol_id, protocol_class_name)).append(LS);
|
||||
}
|
||||
var placeholderMap = Map.of(CodeTemplatePlaceholder.protocol_imports, protocol_imports.toString()
|
||||
, CodeTemplatePlaceholder.protocol_manager_registrations, protocol_manager_registrations.toString());
|
||||
var formatProtocolManagerTemplate = CodeTemplatePlaceholder.formatTemplate(protocolManagerTemplate, placeholderMap);
|
||||
var protocolManagerFile = new File(StringUtils.format("{}/{}", protocolOutputRootPath, "ProtocolManager.h"));
|
||||
FileUtils.writeStringToFile(protocolManagerFile, formatProtocolManagerTemplate, true);
|
||||
logger.info("Generated C++ protocol manager file:[{}] is in path:[{}]", protocolManagerFile.getName(), protocolManagerFile.getAbsolutePath());
|
||||
|
||||
for (var registration : registrations) {
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var protocolTemplate = ClassUtils.getFileFromClassPathToString("cpp/ProtocolTemplate.h");
|
||||
var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of(
|
||||
CodeTemplatePlaceholder.protocol_root_path, protocolOutputRootPath
|
||||
,CodeTemplatePlaceholder.protocol_name, protocol_name
|
||||
, CodeTemplatePlaceholder.protocol_imports, protocol_imports_default(registration)
|
||||
, CodeTemplatePlaceholder.protocol_class, protocol_class(registration)
|
||||
, CodeTemplatePlaceholder.protocol_registration, protocol_registration(registration)
|
||||
));
|
||||
|
||||
var outputPath = StringUtils.format("{}/{}.h", protocolOutputPath, protocol_name);
|
||||
var file = new File(outputPath);
|
||||
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
|
||||
logger.info("Generated C++ protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void createTemplateFile(List<ProtocolRegistration> registrations) throws IOException {
|
||||
var list = List.of("cpp/ByteBuffer.h");
|
||||
|
||||
for (var fileName : list) {
|
||||
var fileInputStream = ClassUtils.getFileFromClassPath(fileName);
|
||||
var createFile = new File(StringUtils.format("{}/{}", protocolOutputPath, StringUtils.substringAfterFirst(fileName, "cpp/")));
|
||||
FileUtils.writeInputStreamToFile(createFile, fileInputStream);
|
||||
}
|
||||
}
|
||||
|
||||
private String protocol_class(ProtocolRegistration registration) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_class_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var protocolClassTemplate = ClassUtils.getFileFromClassPathToString("cpp/ProtocolClassTemplate.h");
|
||||
var placeholderMap = Map.of(
|
||||
CodeTemplatePlaceholder.protocol_note, GenerateProtocolNote.protocol_note(protocol_id, CodeLanguage.Cpp)
|
||||
, CodeTemplatePlaceholder.protocol_name, protocol_class_name
|
||||
, CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id)
|
||||
, CodeTemplatePlaceholder.protocol_field_definition, protocol_field_definition(registration)
|
||||
);
|
||||
return CodeTemplatePlaceholder.formatTemplate(protocolClassTemplate, placeholderMap);
|
||||
}
|
||||
|
||||
private String protocol_registration(ProtocolRegistration registration) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_class_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var protocolRegistrationTemplate = ClassUtils.getFileFromClassPathToString("cpp/ProtocolRegistrationTemplate.h");
|
||||
var placeholderMap = Map.of(
|
||||
CodeTemplatePlaceholder.protocol_note, GenerateProtocolNote.protocol_note(protocol_id, CodeLanguage.Cpp)
|
||||
, CodeTemplatePlaceholder.protocol_name, protocol_class_name
|
||||
, CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id)
|
||||
, CodeTemplatePlaceholder.protocol_write_serialization, protocol_write_serialization(registration)
|
||||
, CodeTemplatePlaceholder.protocol_read_deserialization, protocol_read_deserialization(registration)
|
||||
);
|
||||
return CodeTemplatePlaceholder.formatTemplate(protocolRegistrationTemplate, placeholderMap);
|
||||
}
|
||||
|
||||
|
||||
private String protocol_imports_fold(ProtocolRegistration registration) {
|
||||
var protocolId = registration.getId();
|
||||
var subProtocols = ProtocolAnalysis.getAllSubProtocolIds(protocolId);
|
||||
var cppBuilder = new StringBuilder();
|
||||
for (var subProtocolId : subProtocols) {
|
||||
var protocolClassName = EnhanceObjectProtocolSerializer.getProtocolClassSimpleName(subProtocolId);
|
||||
var subProtocolPath = StringUtils.format("#include \"{}/{}/{}.h\"", protocolOutputRootPath, GenerateProtocolPath.getCapitalizeProtocolPath(subProtocolId), protocolClassName);
|
||||
cppBuilder.append(subProtocolPath).append(LS);
|
||||
}
|
||||
return cppBuilder.toString();
|
||||
}
|
||||
|
||||
private String protocol_imports_default(ProtocolRegistration registration) {
|
||||
var protocolId = registration.getId();
|
||||
var subProtocols = ProtocolAnalysis.getAllSubProtocolIds(protocolId);
|
||||
var cppBuilder = new StringBuilder();
|
||||
for (var subProtocolId : subProtocols) {
|
||||
var protocolClassName = EnhanceObjectProtocolSerializer.getProtocolClassSimpleName(subProtocolId);
|
||||
var subProtocolPath = StringUtils.format("#include \"{}/{}.h\"", protocolOutputRootPath, protocolClassName);
|
||||
cppBuilder.append(subProtocolPath).append(LS);
|
||||
}
|
||||
return cppBuilder.toString();
|
||||
}
|
||||
|
||||
private String protocol_field_definition(ProtocolRegistration registration) {
|
||||
var protocolId = registration.getId();
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
|
||||
var cppBuilder = new StringBuilder();
|
||||
var sequencedFields = ReflectionUtils.notStaticAndTransientFields(registration.getConstructor().getDeclaringClass());
|
||||
for (int i = 0; i < sequencedFields.size(); i++) {
|
||||
var field = sequencedFields.get(i);
|
||||
IFieldRegistration fieldRegistration = fieldRegistrations[GenerateProtocolFile.indexOf(fields, field)];
|
||||
var fieldName = field.getName();
|
||||
var propertyTypeAndName = cppSerializer(fieldRegistration.serializer()).field(field, fieldRegistration);
|
||||
var propertyType = propertyTypeAndName.getKey();
|
||||
var propertyName = propertyTypeAndName.getValue();
|
||||
|
||||
var propertyFullName = StringUtils.format("{} {};", propertyType, propertyName);
|
||||
// 生成注释
|
||||
var fieldNotes = GenerateProtocolNote.fieldNotes(protocolId, fieldName, CodeLanguage.Cpp);
|
||||
for (var fieldNote : fieldNotes) {
|
||||
cppBuilder.append(fieldNote).append(LS);
|
||||
}
|
||||
cppBuilder.append(propertyFullName).append(LS);
|
||||
}
|
||||
|
||||
return cppBuilder.toString().trim();
|
||||
}
|
||||
|
||||
private String protocol_write_serialization(ProtocolRegistration registration) {
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var cppBuilder = new StringBuilder();
|
||||
if (registration.isCompatible()) {
|
||||
cppBuilder.append("auto beforeWriteIndex = buffer.writerIndex();").append(LS);
|
||||
cppBuilder.append(StringUtils.format("buffer.writeInt({});", registration.getPredictionLength())).append(LS);
|
||||
} else {
|
||||
cppBuilder.append("buffer.writeInt(-1);").append(LS);
|
||||
}
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
var field = fields[i];
|
||||
var fieldRegistration = fieldRegistrations[i];
|
||||
var serializer = cppSerializer(fieldRegistration.serializer());
|
||||
if (ProtocolManager.isProtocolClass(field.getType())) {
|
||||
serializer.writeObject(cppBuilder, "&message->" + field.getName(), 0, field, fieldRegistration);
|
||||
} else {
|
||||
serializer.writeObject(cppBuilder, "message->" + field.getName(), 0, field, fieldRegistration);
|
||||
}
|
||||
}
|
||||
if (registration.isCompatible()) {
|
||||
cppBuilder.append(StringUtils.format("buffer.adjustPadding({}, beforeWriteIndex);", registration.getPredictionLength())).append(LS);
|
||||
}
|
||||
return cppBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
private String protocol_read_deserialization(ProtocolRegistration registration) {
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
|
||||
var cppBuilder = new StringBuilder();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
var field = fields[i];
|
||||
var fieldRegistration = fieldRegistrations[i];
|
||||
|
||||
if (field.isAnnotationPresent(Compatible.class)) {
|
||||
cppBuilder.append("if (buffer.compatibleRead(beforeReadIndex, length)) {").append(LS);
|
||||
var compatibleReadObject = cppSerializer(fieldRegistration.serializer()).readObject(cppBuilder, 1, field, fieldRegistration);
|
||||
cppBuilder.append(TAB);
|
||||
if (ProtocolManager.isProtocolClass(field.getType())) {
|
||||
cppBuilder.append(StringUtils.format("packet->{} = *{};", field.getName(), compatibleReadObject));
|
||||
} else {
|
||||
cppBuilder.append(StringUtils.format("packet->{} = {};", field.getName(), compatibleReadObject));
|
||||
}
|
||||
cppBuilder.append(LS).append("}").append(LS);
|
||||
continue;
|
||||
}
|
||||
|
||||
var readObject = cppSerializer(fieldRegistration.serializer()).readObject(cppBuilder, 0, field, fieldRegistration);
|
||||
if (ProtocolManager.isProtocolClass(field.getType())) {
|
||||
cppBuilder.append(StringUtils.format("packet->{} = *{};", field.getName(), readObject));
|
||||
} else {
|
||||
cppBuilder.append(StringUtils.format("packet->{} = {};", field.getName(), readObject));
|
||||
}
|
||||
|
||||
cppBuilder.append(LS);
|
||||
}
|
||||
return cppBuilder.toString();
|
||||
}
|
||||
|
||||
public static String toCppClassName(String typeName) {
|
||||
typeName = typeName.replaceAll("java.util.|java.lang.", StringUtils.EMPTY);
|
||||
typeName = typeName.replaceAll("[a-zA-Z0-9_.]*\\.", StringUtils.EMPTY);
|
||||
|
||||
// CSharp不适用基础类型的泛型,会影响性能
|
||||
switch (typeName) {
|
||||
case "boolean":
|
||||
case "Boolean":
|
||||
typeName = "bool";
|
||||
return typeName;
|
||||
case "byte":
|
||||
case "Byte":
|
||||
typeName = "int8_t";
|
||||
return typeName;
|
||||
case "short":
|
||||
case "Short":
|
||||
typeName = "int16_t";
|
||||
return typeName;
|
||||
case "int":
|
||||
case "Integer":
|
||||
typeName = "int32_t";
|
||||
return typeName;
|
||||
case "long":
|
||||
case "Long":
|
||||
typeName = "int64_t";
|
||||
return typeName;
|
||||
case "Float":
|
||||
typeName = "float";
|
||||
return typeName;
|
||||
case "Double":
|
||||
typeName = "double";
|
||||
return typeName;
|
||||
case "Character":
|
||||
typeName = "char";
|
||||
return typeName;
|
||||
case "String":
|
||||
typeName = "string";
|
||||
return typeName;
|
||||
default:
|
||||
}
|
||||
|
||||
// 将boolean转为bool
|
||||
typeName = typeName.replaceAll("[B|b]oolean\\[", "bool");
|
||||
typeName = typeName.replace("<Boolean", "<bool");
|
||||
typeName = typeName.replace("Boolean>", "bool>");
|
||||
|
||||
// 将Byte转为byte
|
||||
typeName = typeName.replace("Byte[", "int8_t");
|
||||
typeName = typeName.replace("Byte>", "int8_t>");
|
||||
typeName = typeName.replace("<Byte", "<int8_t");
|
||||
|
||||
// 将Short转为short
|
||||
typeName = typeName.replace("Short[", "int16_t");
|
||||
typeName = typeName.replace("Short>", "int16_t>");
|
||||
typeName = typeName.replace("<Short", "<int16_t");
|
||||
|
||||
// 将Integer转为int
|
||||
typeName = typeName.replace("Integer[", "int32_t");
|
||||
typeName = typeName.replace("Integer>", "int32_t>");
|
||||
typeName = typeName.replace("<Integer", "<int32_t");
|
||||
|
||||
|
||||
// 将Long转为long
|
||||
typeName = typeName.replace("Long[", "int64_t");
|
||||
typeName = typeName.replace("Long>", "int64_t>");
|
||||
typeName = typeName.replace("<Long", "<int64_t");
|
||||
|
||||
// 将Float转为float
|
||||
typeName = typeName.replace("Float[", "float");
|
||||
typeName = typeName.replace("Float>", "float>");
|
||||
typeName = typeName.replace("<Float", "<float");
|
||||
|
||||
// 将Double转为double
|
||||
typeName = typeName.replace("Double[", "double");
|
||||
typeName = typeName.replace("Double>", "double>");
|
||||
typeName = typeName.replace("<Double", "<double");
|
||||
|
||||
// 将Character转为Char
|
||||
typeName = typeName.replace("Character[", "char");
|
||||
typeName = typeName.replace("Character>", "char>");
|
||||
typeName = typeName.replace("<Character", "<char");
|
||||
|
||||
// 将String转为string
|
||||
typeName = typeName.replace("String[", "string");
|
||||
typeName = typeName.replace("String>", "string>");
|
||||
typeName = typeName.replace("<String", "<string");
|
||||
|
||||
// 将Map转为map
|
||||
typeName = typeName.replace("Map<", "map<");
|
||||
|
||||
// 将Set转为set
|
||||
typeName = typeName.replace("Set<", "set<");
|
||||
|
||||
// 将List转为vector
|
||||
typeName = typeName.replace("List<", "list<");
|
||||
|
||||
return typeName;
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ public class CppArraySerializer implements ICppSerializer {
|
||||
|
||||
@Override
|
||||
public Pair<String, String> field(Field field, IFieldRegistration fieldRegistration) {
|
||||
var type = GenerateCppUtils.toCppClassName(field.getType().getComponentType().getSimpleName());
|
||||
var type = CodeGenerateCpp.toCppClassName(field.getType().getComponentType().getSimpleName());
|
||||
return new Pair<>(StringUtils.format("vector<{}>", type), field.getName());
|
||||
}
|
||||
|
||||
@@ -56,9 +56,9 @@ public class CppArraySerializer implements ICppSerializer {
|
||||
builder.append(StringUtils.format("for (auto {} = 0; {} < {}; {}++) {", i, i, length, i)).append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
String element = "element" + GenerateProtocolFile.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("{} {} = {}[{}];", GenerateCppUtils.toCppClassName(arrayField.getType().getSimpleName()), element, objectStr, i)).append(LS);
|
||||
builder.append(StringUtils.format("{} {} = {}[{}];", CodeGenerateCpp.toCppClassName(arrayField.getType().getSimpleName()), element, objectStr, i)).append(LS);
|
||||
|
||||
GenerateCppUtils.cppSerializer(arrayField.getArrayElementRegistration().serializer())
|
||||
CodeGenerateCpp.cppSerializer(arrayField.getArrayElementRegistration().serializer())
|
||||
.writeObject(builder, element, deep + 1, field, arrayField.getArrayElementRegistration());
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
@@ -77,7 +77,7 @@ public class CppArraySerializer implements ICppSerializer {
|
||||
var arrayField = (ArrayField) fieldRegistration;
|
||||
var result = "result" + GenerateProtocolFile.index.getAndIncrement();
|
||||
|
||||
var typeName = GenerateCppUtils.toCppClassName(arrayField.getType().getSimpleName());
|
||||
var typeName = CodeGenerateCpp.toCppClassName(arrayField.getType().getSimpleName());
|
||||
|
||||
var i = "index" + GenerateProtocolFile.index.getAndIncrement();
|
||||
var size = "size" + GenerateProtocolFile.index.getAndIncrement();
|
||||
@@ -88,7 +88,7 @@ public class CppArraySerializer implements ICppSerializer {
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("for (int {} = 0; {} < {}; {}++) {", i, i, size, i)).append(LS);
|
||||
var readObject = GenerateCppUtils.cppSerializer(arrayField.getArrayElementRegistration().serializer())
|
||||
var readObject = CodeGenerateCpp.cppSerializer(arrayField.getArrayElementRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, arrayField.getArrayElementRegistration());
|
||||
|
||||
var point = StringUtils.EMPTY;
|
||||
|
||||
@@ -33,7 +33,7 @@ public class CppListSerializer implements ICppSerializer {
|
||||
|
||||
@Override
|
||||
public Pair<String, String> field(Field field, IFieldRegistration fieldRegistration) {
|
||||
var type = GenerateCppUtils.toCppClassName(field.getGenericType().toString());
|
||||
var type = CodeGenerateCpp.toCppClassName(field.getGenericType().toString());
|
||||
return new Pair<>(type, field.getName());
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class CppListSerializer implements ICppSerializer {
|
||||
String i = "i" + GenerateProtocolFile.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("for (auto {} : {}) {", i, objectStr)).append(LS);
|
||||
|
||||
GenerateCppUtils.cppSerializer(listField.getListElementRegistration().serializer())
|
||||
CodeGenerateCpp.cppSerializer(listField.getListElementRegistration().serializer())
|
||||
.writeObject(builder, i, deep + 1, field, listField.getListElementRegistration());
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
@@ -71,7 +71,7 @@ public class CppListSerializer implements ICppSerializer {
|
||||
var listField = (ListField) fieldRegistration;
|
||||
|
||||
var result = "result" + GenerateProtocolFile.index.getAndIncrement();
|
||||
var typeName = GenerateCppUtils.toCppClassName(listField.getType().toString());
|
||||
var typeName = CodeGenerateCpp.toCppClassName(listField.getType().toString());
|
||||
|
||||
var i = "index" + GenerateProtocolFile.index.getAndIncrement();
|
||||
var size = "size" + GenerateProtocolFile.index.getAndIncrement();
|
||||
@@ -83,7 +83,7 @@ public class CppListSerializer implements ICppSerializer {
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("for (int {} = 0; {} < {}; {}++) {", i, i, size, i)).append(LS);
|
||||
var readObject = GenerateCppUtils.cppSerializer(listField.getListElementRegistration().serializer())
|
||||
var readObject = CodeGenerateCpp.cppSerializer(listField.getListElementRegistration().serializer())
|
||||
.readObject(builder, deep + 1, field, listField.getListElementRegistration());
|
||||
|
||||
var point = StringUtils.EMPTY;
|
||||
|
||||
@@ -33,7 +33,7 @@ public class CppMapSerializer implements ICppSerializer {
|
||||
|
||||
@Override
|
||||
public Pair<String, String> field(Field field, IFieldRegistration fieldRegistration) {
|
||||
var type = GenerateCppUtils.toCppClassName(field.getGenericType().toString());
|
||||
var type = CodeGenerateCpp.toCppClassName(field.getGenericType().toString());
|
||||
return new Pair<>(type, field.getName());
|
||||
}
|
||||
|
||||
@@ -55,9 +55,9 @@ public class CppMapSerializer implements ICppSerializer {
|
||||
|
||||
var mapKeyRegistration = mapField.getMapKeyRegistration();
|
||||
var mapValueRegistration = mapField.getMapValueRegistration();
|
||||
GenerateCppUtils.cppSerializer(mapField.getMapKeyRegistration().serializer())
|
||||
CodeGenerateCpp.cppSerializer(mapField.getMapKeyRegistration().serializer())
|
||||
.writeObject(builder, key, deep + 1, field, mapField.getMapKeyRegistration());
|
||||
GenerateCppUtils.cppSerializer(mapField.getMapValueRegistration().serializer())
|
||||
CodeGenerateCpp.cppSerializer(mapField.getMapValueRegistration().serializer())
|
||||
.writeObject(builder, value, deep + 1, field, mapField.getMapValueRegistration());
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
@@ -75,7 +75,7 @@ public class CppMapSerializer implements ICppSerializer {
|
||||
MapField mapField = (MapField) fieldRegistration;
|
||||
String result = "result" + GenerateProtocolFile.index.getAndIncrement();
|
||||
|
||||
var typeName = GenerateCppUtils.toCppClassName(mapField.getType().toString());
|
||||
var typeName = CodeGenerateCpp.toCppClassName(mapField.getType().toString());
|
||||
|
||||
String size = "size" + GenerateProtocolFile.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("int32_t {} = buffer.readInt();", size)).append(LS);
|
||||
@@ -88,10 +88,10 @@ public class CppMapSerializer implements ICppSerializer {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("for (auto {} = 0; {} < {}; {}++) {", i, i, size, i)).append(LS);
|
||||
|
||||
String keyObject = GenerateCppUtils.cppSerializer(mapField.getMapKeyRegistration().serializer())
|
||||
String keyObject = CodeGenerateCpp.cppSerializer(mapField.getMapKeyRegistration().serializer())
|
||||
.readObject(builder, deep + 1, field, mapField.getMapKeyRegistration());
|
||||
|
||||
String valueObject = GenerateCppUtils.cppSerializer(mapField.getMapValueRegistration().serializer())
|
||||
String valueObject = CodeGenerateCpp.cppSerializer(mapField.getMapValueRegistration().serializer())
|
||||
.readObject(builder, deep + 1, field, mapField.getMapValueRegistration());
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ public class CppSetSerializer implements ICppSerializer {
|
||||
|
||||
@Override
|
||||
public Pair<String, String> field(Field field, IFieldRegistration fieldRegistration) {
|
||||
var type = GenerateCppUtils.toCppClassName(field.getGenericType().toString());
|
||||
var type = CodeGenerateCpp.toCppClassName(field.getGenericType().toString());
|
||||
return new Pair<>(type, field.getName());
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ public class CppSetSerializer implements ICppSerializer {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("for (auto {} : {}) {", element, objectStr)).append(LS);
|
||||
|
||||
GenerateCppUtils.cppSerializer(setField.getSetElementRegistration().serializer())
|
||||
CodeGenerateCpp.cppSerializer(setField.getSetElementRegistration().serializer())
|
||||
.writeObject(builder, element, deep + 1, field, setField.getSetElementRegistration());
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
@@ -70,7 +70,7 @@ public class CppSetSerializer implements ICppSerializer {
|
||||
SetField setField = (SetField) fieldRegistration;
|
||||
var result = "result" + GenerateProtocolFile.index.getAndIncrement();
|
||||
|
||||
var typeName = GenerateCppUtils.toCppClassName(setField.getType().toString());
|
||||
var typeName = CodeGenerateCpp.toCppClassName(setField.getType().toString());
|
||||
|
||||
var i = "index" + GenerateProtocolFile.index.getAndIncrement();
|
||||
var size = "size" + GenerateProtocolFile.index.getAndIncrement();
|
||||
@@ -89,7 +89,7 @@ public class CppSetSerializer implements ICppSerializer {
|
||||
point = "*";
|
||||
}
|
||||
|
||||
var readObject = GenerateCppUtils.cppSerializer(setField.getSetElementRegistration().serializer())
|
||||
var readObject = CodeGenerateCpp.cppSerializer(setField.getSetElementRegistration().serializer())
|
||||
.readObject(builder, deep + 1, field, setField.getSetElementRegistration());
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("{}.emplace({}{});", result, point, readObject)).append(LS);
|
||||
|
||||
@@ -1,407 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.cpp;
|
||||
|
||||
import com.zfoo.protocol.ProtocolManager;
|
||||
import com.zfoo.protocol.anno.Compatible;
|
||||
import com.zfoo.protocol.collection.CollectionUtils;
|
||||
import com.zfoo.protocol.generate.GenerateOperation;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolNote;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolPath;
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.registration.IProtocolRegistration;
|
||||
import com.zfoo.protocol.registration.ProtocolAnalysis;
|
||||
import com.zfoo.protocol.registration.ProtocolRegistration;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.CodeLanguage;
|
||||
import com.zfoo.protocol.serializer.enhance.EnhanceObjectProtocolSerializer;
|
||||
import com.zfoo.protocol.serializer.reflect.*;
|
||||
import com.zfoo.protocol.util.ClassUtils;
|
||||
import com.zfoo.protocol.util.FileUtils;
|
||||
import com.zfoo.protocol.util.ReflectionUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
import static com.zfoo.protocol.util.StringUtils.TAB;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public abstract class GenerateCppUtils {
|
||||
private static final Logger logger = LoggerFactory.getLogger(GenerateCppUtils.class);
|
||||
|
||||
// custom configuration
|
||||
public static String protocolOutputRootPath = "zfoocpp";
|
||||
private static String protocolOutputPath = StringUtils.EMPTY;
|
||||
|
||||
private static Map<ISerializer, ICppSerializer> cppSerializerMap;
|
||||
|
||||
public static ICppSerializer cppSerializer(ISerializer serializer) {
|
||||
return cppSerializerMap.get(serializer);
|
||||
}
|
||||
|
||||
public static void init(GenerateOperation generateOperation) {
|
||||
protocolOutputPath = FileUtils.joinPath(generateOperation.getProtocolPath(), protocolOutputRootPath);
|
||||
FileUtils.deleteFile(new File(protocolOutputPath));
|
||||
|
||||
cppSerializerMap = new HashMap<>();
|
||||
cppSerializerMap.put(BooleanSerializer.INSTANCE, new CppBooleanSerializer());
|
||||
cppSerializerMap.put(ByteSerializer.INSTANCE, new CppByteSerializer());
|
||||
cppSerializerMap.put(ShortSerializer.INSTANCE, new CppShortSerializer());
|
||||
cppSerializerMap.put(IntSerializer.INSTANCE, new CppIntSerializer());
|
||||
cppSerializerMap.put(LongSerializer.INSTANCE, new CppLongSerializer());
|
||||
cppSerializerMap.put(FloatSerializer.INSTANCE, new CppFloatSerializer());
|
||||
cppSerializerMap.put(DoubleSerializer.INSTANCE, new CppDoubleSerializer());
|
||||
cppSerializerMap.put(StringSerializer.INSTANCE, new CppStringSerializer());
|
||||
cppSerializerMap.put(ArraySerializer.INSTANCE, new CppArraySerializer());
|
||||
cppSerializerMap.put(ListSerializer.INSTANCE, new CppListSerializer());
|
||||
cppSerializerMap.put(SetSerializer.INSTANCE, new CppSetSerializer());
|
||||
cppSerializerMap.put(MapSerializer.INSTANCE, new CppMapSerializer());
|
||||
cppSerializerMap.put(ObjectProtocolSerializer.INSTANCE, new CppObjectProtocolSerializer());
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
cppSerializerMap = null;
|
||||
protocolOutputRootPath = null;
|
||||
protocolOutputPath = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成协议依赖的工具类
|
||||
*/
|
||||
public static void createProtocolManager(List<IProtocolRegistration> protocolList) throws IOException {
|
||||
var list = List.of("cpp/ByteBuffer.h");
|
||||
|
||||
for (var fileName : list) {
|
||||
var fileInputStream = ClassUtils.getFileFromClassPath(fileName);
|
||||
var createFile = new File(StringUtils.format("{}/{}", protocolOutputPath, StringUtils.substringAfterFirst(fileName, "cpp/")));
|
||||
FileUtils.writeInputStreamToFile(createFile, fileInputStream);
|
||||
}
|
||||
|
||||
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("cpp/ProtocolManagerTemplate.h");
|
||||
|
||||
var headerBuilder = new StringBuilder();
|
||||
var initProtocolBuilder = new StringBuilder();
|
||||
for (var protocol : protocolList) {
|
||||
var protocolId = protocol.protocolId();
|
||||
headerBuilder.append(StringUtils.format("#include \"{}/{}.h\"", protocolOutputRootPath, GenerateProtocolPath.protocolAbsolutePath(protocolId, CodeLanguage.Cpp))).append(LS);
|
||||
initProtocolBuilder.append(TAB).append(TAB).append(StringUtils.format("protocols[{}] = new {}Registration();", protocolId, protocol.protocolConstructor().getDeclaringClass().getSimpleName())).append(LS);
|
||||
}
|
||||
protocolManagerTemplate = StringUtils.format(protocolManagerTemplate, headerBuilder.toString(), initProtocolBuilder.toString().trim());
|
||||
var file = new File(StringUtils.format("{}/{}", protocolOutputRootPath, "ProtocolManager.h"));
|
||||
FileUtils.writeStringToFile(file, protocolManagerTemplate, true);
|
||||
logger.info("Generated C++ protocol manager file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成协议类
|
||||
*/
|
||||
public static void createCppProtocolFile(ProtocolRegistration registration) throws IOException {
|
||||
GenerateProtocolFile.index.set(0);
|
||||
|
||||
var protocolId = registration.protocolId();
|
||||
var registrationConstructor = registration.getConstructor();
|
||||
|
||||
var protocolClazzName = registrationConstructor.getDeclaringClass().getSimpleName();
|
||||
var protocolTemplate = ClassUtils.getFileFromClassPathToString("cpp/ProtocolTemplate.h");
|
||||
|
||||
// protocol object
|
||||
var defineProtocolName = protocolClazzName.toUpperCase();
|
||||
var includeHeaders = includeSubProtocol(registration);
|
||||
var classNote = GenerateProtocolNote.classNote(protocolId, CodeLanguage.Cpp, TAB, 1);
|
||||
var fieldDefinition = fieldDefinition(registration);
|
||||
var valueOfMethod = valueOfMethod(registration);
|
||||
var operator = operator(registration);
|
||||
var writeObject = writeObject(registration);
|
||||
var readObject = readObject(registration);
|
||||
|
||||
protocolTemplate = StringUtils.format(protocolTemplate, defineProtocolName, defineProtocolName, protocolOutputRootPath, includeHeaders, classNote
|
||||
, protocolClazzName, fieldDefinition, protocolClazzName, protocolClazzName, valueOfMethod.getKey(), protocolClazzName
|
||||
, valueOfMethod.getValue().trim(), protocolId, protocolClazzName, operator.trim(),
|
||||
protocolClazzName, protocolId, protocolClazzName, writeObject.trim(), protocolClazzName, readObject.trim());
|
||||
|
||||
var outputPath = StringUtils.format("{}/{}/{}.h"
|
||||
, protocolOutputPath
|
||||
, GenerateProtocolPath.getProtocolPath(protocolId)
|
||||
, protocolClazzName);
|
||||
var file = new File(outputPath);
|
||||
FileUtils.writeStringToFile(file, protocolTemplate, true);
|
||||
logger.info("Generated C++ protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
}
|
||||
|
||||
|
||||
private static String includeSubProtocol(ProtocolRegistration registration) {
|
||||
var protocolId = registration.getId();
|
||||
var subProtocols = ProtocolAnalysis.getAllSubProtocolIds(protocolId);
|
||||
|
||||
if (CollectionUtils.isEmpty(subProtocols)) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
var cppBuilder = new StringBuilder();
|
||||
for (var subProtocolId : subProtocols) {
|
||||
var protocolClassName = EnhanceObjectProtocolSerializer.getProtocolClassSimpleName(subProtocolId);
|
||||
var subProtocolPath = StringUtils.format("#include \"{}/{}/{}.h\""
|
||||
, protocolOutputRootPath
|
||||
, GenerateProtocolPath.getCapitalizeProtocolPath(protocolId)
|
||||
, protocolClassName);
|
||||
subProtocolPath = subProtocolPath.replaceAll("//", StringUtils.SLASH);
|
||||
cppBuilder.append(subProtocolPath).append(LS);
|
||||
}
|
||||
|
||||
return cppBuilder.toString();
|
||||
}
|
||||
|
||||
private static String fieldDefinition(ProtocolRegistration registration) {
|
||||
var protocolId = registration.getId();
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
|
||||
var cppBuilder = new StringBuilder();
|
||||
var sequencedFields = ReflectionUtils.notStaticAndTransientFields(registration.getConstructor().getDeclaringClass());
|
||||
for (int i = 0; i < sequencedFields.size(); i++) {
|
||||
var field = sequencedFields.get(i);
|
||||
IFieldRegistration fieldRegistration = fieldRegistrations[GenerateProtocolFile.indexOf(fields, field)];
|
||||
var fieldName = field.getName();
|
||||
var propertyTypeAndName = cppSerializer(fieldRegistration.serializer()).field(field, fieldRegistration);
|
||||
var propertyType = propertyTypeAndName.getKey();
|
||||
var propertyName = propertyTypeAndName.getValue();
|
||||
|
||||
var propertyFullName = StringUtils.format("{} {};", propertyType, propertyName);
|
||||
// 生成注释
|
||||
var fieldNotes = GenerateProtocolNote.fieldNotes(protocolId, fieldName, CodeLanguage.Cpp);
|
||||
for(var fieldNote : fieldNotes) {
|
||||
cppBuilder.append(TAB + TAB).append(fieldNote).append(LS);
|
||||
}
|
||||
cppBuilder.append(TAB + TAB).append(propertyFullName).append(LS);
|
||||
}
|
||||
|
||||
return cppBuilder.toString().trim();
|
||||
}
|
||||
|
||||
private static Pair<String, String> valueOfMethod(ProtocolRegistration registration) {
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
|
||||
var filedList = new ArrayList<Pair<String, String>>();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
var field = fields[i];
|
||||
var fieldRegistration = fieldRegistrations[i];
|
||||
var propertyTypeAndName = cppSerializer(fieldRegistration.serializer()).field(field, fieldRegistration);
|
||||
filedList.add(propertyTypeAndName);
|
||||
}
|
||||
|
||||
// ValueOf()方法
|
||||
var valueOfParams = filedList.stream()
|
||||
.map(it -> StringUtils.format("{} {}", it.getKey(), it.getValue()))
|
||||
.toList();
|
||||
var valueOfParamsStr = StringUtils.joinWith(StringUtils.COMMA + " ", valueOfParams.toArray());
|
||||
|
||||
var cppBuilder = new StringBuilder();
|
||||
filedList.forEach(it -> cppBuilder.append(TAB + TAB + TAB).append(StringUtils.format("packet.{} = {};", it.getValue(), it.getValue())).append(LS));
|
||||
return new Pair<>(valueOfParamsStr, cppBuilder.toString());
|
||||
}
|
||||
|
||||
private static String operator(ProtocolRegistration registration) {
|
||||
var protocolId = registration.getId();
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
|
||||
var filedList = new ArrayList<Pair<String, String>>();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
var field = fields[i];
|
||||
var fieldRegistration = fieldRegistrations[i];
|
||||
var propertyTypeAndName = cppSerializer(fieldRegistration.serializer()).field(field, fieldRegistration);
|
||||
filedList.add(propertyTypeAndName);
|
||||
}
|
||||
|
||||
// bool operator<
|
||||
var cppBuilder = new StringBuilder();
|
||||
for (var fieldPair : filedList) {
|
||||
cppBuilder.append(TAB + TAB + TAB).append(StringUtils.format("if ({} < _.{}) { return true; }", fieldPair.getValue(), fieldPair.getValue())).append(LS);
|
||||
cppBuilder.append(TAB + TAB + TAB).append(StringUtils.format("if (_.{} < {}) { return false; }", fieldPair.getValue(), fieldPair.getValue())).append(LS);
|
||||
}
|
||||
return cppBuilder.toString();
|
||||
}
|
||||
|
||||
private static String writeObject(ProtocolRegistration registration) {
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var cppBuilder = new StringBuilder();
|
||||
if (registration.isCompatible()) {
|
||||
cppBuilder.append(TAB + TAB + TAB).append("auto beforeWriteIndex = buffer.writerIndex();").append(LS);
|
||||
cppBuilder.append(TAB + TAB + TAB).append(StringUtils.format("buffer.writeInt({});", registration.getPredictionLength())).append(LS);
|
||||
} else {
|
||||
cppBuilder.append(TAB + TAB + TAB).append("buffer.writeInt(-1);").append(LS);
|
||||
}
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
var field = fields[i];
|
||||
var fieldRegistration = fieldRegistrations[i];
|
||||
var serializer = cppSerializer(fieldRegistration.serializer());
|
||||
if (ProtocolManager.isProtocolClass(field.getType())) {
|
||||
serializer.writeObject(cppBuilder, "&message->" + field.getName(), 3, field, fieldRegistration);
|
||||
} else {
|
||||
serializer.writeObject(cppBuilder, "message->" + field.getName(), 3, field, fieldRegistration);
|
||||
}
|
||||
}
|
||||
if (registration.isCompatible()) {
|
||||
cppBuilder.append(TAB + TAB + TAB).append(StringUtils.format("buffer.adjustPadding({}, beforeWriteIndex);", registration.getPredictionLength())).append(LS);
|
||||
}
|
||||
return cppBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
private static String readObject(ProtocolRegistration registration) {
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
|
||||
var cppBuilder = new StringBuilder();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
var field = fields[i];
|
||||
var fieldRegistration = fieldRegistrations[i];
|
||||
|
||||
if (field.isAnnotationPresent(Compatible.class)) {
|
||||
cppBuilder.append(TAB + TAB + TAB).append("if (buffer.compatibleRead(beforeReadIndex, length)) {").append(LS);
|
||||
var compatibleReadObject = cppSerializer(fieldRegistration.serializer()).readObject(cppBuilder, 4, field, fieldRegistration);
|
||||
cppBuilder.append(TAB + TAB + TAB + TAB);
|
||||
if (ProtocolManager.isProtocolClass(field.getType())) {
|
||||
cppBuilder.append(StringUtils.format("packet->{} = *{};", field.getName(), compatibleReadObject));
|
||||
} else {
|
||||
cppBuilder.append(StringUtils.format("packet->{} = {};", field.getName(), compatibleReadObject));
|
||||
}
|
||||
cppBuilder.append(LS).append(TAB + TAB + TAB).append("}").append(LS);
|
||||
continue;
|
||||
}
|
||||
|
||||
var readObject = cppSerializer(fieldRegistration.serializer()).readObject(cppBuilder, 3, field, fieldRegistration);
|
||||
cppBuilder.append(TAB + TAB + TAB);
|
||||
if (ProtocolManager.isProtocolClass(field.getType())) {
|
||||
cppBuilder.append(StringUtils.format("packet->{} = *{};", field.getName(), readObject));
|
||||
} else {
|
||||
cppBuilder.append(StringUtils.format("packet->{} = {};", field.getName(), readObject));
|
||||
}
|
||||
|
||||
cppBuilder.append(LS);
|
||||
}
|
||||
return cppBuilder.toString();
|
||||
}
|
||||
|
||||
public static String toCppClassName(String typeName) {
|
||||
typeName = typeName.replaceAll("java.util.|java.lang.", StringUtils.EMPTY);
|
||||
typeName = typeName.replaceAll("[a-zA-Z0-9_.]*\\.", StringUtils.EMPTY);
|
||||
|
||||
// CSharp不适用基础类型的泛型,会影响性能
|
||||
switch (typeName) {
|
||||
case "boolean":
|
||||
case "Boolean":
|
||||
typeName = "bool";
|
||||
return typeName;
|
||||
case "byte":
|
||||
case "Byte":
|
||||
typeName = "int8_t";
|
||||
return typeName;
|
||||
case "short":
|
||||
case "Short":
|
||||
typeName = "int16_t";
|
||||
return typeName;
|
||||
case "int":
|
||||
case "Integer":
|
||||
typeName = "int32_t";
|
||||
return typeName;
|
||||
case "long":
|
||||
case "Long":
|
||||
typeName = "int64_t";
|
||||
return typeName;
|
||||
case "Float":
|
||||
typeName = "float";
|
||||
return typeName;
|
||||
case "Double":
|
||||
typeName = "double";
|
||||
return typeName;
|
||||
case "Character":
|
||||
typeName = "char";
|
||||
return typeName;
|
||||
case "String":
|
||||
typeName = "string";
|
||||
return typeName;
|
||||
default:
|
||||
}
|
||||
|
||||
// 将boolean转为bool
|
||||
typeName = typeName.replaceAll("[B|b]oolean\\[", "bool");
|
||||
typeName = typeName.replace("<Boolean", "<bool");
|
||||
typeName = typeName.replace("Boolean>", "bool>");
|
||||
|
||||
// 将Byte转为byte
|
||||
typeName = typeName.replace("Byte[", "int8_t");
|
||||
typeName = typeName.replace("Byte>", "int8_t>");
|
||||
typeName = typeName.replace("<Byte", "<int8_t");
|
||||
|
||||
// 将Short转为short
|
||||
typeName = typeName.replace("Short[", "int16_t");
|
||||
typeName = typeName.replace("Short>", "int16_t>");
|
||||
typeName = typeName.replace("<Short", "<int16_t");
|
||||
|
||||
// 将Integer转为int
|
||||
typeName = typeName.replace("Integer[", "int32_t");
|
||||
typeName = typeName.replace("Integer>", "int32_t>");
|
||||
typeName = typeName.replace("<Integer", "<int32_t");
|
||||
|
||||
|
||||
// 将Long转为long
|
||||
typeName = typeName.replace("Long[", "int64_t");
|
||||
typeName = typeName.replace("Long>", "int64_t>");
|
||||
typeName = typeName.replace("<Long", "<int64_t");
|
||||
|
||||
// 将Float转为float
|
||||
typeName = typeName.replace("Float[", "float");
|
||||
typeName = typeName.replace("Float>", "float>");
|
||||
typeName = typeName.replace("<Float", "<float");
|
||||
|
||||
// 将Double转为double
|
||||
typeName = typeName.replace("Double[", "double");
|
||||
typeName = typeName.replace("Double>", "double>");
|
||||
typeName = typeName.replace("<Double", "<double");
|
||||
|
||||
// 将Character转为Char
|
||||
typeName = typeName.replace("Character[", "char");
|
||||
typeName = typeName.replace("Character>", "char>");
|
||||
typeName = typeName.replace("<Character", "<char");
|
||||
|
||||
// 将String转为string
|
||||
typeName = typeName.replace("String[", "string");
|
||||
typeName = typeName.replace("String>", "string>");
|
||||
typeName = typeName.replace("<String", "<string");
|
||||
|
||||
// 将Map转为map
|
||||
typeName = typeName.replace("Map<", "map<");
|
||||
|
||||
// 将Set转为set
|
||||
typeName = typeName.replace("Set<", "set<");
|
||||
|
||||
// 将List转为vector
|
||||
typeName = typeName.replace("List<", "list<");
|
||||
|
||||
return typeName;
|
||||
}
|
||||
}
|
||||
+13
-13
@@ -80,7 +80,7 @@ public class CodeGenerateCsharp implements ICodeGenerate {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mergerProtocol(List<IProtocolRegistration> registrations) throws IOException {
|
||||
public void mergerProtocol(List<ProtocolRegistration> registrations) throws IOException {
|
||||
createProtocolManagerFile(registrations);
|
||||
var mergerProtocolPathMap = GenerateProtocolPath.mergerProtocolPathMap();
|
||||
for (var entry : mergerProtocolPathMap.entrySet()) {
|
||||
@@ -112,13 +112,13 @@ public class CodeGenerateCsharp implements ICodeGenerate {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void foldProtocol(List<IProtocolRegistration> registrations) throws IOException {
|
||||
public void foldProtocol(List<ProtocolRegistration> registrations) throws IOException {
|
||||
createProtocolManagerFile(registrations);
|
||||
|
||||
for (var registration : registrations) {
|
||||
var protocolId = registration.protocolId();
|
||||
var protocolClazzName = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var formatProtocolTemplate = formatProtocolTemplate((ProtocolRegistration) registration);
|
||||
var formatProtocolTemplate = formatProtocolTemplate(registration);
|
||||
var outputPath = StringUtils.format("{}/{}/{}.cs", protocolOutputPath, GenerateProtocolPath.getCapitalizeProtocolPath(protocolId), protocolClazzName);
|
||||
var file = new File(outputPath);
|
||||
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
|
||||
@@ -127,20 +127,20 @@ public class CodeGenerateCsharp implements ICodeGenerate {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defaultProtocol(List<IProtocolRegistration> registrations) throws IOException {
|
||||
public void defaultProtocol(List<ProtocolRegistration> registrations) throws IOException {
|
||||
createProtocolManagerFile(registrations);
|
||||
|
||||
for (var registration : registrations) {
|
||||
var protocol_class_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var formatProtocolTemplate = formatProtocolTemplate((ProtocolRegistration) registration);
|
||||
var outputPath = StringUtils.format("{}/{}.cs", protocolOutputPath, protocol_class_name);
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var formatProtocolTemplate = formatProtocolTemplate(registration);
|
||||
var outputPath = StringUtils.format("{}/{}.cs", protocolOutputPath, protocol_name);
|
||||
var file = new File(outputPath);
|
||||
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
|
||||
logger.info("Generated C# protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
private void createProtocolManagerFile(List<IProtocolRegistration> registrations) throws IOException {
|
||||
private void createProtocolManagerFile(List<ProtocolRegistration> registrations) throws IOException {
|
||||
var list = List.of("csharp/IProtocolRegistration.cs"
|
||||
, "csharp/Buffer/ByteBuffer.cs"
|
||||
, "csharp/Buffer/LittleEndianByteBuffer.cs"
|
||||
@@ -174,12 +174,12 @@ public class CodeGenerateCsharp implements ICodeGenerate {
|
||||
|
||||
private String protocol_class(ProtocolRegistration registration) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_class_name = registration.getConstructor().getDeclaringClass().getSimpleName();
|
||||
var protocol_name = registration.getConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var protocolClassTemplate = ClassUtils.getFileFromClassPathToString("csharp/ProtocolClassTemplate.cs");
|
||||
var placeholderMap = Map.of(
|
||||
CodeTemplatePlaceholder.protocol_note, GenerateProtocolNote.protocol_note(protocol_id, CodeLanguage.CSharp)
|
||||
, CodeTemplatePlaceholder.protocol_name, protocol_class_name
|
||||
, CodeTemplatePlaceholder.protocol_name, protocol_name
|
||||
, CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id)
|
||||
, CodeTemplatePlaceholder.protocol_field_definition, protocol_field_definition(registration)
|
||||
, CodeTemplatePlaceholder.protocol_write_serialization, protocol_write_serialization(registration)
|
||||
@@ -190,12 +190,12 @@ public class CodeGenerateCsharp implements ICodeGenerate {
|
||||
|
||||
private String protocol_registration(ProtocolRegistration registration) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_class_name = registration.getConstructor().getDeclaringClass().getSimpleName();
|
||||
var protocol_name = registration.getConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var protocolRegistrationTemplate = ClassUtils.getFileFromClassPathToString("csharp/ProtocolRegistrationTemplate.cs");
|
||||
var placeholderMap = Map.of(
|
||||
CodeTemplatePlaceholder.protocol_note, GenerateProtocolNote.protocol_note(protocol_id, CodeLanguage.CSharp)
|
||||
, CodeTemplatePlaceholder.protocol_name, protocol_class_name
|
||||
, CodeTemplatePlaceholder.protocol_name, protocol_name
|
||||
, CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id)
|
||||
, CodeTemplatePlaceholder.protocol_field_definition, protocol_field_definition(registration)
|
||||
, CodeTemplatePlaceholder.protocol_write_serialization, protocol_write_serialization(registration)
|
||||
@@ -204,7 +204,7 @@ public class CodeGenerateCsharp implements ICodeGenerate {
|
||||
return CodeTemplatePlaceholder.formatTemplate(protocolRegistrationTemplate, placeholderMap);
|
||||
}
|
||||
|
||||
private String protocol_manager_registrations(List<IProtocolRegistration> protocolList) {
|
||||
private String protocol_manager_registrations(List<ProtocolRegistration> protocolList) {
|
||||
var csBuilder = new StringBuilder();
|
||||
for (var protocol : protocolList) {
|
||||
var protocolId = protocol.protocolId();
|
||||
|
||||
@@ -80,7 +80,7 @@ public abstract class GenerateEsUtils {
|
||||
esSerializerMap = null;
|
||||
}
|
||||
|
||||
public static void createProtocolManager(List<IProtocolRegistration> protocolList) throws IOException {
|
||||
public static void createProtocolManager(List<ProtocolRegistration> protocolList) throws IOException {
|
||||
var list = List.of("es/buffer/ByteBuffer.mjs", "es/buffer/long.mjs", "es/buffer/longbits.mjs");
|
||||
for (var fileName : list) {
|
||||
var fileInputStream = ClassUtils.getFileFromClassPath(fileName);
|
||||
|
||||
@@ -86,7 +86,7 @@ public abstract class GenerateGdUtils {
|
||||
protocolOutputPath = null;
|
||||
}
|
||||
|
||||
public static void createProtocolManager(List<IProtocolRegistration> protocolList) throws IOException {
|
||||
public static void createProtocolManager(List<ProtocolRegistration> protocolList) throws IOException {
|
||||
var byteBufferFile = new File(StringUtils.format("{}/{}", protocolOutputPath, "ByteBuffer.gd"));
|
||||
var byteBufferTemplate = ClassUtils.getFileFromClassPathToString("gdscript/buffer/ByteBuffer.gd");
|
||||
FileUtils.writeStringToFile(byteBufferFile, StringUtils.format(byteBufferTemplate, protocolOutputRootPath), false);
|
||||
|
||||
@@ -84,7 +84,7 @@ public abstract class GenerateGoUtils {
|
||||
/**
|
||||
* 生成协议依赖的工具类
|
||||
*/
|
||||
public static void createProtocolManager(List<IProtocolRegistration> protocolList) throws IOException {
|
||||
public static void createProtocolManager(List<ProtocolRegistration> protocolList) throws IOException {
|
||||
var list = List.of("go/ByteBuffer.go");
|
||||
|
||||
for (var fileName : list) {
|
||||
|
||||
@@ -80,7 +80,7 @@ public abstract class GenerateJsUtils {
|
||||
jsSerializerMap = null;
|
||||
}
|
||||
|
||||
public static void createProtocolManager(List<IProtocolRegistration> protocolList) throws IOException {
|
||||
public static void createProtocolManager(List<ProtocolRegistration> protocolList) throws IOException {
|
||||
var list = List.of("javascript/buffer/ByteBuffer.js", "javascript/buffer/long.js", "javascript/buffer/longbits.js");
|
||||
for (var fileName : list) {
|
||||
var fileInputStream = ClassUtils.getFileFromClassPath(fileName);
|
||||
|
||||
@@ -76,15 +76,15 @@ public class CodeGenerateLua implements ICodeGenerate {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mergerProtocol(List<IProtocolRegistration> registrations) throws IOException {
|
||||
public void mergerProtocol(List<ProtocolRegistration> registrations) throws IOException {
|
||||
createTemplateFile();
|
||||
|
||||
var protocol_manager_registrations = new StringBuilder();
|
||||
protocol_manager_registrations.append(StringUtils.format("local Protocols = require(\"{}.Protocols\")", protocolOutputRootPath)).append(LS);
|
||||
for (var registration : registrations) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_class_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
protocol_manager_registrations.append(StringUtils.format("protocols[{}] = Protocols.{}", protocol_id, protocol_class_name)).append(LS);
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
protocol_manager_registrations.append(StringUtils.format("protocols[{}] = Protocols.{}", protocol_id, protocol_name)).append(LS);
|
||||
}
|
||||
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("lua/ProtocolManagerTemplate.lua");
|
||||
var placeholderMap = Map.of(CodeTemplatePlaceholder.protocol_manager_registrations, protocol_manager_registrations.toString());
|
||||
@@ -99,19 +99,18 @@ public class CodeGenerateLua implements ICodeGenerate {
|
||||
for (var registration : registrations) {
|
||||
GenerateProtocolFile.index.set(0);
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_class_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
// protocol
|
||||
protocol_class.append(protocol_class((ProtocolRegistration) registration)).append(LS);
|
||||
protocol_class.append(protocol_class(registration)).append(LS);
|
||||
|
||||
// registration
|
||||
protocol_registration.append(protocol_registration((ProtocolRegistration) registration)).append(LS);
|
||||
protocol_registration.append(protocol_registration(registration)).append(LS);
|
||||
}
|
||||
|
||||
protocol_registration.append(LS);
|
||||
for (var registration : registrations) {
|
||||
var protocol_class_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
protocol_registration.append(StringUtils.format("Protocols.{} = {}", protocol_class_name, protocol_class_name)).append(LS);
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
protocol_registration.append(StringUtils.format("Protocols.{} = {}", protocol_name, protocol_name)).append(LS);
|
||||
}
|
||||
|
||||
var protocolTemplate = ClassUtils.getFileFromClassPathToString("lua/ProtocolsTemplate.lua");
|
||||
@@ -122,22 +121,22 @@ public class CodeGenerateLua implements ICodeGenerate {
|
||||
var outputPath = StringUtils.format("{}/Protocols.lua", protocolOutputPath);
|
||||
var file = new File(outputPath);
|
||||
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
|
||||
logger.info("Generated C# protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
logger.info("Generated Lua protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void foldProtocol(List<IProtocolRegistration> registrations) throws IOException {
|
||||
public void foldProtocol(List<ProtocolRegistration> registrations) throws IOException {
|
||||
createTemplateFile();
|
||||
|
||||
var protocolManagerRequireBuilder = new StringBuilder();
|
||||
var protocol_manager_registrations = new StringBuilder();
|
||||
for (var registration : registrations) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_class_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var path = GenerateProtocolPath.protocolPath(protocol_id);
|
||||
protocolManagerRequireBuilder.append(StringUtils.format("local {} = require(\"{}.{}.{}\")", protocol_class_name, protocolOutputRootPath, path.replace(StringUtils.SLASH, StringUtils.PERIOD), protocol_class_name)).append(LS);
|
||||
protocol_manager_registrations.append(StringUtils.format("protocols[{}] = {}", protocol_id, protocol_class_name)).append(LS);
|
||||
protocolManagerRequireBuilder.append(StringUtils.format("local {} = require(\"{}.{}.{}\")", protocol_name, protocolOutputRootPath, path.replace(StringUtils.SLASH, StringUtils.PERIOD), protocol_name)).append(LS);
|
||||
protocol_manager_registrations.append(StringUtils.format("protocols[{}] = {}", protocol_id, protocol_name)).append(LS);
|
||||
}
|
||||
|
||||
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("lua/ProtocolManagerTemplate.lua");
|
||||
@@ -150,9 +149,9 @@ public class CodeGenerateLua implements ICodeGenerate {
|
||||
|
||||
for (var registration : registrations) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_class_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var formatProtocolTemplate = formatProtocolTemplate((ProtocolRegistration) registration);
|
||||
var outputPath = StringUtils.format("{}/{}/{}.lua", protocolOutputPath, GenerateProtocolPath.protocolPath(protocol_id), protocol_class_name);
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var formatProtocolTemplate = formatProtocolTemplate(registration);
|
||||
var outputPath = StringUtils.format("{}/{}/{}.lua", protocolOutputPath, GenerateProtocolPath.protocolPath(protocol_id), protocol_name);
|
||||
var file = new File(outputPath);
|
||||
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
|
||||
logger.info("Generated Lua protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
@@ -160,16 +159,16 @@ public class CodeGenerateLua implements ICodeGenerate {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defaultProtocol(List<IProtocolRegistration> registrations) throws IOException {
|
||||
public void defaultProtocol(List<ProtocolRegistration> registrations) throws IOException {
|
||||
createTemplateFile();
|
||||
|
||||
var protocolManagerRequireBuilder = new StringBuilder();
|
||||
var protocol_manager_registrations = new StringBuilder();
|
||||
for (var registration : registrations) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_class_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
protocolManagerRequireBuilder.append(StringUtils.format("local {} = require(\"{}.{}\")", protocol_class_name, protocolOutputRootPath, protocol_class_name)).append(LS);
|
||||
protocol_manager_registrations.append(StringUtils.format("protocols[{}] = {}", protocol_id, protocol_class_name)).append(LS);
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
protocolManagerRequireBuilder.append(StringUtils.format("local {} = require(\"{}.{}\")", protocol_name, protocolOutputRootPath, protocol_name)).append(LS);
|
||||
protocol_manager_registrations.append(StringUtils.format("protocols[{}] = {}", protocol_id, protocol_name)).append(LS);
|
||||
}
|
||||
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("lua/ProtocolManagerTemplate.lua");
|
||||
var placeholderMap = Map.of(CodeTemplatePlaceholder.protocol_manager_registrations, protocolManagerRequireBuilder.toString() + protocol_manager_registrations);
|
||||
@@ -180,9 +179,9 @@ public class CodeGenerateLua implements ICodeGenerate {
|
||||
|
||||
|
||||
for (var registration : registrations) {
|
||||
var protocol_class_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var formatProtocolTemplate = formatProtocolTemplate((ProtocolRegistration) registration);
|
||||
var outputPath = StringUtils.format("{}/{}.lua", protocolOutputPath, protocol_class_name);
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var formatProtocolTemplate = formatProtocolTemplate(registration);
|
||||
var outputPath = StringUtils.format("{}/{}.lua", protocolOutputPath, protocol_name);
|
||||
var file = new File(outputPath);
|
||||
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
|
||||
logger.info("Generated Lua protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
@@ -207,24 +206,24 @@ public class CodeGenerateLua implements ICodeGenerate {
|
||||
// 初始化index
|
||||
GenerateProtocolFile.index.set(0);
|
||||
|
||||
var protocol_class_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var protocolTemplate = ClassUtils.getFileFromClassPathToString("lua/ProtocolTemplate.lua");
|
||||
|
||||
return CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of(
|
||||
CodeTemplatePlaceholder.protocol_class, protocol_class(registration)
|
||||
, CodeTemplatePlaceholder.protocol_registration, protocol_registration(registration)
|
||||
, CodeTemplatePlaceholder.protocol_name, protocol_class_name
|
||||
, CodeTemplatePlaceholder.protocol_name, protocol_name
|
||||
));
|
||||
}
|
||||
|
||||
private String protocol_class(ProtocolRegistration registration) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_class_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var protocolClassTemplate = ClassUtils.getFileFromClassPathToString("lua/ProtocolClassTemplate.lua");
|
||||
var placeholderMap = Map.of(
|
||||
CodeTemplatePlaceholder.protocol_note, GenerateProtocolNote.protocol_note(protocol_id, CodeLanguage.Lua)
|
||||
, CodeTemplatePlaceholder.protocol_name, protocol_class_name
|
||||
, CodeTemplatePlaceholder.protocol_name, protocol_name
|
||||
, CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id)
|
||||
, CodeTemplatePlaceholder.protocol_field_definition, protocol_field_definition(registration)
|
||||
, CodeTemplatePlaceholder.protocol_write_serialization, protocol_write_serialization(registration)
|
||||
@@ -235,12 +234,12 @@ public class CodeGenerateLua implements ICodeGenerate {
|
||||
|
||||
private String protocol_registration(ProtocolRegistration registration) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_class_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var protocolRegistrationTemplate = ClassUtils.getFileFromClassPathToString("lua/ProtocolRegistrationTemplate.lua");
|
||||
var placeholderMap = Map.of(
|
||||
CodeTemplatePlaceholder.protocol_note, GenerateProtocolNote.protocol_note(protocol_id, CodeLanguage.Lua)
|
||||
, CodeTemplatePlaceholder.protocol_name, protocol_class_name
|
||||
, CodeTemplatePlaceholder.protocol_name, protocol_name
|
||||
, CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id)
|
||||
, CodeTemplatePlaceholder.protocol_field_definition, protocol_field_definition(registration)
|
||||
, CodeTemplatePlaceholder.protocol_write_serialization, protocol_write_serialization(registration)
|
||||
|
||||
@@ -82,7 +82,7 @@ public abstract class GeneratePyUtils {
|
||||
pySerializerMap = null;
|
||||
}
|
||||
|
||||
public static void createProtocolManager(List<IProtocolRegistration> protocolList) throws IOException {
|
||||
public static void createProtocolManager(List<ProtocolRegistration> protocolList) throws IOException {
|
||||
var list = List.of("python/ByteBuffer.py");
|
||||
for (var fileName : list) {
|
||||
var fileInputStream = ClassUtils.getFileFromClassPath(fileName);
|
||||
|
||||
@@ -83,7 +83,7 @@ public abstract class GenerateTsUtils {
|
||||
tsSerializerMap = null;
|
||||
}
|
||||
|
||||
public static void createProtocolManager(List<IProtocolRegistration> protocolList) throws IOException {
|
||||
public static void createProtocolManager(List<ProtocolRegistration> protocolList) throws IOException {
|
||||
var list = List.of("typescript/IByteBuffer.ts", "typescript/buffer/ByteBuffer.ts", "typescript/buffer/Long.ts", "typescript/buffer/Longbits.ts");
|
||||
for (var fileName : list) {
|
||||
var fileInputStream = ClassUtils.getFileFromClassPath(fileName);
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
${protocol_note}
|
||||
class ${protocol_name} : public IProtocol {
|
||||
public:
|
||||
${protocol_field_definition}
|
||||
|
||||
~${protocol_name}() override = default;
|
||||
|
||||
int16_t protocolId() override {
|
||||
return ${protocol_id};
|
||||
}
|
||||
};
|
||||
@@ -2,14 +2,14 @@
|
||||
#define ZFOO_PROTOCOLMANAGER_H
|
||||
|
||||
#include "ByteBuffer.h"
|
||||
{}
|
||||
${protocol_imports}
|
||||
namespace zfoo {
|
||||
|
||||
const int16_t MAX_PROTOCOL_NUM = 32767;
|
||||
const IProtocolRegistration *protocols[MAX_PROTOCOL_NUM];
|
||||
|
||||
void initProtocol() {
|
||||
{}
|
||||
${protocol_manager_registrations}
|
||||
}
|
||||
|
||||
inline IProtocolRegistration *getProtocol(int16_t protocolId) {
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
class ${protocol_name}Registration : public IProtocolRegistration {
|
||||
public:
|
||||
int16_t protocolId() override {
|
||||
return ${protocol_id};
|
||||
}
|
||||
|
||||
void write(ByteBuffer &buffer, IProtocol *packet) override {
|
||||
if (packet == nullptr) {
|
||||
buffer.writeInt(0);
|
||||
return;
|
||||
}
|
||||
auto *message = (${protocol_name} *) packet;
|
||||
${protocol_write_serialization}
|
||||
}
|
||||
|
||||
IProtocol *read(ByteBuffer &buffer) override {
|
||||
auto *packet = new ${protocol_name}();
|
||||
auto length = buffer.readInt();
|
||||
if (length == 0) {
|
||||
return packet;
|
||||
}
|
||||
auto beforeReadIndex = buffer.readerIndex();
|
||||
${protocol_read_deserialization}
|
||||
if (length > 0) {
|
||||
buffer.readerIndex(beforeReadIndex + length);
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
};
|
||||
@@ -1,63 +1,12 @@
|
||||
#ifndef ZFOO_{}_H
|
||||
#define ZFOO_{}_H
|
||||
#ifndef ZFOO_${protocol_name}
|
||||
#define ZFOO_${protocol_name}
|
||||
|
||||
#include "{}/ByteBuffer.h"
|
||||
{}
|
||||
#include "${protocol_root_path}/ByteBuffer.h"
|
||||
${protocol_imports}
|
||||
namespace zfoo {
|
||||
${protocol_class}
|
||||
|
||||
{}
|
||||
class {} : public IProtocol {
|
||||
public:
|
||||
{}
|
||||
|
||||
~{}() override = default;
|
||||
|
||||
static {} valueOf({}) {
|
||||
auto packet = {}();
|
||||
{}
|
||||
return packet;
|
||||
}
|
||||
|
||||
int16_t protocolId() override {
|
||||
return {};
|
||||
}
|
||||
|
||||
bool operator<(const {} &_) const {
|
||||
{}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class {}Registration : public IProtocolRegistration {
|
||||
public:
|
||||
int16_t protocolId() override {
|
||||
return {};
|
||||
}
|
||||
|
||||
void write(ByteBuffer &buffer, IProtocol *packet) override {
|
||||
if (packet == nullptr) {
|
||||
buffer.writeInt(0);
|
||||
return;
|
||||
}
|
||||
auto *message = ({} *) packet;
|
||||
{}
|
||||
}
|
||||
|
||||
IProtocol *read(ByteBuffer &buffer) override {
|
||||
auto *packet = new {}();
|
||||
auto length = buffer.readInt();
|
||||
if (length == 0) {
|
||||
return packet;
|
||||
}
|
||||
auto beforeReadIndex = buffer.readerIndex();
|
||||
{}
|
||||
if (length > 0) {
|
||||
buffer.readerIndex(beforeReadIndex + length);
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
};
|
||||
${protocol_registration}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef ZFOO_Protocols
|
||||
#define ZFOO_Protocols
|
||||
|
||||
#include "${protocol_root_path}/ByteBuffer.h"
|
||||
|
||||
namespace zfoo {
|
||||
${protocol_class}
|
||||
|
||||
${protocol_registration}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user