From e8f252351543ca7a2c3426d637fd657baee00c14 Mon Sep 17 00:00:00 2001 From: Tom Conkling Date: Tue, 19 Feb 2008 00:14:17 +0000 Subject: [PATCH] added DisplayUtil.sortDisplayChildren, for quicksorting the contents of a DisplayObjectContainer git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@421 ed5b42cb-e716-0410-a449-f6a68f950b19 --- src/as/com/threerings/flash/DisplayUtil.as | 63 ++++++++++++++++++++-- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/src/as/com/threerings/flash/DisplayUtil.as b/src/as/com/threerings/flash/DisplayUtil.as index 1909129e..6b3f6c7d 100644 --- a/src/as/com/threerings/flash/DisplayUtil.as +++ b/src/as/com/threerings/flash/DisplayUtil.as @@ -21,18 +21,73 @@ package com.threerings.flash { +import com.threerings.util.ClassUtil; + import flash.display.DisplayObject; import flash.display.DisplayObjectContainer; - import flash.geom.Point; import flash.geom.Rectangle; import mx.core.IRawChildrenContainer; -import com.threerings.util.ClassUtil; - public class DisplayUtil { + /** + * Quicksorts container's children. + * + * lessEqualComp is a function that takes two DisplayObjects, and returns Boolean 'true' if the + * first object is less than or equal to the second. + * + * If lessEqualComp is null, sortDisplayChildren will sort container so that objects with smaller + * y-values appear before objects with larger y-values. + */ + public static function sortDisplayChildren (container :DisplayObjectContainer, lessEqualComp :Function = null) :void + { + qsortDisplayChildren(container, 0, container.numChildren - 1, (null != lessEqualComp ? lessEqualComp : displayObjectYLessEqual)); + } + + private static function displayObjectYLessEqual (a :DisplayObject, b :DisplayObject) :Boolean + { + return (a.y <= b.y); + } + + /** Helper function for sortDisplayChildren. */ + private static function qsortDisplayChildren (container :DisplayObjectContainer, left :int, right :int, lessEqualComp :Function) :void + { + if (right - left > 1) { // containers of size 0 or 1 are already sorted + + // arbitrarily choose the element in the middle of the sort list as the pivot element + var pivotIndex :int = left + ((right - left) * 0.5); + + pivotIndex = partitionDisplayChildren(container, left, right, pivotIndex, lessEqualComp); + qsortDisplayChildren(container, left, pivotIndex - 1, lessEqualComp); + qsortDisplayChildren(container, pivotIndex + 1, right, lessEqualComp); + } + } + + /** Helper function for qsortDisplayChildren. */ + private static function partitionDisplayChildren ( + container :DisplayObjectContainer, left :int, right :int, pivotIndex :int, lessEqualComp :Function) :int + { + var pivotObj :DisplayObject = container.getChildAt(pivotIndex); + + container.swapChildrenAt(pivotIndex, right); // move pivot to end + + var storeIndex :int = left; + + for (var i :int = left; i < right; ++i) { + var thisObj :DisplayObject = container.getChildAt(i); + if (lessEqualComp(thisObj, pivotObj)) { + container.swapChildrenAt(i, storeIndex); + storeIndex += 1; + } + } + + container.swapChildrenAt(storeIndex, right); + + return storeIndex; + } + /** * Call the specified function for the display object and all descendants. * @@ -294,5 +349,7 @@ public class DisplayUtil } return inStr; } + + } }