* trigger a Surface.abort; if rendering were done in the same pass,
* rendering work done prior to the Surface.abort would be wasted.
*/
-public final class Box extends JS.Obj implements Task {
+public final class Box extends JS.Obj implements Callable {
private static final JS.Method METHOD = new JS.Method();
//#define CHECKSET_STRING(prop) if ((value==null&&prop==null)||(value!=null&&JSU.toString(value).equals(prop))) break; prop=JSU.toString(value);
// FIXME memory leak
- static Hash boxToCursor = new Hash(500, 3);
+ static Basket.Map boxToCursor = new Basket.HashMap(500, 3);
static final Font DEFAULT_FONT;
static {
public final int fontSize() { return font == null ? DEFAULT_FONT.pointsize : font.pointsize; }
/** invoked when a resource needed to render ourselves finishes loading */
- public void perform() throws JSExn {
- if (texture == null) { Log.warn(Box.class, "perform() called with null texture"); return; }
+ public Object run(Object o) throws JSExn {
+ if (texture == null) { Log.warn(Box.class, "perform() called with null texture"); return null; }
if (texture.isLoaded) {
setWidth(max(texture.width, minwidth), maxwidth);
setHeight(max(texture.height, minheight), maxheight);
dirty(); }
else { JS res = texture.stream; texture = null; throw new JSExn("image not found: "+res.unclone()); }
+ return null;
}
// FEATURE: use cx2/cy2 format
void resize(int x, int y, int width, int height) {
if (x == this.x && y == this.y && width == this.width && height == this.height) return;
- boolean sizechange = (this.width != width || this.height != height) && hasTrap(SIZECHANGE);
+ boolean sizechange = (this.width != width || this.height != height);
+ try { sizechange = sizechange && getTrap(SIZECHANGE) != null; } catch (JSExn e) {}
int thisx = parent == null ? 0 : this.x;
int thisy = parent == null ? 0 : this.y;
Box who = (parent == null ? this : parent);
this.width = width; this.height = height; this.x = x; this.y = y;
dirty();
}
- if (sizechange) putAndTriggerTrapsAndCatchExceptions(SIZECHANGE, T);
+ if (sizechange) putAndTriggerTrapsAndCatchExceptions(SIZECHANGE, JSU.T);
}
private float targetColumnSize = (float)0.0;
// Methods to implement org.ibex.js.JS //////////////////////////////////////
- public JS callMethod(JS method, JS a0, JS a1, JS a2, JS[] rest, int nargs) throws JSExn {
- switch (nargs) {
+ public JS call(JS method, JS[] args) throws JSExn {
+ switch (args.length) {
case 1: {
//#switch(JSU.toString(method))
case "indexof":
- Box b = (Box)a0;
+ Box b = (Box)args[0];
if (b.parent != this)
return (redirect == null || redirect == this) ?
- JSU.N(-1) :
- redirect.callMethod(method, a0, a1, a2, rest, nargs);
+ JSU.N(-1) : redirect.call(method, args);
return JSU.N(b.getIndexInParent());
case "distanceto":
- Box b = (Box)a0;
+ Box b = (Box)args[0];
JS ret = new JS.Obj();
ret.put(JSU.S("x"), JSU.N(b.localToGlobalX(0) - localToGlobalX(0)));
ret.put(JSU.S("y"), JSU.N(b.localToGlobalY(0) - localToGlobalY(0)));
//#end
}
}
- return super.callMethod(method, a0, a1, a2, rest, nargs);
+ return super.call(method, args);
}
public JS get(JS name) throws JSExn {
case "minheight": return JSU.N(minheight);
case "maxheight": return JSU.N(maxheight);
case "clip": return JSU.B(test(CLIP));
- case "visible": return JSU.B(test(VISIBLE) && (parent == null || (parent.get(JSU.S("visible")) == T)));
+ case "visible": return JSU.B(test(VISIBLE) && (parent == null || (parent.get(JSU.S("visible")) == JSU.T)));
case "packed": return JSU.B(test(PACKED));
case "globalx": return JSU.N(localToGlobalX(0));
case "globaly": return JSU.N(localToGlobalY(0));
throw new JSExn("you cannot read from the box.mouse property in background thread context");
return new Mouse();
case "numchildren": return redirect == null ? JSU.N(0) : redirect == this ? JSU.N(treeSize()) : redirect.get(JSU.S("numchildren"));
- case "redirect": return redirect == null ? null : redirect == this ? T : redirect.get(JSU.S("redirect"));
+ case "redirect": return redirect == null ? null : redirect == this ? JSU.T : redirect.get(JSU.S("redirect"));
case "Minimized": if (parent == null && getSurface() != null) return JSU.B(getSurface().minimized);
default: return super.get(name);
//#end
throw new Error("unreachable"); // unreachable
}
- private class Mouse extends JS implements JS.Cloneable {
+ private class Mouse extends JS.Immutable implements JS.Cloneable {
public JS get(JS key) throws JSExn {
//#switch(JSU.toString(key))
case "x": return JSU.N(globalToLocalX(getSurface()._mousex));
// this might not get recomputed if we change mousex/mousey...
case "inside": return JSU.B(test(MOUSEINSIDE));
//#end
- return null;
+ return super.get(key);
}
}
case "bottom": set(ALIGN_BOTTOM);
case "left": set(ALIGN_LEFT);
case "right": set(ALIGN_RIGHT);
- default: JSU.log("invalid alignment \"" + JSU.debugToString(value) + "\"");
+ default: JSU.log("invalid alignment \"" + JSU.str(value) + "\"");
//#end
}
if (texture == newtex) return;
texture = newtex;
fillcolor = 0;
- if (texture != null && texture.isLoaded) perform();
+ if (texture != null && texture.isLoaded) run(null);
}
dirty();
}
boolean isinside = test(VISIBLE) && inside(x, y) && !obscured;
if (!wasinside && isinside) {
set(MOUSEINSIDE);
- putAndTriggerTrapsAndCatchExceptions(JSU.S("Enter"), T);
+ putAndTriggerTrapsAndCatchExceptions(JSU.S("Enter"), JSU.T);
}
if (isinside && test(CURSOR)) getSurface().cursor = (String)boxToCursor.get(this);
if (wasinside && !isinside) {
clear(MOUSEINSIDE);
- putAndTriggerTrapsAndCatchExceptions(JSU.S("Leave"), T);
+ putAndTriggerTrapsAndCatchExceptions(JSU.S("Leave"), JSU.T);
}
boolean found = false;
try {
putAndTriggerTraps(name, val);
} catch (JSExn e) {
- JSU.log("caught js exception while putting to trap \""+ JSU.debugToString(name)+"\"");
+ JSU.log("caught js exception while putting to trap \""+ JSU.str(name)+"\"");
JSU.log(e);
} catch (Exception e) {
- JSU.log("caught exception while putting to trap \""+ JSU.debugToString(name)+"\"");
+ JSU.log("caught exception while putting to trap \""+ JSU.str(name)+"\"");
JSU.log(e);
}
}
Sub(JS key) { this.key = key; }
public void put(JS key, JS val) throws JSExn { Ibex.this.put(JSU.S(JSU.toString(this.key) + "." + JSU.toString(key)), val); }
public JS get(JS key) throws JSExn { return Ibex.this.get(JSU.S(JSU.toString(this.key) + "." + JSU.toString(key))); }
- public JS call(JS a0, JS a1, JS a2, JS[] rest, int nargs) throws JSExn {
- return Ibex.this.callMethod(this.key, a0, a1, a2, rest, nargs);
- }
- public JS callMethod(JS method, JS a0, JS a1, JS a2, JS[] rest, int nargs) throws JSExn {
- return Ibex.this.callMethod(JSU.S(JSU.toString(this.key) + "." + JSU.toString(method)), a0, a1, a2, rest, nargs);
+ public JS call(JS[] args) throws JSExn { return Ibex.this.call(this.key, args); }
+ public JS call(JS method, JS[] args) throws JSExn {
+ return Ibex.this.call(JSU.S(JSU.toString(this.key) + "." + JSU.toString(method)), args);
}
}
- private Cache subCache = new Cache(20);
+ private Cache subCache = new Cache(20, true);
private Sub getSub(JS key) {
Sub ret = (Sub)subCache.get(key);
if (ret == null) subCache.put(key, ret = new Sub(key));
public JS get(JS name) throws JSExn {
// FIXME: SHouldn't need this (just trap [""])
- if (JS.isString(name) && JSU.toString(name).length() == 0) return rr;
+ if (JSU.isString(name) && JSU.toString(name).length() == 0) return rr;
// FEATURE: Preprocessor hack to generate specialized JS instances (avoid all this string concatenation)
//#switch(JSU.toString(name))
case "math": return ibexMath;
case "ui.browser": return METHOD;
case "ui.mouse": return getSub(name);
case "ui.mouse.button":
- if (Surface.button1 && !Surface.button2 && !Surface.button3) return N(1);
- else if (!Surface.button1 && Surface.button2 && !Surface.button3) return N(2);
- else if (!Surface.button1 && !Surface.button2 && Surface.button3) return N(3);
- else return ZERO;
+ if (Surface.button1 && !Surface.button2 && !Surface.button3) return JSU.N(1);
+ else if (!Surface.button1 && Surface.button2 && !Surface.button3) return JSU.N(2);
+ else if (!Surface.button1 && !Surface.button2 && Surface.button3) return JSU.N(3);
+ else return JSU.ZERO;
case "ui.key": return getSub(name);
case "ui.key.name": return getSub(name);
case "ui.key.name.alt": return JSU.S(Platform.altKeyName());
case "ui.key.control": return Surface.control ? JSU.T : JSU.F;
case "ui.key.shift": return Surface.shift ? JSU.T : JSU.F;
case "ui.clipboard": return JSU.S((String)Platform.getClipBoard());
- case "ui.maxdim": return N(Short.MAX_VALUE);
+ case "ui.maxdim": return JSU.N(Short.MAX_VALUE);
case "ui.screen": return getSub(name);
- case "ui.screen.width": return N(Platform.getScreenWidth());
- case "ui.screen.height": return N(Platform.getScreenHeight());
+ case "ui.screen.width": return JSU.N(Platform.getScreenWidth());
+ case "ui.screen.height": return JSU.N(Platform.getScreenHeight());
case "undocumented": return getSub(name);
case "undocumented.initialOrigin": return JSU.S(Main.origin);
case "undocumented.initialTemplate": return JSU.S(Main.initialTemplate);
public void put(JS name, JS value) throws JSExn {
//#switch(JSU.toString(name))
- case "thread": Scheduler.add((Task)value); return;
+ case "thread": Scheduler.add((Callable)value); return;
case "ui.clipboard": Platform.setClipBoard(JSU.toString(value)); return;
case "ui.frame": Platform.createSurface((Box)value, true, true); return;
case "ui.window": Platform.createSurface((Box)value, false, true); return;
throw new JSExn("attempted to put unknown property: ibex."+name);
}
- public JS callMethod(JS name, JS a, JS b, JS c, JS[] rest, int nargs) throws JSExn {
+ public JS call(JS method, JS[] args) throws JSExn {
try {
- //#switch(JSU.toString(name))
- case "date": return new JSDate(a, b, c, rest, nargs);
- case "net.rpc.soap": return new SOAP(JSU.toString(a), "", JSU.toString(b), JSU.toString(c));
+ //#switch(JSU.toString(method))
+ case "date": return new JSDate(args);
+ case "net.rpc.soap": return new SOAP(
+ args.length < 1 ? null : JSU.toString(args[0]),
+ "",
+ args.length < 2 ? null : JSU.toString(args[1]),
+ args.length < 3 ? null : JSU.toString(args[2]));
// FIXME support object dumping
- case "log.debug": JS.debug(a== null ? "**null**" : JS.debugToString(a)); return null;
- case "log.info": JS.info(a== null ? "**null**" : JS.debugToString(a)); return null;
- case "log.warn": JS.warn(a== null ? "**null**" : JS.debugToString(a)); return null;
- case "log.error": JS.error(a== null ? "**null**" : JS.debugToString(a)); return null;
+ case "log.debug": JSU.debug(args.length < 1 ? "**null**" : JSU.str(args[0])); return null;
+ case "log.info": JSU.info(args.length < 1 ? "**null**" : JSU.str(args[0])); return null;
+ case "log.warn": JSU.warn(args.length < 1 ? "**null**" : JSU.str(args[0])); return null;
+ case "log.error": JSU.error(args.length < 1 ? "**null**" : JSU.str(args[0])); return null;
//#end
- switch (nargs) {
+ switch (args.length) {
case 0:
- //#switch(JSU.toString(name))
+ //#switch(JSU.toString(method))
case "thread.yield": sleep(0); return null;
//#end
break;
case 1:
- //#switch(JSU.toString(name))
+ //#switch(JSU.toString(method))
case "clone":
- if(a == null) throw new JSExn("can't clone the null value");
- return ((JS)a).jsclone();
- case "bless": return bless((JS)a);
- case "ui.browser": Platform.newBrowserWindow(JSU.toString(a)); return null;
- case "stream.unzip": return a == null ? null : new Stream.Zip((Stream)a);
+ if(args[0] == null) throw new JSExn("can't clone the null value");
+ return new JS.Clone((JS)args[0]);
+ case "bless": return bless((JS)args[0]);
+ case "ui.browser": Platform.newBrowserWindow(JSU.toString(args[0])); return null;
+ case "stream.unzip": return args[0] == null ? null : new Stream.Zip((Stream)args[0]);
//case "stream.uncab": return a == null ? null : new Stream.Cab(a);
case "stream.cache":
- try { return a == null ? null : new Stream.CachedStream((Stream)a, "resources", true); }
+ try { return args[0] == null ? null : new Stream.CachedStream((Stream)args[0], "resources", true); }
catch (Stream.NotCacheableException e) { throw new JSExn("this resource cannot be cached"); }
case "stream.url": {
- String url = JSU.toString(a);
+ String url = JSU.toString(args[0]);
if (url.startsWith("http://")) return new Stream.HTTP(url);
else if (url.startsWith("https://")) return new Stream.HTTP(url);
- else if (url.startsWith("data:")) return new Stream.ByteArray(Base64.decode(url.substring(5)), null);
+ else if (url.startsWith("data:")) return new Stream.ByteArray(Encode.fromBase64(url.substring(5)), null);
else if (url.startsWith("utf8:")) return new Stream.ByteArray(url.substring(5).getBytes(), null);
else if (url.startsWith("file:")) {
// FIXME
}
throw new JSExn("invalid resource specifier " + url);
}
- case "thread.sleep": sleep(JS.toInt(a)); return null;
- case "regexp": return new JSRegexp(a, null);
- case "net.rpc.xml": return new XMLRPC(JSU.toString(a), "");
+ case "thread.sleep": sleep(JSU.toInt(args[0])); return null;
+ case "regexp": return new JSRegexp(args[0], null);
+ case "net.rpc.xml": return new XMLRPC(JSU.toString(args[0]), "");
case "crypto.rsa": /* FEATURE */ return null;
case "crypto.md5": /* FEATURE */ return null;
case "crypto.sha1": /* FEATURE */ return null;
case "crypto.rc4": /* FEATURE */ return null;
case "stream.parse.html": throw new JSExn("not implemented yet"); //return null;
- case "stream.parse.xml": if(a == null) return null; new XMLHelper(b).doParse(a); return null;
+ case "stream.parse.xml": if(args[0] == null) return null; new XMLHelper(args[1]).doParse(args[0]); return null;
// FIXME backgrounding
- case "stream.parse.utf8": if(a == null) return null;
- try { return JSU.S(new String(InputStreamToByteArray.convert(a.getInputStream()))); }
+ case "stream.parse.utf8": if(args[0] == null) return null;
+ try { return JSU.S(new String(InputStreamToByteArray.convert(args[0].getInputStream()))); }
catch (Exception e) { Log.warn(this, e); }
//#end
break;
case 2:
- //#switch(JSU.toString(name))
- case "stream.watch": return new Stream.ProgressWatcher((Stream)a, b);
- case "regexp": return new JSRegexp(a, b);
+ //#switch(JSU.toString(method))
+ case "stream.watch": return new Stream.ProgressWatcher((Stream)args[0], args[1]);
+ case "regexp": return new JSRegexp(args[0], args[1]);
//#end
case 3:
- //#switch(JSU.toString(name))
- case "ui.font.height": return N(Font.getFont(a, JS.toInt(b)).textheight(JSU.toString(c)));
+ //#switch(JSU.toString(method))
+ case "ui.font.height": return JSU.N(Font.getFont(args[0], JSU.toInt(args[1])).textheight(JSU.toString(args[3])));
case "ui.font.wait": throw new Error("FIXME: ibex.ui.font.wait not implemented");
- case "ui.font.width": return N(Font.getFont(a, JS.toInt(b)).textwidth(JSU.toString(c)));
+ case "ui.font.width": return JSU.N(Font.getFont(args[0], JSU.toInt(args[1])).textwidth(JSU.toString(args[3])));
//#end
break;
}
} catch (RuntimeException e) {
// FIXME: maybe JSExn should take a second argument, Exception
- Log.warn(this, "ibex."+name+"() threw: " + e);
- throw new JSExn("invalid argument for ibex object method "+name+"()");
+ Log.warn(this, "ibex."+method+"() threw: " + e);
+ throw new JSExn("invalid argument for ibex object method "+method+"()");
}
- throw new JSExn("invalid number of arguments ("+nargs+") for ibex object method "+name+"()");
+ throw new JSExn("invalid number of arguments ("+args.length+") for ibex object method "+method+"()");
}
public JS url2res(String url) throws JSExn {
if (url.startsWith("http://")) return new Stream.HTTP(url);
else if (url.startsWith("https://")) return new Stream.HTTP(url);
- else if (url.startsWith("data:")) return new Stream.ByteArray(Base64.decode(url.substring(5)), null);
+ else if (url.startsWith("data:")) return new Stream.ByteArray(Encode.fromBase64(url.substring(5)), null);
else if (url.startsWith("utf8:")) return new Stream.ByteArray(url.substring(5).getBytes(), null);
else throw new JSExn("invalid resource specifier " + url);
// FIXME support file:// via dialog boxes
public static void sleep(final int i) throws JSExn {
try {
- final JS.UnpauseCallback callback = JS.pause();
+ final Pausable callback = JSU.pause();
// FEATURE use a single sleeper thread
new Thread() { public void run() {
try { Thread.sleep(i); } catch (InterruptedException e) { }
Scheduler.add(callback);
} }.start();
- } catch (JSU.NotPauseableException npe) {
+ } catch (Pausable.NotPausableException npe) {
throw new JSExn("you cannot sleep or yield in the foreground thread");
}
}
- public static final JS ibexMath = new JS.Obj() {
+ public static final JS ibexMath = new JS.Immutable() {
// FEATURE: find a cleaner way to do this
private JS gs = /*new JSScope.Global();*/ null; // FIXME: Global scope
public JS get(JS key) throws JSExn {
case "NaN": return METHOD;
case "Infinity": return METHOD;
//#end
- return MATH.get(key);
+ return JSU.MATH.get(key);
}
- public JS callMethod(JS name, JS a, JS b, JS c, JS[] rest, int nargs) throws JSExn {
- //#switch(JSU.toString(name))
- case "isNaN": return gs.callMethod(name,a,b,c,rest,nargs);
- case "isFinite": return gs.callMethod(name,a,b,c,rest,nargs);
- case "NaN": return gs.callMethod(name,a,b,c,rest,nargs);
- case "Infinity": return gs.callMethod(name,a,b,c,rest,nargs);
+ public JS call(JS method, JS[] args) throws JSExn {
+ //#switch(JSU.toString(method))
+ case "isNaN": return gs.call(method, args);
+ case "isFinite": return gs.call(method, args);
+ case "NaN": return gs.call(method, args);
+ case "Infinity": return gs.call(method, args);
//#end
- return MATH.callMethod(name,a,b,c,rest,nargs);
+ return JSU.MATH.call(method, args);
}
};
//#end
return super.get(key);
}
- public JS callMethod(JS name, JS a, JS b, JS c, JS[] rest, int nargs) throws JSExn {
- //#switch(JSU.toString(name))
- case "parseInt": return gs.callMethod(name,a,b,c,rest,nargs);
- case "parseFloat": return gs.callMethod(name,a,b,c,rest,nargs);
- case "decodeURI": return gs.callMethod(name,a,b,c,rest,nargs);
- case "decodeURIComponent": return gs.callMethod(name,a,b,c,rest,nargs);
- case "encodeURI": return gs.callMethod(name,a,b,c,rest,nargs);
- case "encodeURIComponent": return gs.callMethod(name,a,b,c,rest,nargs);
- case "escape": return gs.callMethod(name,a,b,c,rest,nargs);
- case "unescape": return gs.callMethod(name,a,b,c,rest,nargs);
- case "fromCharCode": return gs.callMethod(name,a,b,c,rest,nargs);
+ public JS callMethod(JS method, JS[] args) throws JSExn {
+ //#switch(JSU.toString(method))
+ case "parseInt": return gs.call(method, args);
+ case "parseFloat": return gs.call(method, args);
+ case "decodeURI": return gs.call(method, args);
+ case "decodeURIComponent": return gs.call(method, args);
+ case "encodeURI": return gs.call(method, args);
+ case "encodeURIComponent": return gs.call(method, args);
+ case "escape": return gs.call(method, args);
+ case "unescape": return gs.call(method, args);
+ case "fromCharCode": return gs.call(method, args);
//#end
- return super.callMethod(name,a,b,c,rest,nargs);
+ return super.call(method, args);
}
};
private class Wrapper extends XML.Exn { public JSExn wrapee; public Wrapper(JSExn jse) { super(""); wrapee = jse; } }
private JS characters, whitespace, endElement, startElement;
public XMLHelper(JS b) throws JSExn {
- super(BUFFER_SIZE);
+ super(BUFFER_SIZE, true);
startElement = b.getAndTriggerTraps(JSU.S("startElement"));
endElement = b.getAndTriggerTraps(JSU.S("endElement"));
characters = b.getAndTriggerTraps(JSU.S("characters"));
whitespace = b.getAndTriggerTraps(JSU.S("whitespace"));
}
- public void startElement(XML.Element c) throws XML.Exn { try {
- JS attrs = new JS.O();
+ private final JS[] callargs1= new JS[1], callargs2= new JS[2], callargs3= new JS[3];
+ public void startElement(Tree.Element c) throws XML.Exn { try {
+ Tree.Attributes a = c.getAttributes();
+ JS attrs = new JS.Obj();
// FIXME attribute URIs? add an additional hash?
- for(int i=0; i<c.getAttrLen(); i++) attrs.put(JSU.S(c.getAttrKey(i)), JSU.S(c.getAttrVal(i)));
- startElement.call(JSU.S(c.getLocalName()), attrs, JSU.S(c.getUri()), null, 3);
- } catch (JSExn jse) { throw new Wrapper(jse); } }
+ for(int i=0; i<a.attrSize(); i++) attrs.put(JSU.S(a.getKey(i)), JSU.S(a.getVal(i)));
+ callargs3[0] = JSU.S(c.getLocalName());
+ callargs3[1] = attrs;
+ callargs3[2] = JSU.S(c.getUri());
+ startElement.call(callargs3);
+ } catch (JSExn jse) { throw new Wrapper(jse);
+ } finally { callargs3[0] = callargs3[1] = callargs3[2] = null; } }
- public void endElement(XML.Element c) throws XML.Exn { try {
- endElement.call(JSU.S(c.getLocalName()), JSU.S(c.getUri()), null, null, 2);
- } catch (JSExn jse) { throw new Wrapper(jse); } }
+ public void endElement(Tree.Element c) throws XML.Exn { try {
+ callargs2[0] = JSU.S(c.getLocalName());
+ callargs2[1] = JSU.S(c.getUri());
+ endElement.call(callargs2);
+ } catch (JSExn jse) { throw new Wrapper(jse); } finally { callargs2[0] = callargs2[1] = null; } }
public void characters(char[] ch, int start, int length) throws XML.Exn { try {
- characters.call(JSU.S(new String(ch, start, length)), null, null, null, 1);
- } catch (JSExn jse) { throw new Wrapper(jse); } }
+ callargs1[0] = JSU.S(new String(ch, start, length));
+ characters.call(callargs1);
+ } catch (JSExn jse) { throw new Wrapper(jse); } finally { callargs1[0] = null; } }
public void whitespace(char[] ch, int start, int length) throws XML.Exn { try {
- whitespace.call(JSU.S(new String(ch, start, length)), null, null, null, 1);
- } catch (JSExn jse) { throw new Wrapper(jse); } }
+ callargs1[0] = JSU.S(new String(ch, start, length));
+ whitespace.call(callargs1);
+ } catch (JSExn jse) { throw new Wrapper(jse); } finally { callargs1[0] = null; } }
public void doParse(JS s) throws JSExn {
try {
public JS parentkey = null;
public Blessing parent = null;
public JS clonee;
- private Hash cache = new Hash();
+ private Basket.Map cache = new Basket.HashMap();
public Blessing(JS clonee, Ibex ibex, Blessing parent, JS parentkey) throws JSExn {
this.clonee = clonee; this.ibex = ibex; this.parentkey = parentkey; this.parent = parent; }
public JS get(JS key) throws JSExn {
- if (JS.isString(key) && JSU.toString(key).equals("")) return getStatic();
+ if (JSU.isString(key) && JSU.toString(key).equals("")) return getStatic();
if (cache.get(key) != null) return (JS)cache.get(key);
JS ret = new Blessing(clonee.get(key), ibex, this, key);
cache.put(key, ret);
return ret;
}
public static Blessing getBlessing(JS js) {
- while (js instanceof JS.Clone && !(js instanceof Blessing)) js = ((JS.Clone)js).getClonee();
+ // CHECKME: is unclone() good enough or do we need getClonee() in Cloneable?
+ while (js instanceof JS.Cloneable && !(js instanceof Blessing)) js = js.unclone();
if (!(js instanceof Blessing)) return null;
return (Blessing)js;
}
}
}
private String description() {
- String s = JS.debugToString(parentkey);
- for(Blessing b = parent; b.parentkey != null; b = b.parent) s = JS.debugToString(b.parentkey) + "." + s;
+ String s = JSU.str(parentkey);
+ for(Blessing b = parent; b.parentkey != null; b = b.parent) s = JSU.str(b.parentkey) + "." + s;
return s;
}
- public JS call(JS a, JS b, JS c, JS[] rest, int nargs) throws JSExn {
- if (nargs != 1) throw new JSExn("can only call a template with one arg");
+ public JS call(JS[] args) throws JSExn {
+ if (args.length != 1) throw new JSExn("can only call a template with one arg");
getStatic();
- if (t == null) throw new JSExn("No such template " + JS.debugToString(parentkey));
- if(!(a instanceof Box)) throw new JSExn("can only apply templates to boxes");
- t.apply((Box)a);
- return a;
+ if (t == null) throw new JSExn("No such template " + JSU.str(parentkey));
+ if(!(args[0] instanceof Box)) throw new JSExn("can only apply templates to boxes");
+ t.apply((Box)args[0]);
+ return args[0];
}
// FEATURE: This is a gross hack
Template getTemplate() throws JSExn {
getStatic();
- if (t == null) throw new JSExn("No such template " + JS.debugToString(parentkey));
+ if (t == null) throw new JSExn("No such template " + JSU.str(parentkey));
return t;
}
// JS:FIXME: Blessing shouldn't need to roll its own JS.Clone implementation
- public InputStream getInputStream() throws IOException { return clonee.getInputStream(); }
+ public InputStream getInputStream() throws JSExn, IOException { return clonee.getInputStream(); }
}
}
public static java.io.File getCacheFileForKey(String key) {
// FEATURE: be smarter here
- return new java.io.File(cacheDir.getPath() + File.separatorChar + new String(Base64.encode(key.getBytes())));
+ return new java.io.File(cacheDir.getPath() + File.separatorChar + new String(Encode.toBase64(key.getBytes())));
}
}
org.ibex.graphics.Surface.scarImage =
Picture.load(new Stream.FromInputStream(Encode.JavaSourceCode.decode(Scar.data)),
- new Task() { public void perform() throws JSExn, UnknownHostException {
- if (Log.on) Log.info(Main.class, "invoking initial template");
- ibex.resolveString(startupTemplate, false).call(new Box(), null, null, null, 1);
+ new Callable() {
+ private JS[] callargs = new JS[1];
+ public Object run(Object o) throws JSExn,UnknownHostException {
+ if (Log.on) Log.info(Main.class, "invoking initial template");
+ try {
+ callargs[0] = new Box();
+ ibex.resolveString(startupTemplate, false).call(callargs);
+ } finally { callargs[0] = null; }
+ return null;
} });
Scheduler.init();
// Public API Exposed to org.ibex /////////////////////////////////////////////////
private static Scheduler singleton;
- public static void add(Task t) { Log.debug(Scheduler.class, "scheduling " + t); Scheduler.runnable.append(t); }
+ public static void add(Callable t) { Log.debug(Scheduler.class, "scheduling " + t); Scheduler.runnable.append(t); }
public static void init() { if (singleton == null) (singleton = Platform.getScheduler()).run(); }
- private static Task current = null;
+ private static Callable current = null;
private static volatile boolean rendering = false;
private static volatile boolean again = false;
/**
* SCHEDULER INVARIANT: all scheduler implementations MUST invoke
- * Surface.renderAll() after performing a Task if no tasks remain
+ * Surface.renderAll() after performing a Callable if no tasks remain
* in the queue. A scheduler may choose to invoke
* Surface.renderAll() more often than that if it so chooses.
*/
protected static Queue runnable = new Queue(50);
public void defaultRun() {
while(true) {
- current = (Task)runnable.remove(true);
+ current = (Callable)runnable.remove(true);
try {
// FIXME hideous
synchronized(this) {
}
}
Log.debug(Scheduler.class, "performing " + current);
- current.perform();
+ current.run(null);
}
renderAll();
} catch (JSExn e) {
Log.info(Scheduler.class, "a JavaScript thread spawned with ibex.thread() threw an exception:");
Log.info(Scheduler.class,e);
} catch (Exception e) {
- Log.info(Scheduler.class, "a Task threw an exception which was caught by the scheduler:");
+ Log.info(Scheduler.class, "a Callable threw an exception which was caught by the scheduler:");
Log.info(Scheduler.class, e);
} catch (Throwable t) {
t.printStackTrace();
// streams are "sealed" by default to prevent accidental object leakage
public void put(Object key, Object val) { }
- private Cache getCache = new Cache(100);
+ private Cache getCache = new Cache(100, true);
protected JS _get(JS key) throws JSExn { return null; }
public final JS get(JS key) throws JSExn {
JS ret = (JS)getCache.get(key);
private String url;
//public String toString() { return "Stream.HTTP:" + url; }
public HTTP(String url) { while (url.endsWith("/")) url = url.substring(0, url.length() - 1); this.url = url; }
- public JS _get(JS key) throws JSExn { return new HTTP(url + "/" + JS.toString(key)); }
+ public JS _get(JS key) throws JSExn { return new HTTP(url + "/" + JSU.toString(key)); }
public String getCacheKey(Vec path) throws NotCacheableException { return url; }
public InputStream getInputStream() throws IOException { return new org.ibex.net.HTTP(url).GET(null, null); }
}
public String getCacheKey() throws NotCacheableException { throw new NotCacheableException(); /* already on disk */ }
public InputStream getInputStream() throws IOException { return new FileInputStream(path); }
public JS _get(JS key) throws JSExn {
- System.out.println("get: " + JS.debugToString(key));
- return new File(path + java.io.File.separatorChar + JS.toString(key)); }
+ System.out.println("get: " + JSU.str(key));
+ return new File(path + java.io.File.separatorChar + JSU.toString(key)); }
}
/** "unwrap" a Zip archive */
this.path = path;
}
public String getCacheKey() throws NotCacheableException { return parent.getCacheKey() + "!zip:"; }
- public JS _get(JS key) throws JSExn { return new Zip(parent, path==null?JS.toString(key):path+'/'+JS.toString(key)); }
+ public JS _get(JS key) throws JSExn { return new Zip(parent, path==null?JSU.toString(key):path+'/'+JSU.toString(key)); }
public InputStream getInputStream() throws IOException {
InputStream pis = parent.getInputStream();
ZipInputStream zis = new ZipInputStream(pis);
/** shadow resource which replaces the graft */
public static class ProgressWatcher extends Stream {
+ private final JS[] callargs = new JS[2];
final Stream watchee;
JS callback;
public ProgressWatcher(Stream watchee, JS callback) { this.watchee = watchee; this.callback = callback; }
public int read(byte[] b, int off, int len) throws IOException {
int ret = super.read(b, off, len);
if (ret != 1) bytesDownloaded += ret;
- Scheduler.add(new Task() { public void perform() throws IOException, JSExn {
- callback.call(N(bytesDownloaded),
- N(is instanceof KnownLength ? ((KnownLength)is).getLength() : 0), null, null, 2);
+ Scheduler.add(new Callable() {
+ public Object run(Object o) throws IOException, JSExn {
+ try {
+ int len = is instanceof KnownLength.KnownLengthInputStream ?
+ ((KnownLength.KnownLengthInputStream)is).getLength() : 0;
+ callargs[0] = JSU.N(bytesDownloaded);
+ callargs[1] = JSU.N(len);
+ callback.call(callargs);
+ } finally { callargs[0] = callargs[1] = null; }
+ return null;
} });
return ret;
}
}
}
+ private static final JS[] callempty = new JS[0];
private void apply(Box b, PerInstantiationScope parentPis) throws JSExn, IOException {
if (prev != null) prev.apply(b, null);
if (prev2 != null) prev2.apply(b, null);
b.putAndTriggerTraps(b.get(JSU.S("numchildren")), kid);
}
- if (script != null) JS.cloneWithNewGlobalScope(script, pis).call(null, null, null, null, 0);
+ if (script != null) JSU.cloneWithNewGlobalScope(script, pis).call(callempty);
for(int i=0; keys != null && i < keys.length; i++) {
if (keys[i] == null) continue;
if ("null".equals(val)) val = null;
- if (JS.isString(val) && (JS.toString(val).length() > 0)) {
- switch (JS.toString(val).charAt(0)) {
+ if (JSU.isString(val) && (JSU.toString(val).length() > 0)) {
+ switch (JSU.toString(val).charAt(0)) {
case '$':
val = pis.get(val);
- if (val == null) throw new JSExn("unknown box id '"+JS.toString(vals[i])+"' referenced in XML attribute");
+ if (val == null) throw new JSExn("unknown box id '"+JSU.str(vals[i])+"' referenced in XML attribute");
break;
case '.':
- val = ibex.resolveString(JS.toString(val).substring(1), false);
+ val = ibex.resolveString(JSU.toString(val).substring(1), false);
// FIXME: url case
// FIXME: should we be resolving all of these in the XML-parsing code?
}
/** handles XML parsing; builds a Template tree as it goes */
static final class TemplateHelper extends XML {
- String sourceName;
+ String sourceName;
private int state = STATE_INITIAL;
private static final int STATE_INITIAL = 0;
private static final int STATE_IN_ROOT_NODE = 1;
private static final int STATE_IN_TEMPLATE_NODE = 2;
private static final int STATE_IN_META_NODE = 3;
+ private static final JS[] callempty = new JS[0];
StringBuffer static_content = null;
int static_content_start = 0;
String initial_uri = "";
- public TemplateHelper(String sourceName, JS s, Ibex ibex) throws XML.Exn, IOException, JSExn {
+ public TemplateHelper(String sourceName, JS s, Ibex ibex) throws XML.Exn, IOException, JSExn {
this.sourceName = sourceName;
this.ibex = ibex;
InputStream is = s.getInputStream();
Ibex.Blessing b = Ibex.Blessing.getBlessing(s).parent;
while(b != null) {
- if(b.parentkey != null) initial_uri = JS.toString(b.parentkey) + (initial_uri.equals("") ? "" : "." + initial_uri);
+ if(b.parentkey != null) initial_uri = JSU.toString(b.parentkey) + (initial_uri.equals("") ? "" : "." + initial_uri);
b = b.parent;
}
initial_uri = "";
parse(new InputStreamReader(is));
JS staticScript = parseScript(static_content, static_content_start);
- t.staticObject = new JS.O();
+ t.staticObject = new JS.Obj();
JS staticScope = new PerInstantiationScope(null, ibex, null, t.staticObject);
- if (staticScript != null) JS.cloneWithNewGlobalScope(staticScript, staticScope).call(null, null, null, null, 0);
+ if (staticScript != null) JSU.cloneWithNewGlobalScope(staticScript, staticScope).call(callempty);
}
private JS parseScript(StringBuffer content, int content_start) throws IOException {
if (content == null) return null;
String contentString = content.toString();
- if (contentString.trim().length() > 0) return JS.fromReader(sourceName, content_start, new StringReader(contentString));
+ if (contentString.trim().length() > 0) return JSU.fromReader(sourceName, content_start, new StringReader(contentString));
return null;
}
- public void startElement(XML.Element c) throws XML.Exn {
+ public void startElement(Tree.Element c) throws XML.Exn {
+ Tree.Attributes a = c.getAttributes();
switch(state) {
case STATE_IN_META_NODE: { meta++; return; }
case STATE_INITIAL:
if (!"ibex".equals(c.getLocalName()))
throw new XML.Exn("root element was not <ibex>", XML.Exn.SCHEMA, getLine(), getCol());
- if (c.getAttrLen() != 0)
+ if (a.attrSize() != 0)
throw new XML.Exn("root element must not have attributes", XML.Exn.SCHEMA, getLine(), getCol());
- if (c.getUri("ui") == null || "".equals(c.getUri("ui"))) c.addUri("ui", "ibex://ui");
- if (c.getUri("meta") == null || "".equals(c.getUri("meta"))) c.addUri("meta", "ibex://meta");
- if (c.getUri("") == null || "".equals(c.getUri(""))) c.addUri("", initial_uri);
state = STATE_IN_ROOT_NODE;
return;
case STATE_IN_ROOT_NODE:
Log.error(Template.class, e);
}
}
-
- Hash urimap = c.getUriMap();
- t.urikeys = new String[urimap.size()];
- t.urivals = new String[urimap.size()];
- Enumeration uriEnumeration = urimap.keys();
+
+ Tree.Prefixes prefixes = c.getPrefixes();
+ t.urikeys = new String[prefixes.pfxSize()];
+ t.urivals = new String[prefixes.pfxSize()];
+
int ii = 0;
- while(uriEnumeration.hasMoreElements()) {
- String key = (String)uriEnumeration.nextElement();
- String val = (String)urimap.get(key);
+ for (int i=0; i < prefixes.pfxSize(); i++) {
+ String key = prefixes.getPrefixKey(i);
+ String val = prefixes.getPrefixVal(i);
if (val.equals("ibex://ui")) continue;
if (val.equals("ibex://meta")) continue;
t.urikeys[ii] = key;
t.urivals[ii] = val;
ii++;
}
-
- Vec keys = new Vec(c.getAttrLen());
- Vec vals = new Vec(c.getAttrLen());
+
+ // FIXME: 2-value Array
+ Basket.Array keys = new Basket.Array(a.attrSize());
+ Basket.Array vals = new Basket.Array(a.attrSize());
// process attributes into Vecs, dealing with any XML Namespaces in the process
- ATTR: for (int i=0; i < c.getAttrLen(); i++) {
- if (c.getAttrKey(i).equals("id")) {
- t.id = c.getAttrVal(i).toString().intern();
+ ATTR: for (int i=0; i < a.attrSize(); i++) {
+ if (a.getKey(i).equals("id")) {
+ t.id = a.getVal(i).toString().intern();
continue ATTR;
}
// treat value starting with '.' as resource reference
- String uri = c.getAttrUri(i); if (!uri.equals("")) uri = '.' + uri;
- keys.addElement(c.getAttrKey(i));
- vals.addElement((c.getAttrVal(i).startsWith(".") ? uri : "") + c.getAttrVal(i));
+ String uri = a.getUri(i); if (!uri.equals("")) uri = '.' + uri;
+ keys.add(a.getKey(i));
+ vals.add((a.getVal(i).startsWith(".") ? uri : "") + a.getVal(i));
}
if (keys.size() == 0) return;
// sort the attributes lexicographically
- Vec.sort(keys, vals, new Vec.CompareFunc() { public int compare(Object a, Object b) {
- return ((String)a).compareTo((String)b);
- } });
+ Basket.Array.sort(keys, vals, new Basket.CompareFunc() {
+ public int compare(Object a, Object b) { return ((String)a).compareTo((String)b); }
+ }, 0, keys.size());
t.keys = new JS[keys.size()];
t.vals = new JS[vals.size()];
// convert attributes to appropriate types and intern strings
for(int i=0; i<t.keys.length; i++) {
// FEATURE: Intern
- t.keys[i] = JSU.S((String)keys.elementAt(i));
- String valString = (String) vals.elementAt(i);
+ t.keys[i] = JSU.S((String)keys.get(i));
+ String valString = (String) vals.get(i);
if (valString.equals("true")) t.vals[i] = JSU.T;
else if (valString.equals("false")) t.vals[i] = JSU.F;
}
}
- public void endElement(XML.Element c) throws XML.Exn, IOException {
+ public void endElement(Tree.Element c) throws XML.Exn, IOException {
switch(state) {
case STATE_IN_META_NODE: if (--meta < 0) state = STATE_IN_ROOT_NODE; return;
case STATE_IN_ROOT_NODE: return;
public void whitespace(char[] ch, int start, int length) throws XML.Exn { }
}
- private static class PerInstantiationScope extends JS.O {
+ // FIXME: david, get to work
+ private static class PerInstantiationScope extends JS.Obj {
Ibex ibex = null;
PerInstantiationScope parentBoxPis = null;
JS myStatic = null;
this.box = box;
}
public JS get(JS key) throws JSExn {
- if(JS.isString(key)) {
- String s = JS.toString(key);
+ if(JSU.isString(key)) {
+ String s = JSU.toString(key);
// JS:FIXME This is a hack
if (super.get(key) != null) return super.get(key);
if (s.equals("ibex")) return ibex;
}
// JS:FIXME: Everything below here should come from js.scope or something
public void put(JS key, JS val) throws JSExn { if(box != null) box.putAndTriggerTraps(key,val); else super.put(key,val); }
- public void addTrap(JS key, JSFunction f) throws JSExn { box.addTrap(key,f); }
- public void delTrap(JS key, JSFunction f) throws JSExn { box.delTrap(key,f); }
+ public void addTrap(JS key, JS f) throws JSExn { box.addTrap(key,f); }
+ public void delTrap(JS key, JS f) throws JSExn { box.delTrap(key,f); }
}
}
static final Hashtable glyphsToBeCached = new Hashtable();
static final Hashtable glyphsToBeDisplayed = new Hashtable();
- private static Cache fontCache = new Cache(100);
+ // HACK: replace with Cache<JS, int>
+ private static Basket.Map fonts = new Basket.HashMap();
public static Font getFont(JS stream, int pointsize) {
- Font ret = (Font)fontCache.get(stream, new Integer(pointsize));
- if (ret == null) fontCache.put(stream, new Integer(pointsize), ret = new Font(stream, pointsize));
+ Basket.Map m = (Basket.Map)fonts.get(stream);
+ Font ret = null;
+ if (m != null) ret = (Font)m.get(new Integer(pointsize));
+ else fonts.put(stream, m = new Basket.HashMap());
+ if (ret == null) m.put(new Integer(pointsize), ret = new Font(stream, pointsize));
return ret;
}
}
// FEATURE do we really need to be caching sizes?
- private static Cache sizeCache = new Cache(1000);
+ private static Cache sizeCache = new Cache(1000, true);
public int textwidth(String s) { return (int)((textsize(s) >>> 32) & 0xffffffff); }
public int textheight(String s) { return (int)(textsize(s) & 0xffffffffL); }
public long textsize(String s) {
return ret;
}
- static final Task glyphRenderingTask = new Task() { public void perform() {
+ static final Callable glyphRenderingTask = new Callable() { public Object run(Object o) {
// FIXME: this should be a low-priority task
glyphRenderingTaskIsScheduled = false;
- if (glyphsToBeCached.isEmpty()) return;
+ if (glyphsToBeCached.isEmpty()) return null;
Glyph g = (Glyph)glyphsToBeCached.keys().nextElement();
- if (g == null) return;
+ if (g == null) return null;
glyphsToBeCached.remove(g);
Log.debug(Font.class, "glyphRenderingTask rendering " + g.c + " of " + g.font);
g.render();
Log.debug(Glyph.class, " done rendering glyph " + g.c);
glyphRenderingTaskIsScheduled = true;
Scheduler.add(this);
+ return null;
} };
if(loadedStream == res) return;
try {
- Log.info(Font.class, "loading font " + JS.debugToString(res));
+ Log.info(Font.class, "loading font " + JSU.str(res));
InputStream is = res.getInputStream();
byte[] fontstream = InputStreamToByteArray.convert(is);
rt.free(loadedStreamAddr);
private static boolean withinLI = false;
// FEATURE: This is ugly
- private static class JS extends org.ibex.js.JS.O {
+ private static class JS extends org.ibex.js.JS.Obj {
public void put(String key, Object value) throws JSExn {
if(value instanceof String) put(JSU.S(key),JSU.S((String)value));
else if(value instanceof Number) put(JSU.S(key), JSU.N((Number)value));
- else if(value == null) put(JSU.S(key),null);
+ else if(value == null) put(JSU.S(key), (JS)null);
else throw new Error("FIXME");
}
public Object _get(String key) throws JSExn {
org.ibex.js.JS js = get(JSU.S(key));
- if(JS.isInt(js)) return new Integer(JS.toInt(js));
- return JS.toString(js);
+ if(JSU.isInt(js)) return new Integer(JSU.toInt(js));
+ return JSU.toString(js);
}
}
public Picture() { this.stream = null; }
public Picture(JS r) { this.stream = r; }
- private static Cache cache = new Cache(100); ///< Picture, keyed by the Stream that loaded them
+ private static Cache cache = new Cache(100, true); ///< Picture, keyed by the Stream that loaded them
public JS stream = null; ///< the stream we were loaded from
public int width = -1; ///< the width of the image
protected void loaded() { isLoaded = true; }
/** turns a stream into a Picture.Source and passes it to the callback */
- public static Picture load(final JS stream, final Task callback) {
+ public static Picture load(final JS stream, final Callable callback) {
if(stream == null) throw new NullPointerException();
Picture ret = (Picture)cache.get(stream);
if (ret == null) {
* Platform subclasses should include an inner class subclass of
* Surface to return from the Platform._createSurface() method
*/
-public abstract class Surface extends PixelBuffer implements Task {
+public abstract class Surface extends PixelBuffer implements Callable {
// Static Data ////////////////////////////////////////////////////////////////////////////////
if (button == 1) new Message("_Press1", T, root);
else if (button == 2) new Message("_Press2", T, root);
else if (button == 3) {
- Scheduler.add(new Task() { public void perform() throws JSExn {
+ Scheduler.add(new Callable() { public Object run(Object o) throws JSExn {
Platform.clipboardReadEnabled = true;
try {
root.putAndTriggerTraps(JSU.S("_Press3"), T);
} finally {
Platform.clipboardReadEnabled = false;
}
+ return null;
}});
}
}
private final static JS MOVE = JSU.S("_Move");
/** we enqueue ourselves in the Scheduler when we have a Move message to deal with */
- private Task mover = new Task() {
- public void perform() {
- if (mousex == newmousex && mousey == newmousey) return;
+ private Callable mover = new Callable() {
+ public Object run(Object o) {
+ if (mousex == newmousex && mousey == newmousey) return null;
int oldmousex = mousex; mousex = newmousex;
int oldmousey = mousey; mousey = newmousey;
String oldcursor = cursor; cursor = "default";
if (oldmousex != mousex || oldmousey != mousey)
root.putAndTriggerTrapsAndCatchExceptions(MOVE, T);
if (!cursor.equals(oldcursor)) syncCursor();
+ return null;
} };
/**
// FEATURE: can we avoid creating objects here?
protected final void PosChange(final int x, final int y) {
- Scheduler.add(new Task() { public void perform() throws JSExn {
+ Scheduler.add(new Callable() { public Object run(Object o) throws JSExn {
root.x = x;
root.y = y;
root.putAndTriggerTrapsAndCatchExceptions(JSU.S("PosChange"), T);
+ return null;
}});
}
private boolean scheduled = false;
public void Refresh() { if (!scheduled) Scheduler.add(this); scheduled = true; }
- public void perform() { scheduled = false; Scheduler.renderAll(); }
+ public Object run(Object o) { scheduled = false; Scheduler.renderAll(); return null; }
public final void setMaximized(boolean b) { if (b != maximized) _setMaximized(maximized = b); }
public final void setMinimized(boolean b) { if (b != minimized) _setMinimized(minimized = b); }
}
// FEATURE: reinstate recycler
- public class Message implements Task {
+ public class Message implements Callable {
private Box boxContainingMouse;
private JS value;
Scheduler.add(this);
}
- public void perform() throws JSExn {
+ public Object run(Object o) throws JSExn {
if (name.equals("_KeyPressed")) {
- String value = JS.toString(this.value);
+ String value = JSU.toString(this.value);
if (value.toLowerCase().endsWith("shift")) shift = true; else if (shift) value = value.toUpperCase();
if (value.toLowerCase().equals("alt")) alt = true; else if (alt) value = "A-" + value;
if (value.toLowerCase().endsWith("control")) control = true; else if (control) value = "C-" + value;
if (value.equals("C-v") || value.equals("A-v")) Platform.clipboardReadEnabled = true;
this.value = JSU.S(value);
} else if (name.equals("_KeyReleased")) {
- String value = JS.toString(this.value);
+ String value = JSU.toString(this.value);
if (value.toLowerCase().equals("alt")) alt = false;
else if (value.toLowerCase().equals("control")) control = false;
else if (value.toLowerCase().equals("shift")) shift = false;
this.value = JSU.S(value);
} else if (name.equals("_HScroll") || name.equals("_VScroll")) {
// FIXME: technically points != pixels
- if (JS.isInt(value))
- value = JSU.N(JS.toInt(value) * root.fontSize());
+ if (JSU.isInt(value))
+ value = JSU.N(JSU.toInt(value) * root.fontSize());
}
try {
boxContainingMouse.putAndTriggerTrapsAndCatchExceptions(JSU.S(name), value);
} finally {
Platform.clipboardReadEnabled = false;
}
+ return null;
}
- public String toString() { return "Message [name=" + name + ", value=" + JS.debugToString(value) + "]"; }
+ public String toString() { return "Message [name=" + name + ", value=" + JSU.str(value) + "]"; }
}
public void deleteTexture(final int tex) {
// CHECKME: Is this safe to do from finalize()?
// natDeleteTexture MUST be run from the message queue thread
- Scheduler.add(new Task() { public void perform() { natDeleteTexture(tex); }});
+ Scheduler.add(new Callable() { public Object run(Object o) { natDeleteTexture(tex); return null; }});
}
private static abstract class GLPicture {
ret.Refresh();
}
try {
- if (b.get(JSU.S("titlebar")) != null) ret.setTitleBarText(JS.toString(b.get(JSU.S("titlebar"))));
+ if (b.get(JSU.S("titlebar")) != null) ret.setTitleBarText(JSU.toString(b.get(JSU.S("titlebar"))));
} catch (JSExn e) {
Log.warn(Platform.class, e);
}