- 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
This commit is contained in:
Ray Greenwell
2008-02-19 00:50:08 +00:00
parent 474d616204
commit 16e17444c7
+40 -47
View File
@@ -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.
*/