add basic python writer for bmap binding
This commit is contained in:
parent
bcd58af132
commit
52c2d3f7e0
12
CodeGen/BMapBindings/CSharpWriter.java
Normal file
12
CodeGen/BMapBindings/CSharpWriter.java
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
public class CSharpWriter {
|
||||||
|
|
||||||
|
public static void writeCSharpCode(Vector<ExpFctDecl> data) throws Exception {
|
||||||
|
OutputStreamWriter writer = CommonHelper.openWriter("dest/BMExports.cs");
|
||||||
|
writer.write("// WIP");
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
31
CodeGen/BMapBindings/CommonHelper.java
Normal file
31
CodeGen/BMapBindings/CommonHelper.java
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class CommonHelper {
|
||||||
|
|
||||||
|
public static InputStreamReader openReader(String filename) throws Exception {
|
||||||
|
FileInputStream fs = new FileInputStream(filename);
|
||||||
|
return new InputStreamReader(fs, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OutputStreamWriter openWriter(String filename) throws Exception {
|
||||||
|
FileOutputStream fs = new FileOutputStream(filename);
|
||||||
|
return new OutputStreamWriter(fs, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeSnippet(OutputStreamWriter writer, String snippet_path) throws Exception {
|
||||||
|
// open snippet
|
||||||
|
InputStreamReader reader = openReader(snippet_path);
|
||||||
|
// write into writer
|
||||||
|
reader.transferTo(writer);
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDoxygenInOutStr(boolean isInput) {
|
||||||
|
return isInput ? "in" : "out";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,10 +4,12 @@ public class ExpFctParamDecl {
|
||||||
public VariableType mVarType;
|
public VariableType mVarType;
|
||||||
public String mVarName;
|
public String mVarName;
|
||||||
public boolean mIsInput;
|
public boolean mIsInput;
|
||||||
|
public String mVarDesc;
|
||||||
|
|
||||||
public ExpFctParamDecl() {
|
public ExpFctParamDecl() {
|
||||||
mVarType = new VariableType();
|
mVarType = new VariableType();
|
||||||
mVarName = "";
|
mVarName = "";
|
||||||
|
mVarDesc = "";
|
||||||
mIsInput = true;
|
mIsInput = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,14 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exitFctDecl(ExpFctsParser.FctDeclContext ctx) {
|
public void exitFctDecl(ExpFctsParser.FctDeclContext ctx) {
|
||||||
|
// set name
|
||||||
mCurrentFct.mFctName = ctx.EXPFCTS_IDENTIFIER().getText();
|
mCurrentFct.mFctName = ctx.EXPFCTS_IDENTIFIER().getText();
|
||||||
|
// check return type
|
||||||
|
if (!mCurrentFct.mFctRetType.isValid() || mCurrentFct.mFctRetType.isPointer()
|
||||||
|
|| !mCurrentFct.mFctRetType.getBaseType().equals("bool"))
|
||||||
|
throw new IllegalArgumentException("invalid interface function return type. must be bool.");
|
||||||
|
|
||||||
|
// add into list
|
||||||
mFctList.add(mCurrentFct);
|
mFctList.add(mCurrentFct);
|
||||||
mCurrentFct = null;
|
mCurrentFct = null;
|
||||||
}
|
}
|
||||||
|
@ -42,6 +49,7 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
||||||
public void exitFctArgFileDecl(ExpFctsParser.FctArgFileDeclContext ctx) {
|
public void exitFctArgFileDecl(ExpFctsParser.FctArgFileDeclContext ctx) {
|
||||||
ExpFctParamDecl decl = new ExpFctParamDecl();
|
ExpFctParamDecl decl = new ExpFctParamDecl();
|
||||||
decl.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
decl.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
||||||
|
decl.mVarDesc = "The pointer to corresponding BMFile.";
|
||||||
decl.mIsInput = true;
|
decl.mIsInput = true;
|
||||||
decl.mVarType.fromCType("BMap::BMFile*");
|
decl.mVarType.fromCType("BMap::BMFile*");
|
||||||
mCurrentFct.mFctParams.add(decl);
|
mCurrentFct.mFctParams.add(decl);
|
||||||
|
@ -51,6 +59,7 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
||||||
public void exitFctArgMeshTransDecl(ExpFctsParser.FctArgMeshTransDeclContext ctx) {
|
public void exitFctArgMeshTransDecl(ExpFctsParser.FctArgMeshTransDeclContext ctx) {
|
||||||
ExpFctParamDecl decl = new ExpFctParamDecl();
|
ExpFctParamDecl decl = new ExpFctParamDecl();
|
||||||
decl.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
decl.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
||||||
|
decl.mVarDesc = "The pointer to corresponding BMMeshTransition.";
|
||||||
decl.mIsInput = true;
|
decl.mIsInput = true;
|
||||||
decl.mVarType.fromCType("BMap::BMMeshTransition*");
|
decl.mVarType.fromCType("BMap::BMMeshTransition*");
|
||||||
mCurrentFct.mFctParams.add(decl);
|
mCurrentFct.mFctParams.add(decl);
|
||||||
|
@ -60,12 +69,14 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
||||||
public void exitFctArgObjDecl(ExpFctsParser.FctArgObjDeclContext ctx) {
|
public void exitFctArgObjDecl(ExpFctsParser.FctArgObjDeclContext ctx) {
|
||||||
ExpFctParamDecl first_decl = new ExpFctParamDecl();
|
ExpFctParamDecl first_decl = new ExpFctParamDecl();
|
||||||
first_decl.mVarName = ctx.EXPFCTS_IDENTIFIER(0).getText();
|
first_decl.mVarName = ctx.EXPFCTS_IDENTIFIER(0).getText();
|
||||||
|
first_decl.mVarDesc = "The pointer to corresponding BMFile.";
|
||||||
first_decl.mIsInput = true;
|
first_decl.mIsInput = true;
|
||||||
first_decl.mVarType.fromCType("BMap::BMFile*");
|
first_decl.mVarType.fromCType("BMap::BMFile*");
|
||||||
mCurrentFct.mFctParams.add(first_decl);
|
mCurrentFct.mFctParams.add(first_decl);
|
||||||
|
|
||||||
ExpFctParamDecl second_decl = new ExpFctParamDecl();
|
ExpFctParamDecl second_decl = new ExpFctParamDecl();
|
||||||
second_decl.mVarName = ctx.EXPFCTS_IDENTIFIER(1).getText();
|
second_decl.mVarName = ctx.EXPFCTS_IDENTIFIER(1).getText();
|
||||||
|
second_decl.mVarDesc = "The CKID of object you accessing.";
|
||||||
second_decl.mIsInput = true;
|
second_decl.mIsInput = true;
|
||||||
second_decl.mVarType.fromCType("LibCmo::CK2::CK_ID");
|
second_decl.mVarType.fromCType("LibCmo::CK2::CK_ID");
|
||||||
mCurrentFct.mFctParams.add(second_decl);
|
mCurrentFct.mFctParams.add(second_decl);
|
||||||
|
|
42
CodeGen/BMapBindings/IndentHelper.java
Normal file
42
CodeGen/BMapBindings/IndentHelper.java
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
|
||||||
|
public class IndentHelper {
|
||||||
|
public IndentHelper(OutputStreamWriter writer) {
|
||||||
|
mIndent = 0;
|
||||||
|
mWriter = writer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int mIndent;
|
||||||
|
private OutputStreamWriter mWriter;
|
||||||
|
|
||||||
|
public void inc() {
|
||||||
|
++mIndent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dec() {
|
||||||
|
--mIndent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void indent() throws Exception {
|
||||||
|
for (int i = 0; i < mIndent; ++i) {
|
||||||
|
mWriter.write(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void lineBreak() throws Exception {
|
||||||
|
mWriter.write(System.lineSeparator());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void puts(String data) throws Exception {
|
||||||
|
indent();
|
||||||
|
mWriter.write(data);
|
||||||
|
lineBreak();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printf(String fmt, Object... args) throws Exception {
|
||||||
|
indent();
|
||||||
|
mWriter.write(String.format(fmt, args));
|
||||||
|
lineBreak();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -8,20 +8,24 @@ import org.antlr.v4.runtime.tree.*;
|
||||||
public class MainRunner {
|
public class MainRunner {
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
// get interface structture
|
// get interface structure
|
||||||
FileInputStream fs = new FileInputStream("dest/BMExports.hpp");
|
FileInputStream fs = new FileInputStream("dest/BMExports.hpp");
|
||||||
CharStream antlrfs = CharStreams.fromStream(fs, StandardCharsets.UTF_8);
|
CharStream antlrfs = CharStreams.fromStream(fs, StandardCharsets.UTF_8);
|
||||||
ExpFctsLexer lexer = new ExpFctsLexer(antlrfs);
|
ExpFctsLexer lexer = new ExpFctsLexer(antlrfs);
|
||||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||||
ExpFctsParser parser = new ExpFctsParser(tokens);
|
ExpFctsParser parser = new ExpFctsParser(tokens);
|
||||||
|
|
||||||
|
// parsing data
|
||||||
ParseTree tree = parser.program();
|
ParseTree tree = parser.program();
|
||||||
ParseTreeWalker walker = new ParseTreeWalker();
|
ParseTreeWalker walker = new ParseTreeWalker();
|
||||||
ExpFctsWalker worker = new ExpFctsWalker();
|
ExpFctsWalker worker = new ExpFctsWalker();
|
||||||
walker.walk(worker, tree);
|
walker.walk(worker, tree);
|
||||||
fs.close();
|
fs.close();
|
||||||
|
|
||||||
|
// get data and write them
|
||||||
Vector<ExpFctDecl> result = worker.getResult();
|
Vector<ExpFctDecl> result = worker.getResult();
|
||||||
|
PythonWriter.writePythonCode(result);
|
||||||
|
CSharpWriter.writeCSharpCode(result);
|
||||||
|
|
||||||
// print message.
|
// print message.
|
||||||
System.out.println("DONE!");
|
System.out.println("DONE!");
|
||||||
|
|
85
CodeGen/BMapBindings/PythonWriter.java
Normal file
85
CodeGen/BMapBindings/PythonWriter.java
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Vector;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class PythonWriter {
|
||||||
|
|
||||||
|
private static final Map<String, String> g_CppTypeMap = cppTypeMapCreator();
|
||||||
|
|
||||||
|
private static Map<String, String> cppTypeMapCreator() {
|
||||||
|
Map<String, String> cache = new HashMap<String, String>();
|
||||||
|
cache.put("CKSTRING", "CKSTRING");
|
||||||
|
cache.put("CKDWORD", "CKDWORD");
|
||||||
|
cache.put("CKINT", "CKINT");
|
||||||
|
cache.put("bool", "bool");
|
||||||
|
cache.put("CKFLOAT", "CKFLOAT");
|
||||||
|
cache.put("CKBYTE", "CKBYTE");
|
||||||
|
cache.put("CK_ID", "CKID");
|
||||||
|
cache.put("BMFile", "void");
|
||||||
|
cache.put("BMMeshTransition", "void");
|
||||||
|
cache.put("VxVector3", "VxVector2");
|
||||||
|
cache.put("VxVector2", "VxVector2");
|
||||||
|
cache.put("VxColor", "VxColor");
|
||||||
|
cache.put("VxMatrix", "VxMatrix");
|
||||||
|
cache.put("CK_TEXTURE_SAVEOPTIONS", "enum");
|
||||||
|
cache.put("VX_PIXELFORMAT", "enum");
|
||||||
|
cache.put("VXTEXTURE_BLENDMODE", "enum");
|
||||||
|
cache.put("VXTEXTURE_FILTERMODE", "enum");
|
||||||
|
cache.put("VXTEXTURE_ADDRESSMODE", "enum");
|
||||||
|
cache.put("VXBLEND_MODE", "enum");
|
||||||
|
cache.put("VXFILL_MODE", "enum");
|
||||||
|
cache.put("VXSHADE_MODE", "enum");
|
||||||
|
cache.put("VXCMPFUNC", "enum");
|
||||||
|
return Collections.unmodifiableMap(cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String pythonTypeGetter(ExpFctParamDecl paramdecl) {
|
||||||
|
VariableType vt = paramdecl.mVarType;
|
||||||
|
if (!paramdecl.mIsInput) {
|
||||||
|
vt = vt.getPointerOfThis();
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("bm_");
|
||||||
|
sb.append(g_CppTypeMap.get(vt.getBaseType()));
|
||||||
|
if (vt.isPointer()) {
|
||||||
|
sb.append("_");
|
||||||
|
sb.append(String.join("", Collections.nCopies(vt.getPointerLevel(), "p")));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writePythonCode(Vector<ExpFctDecl> data) throws Exception {
|
||||||
|
OutputStreamWriter writer = CommonHelper.openWriter("dest/BMExports.py");
|
||||||
|
IndentHelper helper = new IndentHelper(writer);
|
||||||
|
|
||||||
|
// write snippet
|
||||||
|
CommonHelper.writeSnippet(writer, "snippets/header.py");
|
||||||
|
|
||||||
|
// write function decls
|
||||||
|
for (ExpFctDecl fctdecl : data) {
|
||||||
|
// write annotation
|
||||||
|
// function name
|
||||||
|
helper.printf("## %s", fctdecl.mFctName);
|
||||||
|
// param
|
||||||
|
for (ExpFctParamDecl paramdecl : fctdecl.mFctParams) {
|
||||||
|
helper.printf("# @param %s[%s] Type: %s. %s%s", paramdecl.mVarName,
|
||||||
|
CommonHelper.getDoxygenInOutStr(paramdecl.mIsInput), paramdecl.mVarType.toCType(),
|
||||||
|
(paramdecl.mIsInput ? "" : "Use ctypes.byref(data) pass it. "), paramdecl.mVarDesc);
|
||||||
|
}
|
||||||
|
// return val
|
||||||
|
helper.puts("# @return True if no error, otherwise False.");
|
||||||
|
|
||||||
|
// write real declaration
|
||||||
|
// first, we need join all param
|
||||||
|
helper.printf("%s = _create_bmap_func('%s', [%s])", fctdecl.mFctName, fctdecl.mFctName, fctdecl.mFctParams
|
||||||
|
.stream().map(value -> pythonTypeGetter(value)).collect(Collectors.joining(", ")));
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -20,7 +20,7 @@ public class VariableType {
|
||||||
}
|
}
|
||||||
|
|
||||||
private VariableType(Vector<String> base_type, int pointer_level) {
|
private VariableType(Vector<String> base_type, int pointer_level) {
|
||||||
mBaseType.addAll(base_type);
|
mBaseType = (Vector<String>) base_type.clone();
|
||||||
mPointerLevel = pointer_level;
|
mPointerLevel = pointer_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,10 @@ public class VariableType {
|
||||||
return mPointerLevel != 0;
|
return mPointerLevel != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getPointerLevel() {
|
||||||
|
return mPointerLevel;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
return mBaseType.size() != 0;
|
return mBaseType.size() != 0;
|
||||||
}
|
}
|
||||||
|
|
63
CodeGen/BMapBindings/snippets/header.py
Normal file
63
CodeGen/BMapBindings/snippets/header.py
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
import ctypes, os
|
||||||
|
|
||||||
|
#region Type Defines
|
||||||
|
|
||||||
|
bm_CKSTRING = ctypes.c_char_p
|
||||||
|
bm_CKSTRING_p = ctypes.POINTER(bm_CKSTRING)
|
||||||
|
bm_CKDWORD = ctypes.c_uint32
|
||||||
|
bm_CKDWORD_p = ctypes.POINTER(bm_CKDWORD)
|
||||||
|
bm_CKWORD = ctypes.c_uint16
|
||||||
|
bm_CKWORD_p = ctypes.POINTER(bm_CKWORD)
|
||||||
|
bm_CKID = ctypes.c_uint32
|
||||||
|
bm_CKID_p = ctypes.POINTER(bm_CKID)
|
||||||
|
bm_CKFLOAT = ctypes.c_float
|
||||||
|
bm_CKFLOAT_p = ctypes.POINTER(bm_CKFLOAT)
|
||||||
|
bm_CKINT = types.c_int32
|
||||||
|
|
||||||
|
bm_enum = bm_CKDWORD
|
||||||
|
bm_bool = ctypes.c_bool
|
||||||
|
bm_void_p = ctypes.c_void_p
|
||||||
|
|
||||||
|
class bm_VxVector2(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
('x', bm_CKFLOAT),
|
||||||
|
('y', bm_CKFLOAT),
|
||||||
|
]
|
||||||
|
bm_VxVector2_p = ctypes.POINTER(bm_VxVector2)
|
||||||
|
class bm_VxVector3(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
('x', bm_CKFLOAT),
|
||||||
|
('y', bm_CKFLOAT),
|
||||||
|
('z', bm_CKFLOAT),
|
||||||
|
]
|
||||||
|
bm_VxVector3_p = ctypes.POINTER(bm_VxVector3)
|
||||||
|
|
||||||
|
class bm_VxMatrix(ctypes.Structure):
|
||||||
|
_fields_ = list(
|
||||||
|
(f'i{idx}', bm_CKFLOAT) for idx in range(16)
|
||||||
|
)
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region BMap Loader
|
||||||
|
|
||||||
|
_g_BMapModule: ctypes.CDLL = None
|
||||||
|
try:
|
||||||
|
_g_BMapModule = ctypes.cdll.LoadLibrary(
|
||||||
|
os.path.join(os.path.dirname(__file__), "BMap.dll")
|
||||||
|
)
|
||||||
|
except:
|
||||||
|
_g_BMapModule = None
|
||||||
|
|
||||||
|
def is_bmap_available() -> bool:
|
||||||
|
return _g_BMapModule is not None
|
||||||
|
|
||||||
|
def _create_bmap_func(fct_name: str, fct_params: list) -> None:
|
||||||
|
if _g_BMapModule is None: return None
|
||||||
|
|
||||||
|
cache = getattr(_g_BMapModule, fct_name)
|
||||||
|
cache.argtypes = fct_params
|
||||||
|
cache.restype = bm_bool
|
||||||
|
return cache
|
||||||
|
|
||||||
|
#endregion
|
Loading…
Reference in New Issue
Block a user