added some changes to AppletLoader

Started by bobjob, June 26, 2010, 21:01:44

Previous topic - Next topic

bobjob

hey guys, i made a little change to the applet loader that other people might be interested in.

in order to decrease the size of that native file download. I made the applet loader also check for 32/64 bit version of natives before falling back on the orignal al_<native> parameter
added the parameters
al_linux32
al_linux64
al_windows32
al_windows64

changes:
// native jar url
		String osName 		= System.getProperty("os.name");
		String nativeJar 	= null;
		String archDM = "";
		try {
			archDM = System.getProperty("sun.arch.data.model");
		} catch (Throwable e) {}
		if (archDM == null) archDM = "";
		
		if (osName.startsWith("Win")) {
			if (archDM.equals("64")) {
				nativeJar = getParameter("al_windows64");
			} else if (archDM.equals("32")) {
				nativeJar = getParameter("al_windows32");
			}
			
			if (nativeJar == null) {
				getParameter("al_windows");
			}
		} else if (osName.startsWith("Linux")) {
			if (archDM.equals("64")) {
				nativeJar = getParameter("al_linux64");
			} else if (archDM.equals("32")) {
				nativeJar = getParameter("al_linux32");
			}
			
			if (nativeJar == null) {
				getParameter("al_linux");
			}
		} else if (osName.startsWith("Mac")) {
			nativeJar = getParameter("al_mac");
		} else if (osName.startsWith("Solaris") || osName.startsWith("SunOS")) {
			nativeJar = getParameter("al_solaris");
		} else if (osName.startsWith("FreeBSD")) {
			nativeJar = getParameter("al_freebsd");
		} else {
			fatalErrorOccured("OS (" + osName + ") not supported", null);
		}


to the best of my ability i made sure it wouldnt effect the current way AppletLoader works.
If anyone is interested in decreasing the download size, this is one way to do that.

bobjob

One other recommendation for the appletLoader that i think is probably a good idea.
is instead of "al_bgcolor":
    <!-- background color to paint with, defaults to white -->
    <param name="al_bgcolor" value="dcf0ff">
   <param name="al_fgcolor" value="ffffff">


use the default :
<param name="boxbgcolor" value="#dcf0ff">
<param name="boxfgcolor" value="#ffffff">


as these colors will be displayed in the applet box even before the applet init is called (well at least on internet explorer).
Not a big deal, but it just prevents the need to put in the same value twice, and the default java param's kick in earlier and makes for a nicer backdrop for the certificate popup.

kappa

nice job bobjob :)

The support for 32 and 64 bit natives for each platform is a good idea and can be pretty useful for certain cases where natives size is substantial as the download size will be smaller.

However the reason there has been been reluctance to add such support was the number of jars you end up with, it just becomes difficult to maintain so many native jars (not forgetting all the other jars e.g. app, 3rd party libraries, lwjgl, etc and html fiddling that must be done). The current method of bundling 32/64 natives for each platform was an attempt to strike a balance between efficiency and maintainability. Besides lwjgl natives aren't that big when bundled together and end user is only likely to download a few extra kb's.

If there is enough demand for this feature it can be added pretty easily however not really convinced that the pro's out weigh the cons. In the rare case users are using their own natives (other then lwjgl's that is), its a useful feature to have. However it is'nt too much hassle to just to customise the appletloader with the above code as your likely to be signing your own jars in such a situation and not relying on the lwjgl certificate.

As for the idea of using boxbgcolor and boxfgcolor instead of al_bgcolor and al_fgcolor, I think its a great idea and will make the user experience much better as well as simplify the AppletLoader api. If there is no objects or further comments on this I'll add this in the next day or two.

kappa

ok we had a discussion about these features on the lwjgl irc channel and it seems they are both good and will be added to the AppletLoader.

However one thing is odd from your code, just curious, why do you use
System.getProperty("sun.arch.data.model")

as opposed to
System.getProperty("os.arch")

is it more reliable or something?

Matthias

I vote for os.arch as it is also used by webstart

bobjob

QuoteHowever one thing is odd from your code, just curious, why do you use
System.getProperty("sun.arch.data.model")

as opposed to
System.getProperty("os.arch")

is it more reliable or something?
The only real way to tell via OS.arch is to check String.endsWith("64") but there are so many variations of os.arch, that maybe down that track "64" will be standard, and the number not included like with all of the 32 os.arch Strings. just a pre-emptive fix  :P

But to tell you the truth I dont really see the problem with either properties.

edit:
here is a list of some os.arch types for those interested:
http://lopica.sourceforge.net/os.html

In bordem, here would be an overKILL check:
public static boolean is64bit() {
		String archDM = null;
		try {
			archDM = System.getProperty("sun.arch.data.model");
		} catch (Throwable e) {}

		if (archDM != null) {
			if (archDM.equals("64")) return true;
			else if (archDM.equals("32")) return false;
		}

		if (System.getProperty("os.arch").endsWith("64")) return true;
		else return false;
	}

bobjob

that said...
I did a bit more reading, and found that some JVM dont support sun.arch.data.model
like "64bit GNU 1.5"

kappa

ok, guess we'll go with "os.arch" then, if the String ends with "86" its 32bit and if it ends with "64" its 64bit (at least that's what I've concluded from looking at the various outputs of "os.arch").

bobjob

Quote from: javalwjgl on July 02, 2010, 08:16:40
ok, guess we'll go with "os.arch" then, if the String ends with "86" its 32bit and if it ends with "64" its 64bit (at least that's what I've concluded from looking at the various outputs of "os.arch").
its probably best not to do a check for 32 bit then,  just check endsWidth("64"). as there are a few types that dont use 86

kappa

Quote from: bobjob on July 02, 2010, 09:57:18
its probably best not to do a check for 32 bit then,  just check endsWidth("64"). as there are a few types that dont use 86

k, good idea, will do that then.

btw just out of curiosity which 32bit arch strings don't end with 86? (for window and linux)

bobjob

not sure if there are any for windows.
but according to that  list, there is a few for linux namely: ppc, sparc

kappa

Quote from: bobjob on July 02, 2010, 10:13:19
not sure if there are any for windows.
but according to that  list, there is a few for linux namely: ppc, sparc

ah, was under the impression that LWJGL's 32bit natives didn't work on those. Doesn't matter anyway as the 64bit check should be sufficient.

bobjob

Quote from: javalwjgl on July 02, 2010, 10:44:38
Quote from: bobjob on July 02, 2010, 10:13:19
not sure if there are any for windows.
but according to that  list, there is a few for linux namely: ppc, sparc
ah, was under the impression that LWJGL's 32bit natives didn't work on those. Doesn't matter anyway as the 64bit check should be sufficient.
Thats interesting, sorry I havnt really read up on LWJGL native support.

kappa

just a heads up, the following changes have been made to the appletloader and should be part of LWJGL 2.5.

1) Appletloader: Added parameter support for al_windows32, al_windows64, al_linux32 and al_linux64 for those that would like to split their 32/64 bit natives files to provide a smaller download.

2) AppletLoader: Parameters boxbgcolor, boxfgcolor and boxerrorcolor have been added. Previous parameters al_bgcolor, al_fgcolor and al_errorcolor have been removed. Unlike the previous color support now you can specify the color as a string name of any AWT Color ("red", "blue", "yellow", etc), RGB format (0-255, e.g. "255,0,0") or html HEX color (must use leading #, previous didn't need to have the # e.g. "#FF0000"). This is to match the color support of boxbgcolor and boxfgcolor of the java plugin, so now the color is set and appears before the appletloader is even loaded.

credit to bobjob for coming up with these ideas and changes, thx.

oh and just for completeness for those that don't know, since LWJGL 2.2 we now have a method called Display.setInitialBackground(float r, float g, float b); which is super cool to use with LWJGL Applets and the above changes.

To use this method you set it before you call Display.create(). If you set it to the same background color as the AppletLoader, you'll get a nice seamless switch from the AppletLoader to the LWJGL applet. Without this you'll get the default black screen which appears for a few seconds (ms?) during the LWJGL Display initialising, which can look a bit odd.

bobjob

A few more things, I understand if you guys are busy, or dont want to implement these changes as they are probably more for people who want to tweek the AppletLoader experience.
:-\ Sorry for constantly bugging you guys on the topic of the AppletLoader, its just that I want to port my game over, and would like to make sure its as smooth as possible, so im finding a few concerns as I go.

1. resizable applet, as the loader screen doesn't resize. This code should update once every second (If needed).
/** time stamp for last screen resize check */
	protected long lastResize;
	
	/*
	 * @see java.awt.Container#paint(java.awt.Graphics)
	 */
	
	public void paint(Graphics g) {
		
		// don't paint loader if applet loaded
		if(state == STATE_DONE) {
			return;
		}
		
		// create offscreen if missing
		if (offscreen == null) {
			offscreen = createImage(getWidth(), getHeight());
			lastResize = System.currentTimeMillis();
		} else {
			if (offscreen.getWidth(null) < getWidth() || offscreen.getHeight(null) < getHeight()) {
				if (System.currentTimeMillis() > lastResize + 1000) {
					lastResize = System.currentTimeMillis();
					offscreen.flush(); // :ADDED FOR MACOSX_IMAGE MEMORY FIX
					offscreen = createImage(getWidth(), getHeight());
					System.gc();// :ADDED FOR MACOSX_IMAGE MEMORY FIX
					System.runFinalization();// :ADDED FOR MACOSX_IMAGE MEMORY FIX
				}
			}
		}

should also clip to the applet size, the complete code is included in the attached AppletLoader.txt

2. I understand the red error writing for most cases, but in regards to the security certificate being declined i was thinking maybe use a nicer error popup.
tends to give the user a "I Killed the virus before it killed my computer" feeling.


3. Adding a "al_redirect" url
if the security popup is declined, offer a "redirect url" option. If the seperate_jvm tag is used on the platforms that support it, applets can just be reloaded without a browser restart, simple solution is to redirect to getDocumentBase().
fine for most cases, except IE Java 1.6(another IE applet lingering bug requires a querystring cache fix)

4. More of a question. Why is the applet loader "Applet" and not "JApplet". One reason JApplet is better, on Windows Java 1.6 there is less flicker on resizing and drawing. What are the reasons for Applet?

5. There is a problem on Internet Explorer with lingering applets. you can prevent this by calling super.destroy(): at the end of destroy method (also i include super.destroy at the start of init());
not sure how this will effect other platforms, if users decline the security dialog, helps to make sure that they will get a popup next time they load the browser (at least using IE).

I included all these changes in the attached AppletLoader.txt for those that are interested.
Test it here: http://have2chat.net/rts, make sure to "CANCEL" the security certificate popup, to test the applet error case.


edit:
Also forgot this one. allows the applet to be resizable, if the user decides to use the appletloader as webstart application.
should be called via a parameter (I didnt include one), as a resizable frame is not always desirable.
/** check if applet is running in Frame and resize paramater **/
	boolean resizeCheck = true;
	/*
	 * @see java.applet.Applet#start()
	 */
	public void start() {
		if (resizeCheck) {
			resizeCheck = false;
			Component parent = getParent();
			Frame root = null;
			while(parent.getParent()!=null) {
				parent = parent.getParent();
				if (parent instanceof Frame) {
					root = (Frame)parent;
				}
			}

			if (root!=null) {
				root.setResizable(true);
			}
		}

removed the appletLoader.txt, proper version in other post