Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Tilengine on Java
#1
Hello! Is the latest version of Tilengine compatible with Java? Can I use the newer functions if I use the bindings? Thanks for the answer.
Reply
#2
Hi!
As any native system C library, you can use Tilengine from any language that suports interfacing with system libraries. Java requires a JNI binding to do this. I developed one at the beginning, to demonstrate Tilengine inside a Java Applet, but it's largely outdated and unmaintained nowadays. However, should the JNI plugin be updated, you could use Tilengine without issue.

Here's the binding:
https://github.com/megamarc/JTilengine
Reply
#3
Thanks! So if I put the latest Tilengine DLL library, I can use the newer features of the library?
Shouldn't I add the new functions to this file? https://github.com/megamarc/JTilengine/b...ngineJNI.c ?
Reply
#4
Hi!
Provided samples should work with old JNI, as they don't use newer features of the engine.
However, to access these newer features, yes, TilengineJNI.c AND Tilengine.java should be updated with required functions, currently not present.
Reply
#5
(12-03-2020, 01:27 AM)megamarc Wrote: Hi!
Provided samples should work with old JNI, as they don't use newer features of the engine.
However, to access these newer features, yes, TilengineJNI.c  AND Tilengine.java should be updated with required functions, currently not present.

I don't know C very well ans I have basic knowledge to Java (but I know OOP). Can I update it easily ?
Reply
#6
Hi,
Doing a binding is more a tedious work than a challenging one. It requires repetitive work done by hand that is error-prone, because you have to map every function and data structure, keeping names, parameter ordering and type. However you need a moderate experience in both languages, as you're interfacing between them. Definitely not a beginner task.

You can figure out the mechanism by examining a working example -in this case TilengineJNI.c and Tilengine.java- and learning about JNI, for example here (but there are many tutorials out there):
https://www.baeldung.com/jni
Reply
#7
I'll take a look to theses exemples and give it a try. By the way, are the bindings stuck to an old version or will they updated some day? Because they can be useful for people that use others languages than C / C++.
Reply
#8
Hi,

The bindings that are updated more are C# (for compiled, managed language) and Python (for interpreted, scripted language). Other bindings are contributed by other people, or are a proof of concept demonstrating the integration of Tilengine. Unitil now nobody has shown interest on the Java binding, so I'm afraid that keeping it alive is not a priority at this moment.

Most people is using the library directly in C.
Reply
#9
(12-04-2020, 04:15 PM)megamarc Wrote: Hi,

The bindings that are updated more are C# (for compiled, managed language) and Python (for interpreted, scripted language). Other bindings are contributed by other people, or are a proof of concept demonstrating the integration of Tilengine. Unitil now nobody has shown interest on the Java binding, so I'm afraid that keeping it alive is not a priority at this moment.

Most people is using the library directly in C.

Thanks anyway! I'll try to learn C and use it in pure C or updating the Java binding.
I took a look to this binding too. The most of the binding is pretty repeatitive and easy to understand. But there is some parts I don't understand well.
For exemple why this part only has 2 lines of code

Code:
JNIEXPORT jboolean JNICALL Java_Tilengine_SetBGPalette (JNIEnv* env, jobject thisobj, jint palette)
{
return TLN_SetBGPalette ((TLN_Palette)palette);
}

and this part has more code?

Code:
JNIEXPORT void JNICALL Java_Tilengine_SetRasterCallback (JNIEnv* env, jobject thisobj, jobject obj, jstring methodname)
{
/* release previous */
TLN_SetRasterCallback (NULL);
if (callback.obj)
(*env)->DeleteGlobalRef (env, callback.obj);
callback.obj = NULL;

/* store new */
if (obj && methodname)
{
const char* strmethod;
jclass cls;

strmethod = (*env)->GetStringUTFChars (env, methodname, NULL);
cls = (*env)->GetObjectClass (env, obj);
callback.env = env;
callback.obj = (*env)->NewGlobalRef (env, obj);
callback.method = (*env)->GetMethodID (env, cls, strmethod, "(I)V");
(*env)->ReleaseStringUTFChars (env, methodname, strmethod);
(*env)->DeleteLocalRef (env, obj);
TLN_SetRasterCallback (raster_callback);
}
}
Reply
#10
You picked two extreme cases Smile

In order to communicate, sometimes the binding must do data conversion before passing the arguments. In other cases, it must create and destroy elements that are needed on the Java side.

The first example is the simplest one: no conversion of any data is needed, just call the function. Done!

The second one manages the callback, the Java function that needs to be called from the native library. Callbacks are always the trickiest part of a binding. In thsi case, it requires destroying a previously allocated Java object, and creating a new one. In addition, it gets a text string, that needs explicit conversion because C and Java don't represent strings internally in the same way. That's why this function is the most complex of all.
Reply


Forum Jump:


Users browsing this thread: 5 Guest(s)