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

Reply via email to