mirror of
https://github.com/tiennm99/zfoo.git
synced 2026-05-21 16:26:43 +00:00
ref[gdscript]: refactor generate gdscript protocol
This commit is contained in:
@@ -19,7 +19,6 @@ 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.gdscript.GenerateGdUtils;
|
||||
import com.zfoo.protocol.serializer.go.GenerateGoUtils;
|
||||
import com.zfoo.protocol.util.FileUtils;
|
||||
import com.zfoo.protocol.util.ReflectionUtils;
|
||||
@@ -125,15 +124,6 @@ public abstract class GenerateProtocolFile {
|
||||
}
|
||||
}
|
||||
|
||||
// 生成GdScript协议
|
||||
if (generateLanguages.contains(CodeLanguage.GdScript)) {
|
||||
GenerateGdUtils.init(generateOperation);
|
||||
GenerateGdUtils.createProtocolManager(generateProtocols);
|
||||
for (var protocolRegistration : generateProtocols) {
|
||||
GenerateGdUtils.createGdProtocolFile((ProtocolRegistration) protocolRegistration);
|
||||
}
|
||||
}
|
||||
|
||||
for (var language : generateOperation.getGenerateLanguages()) {
|
||||
if (language.codeGenerateClass == null) {
|
||||
continue;
|
||||
|
||||
@@ -25,7 +25,6 @@ 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.gdscript.GenerateGdUtils;
|
||||
import com.zfoo.protocol.serializer.go.GenerateGoUtils;
|
||||
import com.zfoo.protocol.serializer.reflect.*;
|
||||
import com.zfoo.protocol.util.*;
|
||||
@@ -395,7 +394,6 @@ public class ProtocolAnalysis {
|
||||
GenerateProtocolNote.clear();
|
||||
GenerateProtocolPath.clear();
|
||||
GenerateGoUtils.clear();
|
||||
GenerateGdUtils.clear();
|
||||
}
|
||||
|
||||
public static List<Field> getFields(Class<?> clazz) {
|
||||
|
||||
@@ -15,6 +15,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.ecmascript.CodeGenerateEcmaScript;
|
||||
import com.zfoo.protocol.serializer.gdscript.CodeGenerateGdScript;
|
||||
import com.zfoo.protocol.serializer.javascript.CodeGenerateJavaScript;
|
||||
import com.zfoo.protocol.serializer.lua.CodeGenerateLua;
|
||||
import com.zfoo.protocol.serializer.python.CodeGeneratePython;
|
||||
@@ -44,7 +45,7 @@ public enum CodeLanguage {
|
||||
|
||||
CSharp(1 << 11, CodeGenerateCsharp.class),
|
||||
|
||||
GdScript(1 << 12, null),
|
||||
GdScript(1 << 12, CodeGenerateGdScript.class),
|
||||
|
||||
Python(1 << 13, CodeGeneratePython.class),
|
||||
|
||||
|
||||
@@ -45,6 +45,10 @@ public enum CodeTemplatePlaceholder {
|
||||
|
||||
protocol_read_deserialization("${protocol_read_deserialization}"),
|
||||
|
||||
protocol_json("${protocol_json}"),
|
||||
|
||||
protocol_to_string("${protocol_to_string}"),
|
||||
|
||||
;
|
||||
public final String placeholder;
|
||||
|
||||
|
||||
@@ -246,8 +246,8 @@ public class CodeGenerateCpp implements ICodeGenerate {
|
||||
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.capitalizeProtocolPathFold(subProtocolId), protocolClassName);
|
||||
var protocolName = EnhanceObjectProtocolSerializer.getProtocolClassSimpleName(subProtocolId);
|
||||
var subProtocolPath = StringUtils.format("#include \"{}/{}/{}.h\"", protocolOutputRootPath, GenerateProtocolPath.capitalizeProtocolPathFold(subProtocolId), protocolName);
|
||||
cppBuilder.append(subProtocolPath).append(LS);
|
||||
}
|
||||
return cppBuilder.toString();
|
||||
@@ -258,8 +258,8 @@ public class CodeGenerateCpp implements ICodeGenerate {
|
||||
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);
|
||||
var protocolName = EnhanceObjectProtocolSerializer.getProtocolClassSimpleName(subProtocolId);
|
||||
var subProtocolPath = StringUtils.format("#include \"{}/{}.h\"", protocolOutputRootPath, protocolName);
|
||||
cppBuilder.append(subProtocolPath).append(LS);
|
||||
}
|
||||
return cppBuilder.toString();
|
||||
|
||||
+6
-6
@@ -94,7 +94,7 @@ public class CodeGenerateEcmaScript implements ICodeGenerate {
|
||||
var formatProtocolManagerTemplate = CodeTemplatePlaceholder.formatTemplate(protocolManagerTemplate, placeholderMap);
|
||||
var protocolManagerFile = new File(StringUtils.format("{}/{}", protocolOutputPath, "ProtocolManager.mjs"));
|
||||
FileUtils.writeStringToFile(protocolManagerFile, formatProtocolManagerTemplate, true);
|
||||
logger.info("Generated ES protocol manager file:[{}] is in path:[{}]", protocolManagerFile.getName(), protocolManagerFile.getAbsolutePath());
|
||||
logger.info("Generated EcmaScript protocol manager file:[{}] is in path:[{}]", protocolManagerFile.getName(), protocolManagerFile.getAbsolutePath());
|
||||
|
||||
|
||||
var protocol_class = new StringBuilder();
|
||||
@@ -114,7 +114,7 @@ public class CodeGenerateEcmaScript implements ICodeGenerate {
|
||||
var outputPath = StringUtils.format("{}/Protocols.mjs", protocolOutputPath);
|
||||
var file = new File(outputPath);
|
||||
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
|
||||
logger.info("Generated ES protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
logger.info("Generated EcmaScript protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -137,7 +137,7 @@ public class CodeGenerateEcmaScript implements ICodeGenerate {
|
||||
var formatProtocolManagerTemplate = CodeTemplatePlaceholder.formatTemplate(protocolManagerTemplate, placeholderMap);
|
||||
var protocolManagerFile = new File(StringUtils.format("{}/{}", protocolOutputPath, "ProtocolManager.mjs"));
|
||||
FileUtils.writeStringToFile(protocolManagerFile, formatProtocolManagerTemplate, true);
|
||||
logger.info("Generated ES protocol manager file:[{}] is in path:[{}]", protocolManagerFile.getName(), protocolManagerFile.getAbsolutePath());
|
||||
logger.info("Generated EcmaScript protocol manager file:[{}] is in path:[{}]", protocolManagerFile.getName(), protocolManagerFile.getAbsolutePath());
|
||||
|
||||
|
||||
for (var registration : registrations) {
|
||||
@@ -147,7 +147,7 @@ public class CodeGenerateEcmaScript implements ICodeGenerate {
|
||||
var outputPath = StringUtils.format("{}/{}/{}.mjs", protocolOutputPath, GenerateProtocolPath.protocolPathSlash(protocol_id), protocol_name);
|
||||
var file = new File(outputPath);
|
||||
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
|
||||
logger.info("Generated ES protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
logger.info("Generated EcmaScript protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ public class CodeGenerateEcmaScript implements ICodeGenerate {
|
||||
var formatProtocolManagerTemplate = CodeTemplatePlaceholder.formatTemplate(protocolManagerTemplate, placeholderMap);
|
||||
var protocolManagerFile = new File(StringUtils.format("{}/{}", protocolOutputPath, "ProtocolManager.mjs"));
|
||||
FileUtils.writeStringToFile(protocolManagerFile, formatProtocolManagerTemplate, true);
|
||||
logger.info("Generated ES protocol manager file:[{}] is in path:[{}]", protocolManagerFile.getName(), protocolManagerFile.getAbsolutePath());
|
||||
logger.info("Generated EcmaScript protocol manager file:[{}] is in path:[{}]", protocolManagerFile.getName(), protocolManagerFile.getAbsolutePath());
|
||||
|
||||
|
||||
for (var registration : registrations) {
|
||||
@@ -181,7 +181,7 @@ public class CodeGenerateEcmaScript implements ICodeGenerate {
|
||||
var outputPath = StringUtils.format("{}/{}.mjs", protocolOutputPath, protocol_name, protocol_name);
|
||||
var file = new File(outputPath);
|
||||
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
|
||||
logger.info("Generated ES protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
logger.info("Generated EcmaScript protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+368
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
* 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.gdscript;
|
||||
|
||||
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.serializer.typescript.CodeGenerateTypeScript;
|
||||
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_ASCII;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public class CodeGenerateGdScript implements ICodeGenerate {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CodeGenerateGdScript.class);
|
||||
|
||||
// custom configuration
|
||||
public static String protocolOutputRootPath = "zfoogd";
|
||||
private static String protocolOutputPath = StringUtils.EMPTY;
|
||||
|
||||
private static Map<ISerializer, IGdSerializer> gdSerializerMap = new HashMap<>();
|
||||
|
||||
public static IGdSerializer gdSerializer(ISerializer serializer) {
|
||||
return gdSerializerMap.get(serializer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(GenerateOperation generateOperation) {
|
||||
protocolOutputPath = FileUtils.joinPath(generateOperation.getProtocolPath(), protocolOutputRootPath);
|
||||
FileUtils.deleteFile(new File(protocolOutputPath));
|
||||
|
||||
gdSerializerMap.put(BooleanSerializer.INSTANCE, new GdBooleanSerializer());
|
||||
gdSerializerMap.put(ByteSerializer.INSTANCE, new GdByteSerializer());
|
||||
gdSerializerMap.put(ShortSerializer.INSTANCE, new GdShortSerializer());
|
||||
gdSerializerMap.put(IntSerializer.INSTANCE, new GdIntSerializer());
|
||||
gdSerializerMap.put(LongSerializer.INSTANCE, new GdLongSerializer());
|
||||
gdSerializerMap.put(FloatSerializer.INSTANCE, new GdFloatSerializer());
|
||||
gdSerializerMap.put(DoubleSerializer.INSTANCE, new GdDoubleSerializer());
|
||||
gdSerializerMap.put(StringSerializer.INSTANCE, new GdStringSerializer());
|
||||
gdSerializerMap.put(ArraySerializer.INSTANCE, new GdArraySerializer());
|
||||
gdSerializerMap.put(ListSerializer.INSTANCE, new GdListSerializer());
|
||||
gdSerializerMap.put(SetSerializer.INSTANCE, new GdSetSerializer());
|
||||
gdSerializerMap.put(MapSerializer.INSTANCE, new GdMapSerializer());
|
||||
gdSerializerMap.put(ObjectProtocolSerializer.INSTANCE, new GdObjectProtocolSerializer());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mergerProtocol(List<ProtocolRegistration> registrations) throws IOException {
|
||||
createTemplateFile();
|
||||
|
||||
|
||||
// 生成ProtocolManager.gd文件
|
||||
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("gdscript/ProtocolManagerTemplate.gd");
|
||||
var protocol_imports = new StringBuilder();
|
||||
var protocol_manager_registrations = new StringBuilder();
|
||||
protocol_imports.append(StringUtils.format("const Protocols = preload(\"res://{}/Protocols.gd\")", protocolOutputRootPath)).append(LS);
|
||||
for (var registration : registrations) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
protocol_manager_registrations.append(StringUtils.format("{}{}: Protocols.{},", TAB_ASCII, protocol_id, protocol_name)).append(LS);
|
||||
}
|
||||
var placeholderMap = Map.of(CodeTemplatePlaceholder.protocol_imports, protocol_imports.toString()
|
||||
, CodeTemplatePlaceholder.protocol_manager_registrations, StringUtils.substringBeforeLast(protocol_manager_registrations.toString(), StringUtils.COMMA));
|
||||
var formatProtocolManagerTemplate = CodeTemplatePlaceholder.formatTemplate(protocolManagerTemplate, placeholderMap);
|
||||
var protocolManagerFile = new File(StringUtils.format("{}/{}", protocolOutputPath, "ProtocolManager.gd"));
|
||||
FileUtils.writeStringToFile(protocolManagerFile, formatProtocolManagerTemplate, true);
|
||||
logger.info("Generated GdScript protocol manager file:[{}] is in path:[{}]", protocolManagerFile.getName(), protocolManagerFile.getAbsolutePath());
|
||||
|
||||
|
||||
var protocol_imports_protocols = new StringBuilder();
|
||||
var protocol_class = new StringBuilder();
|
||||
for (var registration : registrations) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var protocolTemplate = ClassUtils.getFileFromClassPathToString("gdscript/ProtocolClassTemplate.gd");
|
||||
var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of(
|
||||
CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id)
|
||||
, CodeTemplatePlaceholder.protocol_name, protocol_name
|
||||
, CodeTemplatePlaceholder.protocol_note, GenerateProtocolNote.protocol_note(protocol_id, CodeLanguage.GdScript)
|
||||
, CodeTemplatePlaceholder.protocol_field_definition, protocol_field_definition(registration)
|
||||
, CodeTemplatePlaceholder.protocol_write_serialization, protocol_write_serialization(registration)
|
||||
, CodeTemplatePlaceholder.protocol_read_deserialization, protocol_read_deserialization(registration)
|
||||
, CodeTemplatePlaceholder.protocol_json, protocol_json(registration)
|
||||
, CodeTemplatePlaceholder.protocol_to_string, protocol_to_string(registration)
|
||||
));
|
||||
protocol_class.append(formatProtocolTemplate).append(LS);
|
||||
}
|
||||
var protocolTemplate = ClassUtils.getFileFromClassPathToString("gdscript/ProtocolsTemplate.gd");
|
||||
var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of(
|
||||
CodeTemplatePlaceholder.protocol_imports, protocol_imports_protocols.toString()
|
||||
, CodeTemplatePlaceholder.protocol_class, protocol_class.toString()
|
||||
));
|
||||
var outputPath = StringUtils.format("{}/Protocols.gd", protocolOutputPath);
|
||||
var file = new File(outputPath);
|
||||
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
|
||||
logger.info("Generated GdScript protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void foldProtocol(List<ProtocolRegistration> registrations) throws IOException {
|
||||
createTemplateFile();
|
||||
|
||||
|
||||
// 生成ProtocolManager.gd文件
|
||||
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("gdscript/ProtocolManagerTemplate.gd");
|
||||
var protocol_imports = new StringBuilder();
|
||||
var protocol_manager_registrations = new StringBuilder();
|
||||
for (var registration : registrations) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
protocol_imports.append(StringUtils.format("const {} = preload(\"res://{}/{}/{}.gd\")", protocol_name, protocolOutputRootPath, GenerateProtocolPath.protocolPathSlash(protocol_id), protocol_name)).append(LS);
|
||||
protocol_manager_registrations.append(StringUtils.format("{}{}: {},", TAB_ASCII, protocol_id, protocol_name)).append(LS);
|
||||
}
|
||||
var placeholderMap = Map.of(CodeTemplatePlaceholder.protocol_imports, protocol_imports.toString()
|
||||
, CodeTemplatePlaceholder.protocol_manager_registrations, StringUtils.substringBeforeLast(protocol_manager_registrations.toString(), StringUtils.COMMA));
|
||||
var formatProtocolManagerTemplate = CodeTemplatePlaceholder.formatTemplate(protocolManagerTemplate, placeholderMap);
|
||||
var protocolManagerFile = new File(StringUtils.format("{}/{}", protocolOutputPath, "ProtocolManager.gd"));
|
||||
FileUtils.writeStringToFile(protocolManagerFile, formatProtocolManagerTemplate, true);
|
||||
logger.info("Generated GdScript 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("gdscript/ProtocolTemplate.gd");
|
||||
var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of(
|
||||
CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id)
|
||||
, CodeTemplatePlaceholder.protocol_name, protocol_name
|
||||
, CodeTemplatePlaceholder.protocol_note, GenerateProtocolNote.protocol_note(protocol_id, CodeLanguage.GdScript)
|
||||
, CodeTemplatePlaceholder.protocol_imports, protocol_imports_fold(registration)
|
||||
, CodeTemplatePlaceholder.protocol_field_definition, protocol_field_definition(registration)
|
||||
, CodeTemplatePlaceholder.protocol_write_serialization, protocol_write_serialization(registration)
|
||||
, CodeTemplatePlaceholder.protocol_read_deserialization, protocol_read_deserialization(registration)
|
||||
, CodeTemplatePlaceholder.protocol_json, protocol_json(registration)
|
||||
, CodeTemplatePlaceholder.protocol_to_string, protocol_to_string(registration)
|
||||
));
|
||||
var outputPath = StringUtils.format("{}/{}/{}.gd", protocolOutputPath, GenerateProtocolPath.protocolPathSlash(protocol_id), protocol_name);
|
||||
var file = new File(outputPath);
|
||||
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
|
||||
logger.info("Generated GdScript protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defaultProtocol(List<ProtocolRegistration> registrations) throws IOException {
|
||||
createTemplateFile();
|
||||
|
||||
|
||||
// 生成ProtocolManager.gd文件
|
||||
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("gdscript/ProtocolManagerTemplate.gd");
|
||||
var protocol_imports = new StringBuilder();
|
||||
var protocol_manager_registrations = new StringBuilder();
|
||||
for (var registration : registrations) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
protocol_imports.append(StringUtils.format("const {} = preload(\"res://{}/{}.gd\")", protocol_name, protocolOutputRootPath, protocol_name)).append(LS);
|
||||
protocol_manager_registrations.append(StringUtils.format("{}{}: {},", TAB_ASCII, protocol_id, protocol_name)).append(LS);
|
||||
}
|
||||
var placeholderMap = Map.of(CodeTemplatePlaceholder.protocol_imports, protocol_imports.toString()
|
||||
, CodeTemplatePlaceholder.protocol_manager_registrations, StringUtils.substringBeforeLast(protocol_manager_registrations.toString(), StringUtils.COMMA));
|
||||
var formatProtocolManagerTemplate = CodeTemplatePlaceholder.formatTemplate(protocolManagerTemplate, placeholderMap);
|
||||
var protocolManagerFile = new File(StringUtils.format("{}/{}", protocolOutputPath, "ProtocolManager.gd"));
|
||||
FileUtils.writeStringToFile(protocolManagerFile, formatProtocolManagerTemplate, true);
|
||||
logger.info("Generated GdScript 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("gdscript/ProtocolTemplate.gd");
|
||||
var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of(
|
||||
CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id)
|
||||
, CodeTemplatePlaceholder.protocol_name, protocol_name
|
||||
, CodeTemplatePlaceholder.protocol_note, GenerateProtocolNote.protocol_note(protocol_id, CodeLanguage.GdScript)
|
||||
, CodeTemplatePlaceholder.protocol_imports, protocol_imports_default(registration)
|
||||
, CodeTemplatePlaceholder.protocol_field_definition, protocol_field_definition(registration)
|
||||
, CodeTemplatePlaceholder.protocol_write_serialization, protocol_write_serialization(registration)
|
||||
, CodeTemplatePlaceholder.protocol_read_deserialization, protocol_read_deserialization(registration)
|
||||
, CodeTemplatePlaceholder.protocol_json, protocol_json(registration)
|
||||
, CodeTemplatePlaceholder.protocol_to_string, protocol_to_string(registration)
|
||||
));
|
||||
var outputPath = StringUtils.format("{}/{}.gd", protocolOutputPath, protocol_name);
|
||||
var file = new File(outputPath);
|
||||
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
|
||||
logger.info("Generated GdScript protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
private void createTemplateFile() 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);
|
||||
}
|
||||
|
||||
|
||||
private String protocol_imports_fold(ProtocolRegistration registration) {
|
||||
var protocolId = registration.getId();
|
||||
var subProtocols = ProtocolAnalysis.getAllSubProtocolIds(protocolId);
|
||||
var importBuilder = new StringBuilder();
|
||||
for (var subProtocolId : subProtocols) {
|
||||
var name = EnhanceObjectProtocolSerializer.getProtocolClassSimpleName(subProtocolId);
|
||||
importBuilder.append(StringUtils.format("const {} = preload(\"res://{}/{}/{}.gd\")", name, protocolOutputRootPath, GenerateProtocolPath.protocolPathSlash(protocolId), name)).append(LS);
|
||||
}
|
||||
return importBuilder.toString();
|
||||
}
|
||||
|
||||
private String protocol_imports_default(ProtocolRegistration registration) {
|
||||
var protocolId = registration.getId();
|
||||
var subProtocols = ProtocolAnalysis.getAllSubProtocolIds(protocolId);
|
||||
var importBuilder = new StringBuilder();
|
||||
for (var subProtocolId : subProtocols) {
|
||||
var protocolName = EnhanceObjectProtocolSerializer.getProtocolClassSimpleName(subProtocolId);
|
||||
importBuilder.append(StringUtils.format("const {} = preload(\"res://{}/{}.gd\")", protocolName, protocolOutputRootPath, protocolName)).append(LS);
|
||||
}
|
||||
return importBuilder.toString();
|
||||
}
|
||||
|
||||
private String protocol_json(ProtocolRegistration registration) {
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var gdBuilder = new StringBuilder();
|
||||
gdBuilder.append("{");
|
||||
// when generate source code fields, use origin fields sort
|
||||
var sequencedFields = ReflectionUtils.notStaticAndTransientFields(registration.getConstructor().getDeclaringClass());
|
||||
var params = new ArrayList<String>();
|
||||
for (var field : sequencedFields) {
|
||||
var fieldRegistration = fieldRegistrations[GenerateProtocolFile.indexOf(fields, field)];
|
||||
var fieldName = field.getName();
|
||||
var fieldType = gdSerializer(fieldRegistration.serializer()).fieldType(field, fieldRegistration);
|
||||
if (fieldType.equals("String")) {
|
||||
params.add(StringUtils.format("{}:'{}'", fieldName));
|
||||
} else {
|
||||
params.add(StringUtils.format("{}:{}", fieldName));
|
||||
}
|
||||
}
|
||||
gdBuilder.append(StringUtils.joinWith(", ", params.toArray()));
|
||||
gdBuilder.append("}");
|
||||
return gdBuilder.toString();
|
||||
}
|
||||
|
||||
private String protocol_to_string(ProtocolRegistration registration) {
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var gdBuilder = new StringBuilder();
|
||||
// when generate source code fields, use origin fields sort
|
||||
var sequencedFields = ReflectionUtils.notStaticAndTransientFields(registration.getConstructor().getDeclaringClass());
|
||||
var params = new ArrayList<String>();
|
||||
for (var field : sequencedFields) {
|
||||
var fieldRegistration = fieldRegistrations[GenerateProtocolFile.indexOf(fields, field)];
|
||||
var fieldName = field.getName();
|
||||
var fieldType = gdSerializer(fieldRegistration.serializer()).fieldType(field, fieldRegistration);
|
||||
if (fieldType.equals("Dictionary") || fieldType.startsWith("Array")) {
|
||||
params.add(StringUtils.format("JSON.stringify(self.{})", field.getName()));
|
||||
} else {
|
||||
params.add(StringUtils.format("self.{}", field.getName()));
|
||||
}
|
||||
}
|
||||
gdBuilder.append(StringUtils.joinWith(", ", params.toArray()));
|
||||
return gdBuilder.toString();
|
||||
}
|
||||
|
||||
private String protocol_field_definition(ProtocolRegistration registration) {
|
||||
var protocolId = registration.getId();
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var gdBuilder = 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 fieldNotes = GenerateProtocolNote.fieldNotes(protocolId, fieldName, CodeLanguage.GdScript);
|
||||
for (var fieldNote : fieldNotes) {
|
||||
gdBuilder.append(fieldNote).append(LS);
|
||||
}
|
||||
var fieldType = gdSerializer(fieldRegistration.serializer()).fieldType(field, fieldRegistration);
|
||||
// 生成类型的注释
|
||||
gdBuilder.append(StringUtils.format("var {}: {}", fieldName, fieldType));
|
||||
if (fieldType.equals("Dictionary") || fieldType.equals("Array")) {
|
||||
var typeNote = CodeGenerateTypeScript.toTsClassName(field.getGenericType().toString());
|
||||
gdBuilder.append(StringUtils.format(TAB_ASCII + "# {}", typeNote));
|
||||
}
|
||||
gdBuilder.append(LS);
|
||||
}
|
||||
return gdBuilder.toString();
|
||||
}
|
||||
|
||||
private String protocol_write_serialization(ProtocolRegistration registration) {
|
||||
GenerateProtocolFile.localVariableId = 0;
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var gdBuilder = new StringBuilder();
|
||||
if (registration.isCompatible()) {
|
||||
gdBuilder.append("var beforeWriteIndex = buffer.getWriteOffset()").append(LS);
|
||||
gdBuilder.append(StringUtils.format("buffer.writeInt({})", registration.getPredictionLength())).append(LS);
|
||||
} else {
|
||||
gdBuilder.append("buffer.writeInt(-1)").append(LS);
|
||||
}
|
||||
for (var i = 0; i < fields.length; i++) {
|
||||
var field = fields[i];
|
||||
var fieldRegistration = fieldRegistrations[i];
|
||||
gdSerializer(fieldRegistration.serializer()).writeObject(gdBuilder, "packet." + field.getName(), 0, field, fieldRegistration);
|
||||
}
|
||||
if (registration.isCompatible()) {
|
||||
gdBuilder.append(StringUtils.format("buffer.adjustPadding({}, beforeWriteIndex)", registration.getPredictionLength())).append(LS);
|
||||
}
|
||||
return gdBuilder.toString();
|
||||
}
|
||||
|
||||
private String protocol_read_deserialization(ProtocolRegistration registration) {
|
||||
GenerateProtocolFile.localVariableId = 0;
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var gdBuilder = new StringBuilder();
|
||||
for (var i = 0; i < fields.length; i++) {
|
||||
var field = fields[i];
|
||||
var fieldRegistration = fieldRegistrations[i];
|
||||
if (field.isAnnotationPresent(Compatible.class)) {
|
||||
gdBuilder.append("if buffer.compatibleRead(beforeReadIndex, length):").append(LS);
|
||||
var compatibleReadObject = gdSerializer(fieldRegistration.serializer()).readObject(gdBuilder, 1, field, fieldRegistration);
|
||||
gdBuilder.append(TAB_ASCII).append(StringUtils.format("packet.{} = {};", field.getName(), compatibleReadObject)).append(LS);
|
||||
continue;
|
||||
}
|
||||
var readObject = gdSerializer(fieldRegistration.serializer()).readObject(gdBuilder, 0, field, fieldRegistration);
|
||||
gdBuilder.append(StringUtils.format("packet.{} = {}", field.getName(), readObject)).append(LS);
|
||||
}
|
||||
return gdBuilder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -42,7 +42,7 @@ public class GdArraySerializer implements IGdSerializer {
|
||||
public String fieldType(Field field, IFieldRegistration fieldRegistration) {
|
||||
var arrayField = (ArrayField) fieldRegistration;
|
||||
var registration = arrayField.getArrayElementRegistration();
|
||||
var type = GenerateGdUtils.gdSerializer(registration.serializer()).fieldType(field, registration);
|
||||
var type = CodeGenerateGdScript.gdSerializer(registration.serializer()).fieldType(field, registration);
|
||||
return arrayType(type);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ public class GdArraySerializer implements IGdSerializer {
|
||||
String element = "element" + GenerateProtocolFile.localVariableId++;
|
||||
GenerateProtocolFile.addTabAscii(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for {} in {}:", element, objectStr)).append(LS);
|
||||
GenerateGdUtils.gdSerializer(arrayField.getArrayElementRegistration().serializer())
|
||||
CodeGenerateGdScript.gdSerializer(arrayField.getArrayElementRegistration().serializer())
|
||||
.writeObject(builder, element, deep + 2, field, arrayField.getArrayElementRegistration());
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ public class GdArraySerializer implements IGdSerializer {
|
||||
builder.append(StringUtils.format("if ({} > 0):", size)).append(LS);
|
||||
GenerateProtocolFile.addTabAscii(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for {} in range({}):", i, size)).append(LS);
|
||||
String readObject = GenerateGdUtils.gdSerializer(arrayField.getArrayElementRegistration().serializer())
|
||||
String readObject = CodeGenerateGdScript.gdSerializer(arrayField.getArrayElementRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, arrayField.getArrayElementRegistration());
|
||||
GenerateProtocolFile.addTabAscii(builder, deep + 2);
|
||||
builder.append(StringUtils.format("{}.append({})", result, readObject)).append(LS);
|
||||
|
||||
@@ -33,7 +33,7 @@ public class GdListSerializer implements IGdSerializer {
|
||||
public String fieldType(Field field, IFieldRegistration fieldRegistration) {
|
||||
var listField = (ListField) fieldRegistration;
|
||||
var registration = listField.getListElementRegistration();
|
||||
var type = GenerateGdUtils.gdSerializer(registration.serializer()).fieldType(field, registration);
|
||||
var type = CodeGenerateGdScript.gdSerializer(registration.serializer()).fieldType(field, registration);
|
||||
return GdArraySerializer.arrayType(type);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public class GdListSerializer implements IGdSerializer {
|
||||
String element = "element" + GenerateProtocolFile.localVariableId++;
|
||||
GenerateProtocolFile.addTabAscii(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for {} in {}:", element, objectStr)).append(LS);
|
||||
GenerateGdUtils.gdSerializer(listField.getListElementRegistration().serializer())
|
||||
CodeGenerateGdScript.gdSerializer(listField.getListElementRegistration().serializer())
|
||||
.writeObject(builder, element, deep + 2, field, listField.getListElementRegistration());
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ public class GdListSerializer implements IGdSerializer {
|
||||
builder.append(StringUtils.format("if ({} > 0):", size)).append(LS);
|
||||
GenerateProtocolFile.addTabAscii(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for {} in range({}):", i, size)).append(LS);
|
||||
String readObject = GenerateGdUtils.gdSerializer(listField.getListElementRegistration().serializer())
|
||||
String readObject = CodeGenerateGdScript.gdSerializer(listField.getListElementRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, listField.getListElementRegistration());
|
||||
GenerateProtocolFile.addTabAscii(builder, deep + 2);
|
||||
builder.append(StringUtils.format("{}.append({})", result, readObject)).append(LS);
|
||||
|
||||
@@ -59,9 +59,9 @@ public class GdMapSerializer implements IGdSerializer {
|
||||
builder.append(StringUtils.format("for {} in {}:", key, objectStr)).append(LS);
|
||||
GenerateProtocolFile.addTabAscii(builder, deep + 2);
|
||||
builder.append(StringUtils.format("var {} = {}[{}]", value, objectStr, key)).append(LS);
|
||||
GenerateGdUtils.gdSerializer(mapField.getMapKeyRegistration().serializer())
|
||||
CodeGenerateGdScript.gdSerializer(mapField.getMapKeyRegistration().serializer())
|
||||
.writeObject(builder, key, deep + 2, field, mapField.getMapKeyRegistration());
|
||||
GenerateGdUtils.gdSerializer(mapField.getMapValueRegistration().serializer())
|
||||
CodeGenerateGdScript.gdSerializer(mapField.getMapValueRegistration().serializer())
|
||||
.writeObject(builder, value, deep + 2, field, mapField.getMapValueRegistration());
|
||||
}
|
||||
|
||||
@@ -89,11 +89,11 @@ public class GdMapSerializer implements IGdSerializer {
|
||||
GenerateProtocolFile.addTabAscii(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for {} in range({}):", i, size)).append(LS);
|
||||
|
||||
String keyObject = GenerateGdUtils.gdSerializer(mapField.getMapKeyRegistration().serializer())
|
||||
String keyObject = CodeGenerateGdScript.gdSerializer(mapField.getMapKeyRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, mapField.getMapKeyRegistration());
|
||||
|
||||
|
||||
String valueObject = GenerateGdUtils.gdSerializer(mapField.getMapValueRegistration().serializer())
|
||||
String valueObject = CodeGenerateGdScript.gdSerializer(mapField.getMapValueRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, mapField.getMapValueRegistration());
|
||||
GenerateProtocolFile.addTabAscii(builder, deep + 2);
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ public class GdSetSerializer implements IGdSerializer {
|
||||
public String fieldType(Field field, IFieldRegistration fieldRegistration) {
|
||||
var listField = (SetField) fieldRegistration;
|
||||
var registration = listField.getSetElementRegistration();
|
||||
var type = GenerateGdUtils.gdSerializer(registration.serializer()).fieldType(field, registration);
|
||||
var type = CodeGenerateGdScript.gdSerializer(registration.serializer()).fieldType(field, registration);
|
||||
return GdArraySerializer.arrayType(type);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public class GdSetSerializer implements IGdSerializer {
|
||||
String element = "element" + GenerateProtocolFile.localVariableId++;
|
||||
GenerateProtocolFile.addTabAscii(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for {} in {}:", element, objectStr)).append(LS);
|
||||
GenerateGdUtils.gdSerializer(setField.getSetElementRegistration().serializer())
|
||||
CodeGenerateGdScript.gdSerializer(setField.getSetElementRegistration().serializer())
|
||||
.writeObject(builder, element, deep + 2, field, setField.getSetElementRegistration());
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ public class GdSetSerializer implements IGdSerializer {
|
||||
builder.append(StringUtils.format("if ({} > 0):", size)).append(LS);
|
||||
GenerateProtocolFile.addTabAscii(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for {} in range({}):", i, size)).append(LS);
|
||||
String readObject = GenerateGdUtils.gdSerializer(setField.getSetElementRegistration().serializer())
|
||||
String readObject = CodeGenerateGdScript.gdSerializer(setField.getSetElementRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, setField.getSetElementRegistration());
|
||||
GenerateProtocolFile.addTabAscii(builder, deep + 2);
|
||||
builder.append(StringUtils.format("{}.append({})", result, readObject)).append(LS);
|
||||
|
||||
@@ -1,263 +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.gdscript;
|
||||
|
||||
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.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.serializer.typescript.CodeGenerateTypeScript;
|
||||
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_ASCII;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public abstract class GenerateGdUtils {
|
||||
private static final Logger logger = LoggerFactory.getLogger(GenerateGdUtils.class);
|
||||
|
||||
// custom configuration
|
||||
public static String protocolOutputRootPath = "zfoogd";
|
||||
private static String protocolOutputPath = StringUtils.EMPTY;
|
||||
|
||||
private static Map<ISerializer, IGdSerializer> gdSerializerMap;
|
||||
|
||||
public static IGdSerializer gdSerializer(ISerializer serializer) {
|
||||
return gdSerializerMap.get(serializer);
|
||||
}
|
||||
|
||||
public static void init(GenerateOperation generateOperation) {
|
||||
protocolOutputPath = FileUtils.joinPath(generateOperation.getProtocolPath(), protocolOutputRootPath);
|
||||
FileUtils.deleteFile(new File(protocolOutputPath));
|
||||
|
||||
gdSerializerMap = new HashMap<>();
|
||||
gdSerializerMap.put(BooleanSerializer.INSTANCE, new GdBooleanSerializer());
|
||||
gdSerializerMap.put(ByteSerializer.INSTANCE, new GdByteSerializer());
|
||||
gdSerializerMap.put(ShortSerializer.INSTANCE, new GdShortSerializer());
|
||||
gdSerializerMap.put(IntSerializer.INSTANCE, new GdIntSerializer());
|
||||
gdSerializerMap.put(LongSerializer.INSTANCE, new GdLongSerializer());
|
||||
gdSerializerMap.put(FloatSerializer.INSTANCE, new GdFloatSerializer());
|
||||
gdSerializerMap.put(DoubleSerializer.INSTANCE, new GdDoubleSerializer());
|
||||
gdSerializerMap.put(StringSerializer.INSTANCE, new GdStringSerializer());
|
||||
gdSerializerMap.put(ArraySerializer.INSTANCE, new GdArraySerializer());
|
||||
gdSerializerMap.put(ListSerializer.INSTANCE, new GdListSerializer());
|
||||
gdSerializerMap.put(SetSerializer.INSTANCE, new GdSetSerializer());
|
||||
gdSerializerMap.put(MapSerializer.INSTANCE, new GdMapSerializer());
|
||||
gdSerializerMap.put(ObjectProtocolSerializer.INSTANCE, new GdObjectProtocolSerializer());
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
gdSerializerMap = null;
|
||||
protocolOutputRootPath = null;
|
||||
protocolOutputPath = null;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("gdscript/ProtocolManagerTemplate.gd");
|
||||
var importBuilder = new StringBuilder();
|
||||
var initList = new ArrayList<String>();
|
||||
for (var protocol : protocolList) {
|
||||
var protocolId = protocol.protocolId();
|
||||
var name = protocol.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
importBuilder.append(StringUtils.format("const {} = preload(\"res://{}/{}/{}.gd\")", name, protocolOutputRootPath, GenerateProtocolPath.protocolPathSlash(protocolId), name)).append(LS);
|
||||
initList.add(StringUtils.format("{}{}: {}", TAB_ASCII, protocolId, name));
|
||||
}
|
||||
var initProtocols = StringUtils.joinWith(StringUtils.COMMA + LS, initList.toArray());
|
||||
protocolManagerTemplate = StringUtils.format(protocolManagerTemplate, importBuilder.toString().trim(), initProtocols);
|
||||
var file = new File(StringUtils.format("{}/{}", protocolOutputPath, "ProtocolManager.gd"));
|
||||
FileUtils.writeStringToFile(file, protocolManagerTemplate, true);
|
||||
logger.info("Generated GdScript protocol manager file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
}
|
||||
|
||||
public static void createGdProtocolFile(ProtocolRegistration registration) throws IOException {
|
||||
var protocolId = registration.protocolId();
|
||||
var registrationConstructor = registration.getConstructor();
|
||||
var protocolClazzName = registrationConstructor.getDeclaringClass().getSimpleName();
|
||||
|
||||
var includeSubProtocol = includeSubProtocol(registration);
|
||||
var classNote = GenerateProtocolNote.classNote(protocolId, CodeLanguage.GdScript, TAB_ASCII, 0);
|
||||
var fieldDefinition = fieldDefinition(registration);
|
||||
var toStringJsonTemplate = toStringJsonTemplate(registration);
|
||||
var toStringParams = toStringParams(registration);
|
||||
var writeObject = writeObject(registration);
|
||||
var readObject = readObject(registration);
|
||||
|
||||
var protocolTemplate = ClassUtils.getFileFromClassPathToString("gdscript/ProtocolTemplate.gd");
|
||||
protocolTemplate = StringUtils.format(protocolTemplate, protocolId, protocolClazzName, includeSubProtocol, classNote, fieldDefinition.trim(),
|
||||
toStringJsonTemplate, toStringParams, StringUtils.EMPTY_JSON, writeObject.trim(), readObject.trim());
|
||||
|
||||
var outputPath = StringUtils.format("{}/{}/{}.gd", protocolOutputPath, GenerateProtocolPath.protocolPathSlash(protocolId), protocolClazzName);
|
||||
var file = new File(outputPath);
|
||||
FileUtils.writeStringToFile(file, protocolTemplate, true);
|
||||
logger.info("Generated GdScript 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 gdBuilder = new StringBuilder();
|
||||
for (var subProtocolId : subProtocols) {
|
||||
var name = EnhanceObjectProtocolSerializer.getProtocolClassSimpleName(subProtocolId);
|
||||
gdBuilder.append(StringUtils.format("const {} = preload(\"res://{}/{}/{}.gd\")", name, protocolOutputRootPath, GenerateProtocolPath.protocolPathSlash(protocolId), name)).append(LS);
|
||||
}
|
||||
return gdBuilder.toString();
|
||||
}
|
||||
|
||||
private static String fieldDefinition(ProtocolRegistration registration) {
|
||||
var protocolId = registration.getId();
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var gdBuilder = 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 fieldNotes = GenerateProtocolNote.fieldNotes(protocolId, fieldName, CodeLanguage.GdScript);
|
||||
for (var fieldNote : fieldNotes) {
|
||||
gdBuilder.append(fieldNote).append(LS);
|
||||
}
|
||||
var fieldType = gdSerializer(fieldRegistration.serializer()).fieldType(field, fieldRegistration);
|
||||
// 生成类型的注释
|
||||
gdBuilder.append(StringUtils.format("var {}: {}", fieldName, fieldType));
|
||||
if (fieldType.equals("Dictionary") || fieldType.equals("Array")) {
|
||||
var typeNote = CodeGenerateTypeScript.toTsClassName(field.getGenericType().toString());
|
||||
gdBuilder.append(StringUtils.format(TAB_ASCII + "# {}", typeNote));
|
||||
}
|
||||
gdBuilder.append(LS);
|
||||
}
|
||||
return gdBuilder.toString();
|
||||
}
|
||||
|
||||
private static String toStringJsonTemplate(ProtocolRegistration registration) {
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var gdBuilder = new StringBuilder();
|
||||
gdBuilder.append("{");
|
||||
// when generate source code fields, use origin fields sort
|
||||
var sequencedFields = ReflectionUtils.notStaticAndTransientFields(registration.getConstructor().getDeclaringClass());
|
||||
var params = new ArrayList<String>();
|
||||
for (var field : sequencedFields) {
|
||||
var fieldRegistration = fieldRegistrations[GenerateProtocolFile.indexOf(fields, field)];
|
||||
var fieldName = field.getName();
|
||||
var fieldType = gdSerializer(fieldRegistration.serializer()).fieldType(field, fieldRegistration);
|
||||
if (fieldType.equals("String")) {
|
||||
params.add(StringUtils.format("{}:'{}'", fieldName));
|
||||
} else {
|
||||
params.add(StringUtils.format("{}:{}", fieldName));
|
||||
}
|
||||
}
|
||||
gdBuilder.append(StringUtils.joinWith(", ", params.toArray()));
|
||||
gdBuilder.append("}");
|
||||
return gdBuilder.toString();
|
||||
}
|
||||
|
||||
private static String toStringParams(ProtocolRegistration registration) {
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var gdBuilder = new StringBuilder();
|
||||
gdBuilder.append("[");
|
||||
// when generate source code fields, use origin fields sort
|
||||
var sequencedFields = ReflectionUtils.notStaticAndTransientFields(registration.getConstructor().getDeclaringClass());
|
||||
var params = new ArrayList<String>();
|
||||
for (var field : sequencedFields) {
|
||||
var fieldRegistration = fieldRegistrations[GenerateProtocolFile.indexOf(fields, field)];
|
||||
var fieldName = field.getName();
|
||||
var fieldType = gdSerializer(fieldRegistration.serializer()).fieldType(field, fieldRegistration);
|
||||
if (fieldType.equals("Dictionary") || fieldType.startsWith("Array")) {
|
||||
params.add(StringUtils.format("JSON.stringify(self.{})", field.getName()));
|
||||
} else {
|
||||
params.add(StringUtils.format("self.{}", field.getName()));
|
||||
}
|
||||
}
|
||||
gdBuilder.append(StringUtils.joinWith(", ", params.toArray()));
|
||||
gdBuilder.append("]");
|
||||
return gdBuilder.toString();
|
||||
}
|
||||
|
||||
private static String writeObject(ProtocolRegistration registration) {
|
||||
GenerateProtocolFile.localVariableId = 0;
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var gdBuilder = new StringBuilder();
|
||||
if (registration.isCompatible()) {
|
||||
gdBuilder.append("var beforeWriteIndex = buffer.getWriteOffset()").append(LS);
|
||||
gdBuilder.append(TAB_ASCII).append(StringUtils.format("buffer.writeInt({})", registration.getPredictionLength())).append(LS);
|
||||
} else {
|
||||
gdBuilder.append(TAB_ASCII).append("buffer.writeInt(-1)").append(LS);
|
||||
}
|
||||
for (var i = 0; i < fields.length; i++) {
|
||||
var field = fields[i];
|
||||
var fieldRegistration = fieldRegistrations[i];
|
||||
gdSerializer(fieldRegistration.serializer()).writeObject(gdBuilder, "packet." + field.getName(), 1, field, fieldRegistration);
|
||||
}
|
||||
if (registration.isCompatible()) {
|
||||
gdBuilder.append(TAB_ASCII).append(StringUtils.format("buffer.adjustPadding({}, beforeWriteIndex)", registration.getPredictionLength())).append(LS);
|
||||
}
|
||||
return gdBuilder.toString();
|
||||
}
|
||||
|
||||
private static String readObject(ProtocolRegistration registration) {
|
||||
GenerateProtocolFile.localVariableId = 0;
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var gdBuilder = new StringBuilder();
|
||||
for (var i = 0; i < fields.length; i++) {
|
||||
var field = fields[i];
|
||||
var fieldRegistration = fieldRegistrations[i];
|
||||
if (field.isAnnotationPresent(Compatible.class)) {
|
||||
gdBuilder.append(TAB_ASCII).append("if buffer.compatibleRead(beforeReadIndex, length):").append(LS);
|
||||
var compatibleReadObject = gdSerializer(fieldRegistration.serializer()).readObject(gdBuilder, 2, field, fieldRegistration);
|
||||
gdBuilder.append(TAB_ASCII + TAB_ASCII).append(StringUtils.format("packet.{} = {};", field.getName(), compatibleReadObject)).append(LS);
|
||||
continue;
|
||||
}
|
||||
var readObject = gdSerializer(fieldRegistration.serializer()).readObject(gdBuilder, 1, field, fieldRegistration);
|
||||
gdBuilder.append(TAB_ASCII).append(StringUtils.format("packet.{} = {}", field.getName(), readObject)).append(LS);
|
||||
}
|
||||
return gdBuilder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
+4
-4
@@ -237,9 +237,9 @@ public class CodeGenerateTypeScript implements ICodeGenerate {
|
||||
var subProtocols = ProtocolAnalysis.getFirstSubProtocolIds(protocolId);
|
||||
// import other sub protocols
|
||||
for (var subProtocolId : subProtocols) {
|
||||
var protocolClassName = EnhanceObjectProtocolSerializer.getProtocolClassSimpleName(subProtocolId);
|
||||
var protocolName = EnhanceObjectProtocolSerializer.getProtocolClassSimpleName(subProtocolId);
|
||||
var path = GenerateProtocolPath.getRelativePath(protocolId, subProtocolId);
|
||||
importBuilder.append(StringUtils.format("import {} from '{}/{}';", protocolClassName, path, protocolClassName)).append(LS);
|
||||
importBuilder.append(StringUtils.format("import {} from '{}/{}';", protocolName, path, protocolName)).append(LS);
|
||||
}
|
||||
return importBuilder.toString();
|
||||
}
|
||||
@@ -253,8 +253,8 @@ public class CodeGenerateTypeScript implements ICodeGenerate {
|
||||
// import other sub protocols
|
||||
var subProtocols = ProtocolAnalysis.getFirstSubProtocolIds(protocolId);
|
||||
for (var subProtocolId : subProtocols) {
|
||||
var protocolClassName = EnhanceObjectProtocolSerializer.getProtocolClassSimpleName(subProtocolId);
|
||||
importBuilder.append(StringUtils.format("import {} from './{}';", protocolClassName, protocolClassName)).append(LS);
|
||||
var protocolName = EnhanceObjectProtocolSerializer.getProtocolClassSimpleName(subProtocolId);
|
||||
importBuilder.append(StringUtils.format("import {} from './{}';", protocolName, protocolName)).append(LS);
|
||||
}
|
||||
return importBuilder.toString();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
${protocol_note}
|
||||
class ${protocol_name}:
|
||||
${protocol_field_definition}
|
||||
|
||||
const PROTOCOL_ID = ${protocol_id}
|
||||
const PROTOCOL_CLASS_NAME = "${protocol_name}"
|
||||
|
||||
func _to_string() -> String:
|
||||
const jsonTemplate = "${protocol_json}"
|
||||
var params = [${protocol_to_string}]
|
||||
return jsonTemplate.format(params, "{}")
|
||||
|
||||
static func write(buffer, packet):
|
||||
if (packet == null):
|
||||
buffer.writeInt(0)
|
||||
return
|
||||
${protocol_write_serialization}
|
||||
pass
|
||||
|
||||
static func read(buffer):
|
||||
var length = buffer.readInt()
|
||||
if (length == 0):
|
||||
return null
|
||||
var beforeReadIndex = buffer.getReadOffset()
|
||||
var packet = buffer.newInstance(PROTOCOL_ID)
|
||||
${protocol_read_deserialization}
|
||||
if (length > 0):
|
||||
buffer.setReadOffset(beforeReadIndex + length)
|
||||
return packet
|
||||
@@ -1,7 +1,7 @@
|
||||
{}
|
||||
${protocol_imports}
|
||||
|
||||
const protocols: Dictionary = {
|
||||
{}
|
||||
${protocol_manager_registrations}
|
||||
}
|
||||
|
||||
static func getProtocol(protocolId: int):
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
const PROTOCOL_ID = {}
|
||||
const PROTOCOL_CLASS_NAME = "{}"
|
||||
{}
|
||||
{}
|
||||
{}
|
||||
const PROTOCOL_ID = ${protocol_id}
|
||||
const PROTOCOL_CLASS_NAME = "${protocol_name}"
|
||||
${protocol_imports}
|
||||
${protocol_note}
|
||||
${protocol_field_definition}
|
||||
|
||||
func _to_string() -> String:
|
||||
const jsonTemplate = "{}"
|
||||
var params = {}
|
||||
const jsonTemplate = "${protocol_json}"
|
||||
var params = [${protocol_to_string}]
|
||||
return jsonTemplate.format(params, "{}")
|
||||
|
||||
static func write(buffer, packet):
|
||||
if (packet == null):
|
||||
buffer.writeInt(0)
|
||||
return
|
||||
{}
|
||||
${protocol_write_serialization}
|
||||
pass
|
||||
|
||||
static func read(buffer):
|
||||
@@ -22,7 +22,7 @@ static func read(buffer):
|
||||
return null
|
||||
var beforeReadIndex = buffer.getReadOffset()
|
||||
var packet = buffer.newInstance(PROTOCOL_ID)
|
||||
{}
|
||||
${protocol_read_deserialization}
|
||||
if (length > 0):
|
||||
buffer.setReadOffset(beforeReadIndex + length)
|
||||
return packet
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
${protocol_class}
|
||||
Reference in New Issue
Block a user