<?xml version="1.0" encoding="utf-8"?>
<FxApplication xmlns="http://ns.adobe.com/mxml/2009" creationComplete="setup();" viewSourceURL="srcview/index.html">
<Script>
<![CDATA[
import mx.controls.dataGridClasses.DataGridColumn;
import mx.collections.ArrayCollection;
[Embed("MergeExchangeSort.pbj", mimeType="application/octet-stream")]
private var sorter:Class;
private static const RIGHT:uint = 0xFF0000;
private static const LEFT:uint = 0x00FF00;
private static const X_OFFSET:int = 1;
private static const Y_OFFSET:int = 1;
private static const N:int = 16;
private var bookkeeper:BitmapData;
private var current:BitmapData;
private var generationCount:int;
[Bindable]
private var running:Boolean;
private function steps(n:int):int
{
var temp:Number = Math.ceil(Math.log(n)/Math.log(2));
var result:Number = temp * (temp + 1) * 0.5;
return int(result);
}
private function createBitmapData(n:int):BitmapData
{
var bitmapData:BitmapData = new BitmapData(n + X_OFFSET, steps(n) + Y_OFFSET, false, 0x000000);
return bitmapData;
}
private function createBookkeeper(n:int):BitmapData
{
var bitmapData:BitmapData = createBitmapData(n);
bitmapData.lock();
var step:int = -1;
var t:int = Math.ceil(Math.log(n)/Math.log(2));
var p:int = Math.pow(2, t - 1);
do
{
var q:int = Math.pow(2, t - 1);
var r:int = 0;
var d:int = p;
var loopOnQ:Boolean = true;
do
{
step++;
bitmapData.setPixel(0, step + Y_OFFSET, d);
for (var i:int = 0; i < n - d; i++)
{
if ((i & p) == r)
{
bitmapData.setPixel(X_OFFSET + i, step + Y_OFFSET, RIGHT);
bitmapData.setPixel(X_OFFSET + i + d, step + Y_OFFSET, LEFT);
}
}
if (q != p)
{
d = q - p;
q = q / 2;
r = p;
}
else
{
loopOnQ = false;
}
}
while (loopOnQ);
p = Math.floor(p / 2);
}
while (p > 0);
bitmapData.unlock();
return bitmapData;
}
private function randomizedData(bitmapData:BitmapData):void
{
bitmapData.lock();
for (var i:int = X_OFFSET; i < bitmapData.width; i++)
{
var temp:uint = Math.random() * 0xFFFF;
bitmapData.setPixel(i, 0, temp);
}
bitmapData.unlock();
}
private function nextGeneration():void
{
if ((running) || (current == null))
{
return;
}
running = true;
var shader:Shader = new Shader(new sorter() as ByteArray);
shader.data.src.input = current;
shader.data.book.input = bookkeeper;
var result:BitmapData = new BitmapData(current.width, current.height);
var shaderJob:ShaderJob = new ShaderJob(shader, result, current.width, current.height);
shaderJob.addEventListener(ShaderEvent.COMPLETE, handleShaderDone);
shaderJob.start();
}
private function handleShaderDone(shaderEvent:ShaderEvent):void
{
current = shaderEvent.bitmapData;
generationCount++;
running = false;
if (pipeline.selected)
{
randomizedData(current);
}
dumpData(current);
if (automatic.selected)
{
nextGeneration();
}
}
private function setup():void
{
bookkeeper = createBookkeeper(N);
current = createBitmapData(N);
randomizedData(current);
var columns:Array = new Array();
var dgc:DataGridColumn = new DataGridColumn();
dgc.dataField = "step";
columns.push(dgc);
for (var i:int = 1; i <= N; i++)
{
dgc = new DataGridColumn();
dgc.dataField = String(i);
columns.push(dgc);
}
currentData.columns = columns;
dumpData(current);
}
private function dumpData(bitmapData:BitmapData):void
{
var data:ArrayCollection = new ArrayCollection();
for (var y:int = 0; y < bitmapData.height; y++)
{
var row:Object = new Object();
row.step = y;
for (var x:int = X_OFFSET; x < bitmapData.width; x++)
{
row[x] = bitmapData.getPixel(x, y);
}
data.addItem(row);
}
currentData.dataProvider = data;
for (var i:int = X_OFFSET; i < bitmapData.width - 1; i++)
{
if (bitmapData.getPixel(i, bitmapData.height -1) > bitmapData.getPixel(i + 1, bitmapData.height -1))
{
throw new Error("Compare error");
}
}
}
]]>
</Script>
<layout>
<VerticalLayout/>
</layout>
<FxContainer>
<layout>
<HorizontalLayout/>
</layout>
<FxButton label="Next Step" click="nextGeneration();" enabled="{!running}"/>
<FxCheckBox id="pipeline" label="Pipeline"/>
<FxCheckBox id="automatic" label="Automatic Stepping" change="nextGeneration();"/>
</FxContainer>
<DataGrid id="currentData" width="1000" sortableColumns="false" height="400"/>
</FxApplication>