blob: 66df322eacd9fe9e7f669a5cfb3233c3d6715e44 [file] [log] [blame]
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Script>
<![CDATA[
import flash.utils.getTimer;
import mx.collections.ArrayCollection;
import mx.collections.ArrayList;
import mx.collections.Grouping;
import mx.collections.GroupingCollection;
import mx.collections.GroupingCollection2;
import mx.collections.GroupingField;
import mx.collections.HierarchicalCollectionView;
import mx.collections.ICollectionView;
import mx.collections.IList;
import mx.collections.Sort;
import mx.collections.SortField;
import mx.events.FlexEvent;
import mx.managers.LayoutManager;
protected function application1_applicationCompleteHandler(event:FlexEvent):void
{
}
public var collectionTests:CollectionTest = new CollectionTest();
public var testResultsAdd:Array;
public var testResultsUpdate:Array;
public static const NUM_ITERATIONS_PER_SECOND:int = 4;
private static const NON_BINDABLE_OBJECT:int = 0;
private static const PROPERTY_CHANGE_BINDABLE_OBJECT:int = 1;
private static const SINGLE_VERSION_EVENT_BINDABLE_OBJECT:int = 2;
private static const UNIQUE_EVENT_BINDABLE_OBJECT:int = 3;
private static const ARRAY_COLLECTION_TYPE:int = 0;
private static const ARRAY_COLLECTION_FILTER_TYPE:int = 1;
private static const ARRAY_COLLECTION_SORT_TYPE:int = 2;
private static const ARRAY_COLLECTION_FILTER_SORT_TYPE:int = 3;
private static const WRAPPING_COLLECTION_NONE:int = 0;
private static const WRAPPING_COLLECTION_HCV_NO_GROUPING:int = 1;
private static const WRAPPING_COLLECTION_HCV_WITH_GROUPING:int = 2;
public function get numItemsToInitializeWith():int
{
return seedItemAmountInput.value;
}
public function get fillSeedItems():Boolean
{
return fillSeedItemsInput.selected;
}
public function get numIterations():int
{
return numSecondsInput.value * NUM_ITERATIONS_PER_SECOND;
}
public function get numItemsToAddPerSecond():int
{
return numItemsToAddPerSecondInput.value;
}
public function get fillObjectsInitially():Boolean
{
return fillObjectsInitiallyCheckBox.selected;
}
public function get numItemsToUpdatePerSecond():int
{
return numItemsToUpdatePerSecondInput.value;
}
public function get numPropertiesPerUpdate():int
{
return numPropsToUpdatePerObjectUpdateInput.value;
}
public function runTest():void
{
collectionTests.addEventListener(CollectionTest.TEST_COMPLETE, testCompleteHandler);
switch (collectionToUseDropDownList.selectedIndex)
{
case ARRAY_COLLECTION_TYPE:
case ARRAY_COLLECTION_FILTER_TYPE:
case ARRAY_COLLECTION_SORT_TYPE:
case ARRAY_COLLECTION_FILTER_SORT_TYPE:
startCollectionTest();
break;
}
}
private var validationTime:int;
private var layoutManagerStartTime:int;
private var renderTime:int;
private var layoutManagerEndTime:int;
private function layoutManager_layoutManagerStartHandler(event:Event):void
{
layoutManagerStartTime = getTimer();
}
private function layoutManager_layoutManagerEndHandler(event:Event):void
{
layoutManagerEndTime = getTimer();
validationTime += (layoutManagerEndTime - layoutManagerStartTime);
}
private function enterFrameHandler(event:Event):void
{
if (layoutManagerEndTime > 0)
{
renderTime += (getTimer() - layoutManagerEndTime);
layoutManagerEndTime = 0;
}
}
private function startCollectionTest():void
{
var myList:IList = createCollectionObject();
var collectionWrapper:Object = wrapInOtherCollectionIfNeeded(myList);
applySortAndFilterIfNeeded(collectionWrapper, myList);
adg.dataProvider = collectionWrapper;
LayoutManager.getInstance().validateNow();
LayoutManager.getInstance().addEventListener("layoutManagerStart", layoutManager_layoutManagerStartHandler);
LayoutManager.getInstance().addEventListener("updateComplete", layoutManager_layoutManagerEndHandler);
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
if (numItemsToInitializeWith > 0)
{
switch (objectToUseDropDownList.selectedIndex)
{
case NON_BINDABLE_OBJECT:
collectionTests.fillCollectionNonBindable(myList, numItemsToInitializeWith, fillSeedItems);
break;
case PROPERTY_CHANGE_BINDABLE_OBJECT:
collectionTests.fillCollectionPropertyChangeBindable(myList, numItemsToInitializeWith, fillSeedItems);
break;
case UNIQUE_EVENT_BINDABLE_OBJECT:
collectionTests.fillCollectionUniqueEventBindable(myList, numItemsToInitializeWith, fillSeedItems);
break;
case SINGLE_VERSION_EVENT_BINDABLE_OBJECT:
collectionTests.fillCollectionSingleVersionEventBindable(myList, numItemsToInitializeWith, fillSeedItems);
break;
}
}
if (numItemsToAddPerSecond > 0)
{
switch (objectToUseDropDownList.selectedIndex)
{
case NON_BINDABLE_OBJECT:
testResultsAdd = collectionTests.startRandomAdditionsNonBindableCollection(myList, numIterations, numItemsToAddPerSecond, fillObjectsInitially);
break;
case PROPERTY_CHANGE_BINDABLE_OBJECT:
testResultsAdd = collectionTests.startRandomAdditionsPropertyChangeBindableCollection(myList, numIterations, numItemsToAddPerSecond, fillObjectsInitially);
break;
case UNIQUE_EVENT_BINDABLE_OBJECT:
testResultsAdd = collectionTests.startRandomAdditionsUniqueEventBindableCollection(myList, numIterations, numItemsToAddPerSecond, fillObjectsInitially);
break;
case SINGLE_VERSION_EVENT_BINDABLE_OBJECT:
testResultsAdd = collectionTests.startRandomAdditionsSingleVersionEventBindableCollection(myList, numIterations, numItemsToAddPerSecond, fillObjectsInitially);
break;
}
}
if (numItemsToUpdatePerSecond > 0)
{
testResultsUpdate = collectionTests.startRandomPropertyUpdatesCollection(myList, numIterations, numItemsToUpdatePerSecond, numPropertiesPerUpdate);
}
}
private function createCollectionObject():IList
{
return new ArrayCollection();
}
private function applySortAndFilterIfNeeded(
collectionWrapper:Object,
underlyingCollection:IList):void
{
var collectionForFilterAndSort:ICollectionView = collectionWrapper as ICollectionView;
if (!collectionForFilterAndSort)
collectionForFilterAndSort = underlyingCollection as ICollectionView;
if (collectionToUseDropDownList.selectedIndex == ARRAY_COLLECTION_FILTER_TYPE ||
collectionToUseDropDownList.selectedIndex == ARRAY_COLLECTION_FILTER_SORT_TYPE)
{
collectionForFilterAndSort.filterFunction = testFilterFunction;
}
if (collectionToUseDropDownList.selectedIndex == ARRAY_COLLECTION_SORT_TYPE ||
collectionToUseDropDownList.selectedIndex == ARRAY_COLLECTION_FILTER_SORT_TYPE)
{
collectionForFilterAndSort.sort = getTestSort();
}
if (collectionToUseDropDownList.selectedIndex != ARRAY_COLLECTION_TYPE)
{
collectionForFilterAndSort.refresh();
}
}
private function wrapInOtherCollectionIfNeeded(myList:IList):Object
{
var gc2:GroupingCollection2;
var hcv:HierarchicalCollectionView;
switch (wrappingCollectionToUseDropDownList.selectedIndex)
{
case WRAPPING_COLLECTION_NONE:
return myList;
case WRAPPING_COLLECTION_HCV_NO_GROUPING:
gc2 = new GroupingCollection2();
gc2.source = myList;
gc2.refresh();
hcv = new HierarchicalCollectionView(gc2);
return hcv;
case WRAPPING_COLLECTION_HCV_WITH_GROUPING:
gc2 = new GroupingCollection2();
gc2.grouping = getTestGrouping();
gc2.source = myList;
gc2.refresh();
hcv = new HierarchicalCollectionView(gc2);
return hcv;
}
return null;
}
private function getTestGrouping():Grouping
{
var grouping:Grouping = new Grouping();
var gf:GroupingField = new GroupingField("property3");
gf.groupingFunction = testGroupingFunction;
grouping.fields = [gf];
return grouping;
}
[Bindable]
private var numGroupsForGroupingCollection:int = 10;
private function testGroupingFunction(item:Object, field:GroupingField):String
{
var myNumber:Number = item[field.name] as Number;
var groupId:Number = Math.floor(myNumber * numGroupsForGroupingCollection);
return groupId.toString();
}
private function testCompleteHandler(event:Event):void
{
// if haven't finished both tests, wait for next event
if (numItemsToAddPerSecond > 0
&& numItemsToUpdatePerSecond > 0
&& testResultsAdd.length != testResultsUpdate.length)
{
return;
}
var collectionTime:int = 0;
var len:int = testResultsAdd ? testResultsAdd.length : 0;
for (var i:int = 0; i < len; i++)
{
collectionTime += testResultsAdd[i];
}
len = testResultsUpdate ? testResultsUpdate.length : 0;
for (i = 0; i < len; i++)
{
collectionTime += testResultsUpdate[i];
}
testResultsAdd = testResultsUpdate = null;
var totalTime:Number = collectionTime + validationTime + renderTime;
resultLabel.text += ": (" + collectionTime + ", " + validationTime + ", " + renderTime + ", " + totalTime + ") ";
collectionTests.removeEventListener(CollectionTest.TEST_COMPLETE, testCompleteHandler);
LayoutManager.getInstance().removeEventListener("layoutManagerStart", layoutManager_layoutManagerStartHandler);
LayoutManager.getInstance().removeEventListener("updateComplete", layoutManager_layoutManagerEndHandler);
removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
[Bindable]
public var valToTestForGreaterThanInFilterFunction:Number = 0.8;
public function testFilterFunction(item:Object):Boolean
{
if ("property0" in item)
return item.property0 > valToTestForGreaterThanInFilterFunction;
else
return true; // for groups
}
public function getTestSort():Sort
{
var sort:Sort = new Sort();
sort.fields = [new SortField("property1")];
return sort;
}
private function formatIntTo3Digits(value:int):String
{
if (value >= 100)
return "" + value;
else if (value >= 10)
return "0" + value;
else
return "00" + value;
}
private function formatIntTo5Digits(value:int):String
{
if (value >= 10000)
return "" + value;
if (value >= 1000)
return "0" + value;
if (value >= 100)
return "00" + value;
else if (value >= 10)
return "000" + value;
else
return "0000" + value;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<s:NumberFormatter id="decimalFormatterPrecision2" trailingZeros="true" leadingZero="true" fractionalDigits="2" />
</fx:Declarations>
<s:layout>
<s:VerticalLayout />
</s:layout>
<s:FormItem label="Object to use">
<s:DropDownList id="objectToUseDropDownList" requireSelection="true" width="200">
<s:ArrayList>
<fx:String>NonBindableObject</fx:String>
<fx:String>PropertyChangeBindableObject</fx:String>
<fx:String>SingleVersionEventBindableObject</fx:String>
<fx:String>UniqueEventBindableObject</fx:String>
</s:ArrayList>
</s:DropDownList>
</s:FormItem>
<s:HGroup>
<s:FormItem label="Collection to use">
<s:DropDownList id="collectionToUseDropDownList" requireSelection="true" width="200">
<s:ArrayList>
<fx:String>ArrayCollection</fx:String>
<fx:String>ArrayCollection + Filter</fx:String>
<fx:String>ArrayCollection + Sort</fx:String>
<fx:String>ArrayCollection + Filter + Sort</fx:String>
</s:ArrayList>
</s:DropDownList>
</s:FormItem>
<s:FormItem label="Wrapping Collection to use">
<s:DropDownList id="wrappingCollectionToUseDropDownList" requireSelection="true" width="200">
<s:ArrayList>
<fx:String>None</fx:String>
<fx:String>HCV wrapping GC2 no grouping</fx:String>
<fx:String>HCV wrapping GC2 group by 1 field</fx:String>
</s:ArrayList>
</s:DropDownList>
</s:FormItem>
</s:HGroup>
<s:HGroup>
<s:FormItem label="Seed with items ({formatIntTo5Digits(seedItemAmountInput.value)})" >
<s:NumericStepper id="seedItemAmountInput" minimum="10" maximum="1000000" value="100" stepSize="5" />
</s:FormItem>
<s:FormItem label="Fill seed items">
<s:CheckBox id="fillSeedItemsInput" selected="false" />
</s:FormItem>
</s:HGroup>
<s:FormItem label="Num Seconds ({formatIntTo3Digits(numSecondsInput.value)})" >
<s:NumericStepper id="numSecondsInput" minimum="5" maximum="300" value="20" snapInterval="1" stepSize="5" />
</s:FormItem>
<s:HGroup>
<s:FormItem label="Num items to add per second ({formatIntTo3Digits(numItemsToAddPerSecondInput.value)})">
<s:NumericStepper id="numItemsToAddPerSecondInput" minimum="0" maximum="300" value="50" snapInterval="1" stepSize="5" />
</s:FormItem>
<s:FormItem label="Fill added objects initially">
<s:CheckBox id="fillObjectsInitiallyCheckBox" selected="false" />
</s:FormItem>
</s:HGroup>
<s:HGroup>
<s:FormItem label="Num items to update per second ({formatIntTo3Digits(numItemsToUpdatePerSecondInput.value)})">
<s:NumericStepper id="numItemsToUpdatePerSecondInput" minimum="0" maximum="300" value="100" snapInterval="1" stepSize="5" />
</s:FormItem>
<s:FormItem label="Num props per update ({formatIntTo3Digits(numPropsToUpdatePerObjectUpdateInput.value)})">
<s:NumericStepper id="numPropsToUpdatePerObjectUpdateInput" minimum="0" maximum="30" value="10" snapInterval="1" stepSize="5" />
</s:FormItem>
</s:HGroup>
<s:HGroup>
<s:FormItem label="Value to test for greater than in filter function ({decimalFormatterPrecision2.format(valToTestForGreaterThanInFilterFunction)})">
<s:NumericStepper minimum="0" maximum="1" value="@{valToTestForGreaterThanInFilterFunction}" snapInterval="0.05" stepSize="0.05" />
</s:FormItem>
<s:FormItem label="Num groups to have if wrapping with a grouping collection ({formatIntTo3Digits(numGroupsForGroupingCollection)})">
<s:NumericStepper value="@{numGroupsForGroupingCollection}" minimum="1" maximum="200" snapInterval="1" stepSize="1" />
</s:FormItem>
</s:HGroup>
<s:HGroup>
<s:Button label="Run test" click="runTest()" />
<s:Label id="resultLabel" text="Result: " />
</s:HGroup>
<mx:AdvancedDataGrid id="adg" height="600" width="1200"
horizontalScrollPolicy="on" displayItemsExpanded="true">
<mx:groupItemRenderer>
<fx:Component>
<mx:AdvancedDataGridGroupItemRenderer dataChange="advanceddatagridgroupitemrenderer1_dataChangeHandler(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.controls.AdvancedDataGrid;
protected function advanceddatagridgroupitemrenderer1_dataChangeHandler(event:FlexEvent):void
{
if (listData && data)
{
// AdvancedDataGrid(listData.owner).expandItem(data, true);
}
}
]]>
</fx:Script>
</mx:AdvancedDataGridGroupItemRenderer>
</fx:Component>
</mx:groupItemRenderer>
<mx:columns>
<mx:AdvancedDataGridColumn dataField="property3" width="80" />
<mx:AdvancedDataGridColumn dataField="property0" width="80" />
<mx:AdvancedDataGridColumn dataField="property1" width="80" />
<mx:AdvancedDataGridColumn dataField="property2" width="80" />
<mx:AdvancedDataGridColumn dataField="property4" width="80" />
<mx:AdvancedDataGridColumn dataField="property5" width="80" />
<mx:AdvancedDataGridColumn dataField="property6" width="80" />
<mx:AdvancedDataGridColumn dataField="property7" width="80" />
<mx:AdvancedDataGridColumn dataField="property8" width="80" />
<mx:AdvancedDataGridColumn dataField="property9" width="80" />
<mx:AdvancedDataGridColumn dataField="property10" width="80" />
<mx:AdvancedDataGridColumn dataField="property11" width="80" />
<mx:AdvancedDataGridColumn dataField="property13" width="80" />
<mx:AdvancedDataGridColumn dataField="property12" width="80" />
<mx:AdvancedDataGridColumn dataField="property14" width="80" />
<mx:AdvancedDataGridColumn dataField="property15" width="80" />
<mx:AdvancedDataGridColumn dataField="property16" width="80" />
<mx:AdvancedDataGridColumn dataField="property17" width="80" />
<mx:AdvancedDataGridColumn dataField="property18" width="80" />
<mx:AdvancedDataGridColumn dataField="property19" width="80" />
<mx:AdvancedDataGridColumn dataField="property20" width="80" />
<mx:AdvancedDataGridColumn dataField="property21" width="80" />
<mx:AdvancedDataGridColumn dataField="property22" width="80" />
<mx:AdvancedDataGridColumn dataField="property23" width="80" />
<mx:AdvancedDataGridColumn dataField="property24" width="80" />
<mx:AdvancedDataGridColumn dataField="property25" width="80" />
<mx:AdvancedDataGridColumn dataField="property26" width="80" />
<mx:AdvancedDataGridColumn dataField="property27" width="80" />
<mx:AdvancedDataGridColumn dataField="property28" width="80" />
<mx:AdvancedDataGridColumn dataField="property29" width="80" />
</mx:columns>
</mx:AdvancedDataGrid>
</s:Application>