X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2FTrap.java;h=196c445472c11d86d6bb7f8e15925e141ca13b3f;hb=8235361e8601ae7b36ab707058de3b52225d15a2;hp=770ad51b35d1d6d032d3034db72fd11138d744ad;hpb=f2eb7d5128e23542ce51973714eeb41ca1d37a6d;p=org.ibex.core.git diff --git a/src/org/xwt/Trap.java b/src/org/xwt/Trap.java index 770ad51..196c445 100644 --- a/src/org/xwt/Trap.java +++ b/src/org/xwt/Trap.java @@ -1,4 +1,4 @@ -// Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL] +// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL] package org.xwt; import java.util.*; @@ -15,51 +15,36 @@ public class Trap { // Static Data ////////////////////////////////////////////////////////////// - /** a vector of weak references to all instances of Trap; used for retheming */ - private static Hashtable allTraps = new Hashtable(1000); - /** List of properties that cannot be trapped */ private static final Hash PROHIBITED = new Hash(120, 3); static { String[] p = new String[] { - "sizetoimage", "shrink", "hshrink", "vshrink", "x", "y", "width", "height", - "flex", "align", "invisible", "absolute", "globalx", "globaly", - "minwidth", "minheight", "height", "width", "maxwidth", "maxheight", - "numchildren", "hpad", "vpad", "doublebuffered", "cursor", - "mousex", "mousey", "xwt", "static", "mouseinside", "root", "thisbox", "indexof", "svg" + "shrink", "hshrink", "vshrink", "x", "y", + "width", "height", "flex", "colspan", "rowspan", "cols", + "rows", "align", "invisible", "absolute", "globalx", + "globaly", "minwidth", "minheight", "height", "width", + "maxwidth", "maxheight", "numchildren", "hpad", "vpad", + "buffered", "cursor", "mousex", "mousey", + "mouseinside", "thisbox", "indexof", "path", "font", "fontsize" }; for(int i=0; i
b
by the currently-running script */
- public static Trap getTrap(Box b, String name) {
- if (b.traps == null) return null;
-
- String currentFunctionNodeName = JS.getCurrentFunctionSourceName();
- for(Trap cur = (Trap)b.traps.get(name); cur != null; cur = cur.next)
- if (cur.placerNodeName.equals(currentFunctionNodeName))
- return cur;
- return null;
- }
-
- /** Called by Rhino's arguments.cascade. Note: cx will be null if this was invoked from perform() rather than from a script. */
- public static final CascadeFunction cascadeFunction = new CascadeFunction();
- private static class CascadeFunction extends JS.Function {
- CascadeFunction() { setSeal(true); }
- public Object _call(JS.Array args) { return _call(args, JS.getCurrentFunction()); }
- public Object _call(JS.Array args, Function currentFunction) {
- Trap currentTrap = TrapContext.get().currentTrap;
- if (args.length() != 0) TrapContext.get().putCascadeHappened = true;
- Trap t = currentTrap.next;
- // if we've hit the end of the trap stack, just do a put(,,,true)
- if (t == null) {
- if (args.length() == 0) return currentTrap.trapee.get(currentTrap.name, true);
- currentTrap.trapee.put(currentTrap.name, args.elementAt(0), true);
- return null;
- }
- return t.perform(args);
+ /**
+ * deletes a trap.
+ * @param trapee the box to remove the trap from
+ * @param name the name of the property to trap on
+ * @param f the function to remove
+ */
+ static void delTrap(Box trapee, Object name, JS.CompiledFunction f) {
+ Trap t = (Trap)trapee.get(name, Trap.class);
+ if (t.f == f) {
+ trapee.put(name, Trap.class, t.next);
+ return;
}
- };
-
- /** called by Rhino's arguments.trapee hack */
- public static Object currentTrapee() {
- Trap current = TrapContext.get().currentTrap;
- if (current == null) return null;
- else if (current.rp != null) return current.rp;
- else return current.trapee;
- }
-
- /** called by Rhino's arguments.trapname hack */
- public static String currentTrapname() {
- Trap current = TrapContext.get().currentTrap;
- if (current == null) return null;
- else return current.name;
+ for(; t.next != null; t = t.next)
+ if (t.next.f == f) {
+ t.next = t.next.next;
+ return;
+ }
+ Log.logJS("warning: tried to remove a trap that had not been placed");
}
// Instance Methods //////////////////////////////////////////////////////////////////////////
- private Trap() { allTraps.put(myWeak, dummy); }
-
- /** perform this trap -- arg.length == 0 if this is a get; otherwise it contains a single element to be put */
- public Object perform(JS.Array args) {
- TrapContext tc = TrapContext.get();
-
- // save both thread-locals on the stack and update their values
- Trap save_currentTrap = tc.currentTrap;
- tc.currentTrap = this;
+ private Trap() { }
- boolean save_putCascadeHappened = tc.putCascadeHappened;
- tc.putCascadeHappened = false;
-
- // invoke the trap function
- try {
- if (!isreadtrap && args.length() == 0) return cascadeFunction._call(args, f);
-
- if (f == null) {
- if (Log.verbose) Log.log(this, "debug: reclaimed a dangling trap on property " + name);
- Object ret = cascadeFunction._call(args, f);
- delete();
- return ret;
- }
-
- System.out.println("calling trap on " + name);
- Object ret = null;
- try {
- ret = f._call(args);
- } catch (org.xwt.js.ByteCodeBlock.ReturnException re) {
- ret = re.retval;
- }
-
- // autocascade if required
- if (args.length() > 0 && !isreadtrap && !tc.putCascadeHappened) cascadeFunction._call(args, f);
-
- return ret;
-
- } catch (JS.Exn e) {
- if (Log.on) Log.log(this, e);
-
- } finally {
- // restore the thread-locals
- tc.putCascadeHappened = save_putCascadeHappened;
- tc.currentTrap = save_currentTrap;
- tc.trapDepth--;
- }
- return null;
+ public Object perform() throws JS.Exn {
+ if (f.getNumFormalArgs() > 0) return cascade();
+ return f.call(new TrapArgs(this));
}
-
- /** removes this trap */
- public void delete() {
- for(Trap last = null, cur = (Trap)trapee.traps.get(name); cur != null; last = cur, cur = cur.next) {
- if (cur != this) continue;
- else if (last != null) last.next = cur.next;
- else if (cur.next == null) trapee.traps.remove(name);
- else trapee.traps.put(name, cur.next);
- }
- if (trapee.surface != null && !trapee.is_trapped("KeyPressed") && !trapee.is_trapped("KeyReleased"))
- trapee.surface.keywatchers.removeElement(trapee);
- allTraps.remove(myWeak);
+
+ public void perform(Object val) throws JS.Exn {
+ if (f.getNumFormalArgs()== 0) cascade(val);
+ f.call(new TrapArgs(this, val));
+ }
+
+ public Object cascade() {
+ if (next != null) return next.perform();
+ return trapee.get(name, true);
}
- /** per-thread storage for Traps */
- private static class TrapContext {
-
- private static Hash trapContextByThread = new Hash();
- private TrapContext() { }
-
- private boolean putCascadeHappened = false;
- private Trap currentTrap = null;
- private int trapDepth = 0;
+ public void cascade(Object val) {
+ if (next != null) next.perform(val);
+ trapee.put(name, val, true);
+ }
- /** returns the TrapContext for the current thread */
- static TrapContext get() {
- TrapContext ret = (TrapContext)trapContextByThread.get(Thread.currentThread());
- if (ret == null) {
- ret = new TrapContext();
- trapContextByThread.put(Thread.currentThread(), ret);
- }
- return ret;
+ private static class TrapArgs extends JS.Array {
+ private Trap t;
+ public TrapArgs(Trap t) { this.t = t; }
+ public TrapArgs(Trap t, Object value) { this.t = t; addElement(value); }
+
+ public void put(Object key, Object val) {
+ if (key.equals("cascade")) t.cascade(val);
+ else super.put(key, val);
}
+ public Object get(Object key) {
+ // common case
+ if(!(key instanceof String)) return super.get(key);
+ if (key.equals("trapee")) return t.trapee;
+ if (key.equals("trapname")) return t.name;
+ if (key.equals("cascade")) return t.cascade();
+ return super.get(key);
+ }
}
-
}