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 String mVarName;
|
||||
public boolean mIsInput;
|
||||
public String mVarDesc;
|
||||
|
||||
public ExpFctParamDecl() {
|
||||
mVarType = new VariableType();
|
||||
mVarName = "";
|
||||
mVarDesc = "";
|
||||
mIsInput = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,14 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
|||
|
||||
@Override
|
||||
public void exitFctDecl(ExpFctsParser.FctDeclContext ctx) {
|
||||
// set name
|
||||
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);
|
||||
mCurrentFct = null;
|
||||
}
|
||||
|
@ -42,6 +49,7 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
|||
public void exitFctArgFileDecl(ExpFctsParser.FctArgFileDeclContext ctx) {
|
||||
ExpFctParamDecl decl = new ExpFctParamDecl();
|
||||
decl.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
||||
decl.mVarDesc = "The pointer to corresponding BMFile.";
|
||||
decl.mIsInput = true;
|
||||
decl.mVarType.fromCType("BMap::BMFile*");
|
||||
mCurrentFct.mFctParams.add(decl);
|
||||
|
@ -51,6 +59,7 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
|||
public void exitFctArgMeshTransDecl(ExpFctsParser.FctArgMeshTransDeclContext ctx) {
|
||||
ExpFctParamDecl decl = new ExpFctParamDecl();
|
||||
decl.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
||||
decl.mVarDesc = "The pointer to corresponding BMMeshTransition.";
|
||||
decl.mIsInput = true;
|
||||
decl.mVarType.fromCType("BMap::BMMeshTransition*");
|
||||
mCurrentFct.mFctParams.add(decl);
|
||||
|
@ -60,12 +69,14 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
|||
public void exitFctArgObjDecl(ExpFctsParser.FctArgObjDeclContext ctx) {
|
||||
ExpFctParamDecl first_decl = new ExpFctParamDecl();
|
||||
first_decl.mVarName = ctx.EXPFCTS_IDENTIFIER(0).getText();
|
||||
first_decl.mVarDesc = "The pointer to corresponding BMFile.";
|
||||
first_decl.mIsInput = true;
|
||||
first_decl.mVarType.fromCType("BMap::BMFile*");
|
||||
mCurrentFct.mFctParams.add(first_decl);
|
||||
|
||||
ExpFctParamDecl second_decl = new ExpFctParamDecl();
|
||||
second_decl.mVarName = ctx.EXPFCTS_IDENTIFIER(1).getText();
|
||||
second_decl.mVarDesc = "The CKID of object you accessing.";
|
||||
second_decl.mIsInput = true;
|
||||
second_decl.mVarType.fromCType("LibCmo::CK2::CK_ID");
|
||||
mCurrentFct.mFctParams.add(second_decl);
|
||||
|
@ -80,7 +91,7 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
|||
public void exitFctArgParamIn(ExpFctsParser.FctArgParamInContext ctx) {
|
||||
mCurrentParam.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
||||
mCurrentParam.mIsInput = true;
|
||||
|
||||
|
||||
mCurrentFct.mFctParams.add(mCurrentParam);
|
||||
mCurrentParam = null;
|
||||
}
|
||||
|
@ -95,8 +106,8 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
|||
mCurrentParam.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
||||
mCurrentParam.mIsInput = false;
|
||||
// set to its pointer type
|
||||
//mCurrentParam.mVarType = mCurrentParam.mVarType.getPointerOfThis();
|
||||
|
||||
// mCurrentParam.mVarType = mCurrentParam.mVarType.getPointerOfThis();
|
||||
|
||||
mCurrentFct.mFctParams.add(mCurrentParam);
|
||||
mCurrentParam = null;
|
||||
}
|
||||
|
@ -110,7 +121,7 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
|||
if (ctx.EXPFCTS_STAR() != null) {
|
||||
ctype += String.join("", Collections.nCopies(ctx.EXPFCTS_STAR().size(), "*"));
|
||||
}
|
||||
|
||||
|
||||
if (!mCurrentFct.mFctRetType.isValid()) {
|
||||
// fill function ret type first
|
||||
mCurrentFct.mFctRetType.fromCType(ctype);
|
||||
|
|
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 static void main(String[] args) throws Exception {
|
||||
// get interface structture
|
||||
// get interface structure
|
||||
FileInputStream fs = new FileInputStream("dest/BMExports.hpp");
|
||||
CharStream antlrfs = CharStreams.fromStream(fs, StandardCharsets.UTF_8);
|
||||
ExpFctsLexer lexer = new ExpFctsLexer(antlrfs);
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
ExpFctsParser parser = new ExpFctsParser(tokens);
|
||||
|
||||
// parsing data
|
||||
ParseTree tree = parser.program();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
ExpFctsWalker worker = new ExpFctsWalker();
|
||||
walker.walk(worker, tree);
|
||||
fs.close();
|
||||
|
||||
// get data and write them
|
||||
Vector<ExpFctDecl> result = worker.getResult();
|
||||
PythonWriter.writePythonCode(result);
|
||||
CSharpWriter.writeCSharpCode(result);
|
||||
|
||||
// print message.
|
||||
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) {
|
||||
mBaseType.addAll(base_type);
|
||||
mBaseType = (Vector<String>) base_type.clone();
|
||||
mPointerLevel = pointer_level;
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,10 @@ public class VariableType {
|
|||
public boolean isPointer() {
|
||||
return mPointerLevel != 0;
|
||||
}
|
||||
|
||||
public int getPointerLevel() {
|
||||
return mPointerLevel;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
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