Jump to content

Recommended Posts

the simple ability of doing real-time debugging with breakpoints is a massive aid to scripters who grew tired of using hints and such to trace variables
Not to mention that the SQF VM swallows some errors, which makes debugging a real PITA at times ;P

Share this post


Link to post
Share on other sites

A dev blog on this would be great - especially if it has some sample code in there too. The last time I did proper Java was probably about 12 or so years ago and it was in it's infancy back then. I have forgotten a lot and most of what I remember probably isn't relevant any more!

Also How about a real sample mission making use of Java? Much along the lines of the sample missions you have already done for ToH. I'm sure you must have some hanging around from your development work on it so far!

Share this post


Link to post
Share on other sites

Don't believe it is the place to talk about Maven lol. Well with some code like this into jniscripting.jar just think that Maven will be quite useless regarding Java and ArmA 3:

    public void checkPackageAccess(String s)
   {
       if(s != null)
       {
           if(s.startsWith("sun.reflect"))
               return;
           if(s.startsWith("sun.security.provider"))
               return;
           if(s.startsWith("sun.awt"))
               return;
           if(s.startsWith("com.sun.java.swing"))
               return;
       }
       super.checkPackageAccess(s);
   }

Share this post


Link to post
Share on other sites
Even in A3 it will still undergo development and definitely not have replaced the SQF VM.

Let me rephrase the question - does any use of the jvm depend on the sqf vm?

Right now, the jvm relies on being jcalled to be able to (safely) do anything to the game state.

Does the plans include the ability to use jvms directly without calling it up (perhaps even without explicitly loading it up) with sqf code?

Delving into details, as an example: When it's "stable" will eventhandlers still require using sqf using jcall, to handle an event from java?

Share this post


Link to post
Share on other sites
The source code should be kept separate simply so people are free to choose to take the bits they are interested in and don't get bloat they don't want.

You're really losing me here. How is keeping .java and .class files separate going to help this?

I'll note that I have no experience with java projects bigger than 1 .java file yet, so there's probably something java-specific I'm missing out on.

Ah, but that is SQF-think. In Java it is possible to modify the behaviour of other classes (within limits) without having the source code. Well, you don't actually modify the class you create a new class that "extends" the class you want to modify.

That's a good point, and I've used the general concept plenty in both C++ and Lua.

A couple issues that come to mind immediately.

- Other code in that class calling that function, expecting that "wrong" result. AFAIK java methods are default "virtual" (c++ word) meaning the other super functions will call your version instead. This means that you'll either correct them too, or break them if they expected the wrong result.

- If the class is loaded from another source (e.g. mission vs addon vs anotherAddon) that may update separately, you need some kind of version check that disables your code when the version is different (Is this even possible?), or your fix will break the fixed version.

- If somebody updates to a fixed version later, they must remember to remove the override. 6 months may have passed in the meanwhile.

For the last two, compare to copy-pasting the original code for that function and correcting it appropriately.

Don't get me wrong, I am just playing Devil's Advocate.

You had me fooled for a while there...

Agreed, RVEngine et al needs to be thread safe or we are doomed. Ok, maybe not doomed, but it will certainly be alot more work to write thread safe wrappers around them if they are not.

The problem with these thread safe wrappers is that everyone needs to use the same instance. Including any BIS code, which means BIS will have to supply it.

And it would best be done as a change to RVEngine itself.

And that still doesn't solve the other requirement, that we can only call them while we're being jcalled. Hopefully that requirement will be lifted at some point, though.

But that is the nature of concurrent programming. In fact I would think this to be the expected behaviour. Once a thread is started we have absolutely no control over the order the threads will be executed, or that the thread will even be started before the jCalled function returns.

Exactly. I spelled it out for the sake of context,

1) for those who aren't familiar with the pitfalls of multithreaded programming

2) why I think that hint experiment (which it was a reply to) is unsafe/"incorrect" even if it appeared to work at the time.

To expand on it, all my java thread experiments have crashed. Most have crashed with CTDs leaving nothing in RPT or any dumps. And so far that's all been with a single jcall starting a single background thread.

One did some 149.5k calls to RVEngine.diag_log. I think that crash came when I paused the game.

Now I just need more recruits for the Groovy bandwagon :)

Maybe groovy++. Plain groovy performance is so off the charts I'd feel like censuring any mission or addon that uses groovy code in loops. Then again, I'm from Native-land. We're a peculiar sort.

Plus, I like compiler type-checking.

Share this post


Link to post
Share on other sites
Does a project space at DH make sense to report issues and make feature requests?

It is probably a good idea. I'm compiling a list and will be heading over there soon to open some issues.

Well with some code like this into jniscripting.jar just think that Maven will be quite useless regarding Java and ArmA 3

I'm not sure what is special about that code, but I'm already using Maven... If the code can be compiled then it can be compiled by Eclipse, Ant, Maven, Ivy, Gradle, or whatever build system you want to use. Its all just Java.

A couple issues that come to mind immediately.

And these are exactly the issues that Ivy/Maven/Gradle et al are attempting to solve. Naming and versioning is a "Hard Problem", exactly for the reasons you've pointed out. Java 8 will improve things, but that is still over a year away. In the mean time it is up to the authors to mix and match versions of code that play nicely together.

The problem with these thread safe wrappers is that everyone needs to use the same instance.

I didn't mean to imply that it was a good alternative, just pretty much the only thing we could do if RVEngine wasn't thread safe.

One did some 149.5k calls to RVEngine.diag_log. I think that crash came when I paused the game.

That's a stress test! However, at this point there are so many bugs its hard to tell where the real problems are. I've had the game CTD on the statement if (args[0] instanceof GameObject)...

Maybe groovy++.

I could live with that. I love the Groovy syntax not the performance, and dynamic typing is Groovy's biggest drawback. However, being able to write something like [a,b,c,d].each { doSomething() } becomes addictive. Once people see how much the TOH Java API uses List objects (and often Lists of Lists) they are going to want a better syntax.

Share this post


Link to post
Share on other sites

Would anyone recommend this?:

http://www.codecademy.com

Codecademy is the easiest way to learn how to code. It's interactive, fun, and you can do it with your friends.

JavaScript is a programming language that grew out of a need to add interactivity to web sites within the browser. It has since evolved into an incredibly versatile language that is used for both client-side (within the browser) and server-side (code that serves web pages to users) applications.

Who is going to be our Mr-Murray for Arma3? :D

Share this post


Link to post
Share on other sites

The language itself is not hard to learn. Really, it's a very basic set of tools. What is important is to understand and use all the tools how they should (and not necessarily can) be used.

From a quick look, codeacademy seems to have some kind of goal driven learning. Meaning you have a goal and should use the tools you have to reach it (as in building a chair instead of just working wood). That should be a good start. You just have to understand that javascript is not java (though iirc it can compile to java bytecode).

The next step is good practice and then sometime you will find yourself using the last little intricacy of the language. The art there is to keep it simple and not make your life harder by doing so.

Share this post


Link to post
Share on other sites
The language itself is not hard to learn. Really, it's a very basic set of tools. What is important is to understand and use all the tools how they should (and not necessarily can) be used.

Once the exact details are known, I hope someone can suggest some online learning sources. I think many would be grateful if the learning side is given some consideration. Codecademy was suggested to me and while a good code learning site, probably isn't exactly what we need.

Share this post


Link to post
Share on other sites

Problem is, you can't just learn coding like you learn history. For me coding is a lot about creativity mixed with self discipline and most important: experience.

But you're right, we need to make it easy for starters to get into java. I could imagine working out a little training. I've been coding java since almost 4 years now but gained the most experience in web frameworks. I'm far away from being an expert, but I'd volunteer to teach java as good as I can. Just let me dig up my old exercises from the university :)

Share this post


Link to post
Share on other sites

Just a couple of general API design comments I wanted to make. It is probably too late to do anything about these comments now, but I consider them serious design flaws so I wanted to say something just in case.

1. Generics. The API uses raw Collection objects without specifying what they are collections of. This means the compiler can't do any type checking for us to make sure we are passing the values the API expects. Passing the wrong type results in a CTD.

2. Stop the List madness! Please (please please) do not use Java Lists as a replacement for SQF lists. If you must, use arrays of primitive types, or better yet "unroll" the list contents into separate function parameters.

Consider a typical SQF function:

light setLightColor [0.3, 0.0, 0.0];

In Java this becomes RVEngine.setLightColor(GameObject, List)

List red = new ArrayList();
red.add(new Float(0.3));
red.add(new Float(0.0));
red.add(new Float(0.0));
RVEngine.setLightColor(light, red);

Ok, we would actually write something like:

RVEngine.setLightColor(light, Arrays.asList(0.3f, 0.0f, 0.0f));

But the JVM still has to execute the same sequence of instructions. First it has to create a new list object, then it needs to add three floats to the list, but Java collections can't store primitive types like float, so the JVM has to create a java.lang.Float object for each of the numbers.

That is alot of work for what should be:

RVEngine.setLightColor(light, 0.3, 0, 0);

With the above we don't have to create a bunch of unnecessary objects simply to pass three values to the game engine, the compiler is able to do type checking for us again, and the compiler is able to coerce values when needed (i.e. int to float).

Having said all that, I get the sense that the user facing part of the Java API is machine generated, so I am hoping these are things that might be fixed "relatively" easily. Adding Generics is something that has to be done ASAP as adding it later will break all existing code. Getting rid of Lists can be done over time by overriding methods with their listless counterparts, but it's still code bloat that should go ASAP.

Edited by Slapstick
Fix

Share this post


Link to post
Share on other sites

I'll distill all my observations into a one-liner:

It's basically at the stage of proof-of-concept-that-you-can-load-java-code-and-have-things-happen.

So yeah, that one was definitely machine generated. See also my list of things at page 16 - some of which are absolutely critical.

Share this post


Link to post
Share on other sites
Once the exact details are known, I hope someone can suggest some online learning sources. I think many would be grateful if the learning side is given some consideration. Codecademy was suggested to me and while a good code learning site, probably isn't exactly what we need.

Hello PELHAM,

If you are looking for an online video tutorials you can refer to this link(http://thenewboston.org/tutorials.php) where you can learn more than just Java, and they are all free.

Anyways, if you navigate to the tutorials section and search for the java beginner and start your way from there. You will start learning from the very basic, including how to install the JDK, and eclipse. And as you get comfortable, you move to higher level tutorials. Another very important link you should always refer to is : http://docs.oracle.com/javase/7/docs/api/ .

Good luck, if you have any questions you can send me a PM.

Share this post


Link to post
Share on other sites

Guys you definitely deserve my money more than any other game developers in world.

But please, heavily improve the animations in Arma3, cause in Arma2 it was not good at all and it is very much needed.

Share this post


Link to post
Share on other sites

If somebody want know and learn Java, explore lynda.com ;) he have a good video courses

Share this post


Link to post
Share on other sites

Does anyone know how to use the RVEngine.sleep() function? I've tried it in the body of the main static method called by jCall, and also as a regular method in a class instantiated by the main static method called by jCall, but I get a "generic error in expression" error accompanied by a "suspending not allowed in this context" .rpt file message. I understand that when using .sqf this error applies when you try to execute a script with the call command instead of the spawn or execVM command. I'm assuming that jCall is equivalent to call which is why I'm getting the message. Is there a Java equivalent to execVM or spawn that I should be using (or another way to utilise RVEngine.sleep())?

Share this post


Link to post
Share on other sites
Preacher;2185985']Does anyone know how to use the RVEngine.sleep() function? I've tried it in the body of the main static method called by jCall' date=' and also as a regular method in a class instantiated by the main static method called by jCall, but I get a "generic error in expression" error accompanied by a "suspending not allowed in this context" .rpt file message. I understand that when using .sqf this error applies when you try to execute a script with the call command instead of the spawn or execVM command. I'm assuming that jCall is equivalent to call which is why I'm getting the message. Is there a Java equivalent to execVM or spawn that I should be using (or another way to utilise RVEngine.sleep())?[/quote']

In this context, wouldn't you do this with a Java statement instead of the exposed RVEngine functions? Never touched Java, but wouldn't this be something that could help you?

Share this post


Link to post
Share on other sites

If you do it by java functions, you'll very probably halt the game engine for the duration. Can't remember actually trying it, (maybe I did) but the way it works otherwise is a strong indication that this is what will happen.

In pure sqf, you have two contexts - scheduled and nonscheduled. Non-scheduled will run until it finishes. Scheduled can be paused - by the code calling sleep or when the game engine finds it has run for long enough. We do not have a good specification on when. You can "jump into" scheduled with spawn, execvm, but you can't jump back. Using call just means the current function won't proceed until the called code is finished; with call it basically inherits the context of the caller.

Jcall, however, has nothing to do with that. The problem is that the game engine will halt until the jcalled function returns. It currently has to do this because unless you're in the time window between the jcallee starting and returning, RVEngine calls are race conditions usually ending in crashes. Try spawning a java thread to call the rvengine functions after the jcalled function returns; when I did, it always crashed. Sometimes took a while (up to 47 seconds), but always crashed. In theory it could be possible to make RVEngine.Sleep() suspend the sqf "thread" that called it, but that's going to be advanced and highly reliant on the jre; possibly relying on undocumented features. That's a question for java gurus; of which BIS has none on the payroll.

Short version: Java code has to do everything in one go, and return. This severely limits its usefulness.

If the race condition problem was fixed, you could work around this by spawning a new thread and using the java method.

Share this post


Link to post
Share on other sites

I've been away for most of the summer and my Windows machine has died so I haven't been doing much with TOH. After being away for so long I was hoping to come back and find lots of new updates and more information on the Java API... but things don't seem to have progressed at all since I was last here...

Is the Java API going to get any love? Are there any patches or updates in the pipeline that address some of the issues that have been raised? Now that the summer is (almost) over and I have some spare time I was hoping to get back into TOH Java programming.

---------- Post added at 06:20 PM ---------- Previous post was at 05:46 PM ----------

Jcall, however, has nothing to do with that. The problem is that the game engine will halt until the jcalled function returns. It currently has to do this because unless you're in the time window between the jcallee starting and returning, RVEngine calls are race conditions usually ending in crashes. Try spawning a java thread to call the rvengine functions after the jcalled function returns; when I did, it always crashed.

I have not experienced this. I have spawned several threads that call RVEngine methods but I use Thread.sleep() to pause my thread. RVEngine.sleep() is likely just a left over from porting the SQF API to Java and should likely be avoided. Having said that, I have only been attempting relatively simple tasks with relatively long sleep periods and I haven't been testing to see if I can find race conditions.

All my Java code is on my dead Windows box, but basically I:

  1. jCall a Java method that starts a worker thread
  2. Call RVEngine methods from the thread.
  3. Use Thread.sleep() when I want to pause processing.

Share this post


Link to post
Share on other sites

Slapstick ,

will you be entering this world of Java again as it is or you need some fixes ? , i have some code i need to maybe convert to Java because its very hmmm Intense at the moment for normal Engine usages inSQF format , iam trying to get more mileage on FPS and hoping java will help.

Basicly i looked at this addon

http://www.armaholic.com/page.php?id=10695&highlight=DYNAMIC%2BTERRAIN

But i didnt make mission like they did, i placed them in Visitor so it not Lag so much , this make a little more Harder to track Tiles but still not so much really, However the code to Define what happens when someone fires and the consequence animations i feel could really utilize this Java maybe, what is your thoughts ?

The code i feel will benefit from Java ??

Cause

SPON_DT_addFiredHandler =
{
SPON_GET_PARAMS_1(_vehicle);

_vehicle addEventHandler ["FIRED",
{
	_firer = _this select 0;
	if (not local _firer) exitWith {};
	_ammo = _this select 4;

	_round = nearestObject [_firer, _ammo];
	_pos = getPos _round;

	_config = configFile >> "CfgAmmo" >> _ammo;

	if ((getNumber (_config >> "explosive")) >.5) then
	{
		private ["_damage", "_range", "_damageDirect"];

		_damage = getNumber (_config >> "indirectHit");
		_range = getNumber (_config >> "indirectHitRange");
		_damageDirect = getNumber (_config >> "hit");


		[_round, _pos, (toLower _ammo) == "pipebomb", log ((_damageDirect + (_damage * _range)))+0.5] spawn
		{
			SPON_GET_PARAMS_4(_round,_pos,_isBomb,_power);

			waitUntil
			{
				if (isNull _round) then
				{
					if ((not _isBomb) or ((_pos distance player) > 3)) then
					{
						// TODO: This should be atomic.
						[_pos, _power ,_power ] call SPON_DT_dig;
						[_pos] call thromp_TileDam;

					};

					true; // Finished.
				}
				else
				{
					_pos = getPos _round;
					false; // Continue.
				};
			};
		};
	};
}];
};

{
[_x] call SPON_DT_addFiredHandler;
} forEach allUnits;

{
[_x] call SPON_DT_addFiredHandler;
} forEach vehicles;

Effect

SPON_GET_PARAMS_3(_pos,_depth,_range);

private ["_tiles", "_tile", "_pos2D", "_tileTopLeft", "_distance", "_offset",
"_vertex", "_height"];

_pos = _pos + [];
_pos set [2, 10 ];

_tiles = nearestObjects [_pos, [TILE_CLASS,TILE_CLASS2,TILE_CLASS3], TILE_WIDTH * 2];
_tile = _tiles select 0;
_tile setobjecttexture [0,"\dbo_tile\data\mesto_dam_detail_co.paa"];
waitUntil { (count SPON_DT_pendingAnimations) == 0 };

{
_tile = _x;

_pos2D = [_pos select 0, _pos select 1];
_tileTopLeft = [((getPos _tile) select 0) - (TILE_WIDTH / 2), ((getPos _tile) select 1) - (TILE_WIDTH / 2)];

for "_k" from 0 to (NUM_VERTICES - 1) do
{
	for "_l" from 0 to (NUM_VERTICES - 1) do
	{
		_distance = [(_tileTopLeft select 0) + (_l * CELL_WIDTH),
			(_tileTopLeft select 1) + (_k * CELL_WIDTH)] distance _pos2D;
		if (_distance < _range) then
		{
			_offset = ((_range - _distance) * _depth) / _range;
			_vertex = format ["%1_%2", _k, _l];
			_height = _tile animationPhase _vertex;
			_height = _height - _offset;
			_tile animate [_vertex, _height/4];
		};
	};
};
} forEach _tiles;



SPON_DT_pendingAnimations = [];

nil; // Return.

i tried make Result video but cant see really :(.

Result

6iDATgFnacU

Edited by Thromp

Share this post


Link to post
Share on other sites
You may want to look into Arma2Net or Carma.

Well, there isn't anything specific I want to do other than play around with the Java API and provide some feedback for BIS.

Slapstick ,

will you be entering this world of Java again as it is or you need some fixes ?

I am just here to play around, but there are definite areas that need improvement and I was hoping there would have been some progress over the last few months…

i have some code i need to maybe convert to Java because its very hmmm Intense at the moment for normal Engine usages inSQF format , iam trying to get more mileage on FPS and hoping java will help.

Actually, event handlers are one thing that needs work in the current Java API. There is an RVEngine.addEventHandler method, but the event handler has to be written in SQF (as far as I can determine), so you can't stay in pure Java Land. So, at this point I would say that want you want to do is best done in SQF.

However, the lack of progress or any new information has me concerned… If BIS wants to open a New York office I would be happy to apply for a job as a Java developer and help out! ;-)

Share this post


Link to post
Share on other sites

That's a shame ,

I think they must be doing so much with Arma3 and Dayz and commander game ,I'm sure it's advanced but maybe not stable , unless dayz won't use java with TOH engine and its been dropped by arma3 ,

However from what I see of BIS , if you can put business case ,I'm sure they would hire you by proxy from home :) .

Share this post


Link to post
Share on other sites

Java was pretty much an experiment and it has been confirmed in multiple places by multiple people that its not going to be developed any further, at least not in the near future.

As far as SQF and performance goes it is fine if you know how to use it. ACRE does roughly 500-3000+ operations PER FRAME depending on the load/circumstances with no appreciable performance loss, and that includes real time radio signal calculations covering huge distances in the game world.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×