Revision: 3183 http://vexi.svn.sourceforge.net/vexi/?rev=3183&view=rev Author: clrg Date: 2008-11-07 14:46:38 +0000 (Fri, 07 Nov 2008)
Log Message: ----------- Add assignParent locking to prevent inconsistencies when looping over box children + updates to TimedTest Modified Paths: -------------- trunk/core/org.vexi.core/src/org/vexi/core/Box.jpp trunk/core/org.vexi.core/src_dev/org/vexi/core/TimedTest.java Modified: trunk/core/org.vexi.core/src/org/vexi/core/Box.jpp =================================================================== --- trunk/core/org.vexi.core/src/org/vexi/core/Box.jpp 2008-11-06 22:49:47 UTC (rev 3182) +++ trunk/core/org.vexi.core/src/org/vexi/core/Box.jpp 2008-11-07 14:46:38 UTC (rev 3183) @@ -355,8 +355,13 @@ if (box.text.fontsize_trap) box.justTriggerTraps(SC_fontsize, box.text.sizeToJS()); } - for (int i=0; box.treeSize()>i; i++) + int i=0; + boolean lock = !box.test(LOCK_CHILDREN); + if (lock) box.set(LOCK_CHILDREN); + for (Box b = box.getChild(i); b!=null; b=box.getChild(++i)) { reflowTreeTextSize(box.getChild(i)); + } + if (lock) box.clear(LOCK_CHILDREN); } /** used to invoke reflow on a box and it's children */ @@ -391,13 +396,16 @@ /** constrain box children then establish the minimum size of a box */ private void constrain() { int i; + boolean lock = !test(LOCK_CHILDREN); // reconstrain any children if (test(CONSTRAIN_DESCENDENT)) { + if (lock) set(LOCK_CHILDREN); for (Box c = getChild(i=0); c != null; c = getChild(++i)) { if (!c.test(DISPLAY)) continue; c.constrain(); } + if (lock) clear(LOCK_CHILDREN); clear(CONSTRAIN_DESCENDENT); } @@ -406,7 +414,7 @@ // remember current size int newwidth = 0, newheight = 0; - + if (lock) set(LOCK_CHILDREN); if (test(PACK)) { //#repeat width/height HORIZONTAL/VERTICAL // accumulate child contentwidth @@ -432,6 +440,7 @@ newheight = max(newheight, c.contentheight); } } + if (lock) clear(LOCK_CHILDREN); //#repeat width/height WIDTH/HEIGHT if (newwidth < minwidth || newwidth < text.width) @@ -462,11 +471,14 @@ placeChildren(); if (test(PLACE_DESCENDENT)) { clear(PLACE_DESCENDENT); + boolean lock = !test(LOCK_CHILDREN); + if (lock) set(LOCK_CHILDREN); int i = 0; for (Box child = getChild(0); child != null; child = getChild(++i)) { if (!child.test(DISPLAY)) continue; child.place(); } + if (lock) clear(LOCK_CHILDREN); } } else clear(PLACE|PLACE_DESCENDENT); } @@ -474,7 +486,8 @@ private final void placeChildren() { if (test(PLACE)) { clear(PLACE); - + boolean lock = !test(LOCK_CHILDREN); + if (lock) set(LOCK_CHILDREN); // needed for later resize() int child_width, child_height, i; @@ -712,6 +725,7 @@ } } } + if (lock) clear(LOCK_CHILDREN); } } @@ -990,8 +1004,11 @@ private final void propagateLeave() throws JSExn { clear(MOUSEINSIDE); int i = treeSize()-1; + boolean lock = !test(LOCK_CHILDREN); + if (lock) set(LOCK_CHILDREN); for (Box b = getChild(i); b != null; b = getChild(--i)) if (b.test(MOUSEINSIDE)) b.propagateLeave(); + if (lock) clear(LOCK_CHILDREN); if (test(LEAVE_TRAP)) justTriggerTraps(SC_Leave, JSU.T); } @@ -1007,6 +1024,8 @@ return true; int i; + boolean lock = !test(LOCK_CHILDREN); + if (lock) set(LOCK_CHILDREN); // absolute layout - allows for interruption by overlaying siblings if (!test(PACK)) { for (Box b = getChild(i=treeSize()-1); b != null; b = getChild(--i)) { @@ -1024,6 +1043,7 @@ else if (b.test(MOUSEINSIDE)) b.propagateLeave(); } } + if (lock) clear(LOCK_CHILDREN); // set cursor if applicable to this box if (test(CURSOR)) { @@ -1066,6 +1086,8 @@ return true; int i; + boolean lock = !test(LOCK_CHILDREN); + if (lock) set(LOCK_CHILDREN); // absolute layout - check all children if (!test(PACK)) { for (Box b = getChild(i=treeSize()-1); b != null; b = getChild(--i)) { @@ -1083,6 +1105,7 @@ // packing so no other sibling has mouse inside break; } } } + if (lock) clear(LOCK_CHILDREN); if (Interpreter.CASCADE_PREVENTED == justTriggerTraps(JSU.S(event), value)) return true; @@ -1607,13 +1630,16 @@ if (trapchain.exn != null) return trapchain; } - for (int i = 0; i < treeSize(); i++) { - Box b = getChild(i); + int i=0; + boolean lock = !test(LOCK_CHILDREN); + if (lock) set(LOCK_CHILDREN); + for (Box b = getChild(i); b!=null; b=getChild(++i)) { trapchain = b.fireSurfaceTraps(val, trapchain); // interrupted by a JS exception if (trapchain != null && trapchain.exn != null) return trapchain; } + if (lock) clear(LOCK_CHILDREN); return trapchain; } @@ -1631,8 +1657,10 @@ if (trapchain.exn != null) return trapchain; } - for (int i = 0; i < treeSize(); i++) { - Box b = getChild(i); + int i=0; + boolean lock = !test(LOCK_CHILDREN); + if (lock) set(LOCK_CHILDREN); + for (Box b = getChild(i); b!=null; b=getChild(++i)) { if (b.test(DISPLAY)) { trapchain = b.fireVisibleTraps(val, trapchain); // interrupted by a JS exception @@ -1640,6 +1668,7 @@ return trapchain; } } + if (lock) clear(LOCK_CHILDREN); return trapchain; } @@ -1647,10 +1676,10 @@ // Tree Handling ////////////////////////////////////////////////////////////////////// // children - private final Box getChild(int i) { if (i < 0 || i >= treeSize()) return null; return getNode(i); } + protected final int treeSize() { return bt == null ? 0 : bt.treeSize(); } + protected final Box getChild(int i) { if (i < 0 || i >= treeSize()) return null; return getNode(i); } private final Box getNode(int p) { return (Box)bt.getNode(p); } private final int indexNode(Box b) { return bt == null ? -1 : bt.indexNode(b); } - private final int treeSize() { return bt == null ? 0 : bt.treeSize(); } private final void deleteNode(int p) { bt.deleteNode(p); } private final void insertNode(int p, Box b) { if (bt == null) bt = new BasicTree(); bt.insertNode(p,b); } @@ -1662,7 +1691,7 @@ // Tree Manipulation ///////////////////////////////////////////////////////////////////// /** change the parent of the box and fire relevant traps */ - protected void removeFromParent() throws JSExn { + protected final void removeFromParent() throws JSExn { parent.deleteNode(parent.indexNode(this)); if (test(DISPLAY)) { if (parent.test(PACK) || !parent.test(CLIP)) @@ -1673,12 +1702,14 @@ } /** handle the internal reflow/layout logic of parent assignment */ - private void assignToParent(Box newparent, int i) throws JSExn { + protected final void assignToParent(Box newparent, int i) throws JSExn { // do not put null to Children trap if parent does not change if (newparent == parent) { if (parent == null) return; int ind = parent.indexNode(this); if (ind == i) return; + if (parent.test(LOCK_CHILDREN)) + throw new JSExn("Attempt to remove child from parent whilst box tree is active"); if (test(DISPLAY)) dirty(); parent.deleteNode(ind); parent.insertNode(i, this); @@ -1686,8 +1717,11 @@ return; } // check validity of new parent assignment - if (newparent != null && i == -1) { - throw new JSExn("Illegal attempt to set the parent of a box"); + if (newparent != null) { + if (i == -1) + throw new JSExn("Illegal attempt to set the parent of a box"); + if (newparent.test(LOCK_CHILDREN)) + throw new JSExn("Attempt to add child to parent whilst box tree is active"); } // FIXME handle Enter/Leave better clear(MOUSEINSIDE); Modified: trunk/core/org.vexi.core/src_dev/org/vexi/core/TimedTest.java =================================================================== --- trunk/core/org.vexi.core/src_dev/org/vexi/core/TimedTest.java 2008-11-06 22:49:47 UTC (rev 3182) +++ trunk/core/org.vexi.core/src_dev/org/vexi/core/TimedTest.java 2008-11-07 14:46:38 UTC (rev 3183) @@ -5,33 +5,49 @@ abstract class TimedTest { - static final int num = 10000; - static final Box box = new Box(); - abstract void test(); - void timedTest() { + private long timedTest() { long start = System.currentTimeMillis(); test(); long end = System.currentTimeMillis(); - System.out.println((end - start) + " milli seconds for '"+this.getClass().getSimpleName()+"' loop"); + return end - start; } + void singleTimedTest() { + System.out.println(timedTest() + " milli seconds for '"+this.getClass().getSimpleName()+"'"); + } + + void averageTimedTest() { averageTimedTest(20); } + void averageTimedTest(int numtests) { + long time = 0; + for (int i=0; numtests>i; i++) time += timedTest(); + System.out.println((time/numtests) + "ms average for '"+this.getClass().getSimpleName()+"'"); + } + + static final int numboxes = 10000; + static final Box testroot = new Box(); + static final void reset() throws JSExn { + System.out.println("prepare boxes for test"); + for (int i = 0; i < numboxes; i++) { + (new Box()).assignToParent(testroot, i); + } + System.out.println("start tests"); + } + public static void main(String[] args) { try { - System.out.println("prepare boxes for test"); - - for (int i = 0; i < num; i++) { - (new Box()).assignToParent(box, i); - } - - System.out.println("start tests"); + reset(); - new IntLoopStandard().timedTest(); - new IntLoopCompareToZero().timedTest(); - new TreeSizeLoopInline().timedTest(); - new TreeSizeLoopSizeToZero().timedTest(); - new TreeSizeLoopZeroToSize().timedTest(); + new IntLoopStandard().averageTimedTest(); + new IntLoopCompareToZero().averageTimedTest(); + new TreeSizeLoopInline().averageTimedTest(); + new TreeSizeLoopSizeToZero().averageTimedTest(); + new TreeSizeLoopZeroToSize().averageTimedTest(); + new GetChildLoopBoxInline().averageTimedTest(); + new GetChildLoopBoxInFor().averageTimedTest(); + new GetChildLoopBoxOutsideFor().averageTimedTest(); + new GetChildLoopBoxOutsideForCompareToZero().averageTimedTest(); } catch (JSExn e) { Log.uWarn(Box.class, "Caught JS Exception in LoopTest"); @@ -41,12 +57,10 @@ } class IntLoopStandard extends TimedTest { - String getName() { return "standard int loop"; } - IntLoopStandard() { } void test() { for (int j = 0; j < 1000; j++) { - for (int i = 0; i < num; i++) { - if (i == num) + for (int i = 0; i < numboxes; i++) { + if (i == numboxes) System.out.println("never happens"); } } @@ -54,12 +68,10 @@ } class IntLoopCompareToZero extends TimedTest { - String getName() { return "standard int loop"; } - IntLoopCompareToZero() { } void test() { for (int j = 0; j < 1000; j++) { - for (int i = 0; i < num; i++) { - if (i == num) + for (int i = 0; i < numboxes; i++) { + if (i == numboxes) System.out.println("never happens"); } } @@ -67,12 +79,10 @@ } class TreeSizeLoopInline extends TimedTest { - String name = "treeSize() loop"; - TreeSizeLoopInline() { } void test() { for (int j = 0; j < 1000; j++) { - for (int i = 0; i < box.treeSize(); i++) { - if (i-1 == num) + for (int i = 0; i < testroot.treeSize(); i++) { + if (i-1 == numboxes) System.out.println("never happens"); } } @@ -80,13 +90,11 @@ } class TreeSizeLoopZeroToSize extends TimedTest { - String name = "treeSize() loop 2"; - TreeSizeLoopZeroToSize() { } void test() { for (int j = 1000; j > 0; j--) { - int s = box.treeSize(); + int s = testroot.treeSize(); for (int i = 0; i < s; i++) { - if (i-1 == num) + if (i-1 == numboxes) System.out.println("never happens"); } } @@ -94,15 +102,66 @@ } class TreeSizeLoopSizeToZero extends TimedTest { - String name = "treeSize() loop 3"; - TreeSizeLoopSizeToZero() { } void test() { for (int j = 1000; j > 0; j--) { - int s = box.treeSize(); + int s = testroot.treeSize(); for (int i = s; 0 < i; i--) { - if (i-1 == num) + if (i-1 == numboxes) System.out.println("never happens"); } } } } + +class GetChildLoopBoxInline extends TimedTest { + void test() { + for (int j = 1000; j > 0; j--) { + int s = testroot.treeSize(); + for (int i=0; i<s; i++) { + Box b = testroot.getChild(i); + if (b == testroot) + System.out.println("never happens"); + } + } + } +} + +class GetChildLoopBoxInFor extends TimedTest { + void test() { + for (int j = 1000; j > 0; j--) { + int i; + for (Box b = testroot.getChild(i=0); b!=null; b=testroot.getChild(++i)) { + if (b == testroot) + System.out.println("never happens"); + } + } + } +} + +class GetChildLoopBoxOutsideFor extends TimedTest { + void test() { + for (int j = 1000; j > 0; j--) { + int s = testroot.treeSize(); + Box b; + for (int i=0; i<s; i++) { + b = testroot.getChild(i); + if (b == testroot) + System.out.println("never happens"); + } + } + } +} + +class GetChildLoopBoxOutsideForCompareToZero extends TimedTest { + void test() { + for (int j = 1000; j > 0; j--) { + int s = testroot.treeSize(); + Box b; + for (int i=s; i>0; i--) { + b = testroot.getChild(s-i); + if (b == testroot) + System.out.println("never happens"); + } + } + } +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ Vexi-svn mailing list Vexi-svn@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/vexi-svn