Java AI Interface for Spring
Moderators: hoijui, Moderators
Java AI Interface for Spring
Hello,
I though it would be nice for Java-only devs interested in Spring and AI, like me.
So far i succeeded invoking the JVM from a TestAI dll from inside spring.
(was in this thread so far: http://spring.clan-sy.com/phpbb/viewtopic.php?t=12194)
I tried to find a good utility to help me creating the interface-code.
I looked at some utilities/libs:
- JNI
- JNA
- SWIG (mentioned by AF once)
- GlueGen
- JNative
- JNI++
- UNO
- JNIEasy
- JACE
- NoodleGlue
After about 2 days reading, i though SWIG would be best.
As it is free, serves both ways (C++ -> Java and Java -> C++), and it would work after changes still (one just had to let swig generate the code again).
I looked at the interface code a bit, but i though i will ask you first about what is needed for the AI (for my interface).
In the end, i imagine there to be one Java class (i call it JGlobalAI), that will be fed by spring through the smae set of methods there are in IGlobalAI and its superclasses.
Then this calss will have to be able to query some things from spring through the following classes/files:
IGlobalAICallback.h
IAICallback.h
IGlobalAI.h
IAICheats.h
What other classes would have to be accessible from Java?
I guess weapon and unit or something.
Though i ask, as you should knwo it, and it would take me ... quite some time to find it out.
I though it would be nice for Java-only devs interested in Spring and AI, like me.
So far i succeeded invoking the JVM from a TestAI dll from inside spring.
(was in this thread so far: http://spring.clan-sy.com/phpbb/viewtopic.php?t=12194)
I tried to find a good utility to help me creating the interface-code.
I looked at some utilities/libs:
- JNI
- JNA
- SWIG (mentioned by AF once)
- GlueGen
- JNative
- JNI++
- UNO
- JNIEasy
- JACE
- NoodleGlue
After about 2 days reading, i though SWIG would be best.
As it is free, serves both ways (C++ -> Java and Java -> C++), and it would work after changes still (one just had to let swig generate the code again).
I looked at the interface code a bit, but i though i will ask you first about what is needed for the AI (for my interface).
In the end, i imagine there to be one Java class (i call it JGlobalAI), that will be fed by spring through the smae set of methods there are in IGlobalAI and its superclasses.
Then this calss will have to be able to query some things from spring through the following classes/files:
IGlobalAICallback.h
IAICallback.h
IGlobalAI.h
IAICheats.h
What other classes would have to be accessible from Java?
I guess weapon and unit or something.
Though i ask, as you should knwo it, and it would take me ... quite some time to find it out.
Simply put, any non-POD types that are
transferred across the .so/.dll boundary
would need Java AI-side representations
(so at the very least UnitDef*, WeaponDef*,
Command*, float3*, CCommandQueue*,
CommandDescription, and maybe a few
others). Most of those should carry over
with not too much effort, but beware.
transferred across the .so/.dll boundary
would need Java AI-side representations
(so at the very least UnitDef*, WeaponDef*,
Command*, float3*, CCommandQueue*,
CommandDescription, and maybe a few
others). Most of those should carry over
with not too much effort, but beware.

Pointers to these are returned by some of the interface functions:
Command
CommandDescription
CCommandQue
FeatureDef
float3
UnitDef
WeaponDef
There are also some helper structs, but maybe you want to handle these another way:
UnitResourceInfo
PointMarker
LineMarker
AIHCAddMapPoint
AIHCAddMapLine
AIHCRemoveMapPoint
Also I noticed std::vector is sometimes used, but possibly SWIG handles that correctly already.
Command
CommandDescription
CCommandQue
FeatureDef
float3
UnitDef
WeaponDef
There are also some helper structs, but maybe you want to handle these another way:
UnitResourceInfo
PointMarker
LineMarker
AIHCAddMapPoint
AIHCAddMapLine
AIHCRemoveMapPoint
Also I noticed std::vector is sometimes used, but possibly SWIG handles that correctly already.
thanks 
yes, SWIG handles std::vector.
thanks for the list of classes and structs
SWIG has support for structs.. will look at it when i get to that.
will write again when i need help or when i got some further

yes, SWIG handles std::vector.
thanks for the list of classes and structs

SWIG has support for structs.. will look at it when i get to that.
(with the words of Mr. Burns:) excellent! :DBigHead wrote:for the sake of my personal life I hope you'll fail (I wouldn't be able to resist the temptation to start my own AI)
will write again when i need help or when i got some further
Personally I find SWIG documentation quite poor, especially how to deal with situations that are not totally standard (which you will encounter at some point). I use it for an upspring lua binding, but there are certain memory problems that are not even solvable for lua.
Java problably has similar problems, and because of all the alternative binding solutions you mentioned, its probably better to try those first.
Java problably has similar problems, and because of all the alternative binding solutions you mentioned, its probably better to try those first.
hmm..
i already encountered some problems (which probably are solvable).
but all the other bindings are worse, sadly :/
some are outdated (latest version from 2003, development ceased), most support only Java -> C++, not the other way, some are too complicated, some are not free, and some other issues.
SWIG seems to be the only one (possibly) capable of the job, with (possibly) not an immense investment of time. :/
i already encountered some problems (which probably are solvable).
but all the other bindings are worse, sadly :/
some are outdated (latest version from 2003, development ceased), most support only Java -> C++, not the other way, some are too complicated, some are not free, and some other issues.
SWIG seems to be the only one (possibly) capable of the job, with (possibly) not an immense investment of time. :/
I believe with JNI you would create a C/C++ dll AI and inside it you would spawn a Java virtual machine then using the JNI APIs to export c++ classes into the java runtime aswell as spawning the initial java class inside the VM that the AI would run with.
JNA isn't usable for this, JNA is used to allow java programs to make direct dll calls without the dll needing a JNI wrapper function or a wrapper library. Its not something you can use to embed java into C++. There may be more to it though I cant really say.
JNI seems to be the most appropriate. I have some JNI and JNA experience calling across dll boundaries from java although I've never handled it the other way around as you're doing.
I would be very interested in developing using java AI, as it means I would no longer have the mingw32/VS2005 c++ issues, and I'd be able to use netbeans, and I'd have a much prettier debugger, much nicer threading support, and a very pretty profiler all for free.
JNA isn't usable for this, JNA is used to allow java programs to make direct dll calls without the dll needing a JNI wrapper function or a wrapper library. Its not something you can use to embed java into C++. There may be more to it though I cant really say.
JNI seems to be the most appropriate. I have some JNI and JNA experience calling across dll boundaries from java although I've never handled it the other way around as you're doing.
I would be very interested in developing using java AI, as it means I would no longer have the mingw32/VS2005 c++ issues, and I'd be able to use netbeans, and I'd have a much prettier debugger, much nicer threading support, and a very pretty profiler all for free.
i AM netbeans! 
yeah.. i came to the same conclusion about JNA as you, thats why i didn't use it.
When using SWIG with/for Java, al it does is actually generate code using JNI.
It can do so both ways:
using the "normal" JNI to call C++ stuff from Java, and using the JNI Invocation API to call Java stuff from within C++; in SWIG language, they talk about Directors when going from native to the other language (Java in this case).
As i think of it right now, i want to do the following:
Generate SWIG proxy classes for:
Classes
IGlobalAICallback
IAICallback
IGlobalAI
IAICheats
UnitDef
WeaponDef
float3
Command
CommandDescription
CCommandQue
FeatureDef
.. and for
structs
ChangeTeamEvent
WeaponFireEvent
PlayerCommandEvent
SeismicPingEvent
UnitResourceInfo
PointMarker
LineMarker
AIHCAddMapPoint
AIHCAddMapLine
AIHCRemoveMapPoint
and additionally let SWIG create a Director for IGlobalAI.
I would then write a small IGlobalAIFactory class in Java, which reads a kind of "config file" containing the class name of the real pure Java AI implementation (a class that extends the SWIG generated IGlobalAI class).
from the dll i just had to create a JVM with the JNI invocation API (this is what i tested already), and then load and instantiate the Factory class, let it create the IGlobalAI class for me which i would be able to use like a C++ implementation then.
Sounds like little work, but well... as jcnossen said, there will be some problems.
btw...
in the list of classes listed above, there seems to be nothing representing the map (at least from the name).
is it possible to get map information through one of these classes somehow, or is one still missing in the list?

yeah.. i came to the same conclusion about JNA as you, thats why i didn't use it.
When using SWIG with/for Java, al it does is actually generate code using JNI.
It can do so both ways:
using the "normal" JNI to call C++ stuff from Java, and using the JNI Invocation API to call Java stuff from within C++; in SWIG language, they talk about Directors when going from native to the other language (Java in this case).
As i think of it right now, i want to do the following:
Generate SWIG proxy classes for:
Classes
IGlobalAICallback
IAICallback
IGlobalAI
IAICheats
UnitDef
WeaponDef
float3
Command
CommandDescription
CCommandQue
FeatureDef
.. and for
structs
ChangeTeamEvent
WeaponFireEvent
PlayerCommandEvent
SeismicPingEvent
UnitResourceInfo
PointMarker
LineMarker
AIHCAddMapPoint
AIHCAddMapLine
AIHCRemoveMapPoint
and additionally let SWIG create a Director for IGlobalAI.
I would then write a small IGlobalAIFactory class in Java, which reads a kind of "config file" containing the class name of the real pure Java AI implementation (a class that extends the SWIG generated IGlobalAI class).
from the dll i just had to create a JVM with the JNI invocation API (this is what i tested already), and then load and instantiate the Factory class, let it create the IGlobalAI class for me which i would be able to use like a C++ implementation then.
Sounds like little work, but well... as jcnossen said, there will be some problems.
btw...
in the list of classes listed above, there seems to be nothing representing the map (at least from the name).
is it possible to get map information through one of these classes somehow, or is one still missing in the list?
IAICallback
Map data takes the form of float arrys of various resolutions representing metalmap and height field. There's also callbacks for map size, biggest height, and smallest height.
You may also want to put krogoths mex spot finder class in the C++ side and add a java API for it. Some things work best in C++.
Map data takes the form of float arrys of various resolutions representing metalmap and height field. There's also callbacks for map size, biggest height, and smallest height.
You may also want to put krogoths mex spot finder class in the C++ side and add a java API for it. Some things work best in C++.
@hoijui its here http://www.fileuniverse.com/?p=show&a=it&id=3152 good luck with this project!
an problem:
as much as i got, one can not find out the filename from an ifstream.
so it is not easily possible to use the Load and Save functions from the IGlobalAI interface in Java.
is it possible that we change those functions to supply the filenames instead of the streams? or would it cause too much problems?
well.. i guess i go on trying to get the rest working first
as much as i got, one can not find out the filename from an ifstream.
so it is not easily possible to use the Load and Save functions from the IGlobalAI interface in Java.
is it possible that we change those functions to supply the filenames instead of the streams? or would it cause too much problems?
well.. i guess i go on trying to get the rest working first

GuiSoundSet::Data, UnitDef::UnitDefWeapon and UnitDef::SoundStruct from UnitDef.h wont be available from Java, as SWIG doesn't support nested structs.
to me, it looks like they weren't of interest to an AI anyway.
I get a syntax error from swig at the following code in Command.h:
when i change it to this:
(added 2x ';') the error is gone.
should i upload this change to the SVN trunk?
to me, it looks like they weren't of interest to an AI anyway.
I get a syntax error from swig at the following code in Command.h:
Code: Select all
struct CommandDescription {
CR_DECLARE_STRUCT(CommandDescription)
CommandDescription()
: showUnique(false),
onlyKey(false),
onlyTexture(false),
disabled(false) {}
Code: Select all
struct CommandDescription {
CR_DECLARE_STRUCT(CommandDescription);
CommandDescription()
: showUnique(false),
onlyKey(false),
onlyTexture(false),
disabled(false) {};
should i upload this change to the SVN trunk?