feat[python]: support python

This commit is contained in:
godotg
2023-08-26 22:14:55 +08:00
parent ec7f7eff92
commit 2ea9570996
13 changed files with 88 additions and 40 deletions
@@ -53,13 +53,29 @@ public abstract class GenerateProtocolPath {
switch (language) {
case Cpp:
break;
case Go:
break;
case JavaScript:
break;
case TypeScript:
break;
case CSharp:
break;
case Protobuf:
break;
case Lua:
break;
case GdScript:
break;
case Python:
if (StringUtils.isBlank(getProtocolPath(protocolId))) {
path = StringUtils.PERIOD;
} else {
path = StringUtils.format("{}.{}", path, name);
path = path.replaceAll(StringUtils.SLASH , StringUtils.PERIOD);
}
break;
case Enhance:
break;
default:
@@ -24,7 +24,10 @@ import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.serializer.CodeLanguage;
import com.zfoo.protocol.serializer.csharp.GenerateCsUtils;
import com.zfoo.protocol.serializer.reflect.*;
import com.zfoo.protocol.util.*;
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 java.io.File;
import java.io.IOException;
@@ -34,7 +37,6 @@ import java.util.Map;
import static com.zfoo.protocol.util.FileUtils.LS;
import static com.zfoo.protocol.util.StringUtils.TAB;
import static com.zfoo.protocol.util.StringUtils.TAB_ASCII;
/**
* @author godotg
@@ -80,28 +82,27 @@ public abstract class GeneratePyUtils {
}
public static void createProtocolManager(List<IProtocolRegistration> protocolList) throws IOException {
var list = List.of("python/byte_buffer.py");
var list = List.of("python/ByteBuffer.py");
for (var fileName : list) {
var fileInputStream = ClassUtils.getFileFromClassPath(fileName);
var createFile = new File(StringUtils.format("{}/{}", protocolOutputRootPath, StringUtils.substringAfterFirst(fileName, "python/")));
FileUtils.writeInputStreamToFile(createFile, fileInputStream);
}
// 生成ProtocolManager.js文件
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("javascript/ProtocolManagerTemplate.js");
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("python/ProtocolManagerTemplate.py");
var importBuilder = new StringBuilder();
var initProtocolBuilder = new StringBuilder();
for (var protocol : protocolList) {
var protocolId = protocol.protocolId();
var protocolName = protocol.protocolConstructor().getDeclaringClass().getSimpleName();
var path = GenerateProtocolPath.protocolAbsolutePath(protocol.protocolId(), CodeLanguage.JavaScript);
importBuilder.append(StringUtils.format("import {} from './{}.js';", protocolName, path)).append(LS);
initProtocolBuilder.append(StringUtils.format("protocols.set({}, {});", protocolId, protocolName)).append(LS);
var path = GenerateProtocolPath.protocolAbsolutePath(protocolId, CodeLanguage.Python);
importBuilder.append(StringUtils.format("from {} import {}", path, protocolName)).append(LS);
initProtocolBuilder.append(StringUtils.format("protocols[{}] = {}.{}", protocolId, protocolName, protocolName)).append(LS);
}
protocolManagerTemplate = StringUtils.format(protocolManagerTemplate, importBuilder.toString().trim(), StringUtils.EMPTY_JSON, initProtocolBuilder.toString().trim());
FileUtils.writeStringToFile(new File(StringUtils.format("{}/{}", protocolOutputRootPath, "ProtocolManager.js")), protocolManagerTemplate, true);
FileUtils.writeStringToFile(new File(StringUtils.format("{}/{}", protocolOutputRootPath, "ProtocolManager.py")), protocolManagerTemplate, true);
}
public static void createPyProtocolFile(ProtocolRegistration registration) {
@@ -119,7 +120,7 @@ public abstract class GeneratePyUtils {
var readObject = readObject(registration);
protocolTemplate = StringUtils.format(protocolTemplate, classNote, protocolClazzName
, fieldDefinition.trim(), protocolId, writeObject.trim(), readObject.trim(), protocolClazzName);
, fieldDefinition.trim(), protocolId, writeObject.trim(), protocolClazzName, readObject.trim());
var protocolOutputPath = StringUtils.format("{}/{}/{}.py", protocolOutputRootPath
, GenerateProtocolPath.getProtocolPath(protocolId), protocolClazzName);
FileUtils.writeStringToFile(new File(protocolOutputPath), protocolTemplate, true);
@@ -144,7 +145,7 @@ public abstract class GeneratePyUtils {
var fieldDefaultValue = pySerializer(fieldRegistration.serializer()).fieldDefaultValue(field, fieldRegistration);
// 生成类型的注释
pyBuilder.append(StringUtils.format("{}{} = {}", TAB, fieldName, fieldDefaultValue));
pyBuilder.append(StringUtils.format(" # {}", GenerateCsUtils.toCsClassName(field.getGenericType().getTypeName())));
pyBuilder.append(StringUtils.format(" # {}", GenerateCsUtils.toCsClassName(field.getGenericType().getTypeName())));
pyBuilder.append(LS);
}
return pyBuilder.toString();
@@ -170,9 +171,9 @@ public abstract class GeneratePyUtils {
var field = fields[i];
var fieldRegistration = fieldRegistrations[i];
if (field.isAnnotationPresent(Compatible.class)) {
pyBuilder.append(TAB+ TAB).append("if !buffer.isReadable():").append(LS);
pyBuilder.append(TAB + TAB+ TAB).append("return packet").append(LS);
pyBuilder.append(TAB+ TAB).append("pass").append(LS);
pyBuilder.append(TAB + TAB).append("if not buffer.isReadable():").append(LS);
pyBuilder.append(TAB + TAB + TAB).append("return packet").append(LS);
pyBuilder.append(TAB + TAB).append("pass").append(LS);
}
var readObject = pySerializer(fieldRegistration.serializer()).readObject(pyBuilder, 2, field, fieldRegistration);
pyBuilder.append(TAB + TAB).append(StringUtils.format("packet.{} = {}", field.getName(), readObject)).append(LS);
@@ -181,7 +182,7 @@ public abstract class GeneratePyUtils {
}
public static StringBuilder addTab(StringBuilder builder, int deep) {
builder.append(TAB_ASCII.repeat(Math.max(0, deep)));
builder.append(TAB.repeat(Math.max(0, deep)));
return builder;
}
}
@@ -38,13 +38,13 @@ public class PyArraySerializer implements IPySerializer {
@Override
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.addTab(builder, deep);
if (CutDownArraySerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.GdScript)) {
if (CutDownArraySerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.Python)) {
return;
}
ArrayField arrayField = (ArrayField) fieldRegistration;
builder.append(StringUtils.format("if ({} == null):", objectStr)).append(LS);
builder.append(StringUtils.format("if {} is None:", objectStr)).append(LS);
GeneratePyUtils.addTab(builder, deep + 1);
builder.append("buffer.writeInt(0)").append(LS);
GeneratePyUtils.addTab(builder, deep);
@@ -63,7 +63,7 @@ public class PyArraySerializer implements IPySerializer {
@Override
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.addTab(builder, deep);
var cutDown = CutDownArraySerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.GdScript);
var cutDown = CutDownArraySerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.Python);
if (cutDown != null) {
return cutDown;
}
@@ -80,7 +80,7 @@ public class PyArraySerializer implements IPySerializer {
builder.append(StringUtils.format("{} = buffer.readInt()", size)).append(LS);
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("if ({} > 0):", size)).append(LS);
builder.append(StringUtils.format("if {} > 0:", size)).append(LS);
GeneratePyUtils.addTab(builder, deep + 1);
builder.append(StringUtils.format("for {} in range({}):", i, size)).append(LS);
String readObject = GeneratePyUtils.pySerializer(arrayField.getArrayElementRegistration().serializer())
@@ -29,7 +29,7 @@ import static com.zfoo.protocol.util.FileUtils.LS;
public class PyCharSerializer implements IPySerializer {
@Override
public String fieldDefaultValue(Field field, IFieldRegistration fieldRegistration) {
return StringUtils.EMPTY;
return "\"\"";
}
@Override
@@ -38,13 +38,13 @@ public class PyListSerializer implements IPySerializer {
@Override
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.addTab(builder, deep);
if (CutDownListSerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.GdScript)) {
if (CutDownListSerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.Python)) {
return;
}
ListField listField = (ListField) fieldRegistration;
builder.append(StringUtils.format("if ({} == null):", objectStr)).append(LS);
builder.append(StringUtils.format("if {} is None:", objectStr)).append(LS);
GeneratePyUtils.addTab(builder, deep + 1);
builder.append("buffer.writeInt(0)").append(LS);
GeneratePyUtils.addTab(builder, deep);
@@ -63,7 +63,7 @@ public class PyListSerializer implements IPySerializer {
@Override
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.addTab(builder, deep);
var cutDown = CutDownListSerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.GdScript);
var cutDown = CutDownListSerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.Python);
if (cutDown != null) {
return cutDown;
}
@@ -80,7 +80,7 @@ public class PyListSerializer implements IPySerializer {
builder.append(StringUtils.format("{} = buffer.readInt()", size)).append(LS);
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("if ({} > 0):", size)).append(LS);
builder.append(StringUtils.format("if {} > 0:", size)).append(LS);
GeneratePyUtils.addTab(builder, deep + 1);
builder.append(StringUtils.format("for {} in range({}):", i, size)).append(LS);
String readObject = GeneratePyUtils.pySerializer(listField.getListElementRegistration().serializer())
@@ -38,12 +38,12 @@ public class PyMapSerializer implements IPySerializer {
@Override
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.addTab(builder, deep);
if (CutDownMapSerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.GdScript)) {
if (CutDownMapSerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.Python)) {
return;
}
MapField mapField = (MapField) fieldRegistration;
builder.append(StringUtils.format("if ({} == null):", objectStr)).append(LS);
builder.append(StringUtils.format("if {} is None:", objectStr)).append(LS);
GeneratePyUtils.addTab(builder, deep + 1);
builder.append("buffer.writeInt(0)").append(LS);
@@ -69,7 +69,7 @@ public class PyMapSerializer implements IPySerializer {
@Override
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.addTab(builder, deep);
var cutDown = CutDownMapSerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.GdScript);
var cutDown = CutDownMapSerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.Python);
if (cutDown != null) {
return cutDown;
}
@@ -84,7 +84,7 @@ public class PyMapSerializer implements IPySerializer {
builder.append(StringUtils.format("{} = buffer.readInt()", size)).append(LS);
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("if ({} > 0):", size)).append(LS);
builder.append(StringUtils.format("if {} > 0:", size)).append(LS);
String i = "index" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep + 1);
@@ -38,13 +38,13 @@ public class PySetSerializer implements IPySerializer {
@Override
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.addTab(builder, deep);
if (CutDownSetSerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.GdScript)) {
if (CutDownSetSerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.Python)) {
return;
}
SetField setField = (SetField) fieldRegistration;
builder.append(StringUtils.format("if ({} == null):", objectStr)).append(LS);
builder.append(StringUtils.format("if {} is None:", objectStr)).append(LS);
GeneratePyUtils.addTab(builder, deep + 1);
builder.append("buffer.writeInt(0)").append(LS);
GeneratePyUtils.addTab(builder, deep);
@@ -63,7 +63,7 @@ public class PySetSerializer implements IPySerializer {
@Override
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.addTab(builder, deep);
var cutDown = CutDownSetSerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.GdScript);
var cutDown = CutDownSetSerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.Python);
if (cutDown != null) {
return cutDown;
}
@@ -80,7 +80,7 @@ public class PySetSerializer implements IPySerializer {
builder.append(StringUtils.format("{} = buffer.readInt()", size)).append(LS);
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("if ({} > 0):", size)).append(LS);
builder.append(StringUtils.format("if {} > 0:", size)).append(LS);
GeneratePyUtils.addTab(builder, deep + 1);
builder.append(StringUtils.format("for {} in range({}):", i, size)).append(LS);
String readObject = GeneratePyUtils.pySerializer(setField.getSetElementRegistration().serializer())
@@ -29,7 +29,7 @@ import static com.zfoo.protocol.util.FileUtils.LS;
public class PyStringSerializer implements IPySerializer {
@Override
public String fieldDefaultValue(Field field, IFieldRegistration fieldRegistration) {
return StringUtils.EMPTY;
return "\"\"";
}
@Override
@@ -103,7 +103,7 @@ public abstract class GenerateTsUtils {
for (var protocol : protocolList) {
var protocolId = protocol.protocolId();
var name = protocol.protocolConstructor().getDeclaringClass().getSimpleName();
var path = GenerateProtocolPath.protocolAbsolutePath(protocolId, CodeLanguage.GdScript);
var path = GenerateProtocolPath.protocolAbsolutePath(protocolId, CodeLanguage.TypeScript);
importBuilder.append(StringUtils.format("import {} from './{}';", name, path)).append(LS);
initProtocolBuilder.append(StringUtils.format("protocols.set({}, {});", protocolId, name)).append(LS);
@@ -18,7 +18,7 @@ static func write(buffer, packet):
protocol.write(buffer, packet)
static func read(buffer):
var protocolId = buffer.readShort();
var protocolId = buffer.readShort()
var protocol = protocols[protocolId]
var packet = protocol.read(buffer);
return packet;
var packet = protocol.read(buffer)
return packet
@@ -64,6 +64,12 @@ class ByteBuffer():
self.readOffset += 1
return value
def writeBytes(self, value):
length = len(value)
self.ensureCapacity(length)
self.buffer[self.writeOffset:length] = value[:]
self.writeOffset += length
def writeUByte(self, value):
self.ensureCapacity(1)
struct.pack_into('>B', self.buffer, self.writeOffset, value)
@@ -0,0 +1,20 @@
{}
protocols = {}
{}
def getProtocol(protocolId):
return protocols[protocolId]
def write(buffer, packet):
protocolId = packet.protocolId()
buffer.writeShort(protocolId)
protocol = protocols[protocolId]
protocol.write(buffer, packet)
def read(buffer):
protocolId = buffer.readShort()
protocol = protocols[protocolId]
packet = protocol.read(buffer)
return packet
@@ -1,5 +1,5 @@
{}
class {}():
class {}:
{}
@@ -8,11 +8,16 @@ class {}():
@classmethod
def write(cls, buffer, packet):
if (buffer.writePacketFlag(packet)):
if buffer.writePacketFlag(packet):
return
{}
pass
@classmethod
def read(cls, buffer):
if not buffer.readBool():
return None
packet = {}()
{}
pass
return packet