refactor: finish refactor ExpFctsAnalyzer in BMapBinder
This commit is contained in:
@@ -1,286 +0,0 @@
|
|||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.util.Vector;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class CSharpWriter {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The class represent the C# type corresponding to extracted variable type.
|
|
||||||
*/
|
|
||||||
private static class CsInteropType {
|
|
||||||
public CsInteropType() {
|
|
||||||
mMarshalAs = null;
|
|
||||||
mCsType = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The argument of MarshalAsAttribute constructor. In generation, this field
|
|
||||||
* should be used like this: "[MarshalAs(THIS)]" (for parameter) or "[return:
|
|
||||||
* MarshalAs(THIS)]" (for return value).
|
|
||||||
*/
|
|
||||||
public String mMarshalAs;
|
|
||||||
/**
|
|
||||||
* The C# type used in interop function declaration for corresponding parameter.
|
|
||||||
*/
|
|
||||||
public String mCsType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* C# specified function which get C# used interop MarshalAs constructor
|
|
||||||
* arguments and C# type used in interop function declaration.
|
|
||||||
*
|
|
||||||
* @param vt The instance of {@linkplain VariableType} for fetching interop
|
|
||||||
* type.
|
|
||||||
* @return The corresponding interop type of given variable type.
|
|
||||||
*/
|
|
||||||
private static CsInteropType getCsInteropType(ExpFctParamDecl paramdecl) {
|
|
||||||
// get essential variable type properties first
|
|
||||||
VariableType vt = paramdecl.mVarType;
|
|
||||||
String vt_base_type = vt.getBaseType();
|
|
||||||
int vt_pointer_level = vt.getPointerLevel();
|
|
||||||
|
|
||||||
// create return value
|
|
||||||
CsInteropType ret = new CsInteropType();
|
|
||||||
|
|
||||||
// use "switch" to check variable type
|
|
||||||
switch (vt_base_type) {
|
|
||||||
case "CKSTRING":
|
|
||||||
// decide direction cookies
|
|
||||||
String direction_cookie = "";
|
|
||||||
if (paramdecl.mIsInput) {
|
|
||||||
direction_cookie = "In";
|
|
||||||
} else {
|
|
||||||
direction_cookie = "Out";
|
|
||||||
}
|
|
||||||
// only allow 0 and 1 pointer level for string.
|
|
||||||
switch (vt_pointer_level) {
|
|
||||||
case 0:
|
|
||||||
ret.mMarshalAs = "UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringMarshaler), MarshalCookie = \"" + direction_cookie + "\"";
|
|
||||||
// ret.mMarshalAs = "UnmanagedType.LPUTF8Str";
|
|
||||||
ret.mCsType = "string";
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
ret.mMarshalAs = "UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringArrayMarshaler), MarshalCookie = \"" + direction_cookie + "\"";
|
|
||||||
ret.mCsType = "string[]";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "CKDWORD":
|
|
||||||
if (vt_pointer_level == 0) {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.U4";
|
|
||||||
ret.mCsType = "uint";
|
|
||||||
} else {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
|
||||||
ret.mCsType = "IntPtr";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "CKWORD":
|
|
||||||
if (vt_pointer_level == 0) {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.U2";
|
|
||||||
ret.mCsType = "ushort";
|
|
||||||
} else {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
|
||||||
ret.mCsType = "IntPtr";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "CKINT":
|
|
||||||
if (vt_pointer_level == 0) {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.I4";
|
|
||||||
ret.mCsType = "int";
|
|
||||||
} else {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
|
||||||
ret.mCsType = "IntPtr";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "bool":
|
|
||||||
if (vt_pointer_level == 0) {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.U1";
|
|
||||||
ret.mCsType = "bool";
|
|
||||||
} else {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
|
||||||
ret.mCsType = "IntPtr";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "CKFLOAT":
|
|
||||||
if (vt_pointer_level == 0) {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.R4";
|
|
||||||
ret.mCsType = "float";
|
|
||||||
} else {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
|
||||||
ret.mCsType = "IntPtr";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "CKBYTE":
|
|
||||||
if (vt_pointer_level == 0) {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.U1";
|
|
||||||
ret.mCsType = "byte";
|
|
||||||
} else {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
|
||||||
ret.mCsType = "IntPtr";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "CK_ID":
|
|
||||||
if (vt_pointer_level == 0) {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.U4";
|
|
||||||
ret.mCsType = "uint";
|
|
||||||
} else {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
|
||||||
ret.mCsType = "IntPtr";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "NakedOutputCallback":
|
|
||||||
// callback actually is a function pointer
|
|
||||||
// so it only allow base type without any pointer level.
|
|
||||||
if (vt_pointer_level == 0) {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.FunctionPtr";
|
|
||||||
ret.mCsType = "OutputCallback";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "BMFile":
|
|
||||||
// In any case, BMFile only should be raw pointer
|
|
||||||
if (vt_pointer_level != 0) {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
|
||||||
ret.mCsType = "IntPtr";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "BMMeshTransition":
|
|
||||||
// In any case, BMMeshTransition only should be raw pointer
|
|
||||||
if (vt_pointer_level != 0) {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
|
||||||
ret.mCsType = "IntPtr";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "VxVector3":
|
|
||||||
if (vt_pointer_level == 0) {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.Struct";
|
|
||||||
ret.mCsType = "VxVector3";
|
|
||||||
} else {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
|
||||||
ret.mCsType = "IntPtr";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "VxVector2":
|
|
||||||
if (vt_pointer_level == 0) {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.Struct";
|
|
||||||
ret.mCsType = "VxVector2";
|
|
||||||
} else {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
|
||||||
ret.mCsType = "IntPtr";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "VxColor":
|
|
||||||
if (vt_pointer_level == 0) {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.Struct";
|
|
||||||
ret.mCsType = "VxColor";
|
|
||||||
} else {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
|
||||||
ret.mCsType = "IntPtr";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "VxMatrix":
|
|
||||||
if (vt_pointer_level == 0) {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.Struct";
|
|
||||||
ret.mCsType = "VxMatrix";
|
|
||||||
} else {
|
|
||||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
|
||||||
ret.mCsType = "IntPtr";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "CK_TEXTURE_SAVEOPTIONS":
|
|
||||||
case "VX_PIXELFORMAT":
|
|
||||||
case "VXLIGHT_TYPE":
|
|
||||||
case "VXTEXTURE_BLENDMODE":
|
|
||||||
case "VXTEXTURE_FILTERMODE":
|
|
||||||
case "VXTEXTURE_ADDRESSMODE":
|
|
||||||
case "VXBLEND_MODE":
|
|
||||||
case "VXFILL_MODE":
|
|
||||||
case "VXSHADE_MODE":
|
|
||||||
case "VXCMPFUNC":
|
|
||||||
case "VXMESH_LITMODE":
|
|
||||||
// all enum type use the same strategy
|
|
||||||
if (vt_pointer_level == 0) {
|
|
||||||
// all enum type should be marshaled as its underlying type
|
|
||||||
// but we can use its name in C# directly.
|
|
||||||
ret.mMarshalAs = "UnmanagedType.U4";
|
|
||||||
ret.mCsType = vt_base_type;
|
|
||||||
} else {
|
|
||||||
// for pointer type, use IntPtr instead.
|
|
||||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
|
||||||
ret.mCsType = "IntPtr";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check whether we successfully get result
|
|
||||||
if (ret.mMarshalAs == null || ret.mCsType == null) {
|
|
||||||
throw new IllegalArgumentException("Unexpected type: " + vt.toCType());
|
|
||||||
}
|
|
||||||
|
|
||||||
// return value
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void writeCSharpCode(Vector<ExpFctDecl> data) throws Exception {
|
|
||||||
OutputStreamWriter writer = CommonHelper.openWriter("dest/BMExports.cs");
|
|
||||||
IndentHelper helper = new IndentHelper(writer);
|
|
||||||
|
|
||||||
// write function decls
|
|
||||||
for (ExpFctDecl fctdecl : data) {
|
|
||||||
// write annotation
|
|
||||||
// summary (just plain function name)
|
|
||||||
helper.printf("/// <summary>%s</summary>", fctdecl.mFctName);
|
|
||||||
// parameter list
|
|
||||||
for (ExpFctParamDecl paramdecl : fctdecl.mFctParams) {
|
|
||||||
helper.printf("/// <param name=\"%s\">Type: %s. %s%s</param>", paramdecl.mVarName,
|
|
||||||
paramdecl.mVarType.toCType(), (paramdecl.mIsInput ? "" : "This is OUT parameter. "),
|
|
||||||
paramdecl.mVarDesc);
|
|
||||||
}
|
|
||||||
// return value
|
|
||||||
helper.puts("/// <returns>True if no error, otherwise False.</returns>");
|
|
||||||
|
|
||||||
// write real function declaration
|
|
||||||
// first, write DllImportAttribute
|
|
||||||
helper.printf(
|
|
||||||
"[DllImport(g_DllName, EntryPoint = \"%s\", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]",
|
|
||||||
fctdecl.mFctName);
|
|
||||||
// second, write return value MarshalAsAttribute
|
|
||||||
helper.printf("[return: MarshalAs(UnmanagedType.U1)]");
|
|
||||||
// then, before we write function body, we need origanize its parameter list
|
|
||||||
// first
|
|
||||||
Vector<String> cs_param_list = new Vector<String>();
|
|
||||||
for (ExpFctParamDecl paramdecl : fctdecl.mFctParams) {
|
|
||||||
// create string builder
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
// push in out symbol
|
|
||||||
if (paramdecl.mIsInput) {
|
|
||||||
sb.append("[In, ");
|
|
||||||
} else {
|
|
||||||
sb.append("[Out, ");
|
|
||||||
}
|
|
||||||
// get interop type now
|
|
||||||
CsInteropType interop_type = getCsInteropType(paramdecl);
|
|
||||||
// push MarshalAsAttribute
|
|
||||||
sb.append("MarshalAs(");
|
|
||||||
sb.append(interop_type.mMarshalAs);
|
|
||||||
sb.append(")] ");
|
|
||||||
// push out keyword if parameter is out parameter
|
|
||||||
if (!paramdecl.mIsInput) {
|
|
||||||
sb.append("out ");
|
|
||||||
}
|
|
||||||
// push parameter cs type
|
|
||||||
sb.append(interop_type.mCsType);
|
|
||||||
sb.append(" ");
|
|
||||||
// push parameter name
|
|
||||||
sb.append(paramdecl.mVarName);
|
|
||||||
// insert built string into list
|
|
||||||
cs_param_list.add(sb.toString());
|
|
||||||
}
|
|
||||||
// join built parameter list and output real function declaration
|
|
||||||
helper.printf("internal static extern bool %s(%s);", fctdecl.mFctName,
|
|
||||||
cs_param_list.stream().collect(Collectors.joining(", ")));
|
|
||||||
}
|
|
||||||
|
|
||||||
writer.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -3,29 +3,32 @@ import java.io.FileOutputStream;
|
|||||||
//import java.io.InputStreamReader;
|
//import java.io.InputStreamReader;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
public class CommonHelper {
|
public class CommonHelper {
|
||||||
|
|
||||||
// public static InputStreamReader openReader(String filename) throws Exception {
|
// =========== File Operations ===========
|
||||||
// FileInputStream fs = new FileInputStream(filename);
|
|
||||||
// return new InputStreamReader(fs, StandardCharsets.UTF_8);
|
|
||||||
// }
|
|
||||||
|
|
||||||
public static OutputStreamWriter openWriter(String filename) throws Exception {
|
private static Path getRootDirectoryPath() throws Exception {
|
||||||
FileOutputStream fs = new FileOutputStream(filename);
|
String rootDir = System.getenv("BMAP_BINDER_ROOT");
|
||||||
return new OutputStreamWriter(fs, StandardCharsets.UTF_8);
|
if (rootDir == null) {
|
||||||
|
throw new RuntimeException("Can not find essential environment variable BMAP_BINDER_ROOT");
|
||||||
|
} else {
|
||||||
|
return Paths.get(rootDir);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// public static void writeSnippet(OutputStreamWriter writer, String snippet_path) throws Exception {
|
public static String getInputFilePath(String filename) throws Exception {
|
||||||
// // open snippet
|
Path rootDir = getRootDirectoryPath();
|
||||||
// InputStreamReader reader = openReader(snippet_path);
|
Path filePath = rootDir.resolve("Extracted").resolve(filename);
|
||||||
// // write into writer
|
return filePath.toString();
|
||||||
// reader.transferTo(writer);
|
}
|
||||||
// reader.close();
|
|
||||||
// }
|
|
||||||
|
|
||||||
public static String getDoxygenInOutStr(boolean isInput) {
|
public static String getOutputFilePath(String filename) throws Exception {
|
||||||
return isInput ? "in" : "out";
|
Path rootDir = getRootDirectoryPath();
|
||||||
|
Path filePath = rootDir.resolve("Analyzed").resolve(filename);
|
||||||
|
return filePath.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The class represent an export BMap function.
|
|
||||||
*/
|
|
||||||
public class ExpFctDecl {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of this function.
|
|
||||||
*/
|
|
||||||
public String mFctName;
|
|
||||||
/**
|
|
||||||
* The return value type of this function.
|
|
||||||
*/
|
|
||||||
public VariableType mFctRetType;
|
|
||||||
/**
|
|
||||||
* The parameters (arguments) list of this function. Each items are
|
|
||||||
* {@linkplain ExpFctParamDecl} and represent parameter one by one from left to
|
|
||||||
* right.
|
|
||||||
*/
|
|
||||||
public Vector<ExpFctParamDecl> mFctParams;
|
|
||||||
|
|
||||||
public ExpFctDecl() {
|
|
||||||
mFctName = "";
|
|
||||||
mFctRetType = new VariableType();
|
|
||||||
mFctParams = new Vector<ExpFctParamDecl>();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
|
|
||||||
/**
|
|
||||||
* The class represent a single parameter (argument) of function. This class
|
|
||||||
* usually is the member of {@linkplain ExpFctDecl}.
|
|
||||||
*/
|
|
||||||
public class ExpFctParamDecl {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The type of this parameter.
|
|
||||||
*/
|
|
||||||
public VariableType mVarType;
|
|
||||||
/**
|
|
||||||
* The name of this parameter.
|
|
||||||
*/
|
|
||||||
public String mVarName;
|
|
||||||
/**
|
|
||||||
* True if this paramter is marked as input parameter, otherwise false.
|
|
||||||
* <p>
|
|
||||||
* Input parameter and output paramter is commonly used in C/C++ code. By using
|
|
||||||
* this feature, each function can receive multiple arguments and return
|
|
||||||
* multiple arguments without defining a struct to hold it.
|
|
||||||
* <p>
|
|
||||||
* The type of input parameter is itself. However, the type of output parameter
|
|
||||||
* is the pointer of itself. So you may need get its pointer type when
|
|
||||||
* processing output paramter, especially for the scenario that the target
|
|
||||||
* language do not support explicit output parameter keyword.
|
|
||||||
*/
|
|
||||||
public boolean mIsInput;
|
|
||||||
/**
|
|
||||||
* The description of this parameter.
|
|
||||||
* <p>
|
|
||||||
* This description is generated by this program. It will indicate the
|
|
||||||
* underlying C++ type to tell end user how to treat this paramter because some
|
|
||||||
* target languages' native calling style can not represent these detail.
|
|
||||||
* <p>
|
|
||||||
* In this program, this field must be written as a annotation of corresponding
|
|
||||||
* function.
|
|
||||||
*/
|
|
||||||
public String mVarDesc;
|
|
||||||
|
|
||||||
public ExpFctParamDecl() {
|
|
||||||
mVarType = new VariableType();
|
|
||||||
mVarName = "";
|
|
||||||
mVarDesc = "";
|
|
||||||
mIsInput = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
248
Assets/CodeGen/BMapBinder/ExpFctsAnalyzer/ExpFctsHelper.java
Normal file
248
Assets/CodeGen/BMapBinder/ExpFctsAnalyzer/ExpFctsHelper.java
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Vector;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ExpFctsHelper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class represent the type of each parameters and function return value.
|
||||||
|
*/
|
||||||
|
public static class VariableType {
|
||||||
|
/**
|
||||||
|
* The base type of this variable removing all ending stars (remove all pointer levels).
|
||||||
|
* Each item in this Vector is a part of namespace and the last one must be the type itself
|
||||||
|
* (without any namespace constraint).
|
||||||
|
* If no namespace constraint for this type, this Vector will only have one item.
|
||||||
|
* <p>
|
||||||
|
* For end user, it is enough that knowing the last item is type itself.
|
||||||
|
*/
|
||||||
|
private Vector<String> mBaseType;
|
||||||
|
/**
|
||||||
|
* The pointer level of this type. It is equal to the count of trailing star of
|
||||||
|
* this field in C style representation.
|
||||||
|
*/
|
||||||
|
private int mPointerLevel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct an empty varible type. This is commonly used constructor.
|
||||||
|
*/
|
||||||
|
public VariableType() {
|
||||||
|
mBaseType = new Vector<String>();
|
||||||
|
mPointerLevel = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The constructor used for cloning self. This constructor is only can be used
|
||||||
|
* by self.
|
||||||
|
*
|
||||||
|
* @param base_type The hierarchy of the variable type.
|
||||||
|
* @param pointer_level The pointer level of new created variable type.
|
||||||
|
*/
|
||||||
|
private VariableType(Vector<String> base_type, int pointer_level) {
|
||||||
|
mBaseType = (Vector<String>) base_type.clone();
|
||||||
|
mPointerLevel = pointer_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this variable type with a type string in C/C++ style. For example
|
||||||
|
* "NSTest::NSTest2::MyType**".
|
||||||
|
*
|
||||||
|
* @param ctype The type string in C/C++ style.
|
||||||
|
*/
|
||||||
|
public void fromCType(String ctype) {
|
||||||
|
if (ctype.isEmpty())
|
||||||
|
throw new IllegalArgumentException("empty string can not be parsed.");
|
||||||
|
|
||||||
|
// get pointer part and name part
|
||||||
|
int len = ctype.length();
|
||||||
|
int star_pos = ctype.indexOf('*');
|
||||||
|
String namepart;
|
||||||
|
if (star_pos == -1) {
|
||||||
|
// no star
|
||||||
|
namepart = ctype;
|
||||||
|
mPointerLevel = 0;
|
||||||
|
} else {
|
||||||
|
// has star
|
||||||
|
if (star_pos == 0)
|
||||||
|
throw new IllegalArgumentException("base type not found.");
|
||||||
|
namepart = ctype.substring(0, star_pos);
|
||||||
|
mPointerLevel = len - star_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// resolve name part
|
||||||
|
mBaseType.clear();
|
||||||
|
for (String item : namepart.split("::")) {
|
||||||
|
mBaseType.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a type string represented by this variable type in C/C++ style.
|
||||||
|
*
|
||||||
|
* @return The type string in C/C++ style.
|
||||||
|
*/
|
||||||
|
public String toCType() {
|
||||||
|
return mBaseType.stream().collect(Collectors.joining("::"))
|
||||||
|
+ String.join("", Collections.nCopies(mPointerLevel, "*"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the base type of this variable type without any namespace. It just simply
|
||||||
|
* get the last entry in type hierarchy.
|
||||||
|
*
|
||||||
|
* @return The base type string without namespace prefix.
|
||||||
|
*/
|
||||||
|
public String getBaseType() {
|
||||||
|
return mBaseType.lastElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether this variable type is a pointer. This function just check
|
||||||
|
* whether the pointer level of this variavle type is zero.
|
||||||
|
*
|
||||||
|
* @return True if it is pointer, otherwise false.
|
||||||
|
*/
|
||||||
|
public boolean isPointer() {
|
||||||
|
return mPointerLevel != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the pointer level of this variable type. You can simply assume the
|
||||||
|
* pointer level is equal to the count of trailing star.
|
||||||
|
*
|
||||||
|
* @return The pointer level integer. Zero means that this type is not a
|
||||||
|
* pointer.
|
||||||
|
*/
|
||||||
|
public int getPointerLevel() {
|
||||||
|
return mPointerLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the clone of the type hierarchy of this variable type.
|
||||||
|
* <p>
|
||||||
|
* It is rarely used. This only should be used when you need the namespace
|
||||||
|
* hierarchy of this variable type.
|
||||||
|
*
|
||||||
|
* @return The clone of current variable type hierarchy.
|
||||||
|
*/
|
||||||
|
public Vector<String> getBaseTypeHierarchy() {
|
||||||
|
return (Vector<String>) mBaseType.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether this type is a valid one. It actually check whether type
|
||||||
|
* hierarchy include at least one entry.
|
||||||
|
*
|
||||||
|
* @return True if no problem of this type, otherwise false.
|
||||||
|
*/
|
||||||
|
public boolean isValid() {
|
||||||
|
return mBaseType.size() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a new created variable type which is the pointer of this variable
|
||||||
|
* type.
|
||||||
|
* <p>
|
||||||
|
* In internal implementation, it just create a clone of current variable type
|
||||||
|
* with the increase of pointer level by 1.
|
||||||
|
*
|
||||||
|
* @return The new created pointer type of this variable type.
|
||||||
|
*/
|
||||||
|
public VariableType getPointerOfThis() {
|
||||||
|
return new VariableType(mBaseType, mPointerLevel + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class represent a single parameter (argument) of function. This class
|
||||||
|
* usually is the member of {@linkplain ExpFct}.
|
||||||
|
*/
|
||||||
|
public static class ExpFctParam {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of this parameter.
|
||||||
|
*/
|
||||||
|
public VariableType mVarType;
|
||||||
|
/**
|
||||||
|
* The name of this parameter.
|
||||||
|
*/
|
||||||
|
public String mVarName;
|
||||||
|
/**
|
||||||
|
* True if this paramter is marked as input parameter, otherwise false.
|
||||||
|
* <p>
|
||||||
|
* Input parameter and output paramter is commonly used in C/C++ code. By using
|
||||||
|
* this feature, each function can receive multiple arguments and return
|
||||||
|
* multiple arguments without defining a struct to hold it.
|
||||||
|
* <p>
|
||||||
|
* The type of input parameter is itself. However, the type of output parameter
|
||||||
|
* is the pointer of itself. So you may need get its pointer type when
|
||||||
|
* processing output paramter, especially for the scenario that the target
|
||||||
|
* language do not support explicit output parameter keyword.
|
||||||
|
*/
|
||||||
|
public boolean mIsInput;
|
||||||
|
/**
|
||||||
|
* The description of this parameter.
|
||||||
|
* <p>
|
||||||
|
* This description is generated by this program. It will indicate the
|
||||||
|
* underlying C++ type to tell end user how to treat this paramter because some
|
||||||
|
* target languages' native calling style can not represent these detail.
|
||||||
|
* <p>
|
||||||
|
* In this program, this field must be written as a annotation of corresponding
|
||||||
|
* function.
|
||||||
|
*/
|
||||||
|
public String mVarDesc;
|
||||||
|
|
||||||
|
public ExpFctParam() {
|
||||||
|
mVarType = new VariableType();
|
||||||
|
mVarName = "";
|
||||||
|
mVarDesc = "";
|
||||||
|
mIsInput = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class represent an export BMap function.
|
||||||
|
*/
|
||||||
|
public static class ExpFct {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of this function.
|
||||||
|
*/
|
||||||
|
public String mFctName;
|
||||||
|
/**
|
||||||
|
* The return value type of this function.
|
||||||
|
*/
|
||||||
|
public VariableType mFctRetType;
|
||||||
|
/**
|
||||||
|
* The parameters (arguments) list of this function. Each items are
|
||||||
|
* {@linkplain ExpFctParam} and represent parameter one by one from left to
|
||||||
|
* right.
|
||||||
|
*/
|
||||||
|
public Vector<ExpFctParam> mFctParams;
|
||||||
|
|
||||||
|
public ExpFct() {
|
||||||
|
mFctName = "";
|
||||||
|
mFctRetType = new VariableType();
|
||||||
|
mFctParams = new Vector<ExpFctParam>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class represent a collection of export BMap functions.
|
||||||
|
*/
|
||||||
|
public static class ExpFctCollection {
|
||||||
|
/**
|
||||||
|
* The collection of exported BMap functions.
|
||||||
|
*/
|
||||||
|
public Vector<ExpFct> mFcts;
|
||||||
|
|
||||||
|
public ExpFctCollection() {
|
||||||
|
mFcts = new Vector<ExpFct>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,34 +1,30 @@
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Vector;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.antlr.v4.runtime.*;
|
|
||||||
import org.antlr.v4.runtime.tree.*;
|
|
||||||
|
|
||||||
public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
||||||
|
|
||||||
public ExpFctsWalker() {
|
public ExpFctsWalker() {
|
||||||
mFctList = new Vector<ExpFctDecl>();
|
mFctCollection = null;
|
||||||
mCurrentFct = null;
|
mCurrentFct = null;
|
||||||
mCurrentParam = null;
|
mCurrentParam = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector<ExpFctDecl> getResult() {
|
public ExpFctsHelper.ExpFctCollection getResult() {
|
||||||
return mFctList;
|
return mFctCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector<ExpFctDecl> mFctList;
|
private ExpFctsHelper.ExpFctCollection mFctCollection;
|
||||||
private ExpFctDecl mCurrentFct;
|
private ExpFctsHelper.ExpFct mCurrentFct;
|
||||||
private ExpFctParamDecl mCurrentParam;
|
private ExpFctsHelper.ExpFctParam mCurrentParam;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enterProgram(ExpFctsParser.ProgramContext ctx) {
|
public void enterProgram(ExpFctsParser.ProgramContext ctx) {
|
||||||
mFctList.clear();
|
mFctCollection = new ExpFctsHelper.ExpFctCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enterFctDecl(ExpFctsParser.FctDeclContext ctx) {
|
public void enterFctDecl(ExpFctsParser.FctDeclContext ctx) {
|
||||||
mCurrentFct = new ExpFctDecl();
|
mCurrentFct = new ExpFctsHelper.ExpFct();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -41,50 +37,50 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
|||||||
throw new IllegalArgumentException("invalid interface function return type. must be bool.");
|
throw new IllegalArgumentException("invalid interface function return type. must be bool.");
|
||||||
|
|
||||||
// add into list
|
// add into list
|
||||||
mFctList.add(mCurrentFct);
|
mFctCollection.mFcts.add(mCurrentFct);
|
||||||
mCurrentFct = null;
|
mCurrentFct = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exitFctArgFileDecl(ExpFctsParser.FctArgFileDeclContext ctx) {
|
public void exitFctArgFileDecl(ExpFctsParser.FctArgFileDeclContext ctx) {
|
||||||
ExpFctParamDecl decl = new ExpFctParamDecl();
|
ExpFctsHelper.ExpFctParam param = new ExpFctsHelper.ExpFctParam();
|
||||||
decl.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
param.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
||||||
decl.mVarDesc = "The pointer to corresponding BMFile.";
|
param.mVarDesc = "The pointer to corresponding BMFile.";
|
||||||
decl.mIsInput = true;
|
param.mIsInput = true;
|
||||||
decl.mVarType.fromCType("BMap::BMFile*");
|
param.mVarType.fromCType("BMap::BMFile*");
|
||||||
mCurrentFct.mFctParams.add(decl);
|
mCurrentFct.mFctParams.add(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exitFctArgMeshTransDecl(ExpFctsParser.FctArgMeshTransDeclContext ctx) {
|
public void exitFctArgMeshTransDecl(ExpFctsParser.FctArgMeshTransDeclContext ctx) {
|
||||||
ExpFctParamDecl decl = new ExpFctParamDecl();
|
ExpFctsHelper.ExpFctParam param = new ExpFctsHelper.ExpFctParam();
|
||||||
decl.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
param.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
||||||
decl.mVarDesc = "The pointer to corresponding BMMeshTransition.";
|
param.mVarDesc = "The pointer to corresponding BMMeshTransition.";
|
||||||
decl.mIsInput = true;
|
param.mIsInput = true;
|
||||||
decl.mVarType.fromCType("BMap::BMMeshTransition*");
|
param.mVarType.fromCType("BMap::BMMeshTransition*");
|
||||||
mCurrentFct.mFctParams.add(decl);
|
mCurrentFct.mFctParams.add(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exitFctArgObjDecl(ExpFctsParser.FctArgObjDeclContext ctx) {
|
public void exitFctArgObjDecl(ExpFctsParser.FctArgObjDeclContext ctx) {
|
||||||
ExpFctParamDecl first_decl = new ExpFctParamDecl();
|
ExpFctsHelper.ExpFctParam firstParam = new ExpFctsHelper.ExpFctParam();
|
||||||
first_decl.mVarName = ctx.EXPFCTS_IDENTIFIER(0).getText();
|
firstParam.mVarName = ctx.EXPFCTS_IDENTIFIER(0).getText();
|
||||||
first_decl.mVarDesc = "The pointer to corresponding BMFile.";
|
firstParam.mVarDesc = "The pointer to corresponding BMFile.";
|
||||||
first_decl.mIsInput = true;
|
firstParam.mIsInput = true;
|
||||||
first_decl.mVarType.fromCType("BMap::BMFile*");
|
firstParam.mVarType.fromCType("BMap::BMFile*");
|
||||||
mCurrentFct.mFctParams.add(first_decl);
|
mCurrentFct.mFctParams.add(firstParam);
|
||||||
|
|
||||||
ExpFctParamDecl second_decl = new ExpFctParamDecl();
|
ExpFctsHelper.ExpFctParam secondParam = new ExpFctsHelper.ExpFctParam();
|
||||||
second_decl.mVarName = ctx.EXPFCTS_IDENTIFIER(1).getText();
|
secondParam.mVarName = ctx.EXPFCTS_IDENTIFIER(1).getText();
|
||||||
second_decl.mVarDesc = "The CKID of object you accessing.";
|
secondParam.mVarDesc = "The CKID of object you accessing.";
|
||||||
second_decl.mIsInput = true;
|
secondParam.mIsInput = true;
|
||||||
second_decl.mVarType.fromCType("LibCmo::CK2::CK_ID");
|
secondParam.mVarType.fromCType("LibCmo::CK2::CK_ID");
|
||||||
mCurrentFct.mFctParams.add(second_decl);
|
mCurrentFct.mFctParams.add(secondParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enterFctArgParamIn(ExpFctsParser.FctArgParamInContext ctx) {
|
public void enterFctArgParamIn(ExpFctsParser.FctArgParamInContext ctx) {
|
||||||
mCurrentParam = new ExpFctParamDecl();
|
mCurrentParam = new ExpFctsHelper.ExpFctParam();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -98,7 +94,7 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enterFctArgParamOut(ExpFctsParser.FctArgParamOutContext ctx) {
|
public void enterFctArgParamOut(ExpFctsParser.FctArgParamOutContext ctx) {
|
||||||
mCurrentParam = new ExpFctParamDecl();
|
mCurrentParam = new ExpFctsHelper.ExpFctParam();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.util.Vector;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
@@ -7,7 +9,7 @@ import com.google.gson.GsonBuilder;
|
|||||||
|
|
||||||
public class JsonWriter {
|
public class JsonWriter {
|
||||||
|
|
||||||
private static JsonObject writeVariableType(VariableType vt) {
|
private static JsonObject writeVariableType(ExpFctsHelper.VariableType vt) {
|
||||||
JsonObject data = new JsonObject();
|
JsonObject data = new JsonObject();
|
||||||
|
|
||||||
JsonArray hierarchy = new JsonArray();
|
JsonArray hierarchy = new JsonArray();
|
||||||
@@ -20,41 +22,44 @@ public class JsonWriter {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static JsonObject writeExpFctParamDecl(ExpFctParamDecl paramdecl) {
|
private static JsonObject writeExpFctParam(ExpFctsHelper.ExpFctParam param) {
|
||||||
JsonObject data = new JsonObject();
|
JsonObject data = new JsonObject();
|
||||||
data.addProperty("name", paramdecl.mVarName);
|
data.addProperty("name", param.mVarName);
|
||||||
data.addProperty("is_input", paramdecl.mIsInput);
|
data.addProperty("is_input", param.mIsInput);
|
||||||
data.addProperty("desc", paramdecl.mVarDesc);
|
data.addProperty("desc", param.mVarDesc);
|
||||||
data.add("type", writeVariableType(paramdecl.mVarType));
|
data.add("type", writeVariableType(param.mVarType));
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static JsonObject writeExpFctDecl(ExpFctDecl fctdecl) {
|
private static JsonObject writeExpFct(ExpFctsHelper.ExpFct fct) {
|
||||||
JsonObject data = new JsonObject();
|
JsonObject data = new JsonObject();
|
||||||
data.addProperty("name", fctdecl.mFctName);
|
data.addProperty("name", fct.mFctName);
|
||||||
data.add("return", writeVariableType(fctdecl.mFctRetType));
|
data.add("return", writeVariableType(fct.mFctRetType));
|
||||||
|
|
||||||
JsonArray paramlist = new JsonArray();
|
JsonArray paramList = new JsonArray();
|
||||||
for (ExpFctParamDecl paramdecl : fctdecl.mFctParams) {
|
for (ExpFctsHelper.ExpFctParam param : fct.mFctParams) {
|
||||||
paramlist.add(writeExpFctParamDecl(paramdecl));
|
paramList.add(writeExpFctParam(param));
|
||||||
}
|
}
|
||||||
data.add("params", paramlist);
|
data.add("params", paramList);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeJson(Vector<ExpFctDecl> data) throws Exception {
|
private static JsonArray writeExpFctCollection(ExpFctsHelper.ExpFctCollection fctCollection) {
|
||||||
OutputStreamWriter writer = CommonHelper.openWriter("dest/BMExports.json");
|
JsonArray data = new JsonArray();
|
||||||
//Gson gson_instance = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
for (ExpFctsHelper.ExpFct fct : fctCollection.mFcts) {
|
||||||
Gson gson_instance = new GsonBuilder().disableHtmlEscaping().create();
|
data.add(writeExpFct(fct));
|
||||||
|
|
||||||
JsonArray fcts = new JsonArray();
|
|
||||||
for (ExpFctDecl fctdecl : data) {
|
|
||||||
fcts.add(writeExpFctDecl(fctdecl));
|
|
||||||
}
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
writer.write(gson_instance.toJson(fcts));
|
public static void writeJson(ExpFctsHelper.ExpFctCollection data) throws Exception {
|
||||||
|
FileOutputStream fs = new FileOutputStream(CommonHelper.getOutputFilePath("BMExports.json"));
|
||||||
|
OutputStreamWriter writer = new OutputStreamWriter(fs, StandardCharsets.UTF_8);
|
||||||
|
//Gson gsonInstance = new GsonBuilder().serializeNulls().setPrettyPrinting().disableHtmlEscaping().create();
|
||||||
|
Gson gsonInstance = new GsonBuilder().serializeNulls().disableHtmlEscaping().create();
|
||||||
|
writer.write(gsonInstance.toJson(writeExpFctCollection(data)));
|
||||||
writer.close();
|
writer.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ public class MainRunner {
|
|||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
// get interface structure
|
// get interface structure
|
||||||
FileInputStream fs = new FileInputStream("dest/BMExports.hpp");
|
FileInputStream fs = new FileInputStream(CommonHelper.getInputFilePath("BMExports.hpp"));
|
||||||
CharStream antlrfs = CharStreams.fromStream(fs, StandardCharsets.UTF_8);
|
CharStream antlrStream = CharStreams.fromStream(fs, StandardCharsets.UTF_8);
|
||||||
ExpFctsLexer lexer = new ExpFctsLexer(antlrfs);
|
ExpFctsLexer lexer = new ExpFctsLexer(antlrStream);
|
||||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||||
ExpFctsParser parser = new ExpFctsParser(tokens);
|
ExpFctsParser parser = new ExpFctsParser(tokens);
|
||||||
|
|
||||||
@@ -23,12 +23,10 @@ public class MainRunner {
|
|||||||
fs.close();
|
fs.close();
|
||||||
|
|
||||||
// get data and write them
|
// get data and write them
|
||||||
Vector<ExpFctDecl> result = worker.getResult();
|
ExpFctsHelper.ExpFctCollection result = worker.getResult();
|
||||||
PythonWriter.writePythonCode(result);
|
|
||||||
CSharpWriter.writeCSharpCode(result);
|
|
||||||
JsonWriter.writeJson(result);
|
JsonWriter.writeJson(result);
|
||||||
|
|
||||||
// print message.
|
// print message.
|
||||||
System.out.println("DONE!");
|
System.out.println("Done");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,96 +0,0 @@
|
|||||||
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("CKWORD", "CKWORD");
|
|
||||||
cache.put("CKINT", "CKINT");
|
|
||||||
cache.put("bool", "bool");
|
|
||||||
cache.put("CKFLOAT", "CKFLOAT");
|
|
||||||
cache.put("CKBYTE", "CKBYTE");
|
|
||||||
cache.put("CK_ID", "CKID");
|
|
||||||
cache.put("NakedOutputCallback", "callback");
|
|
||||||
cache.put("BMFile", "void");
|
|
||||||
cache.put("BMMeshTransition", "void");
|
|
||||||
cache.put("VxVector3", "VxVector3");
|
|
||||||
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("VXLIGHT_TYPE", "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");
|
|
||||||
cache.put("VXMESH_LITMODE", "enum");
|
|
||||||
return Collections.unmodifiableMap(cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String pythonTypeGetter(ExpFctParamDecl paramdecl) throws IllegalArgumentException {
|
|
||||||
VariableType vt = paramdecl.mVarType;
|
|
||||||
if (!paramdecl.mIsInput) {
|
|
||||||
vt = vt.getPointerOfThis();
|
|
||||||
}
|
|
||||||
|
|
||||||
// create string builder for build final type string
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
// add type prefix
|
|
||||||
sb.append("bm_");
|
|
||||||
// try getting cpp type from base type
|
|
||||||
String cpp_type = g_CppTypeMap.get(vt.getBaseType());
|
|
||||||
if (cpp_type == null) {
|
|
||||||
throw new IllegalArgumentException("Unexpected type: " + vt.toCType());
|
|
||||||
}
|
|
||||||
// assign cpp type
|
|
||||||
sb.append(cpp_type);
|
|
||||||
// add pointer suffix
|
|
||||||
if (vt.isPointer()) {
|
|
||||||
sb.append("_");
|
|
||||||
sb.append(String.join("", Collections.nCopies(vt.getPointerLevel(), "p")));
|
|
||||||
}
|
|
||||||
// return built type string.
|
|
||||||
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 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
import java.util.Collections;
|
|
||||||
import java.util.Vector;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The class represent the type of each parameters and function return value.
|
|
||||||
*/
|
|
||||||
public class VariableType {
|
|
||||||
/**
|
|
||||||
* The base type of this variable removing all ending stars (remove all pointer
|
|
||||||
* levels) Each item in this a part of namespace and the last one must be the
|
|
||||||
* type itself (without any namespace restriction). If no namespace restriction
|
|
||||||
* for this type, this Vector will only have one item.
|
|
||||||
* <p>
|
|
||||||
* For end user, it is enough that knowing the last item is type itself.
|
|
||||||
*/
|
|
||||||
private Vector<String> mBaseType;
|
|
||||||
/**
|
|
||||||
* The pointer level of this type. It is equal to the count of trailing star of
|
|
||||||
* this field in C style representation.
|
|
||||||
*/
|
|
||||||
private int mPointerLevel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct an empty varible type. This is commonly used constructor.
|
|
||||||
*/
|
|
||||||
public VariableType() {
|
|
||||||
mBaseType = new Vector<String>();
|
|
||||||
mPointerLevel = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The constructor used for cloning self. This constructor is only can be used
|
|
||||||
* by self.
|
|
||||||
*
|
|
||||||
* @param base_type The hierarchy of the variable type.
|
|
||||||
* @param pointer_level The pointer level of new created variable type.
|
|
||||||
*/
|
|
||||||
private VariableType(Vector<String> base_type, int pointer_level) {
|
|
||||||
mBaseType = (Vector<String>) base_type.clone();
|
|
||||||
mPointerLevel = pointer_level;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set this variable type with a type string in C/C++ style. For example
|
|
||||||
* "NSTest::NSTest2::MyType**".
|
|
||||||
*
|
|
||||||
* @param ctype The type string in C/C++ style.
|
|
||||||
*/
|
|
||||||
public void fromCType(String ctype) {
|
|
||||||
if (ctype.isEmpty())
|
|
||||||
throw new IllegalArgumentException("empty string can not be parsed.");
|
|
||||||
|
|
||||||
// get pointer part and name part
|
|
||||||
int len = ctype.length();
|
|
||||||
int star_pos = ctype.indexOf('*');
|
|
||||||
String namepart;
|
|
||||||
if (star_pos == -1) {
|
|
||||||
// no star
|
|
||||||
namepart = ctype;
|
|
||||||
mPointerLevel = 0;
|
|
||||||
} else {
|
|
||||||
// has star
|
|
||||||
if (star_pos == 0)
|
|
||||||
throw new IllegalArgumentException("base type not found.");
|
|
||||||
namepart = ctype.substring(0, star_pos);
|
|
||||||
mPointerLevel = len - star_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
// resolve name part
|
|
||||||
mBaseType.clear();
|
|
||||||
for (String item : namepart.split("::")) {
|
|
||||||
mBaseType.add(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build a type string represented by this variable type in C/C++ style.
|
|
||||||
*
|
|
||||||
* @return The type string in C/C++ style.
|
|
||||||
*/
|
|
||||||
public String toCType() {
|
|
||||||
return mBaseType.stream().collect(Collectors.joining("::"))
|
|
||||||
+ String.join("", Collections.nCopies(mPointerLevel, "*"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the base type of this variable type without any namespace. It just simply
|
|
||||||
* get the last entry in type hierarchy.
|
|
||||||
*
|
|
||||||
* @return The base type string without namespace prefix.
|
|
||||||
*/
|
|
||||||
public String getBaseType() {
|
|
||||||
return mBaseType.lastElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether this variable type is a pointer. This function just check
|
|
||||||
* whether the pointer level of this variavle type is zero.
|
|
||||||
*
|
|
||||||
* @return True if it is pointer, otherwise false.
|
|
||||||
*/
|
|
||||||
public boolean isPointer() {
|
|
||||||
return mPointerLevel != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the pointer level of this variable type. You can simply assume the
|
|
||||||
* pointer level is equal to the count of trailing star.
|
|
||||||
*
|
|
||||||
* @return The pointer level integer. Zero means that this type is not a
|
|
||||||
* pointer.
|
|
||||||
*/
|
|
||||||
public int getPointerLevel() {
|
|
||||||
return mPointerLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the clone of the type hierarchy of this variable type.
|
|
||||||
* <p>
|
|
||||||
* It is rarely used. This only should be used when you need the namespace
|
|
||||||
* hierarchy of this variable type.
|
|
||||||
*
|
|
||||||
* @return The clone of current variable type hierarchy.
|
|
||||||
*/
|
|
||||||
public Vector<String> getBaseTypeHierarchy() {
|
|
||||||
return (Vector<String>) mBaseType.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether this type is a valid one. It actually check whether type
|
|
||||||
* hierarchy include at least one entry.
|
|
||||||
*
|
|
||||||
* @return True if no problem of this type, otherwise false.
|
|
||||||
*/
|
|
||||||
public boolean isValid() {
|
|
||||||
return mBaseType.size() != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a new created variable type which is the pointer of this variable
|
|
||||||
* type.
|
|
||||||
* <p>
|
|
||||||
* In internal implementation, it just create a clone of current variable type
|
|
||||||
* with the increase of pointer level by 1.
|
|
||||||
*
|
|
||||||
* @return The new created pointer type of this variable type.
|
|
||||||
*/
|
|
||||||
public VariableType getPointerOfThis() {
|
|
||||||
return new VariableType(mBaseType, mPointerLevel + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -53,7 +53,7 @@ public class JsonWriter {
|
|||||||
|
|
||||||
private static void writeJson(String filename, EnumsHelper.BEnumCollection enumCollection) throws Exception {
|
private static void writeJson(String filename, EnumsHelper.BEnumCollection enumCollection) throws Exception {
|
||||||
OutputStreamWriter writer = CommonHelper.openOutputFile(filename);
|
OutputStreamWriter writer = CommonHelper.openOutputFile(filename);
|
||||||
//Gson gsonInstance = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
//Gson gsonInstance = new GsonBuilder().serializeNulls().setPrettyPrinting().disableHtmlEscaping().create();
|
||||||
Gson gsonInstance = new GsonBuilder().serializeNulls().disableHtmlEscaping().create();
|
Gson gsonInstance = new GsonBuilder().serializeNulls().disableHtmlEscaping().create();
|
||||||
writer.write(gsonInstance.toJson(writeBEnumCollection(enumCollection)));
|
writer.write(gsonInstance.toJson(writeBEnumCollection(enumCollection)));
|
||||||
writer.close();
|
writer.close();
|
||||||
|
|||||||
@@ -41,8 +41,6 @@ Following these steps to prepare stb:
|
|||||||
|
|
||||||
### zlib
|
### zlib
|
||||||
|
|
||||||
If you are in Windows, you should download zlib source code and build it with given Visual Studio solution files. The final file we needed is `zlibwapi.dll` with `ZlibDllRelease` build type.
|
|
||||||
|
|
||||||
If you are running on non-Windows system. You usually do not need to do anything. Because zlib development environment may be configured by your package manager correctly.
|
If you are running on non-Windows system. You usually do not need to do anything. Because zlib development environment may be configured by your package manager correctly.
|
||||||
|
|
||||||
If you are in Windows, or in Linux but want to use specific zlib version due to various reasons, following these steps to prepare zlib:
|
If you are in Windows, or in Linux but want to use specific zlib version due to various reasons, following these steps to prepare zlib:
|
||||||
@@ -89,7 +87,7 @@ If you are coming from my another project [BallanceBlenderPlugin](https://github
|
|||||||
It may be useful for the developer who firstly use this project in their own projects.
|
It may be useful for the developer who firstly use this project in their own projects.
|
||||||
Please note that generated documentation is different in different platforms.
|
Please note that generated documentation is different in different platforms.
|
||||||
* `YYCCommonplace_ROOT`: Set to the install path of YYCCommonplace.
|
* `YYCCommonplace_ROOT`: Set to the install path of YYCCommonplace.
|
||||||
* `stb_ROOT`: Set to the root directory of stb.
|
* `STB_ROOT`: Set to the root directory of stb.
|
||||||
* `ZLIB_ROOT`: Set to the install path of zlib.
|
* `ZLIB_ROOT`: Set to the install path of zlib.
|
||||||
If you are using zlib which is not build by your own, you usually do not need specify this variable.
|
If you are using zlib which is not build by your own, you usually do not need specify this variable.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user