From 16e17444c7d97c99de0e9bc963722b7fc9911663 Mon Sep 17 00:00:00 2001 From: Ray Greenwell Date: Tue, 19 Feb 2008 00:50:08 +0000 Subject: [PATCH] - Removed pointless "default" sorting method. - Since quicksort is unstable anyway, might as well avoid a swap if two elements are equal. - Be generous with the comparator function. It should really return -1, 0, 1, but sometimes people return positive numbers, 0, negative numbers... - If Array.sort() is a stable sort, I think we should just change this impl to put all children into an array, sort'em, then set their indexes back into the parent. git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@423 ed5b42cb-e716-0410-a449-f6a68f950b19 --- src/as/com/threerings/flash/DisplayUtil.as | 87 ++++++++++------------ 1 file changed, 40 insertions(+), 47 deletions(-) diff --git a/src/as/com/threerings/flash/DisplayUtil.as b/src/as/com/threerings/flash/DisplayUtil.as index c4060ba8..9f358164 100644 --- a/src/as/com/threerings/flash/DisplayUtil.as +++ b/src/as/com/threerings/flash/DisplayUtil.as @@ -39,55 +39,10 @@ public class DisplayUtil * object should appear before the second in the container, 1 if it should appear after, * and 0 if the order does not matter. (Since quicksort is not a stable sort algorithm, * returning 0 in the compare function is equivalent to returning -1). - * - * If comp 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, comp :Function = null) :void + public static function sortDisplayChildren (container :DisplayObjectContainer, comp :Function) :void { - qsortDisplayChildren(container, 0, container.numChildren - 1, (null != comp ? comp : displayObjectYLessEqual)); - } - - private static function displayObjectYLessEqual (a :DisplayObject, b :DisplayObject) :int - { - return (a.y <= b.y ? -1 : 1); - } - - /** Helper function for sortDisplayChildren. */ - private static function qsortDisplayChildren (container :DisplayObjectContainer, left :int, right :int, comp :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, comp); - qsortDisplayChildren(container, left, pivotIndex - 1, comp); - qsortDisplayChildren(container, pivotIndex + 1, right, comp); - } - } - - /** Helper function for qsortDisplayChildren. */ - private static function partitionDisplayChildren ( - container :DisplayObjectContainer, left :int, right :int, pivotIndex :int, comp :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 (1 != comp(thisObj, pivotObj)) { - container.swapChildrenAt(i, storeIndex); - storeIndex += 1; - } - } - - container.swapChildrenAt(storeIndex, right); - - return storeIndex; + qsortDisplayChildren(container, 0, container.numChildren - 1, comp); } /** @@ -268,6 +223,44 @@ public class DisplayUtil return dumpHierarchy0(top); } + /** Helper function for sortDisplayChildren. */ + private static function qsortDisplayChildren ( + container :DisplayObjectContainer, left :int, right :int, comp :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) / 2); + + pivotIndex = partitionDisplayChildren(container, left, right, pivotIndex, comp); + qsortDisplayChildren(container, left, pivotIndex - 1, comp); + qsortDisplayChildren(container, pivotIndex + 1, right, comp); + } + } + + /** Helper function for qsortDisplayChildren. */ + private static function partitionDisplayChildren ( + container :DisplayObjectContainer, left :int, right :int, pivotIndex :int, comp :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 (0 > comp(thisObj, pivotObj)) { + container.swapChildrenAt(i, storeIndex); + storeIndex += 1; + } + } + + container.swapChildrenAt(storeIndex, right); + + return storeIndex; + } + /** * Internal worker method for findInHierarchy. */