SWIG
|
LiquidFun JNI is a project that contains JNI (Java Native Interface) bindings for LiquidFun. SWIG generates these bindings, and is required for this project.
This document describes how to set up a Java project to use LiquidFun. It comprises the following sections:
A subset of LiquidFun API has been exposed to SWIG. The SWIG interface files are all of the .swig file type. They are located in Box2D/swig/java
. For convenience, the file structure mirrors the file structure of Box2D. Some LiquidFun header files are not directly pulled into SWIG, which allows users to pull in only the functionality they need. This reducing the number of JNI bindings produced.
Current SWIG version tested: 2.0.11 To learn more about SWIG, and to install it, please visit their website.
In addition, on Linux, you have to install PCRE, as SWIG depends on it:
apt-get install libpcre3-dev
Set up an environment variable to point to your swig installation. One way to do this (on Linux / OSX / Cygwin) is to add the following to your ~/.bashrc
file:
export SWIG_BIN=$("which" swig)
Include the library in your jni/Android.mk
file as a shared library:
LOCAL_SHARED_LIBRARIES := libliquidfun_jni include $(BUILD_SHARED_LIBRARY) $(call import-add-path,/path/to/liquidfun/) $(call import-module,Box2D/swig/jni)
This will invoke SWIG, and build the C++ components of the library.
Next, launch Eclipse, and perform the following steps:
Box2D/swig/gen
folder, and give it a name.You should now be able to build and run your application using LiquidFun. All generated Java files reside in Liquidfun/Box2D/swig/gen
. You can refer to these files to confirm class, method, and other names.
The LiquidFun SWIG interface files pulls in a subset of the LiquidFun API, extends it, and presents it in a way consistent with typical Java style.
JVM (Java Virtual Machine) uses garbage collection to clean up memory, which is very different from the user-managed memory model in C++. The following points are critical in order to facilitate efficient JNI memory management.
The user must use the SWIG-generated delete() method to clean up all LiquidFun objects exposed through SWIG. This is because SWIG-generated (Java) proxy classes–not the JVM–are allocating C++ memory through every new object.
For example:
BodyDef* bodyDef = new BodyDef();
...
`bodyDef.delete();
For a member variable that is a native object:
private World mWorld = new World(0, 0);
...
@Override
protected void finalize() {
mWorld.delete();
}
Because the user has to be conscientious about cleaning up any new objects, directly exposing to Java a C++ function signature like
void SetPosition(const b2Vec2& pos);
will create this method:
void setPosition(Vec2 pos);
This method requires that the user creates Vec2 objects. Since Vec2 objects are native objects, you must clean them up using a delete() method, which can be quite unwieldy when you are initializing large amounts of data.
Instead, use SWIG to extend the interface. Do this by adding a new function to the corresponding SWIG interface file:
extend b2ParticleDef {
void setPosition(float32 x, float32 y) {
$self->position.Set(x, y);
}
};
This file generates the following Java code:
void setPosition(float x, float y);
which allows the user to call the function with primitive types (in this case, floats) directly.