<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
   <channel>
      <title>Alex’s Flex Closet</title>
      <link>http://blogs.adobe.com/aharui/</link>
      <description>A collection of Flex-related things.  Warning: contains cobwebs, decaying matter and skeletons, but maybe some jewels as well.</description>
      <language>en</language>
      <copyright>Copyright 2008</copyright>
      <lastBuildDate>Wed, 12 Mar 2008 16:14:30 -0800</lastBuildDate>
      <generator>http://www.sixapart.com/movabletype/?v=3.2</generator>
      <docs>http://blogs.law.harvard.edu/tech/rss</docs> 

            <item>
         <title>Flex 3 DataGrid Footers</title>
         <description><![CDATA[<p>I took a few minutes to prove that there is another way to add Footers to DataGrid in Flex 3.  The old blog post showed how to add footers to the border.  In Flex 3 we added more hooks so  you can add other "content areas" to the DataGrid.</p>

<p>I'm short on time so the example isn't fully fleshed out.  It could definitely use some optimization as to when and how often it refreshes.  It probably needs masking if horizontal scrollbars are on, but at least it should show up in the right place relative to the horizontal scroll bar.  There's probably bugs as well, so the usual caveats apply, but it should get you started in the right direction.  Also, I did not try this with AdvancedDataGrid.  It is actually developed by an entirely different team.</p>

<p><a href="http://blogs.adobe.com/aharui/DataGridFooter3/DataGridFooter.zip">Download Source</a><br />
<a href="http://blogs.adobe.com/aharui/DataGridFooter3/dg.swf">Run Demo</a><br />
</p>]]></description>
         <link>http://blogs.adobe.com/aharui/2008/03/flex_3_datagrid_footers.html</link>
         <guid>http://blogs.adobe.com/aharui/2008/03/flex_3_datagrid_footers.html</guid>
         <category>Item Renderers</category>
         <pubDate>Wed, 12 Mar 2008 16:14:30 -0800</pubDate>
      </item>
            <item>
         <title>Custom ArrayCollections, Adding New Items to DataGrid</title>
         <description><![CDATA[<p>The previous posts used custom ILists to merge or concatenate other ILists.  This example uses a custom subclass of ArrayCollection to fake an empty object at the end of the actual ArrayCollection which can be used to add new entries to the DataGrid.</p>

<p>If the user fills out the new entry, it is added to the actual collection and another new entry is faked.  Additional logic dictates that if the user strips all information out of an entry, that entry is removed from the actual collection.</p>

<p>Usual caveats apply</p>

<p><a href="http://blogs.adobe.com/aharui/NewEntryDG/NewEntryDataGrid.zip">Download Source</a><br />
<a href="http://blogs.adobe.com/aharui/NewEntryDG/NewEntryDataGridApp.swf">Run Demo</a><br />
</p>]]></description>
         <link>http://blogs.adobe.com/aharui/2008/03/custom_arraycollections_adding.html</link>
         <guid>http://blogs.adobe.com/aharui/2008/03/custom_arraycollections_adding.html</guid>
         <category>General</category>
         <pubDate>Tue, 11 Mar 2008 14:25:31 -0800</pubDate>
      </item>
            <item>
         <title>Custom ILists, ComboBox Prompts</title>
         <description><![CDATA[<p>Following up on the last post which showed how to use custom ILists to merge two collections, this post shows how to use a custom IList to concatenate or append two collections.</p>

<p>Such a thing might be useful in a situation where you want to add more than one prompt to a ComboBox.  In the example, I have the days of the week to choose from, but also want to add "Every Day", "Weekdays" and "Weekends" without modifying the original days of the week collection.  Of course, if you concatenate the two collections, it offsets your selectedIndex.</p>

<p><a href="http://blogs.adobe.com/aharui/ConcatIList/PromptsComboBoxApp.zip">Download Source</a><br />
<a href="http://blogs.adobe.com/aharui/ConcatIList/PromptsComboBoxApp.swf">Run Demo</a></p>

<p><br />
</p>]]></description>
         <link>http://blogs.adobe.com/aharui/2008/03/custom_ilists_combobox_prompts.html</link>
         <guid>http://blogs.adobe.com/aharui/2008/03/custom_ilists_combobox_prompts.html</guid>
         <category>General</category>
         <pubDate>Mon, 10 Mar 2008 13:53:29 -0800</pubDate>
      </item>
            <item>
         <title>Custom ILists, CheckBoxDataGrid, Merged Arrays</title>
         <description><![CDATA[<p>Earlier I published how to do a CheckBoxDataGrid where the selection model uses CheckBoxes instead of mouse clicks.  I should have mentioned that the example used the DataGrid's selection logic which meant that the dataprovider item's selected state was not stored in the dataProvider and thus you couldn't sort by whether an item was selected or not.</p>

<p>If you have a selected field in your data, then the code to handle checkbox selection is quite different.  You basically shut down the DataGrid's selection code and update the collection instead.  You can see that in the source code for this example.</p>

<p>This example goes one step further, however.  It assumes that you want to store selection in the dataProvider, but the dataProvider items don't have a selected field and are "immutable".  The example code shows how to use a custom IList to merge two arrays or ArrayCollections into one merged collection where the data objects contain fields from both arrays.  By doing that you can "add" a selected field to each item.</p>

<p>Custom ILists are a powerful way to change data without having to process each data item.  The example code merges the items on-demand instead of up-front thus saving startup time.  It would be wasteful to process 1000 items if you only show 7 and the user doesn't scroll past 20.</p>

<p>Anyway, here's the code.  Usual caveats apply.</p>

<p><a href="http://blogs.adobe.com/aharui/CheckBoxDG/CheckBoxDataGridApp3.zip">Download Source</a><br />
<a href="http://blogs.adobe.com/aharui/CheckBoxDG/CheckBoxDataGridApp3.swf">Run Demo</a><br />
</p>]]></description>
         <link>http://blogs.adobe.com/aharui/2008/03/custom_ilists_checkboxdatagrid_1.html</link>
         <guid>http://blogs.adobe.com/aharui/2008/03/custom_ilists_checkboxdatagrid_1.html</guid>
         <category>General</category>
         <pubDate>Sat, 08 Mar 2008 23:07:21 -0800</pubDate>
      </item>
            <item>
         <title>DataGrid Double-Click To Edit</title>
         <description><![CDATA[<p>Several people have asked about changing the default editing behavior of a DataGrid so that starting an edit session requires a double-click instead of the default single-click.</p>

<p>Here's my approach:</p>

<p><a href="http://blogs.adobe.com/aharui/DblClkDG/DoubleClickDataGridApp.zip">Download Source</a><br />
<a href="http://blogs.adobe.com/aharui/DblClkDG/DoubleClickDataGridApp.swf">Run Demo</a><br />
</p>]]></description>
         <link>http://blogs.adobe.com/aharui/2008/03/datagrid_doubleclick_to_edit.html</link>
         <guid>http://blogs.adobe.com/aharui/2008/03/datagrid_doubleclick_to_edit.html</guid>
         <category>General</category>
         <pubDate>Fri, 07 Mar 2008 14:56:47 -0800</pubDate>
      </item>
            <item>
         <title>Smooth Scrolling List</title>
         <description><![CDATA[<p>One of the features that got cut from 3.0 was "smooth scrolling".  List and other list-related classes scroll by row/column which can be  a bit choppy at times.  We tried to leave the hooks in to allow someone to do it, but we ran out of time to finish the job.</p>

<p>It's too bad we didn't finish the job as there are some difficult things to workaround in trying to get smooth scrolling to work, but I cooked this prototype up to give you a sense for how you might be able to get it working in your apps.   Note that the prototype assumes that all rows are the same height.  If you have variableRowHeight, that's a whole different problem.</p>

<p>Usual caveats apply, and no, I don't currently have time to make examples for TileList and DataGrid.  Maybe some one else will have the time.</p>

<p><a href="http://blogs.adobe.com/aharui/SmoothScrollingList.zip">Download Source</a><br />
<a href="http://blogs.adobe.com/aharui/SmoothScrollingApp.swf">Run Demo</a><br />
</p>]]></description>
         <link>http://blogs.adobe.com/aharui/2008/03/smooth_scrolling_list.html</link>
         <guid>http://blogs.adobe.com/aharui/2008/03/smooth_scrolling_list.html</guid>
         <category>General</category>
         <pubDate>Sun, 02 Mar 2008 23:05:19 -0800</pubDate>
      </item>
            <item>
         <title>CheckBox selection in DataGrid and List</title>
         <description><![CDATA[<p>Several folks have asked how to use Checkbox renderers to handle multiple selection in a DataGrid or List.  There are some solutions out there already, but here's mine.  Usual caveats apply.</p>

<p><a href="http://blogs.adobe.com/aharui/CheckBoxDataGrid/CheckBoxListAndDataGrid.zip">Download Source</a><br />
<a href="http://blogs.adobe.com/aharui/CheckBoxDataGrid/CheckBoxDataGridApp.swf">Run Demo</a><br />
</p>]]></description>
         <link>http://blogs.adobe.com/aharui/2008/02/checkbox_selection_in_datagrid.html</link>
         <guid>http://blogs.adobe.com/aharui/2008/02/checkbox_selection_in_datagrid.html</guid>
         <category>Item Renderers</category>
         <pubDate>Fri, 29 Feb 2008 17:10:16 -0800</pubDate>
      </item>
            <item>
         <title>Flex and ScaleMode</title>
         <description><![CDATA[<p>Flex&#8217;s underlying Flash Player has various ScaleModes that dictate how the screen should respond when the Flash &#8216;window&#8217; is resized.  By default, Flex apps use the NO_SCALE, which means that the screen area gets larger or smaller and can clip off the right and bottom of the screen.  Flex will put up scrollbars in that case.  It is the most common way applications respond to changes in screen size.</p>

<p>Every once in a while, someone wants to use one of the other ScaleModes which essentially magnify or reduce what you see in the Flash &#8216;window&#8217;.  There is a trick to getting this to work correctly in Flex.</p>

<p>The problem is that the magnification is based on the &#8216;default&#8217; size of the application.  For Flex, the default size is based on the width and height attributes of the application tag.  If none are specified, or percentages are used, the default is 500&#215;375.  If your applications visuals are different from that size, the magnification will look funny as the Flash Player will be trying to resize the upper 500&#215;376 of your application into the current window size.</p>

<p>However, if you specify a width/height that just bounds your visuals, the <span class="caps">HTML </span>template generated by FlexBuilder will not allow resizing.  What you have to do is choose the correct size for your application, and customize the <span class="caps">HTML </span>template.  Here&#8217;s the recipe:</p>

<p>1) Create your app with the default scale mode.<br />
2) Figure out how big the app is.  In the example, I placed a label at 600,600, but it extends beyond that.  One way is to just guess at numbers and see when there isn’t scrollbars or too much excess space.  Otherwise, use the debugger or trace out positions and sizes on creationComplete.<br />
3) Set the application’s width/height tags to those exact dimensions<br />
4) Open the html-templates folder.  Right-click the index.template   Choose: Open with -&gt; text editor</p>

<p>You’ll see this:</p>

<blockquote>} else if (hasRequestedVersion) {
	// if we&#8217;ve detected an acceptable version<br />
	// embed the Flash Content <span class="caps">SWF </span>when all tests are passed<br />
	AC_FL_RunContent(<br />
			&#8220;src&#8221;, &#8220;${swf}&#8221;,<br />
			&#8220;width&#8221;, &#8220;${width}&#8221;,<br />
			&#8220;height&#8221;, &#8220;${height}&#8221;,</blockquote>

<p>Change the width/height tags back to use %:</p>

<blockquote>} else if (hasRequestedVersion) {
	// if we&#8217;ve detected an acceptable version<br />
	// embed the Flash Content <span class="caps">SWF </span>when all tests are passed<br />
	AC_FL_RunContent(<br />
			&#8220;src&#8221;, &#8220;${swf}&#8221;,<br />
			&#8220;width&#8221;, &#8220;100%&#8221;,<br />
			&#8220;height&#8221;, &#8220;100%&#8221;,</blockquote>
There are also other ${width} and ${height| tags for non-scripting browser that you can change as well.

<p>5) Clean re-build</p>

<p>That should do it.  As long as the application fully covers the size you specified, you should see the correct scale effect as you resize the window.</p>

<p><a href="http://blogs.adobe.com/aharui/StageScaleModes.swf">Example</a><br />
<a href="http://blogs.adobe.com/aharui/StageScaleModes.mxml">Example Source Code</a></p>

<p>Usual caveats apply.</p>]]></description>
         <link>http://blogs.adobe.com/aharui/2008/01/flex_and_scalemodes.html</link>
         <guid>http://blogs.adobe.com/aharui/2008/01/flex_and_scalemodes.html</guid>
         <category></category>
         <pubDate>Fri, 04 Jan 2008 15:30:46 -0800</pubDate>
      </item>
            <item>
         <title>SelectedItem and ComboBox</title>
         <description><![CDATA[<p>Seems like it is once a month where someone is having trouble setting the selectedItem of a ComboBox.  The key is that the ComboBox does an exact reference match on the items in the dataProvider.  It doesnt take the time to compare values within the dataProvider items with the values in the item you are setting as the selectedItem.</p>

<p>In other words, if you have an array of objects:</p>

<blockquote>[{ firstName: "Alex", lastName: "Harris" }, { firstname: "Alex", lastName: "Harui"}, {firstName: "Alex", lastName: "Trebek"}]</blockquote>
you can't just set:

<blockquote>selectedItem = { firstName: "Alex", lastName: "Harui }</blockquote>
as that assigns the selectedItem to a different Object instance with the same values.  The ComboBox class will simply look to see if there is a reference to that instance in its dataProvider, which there is not.  Instead, you have to scan the dataprovider and match up values.

<p>So many folks are doing this, that I decided to post an example so we don't have to keep writing that scan-the-dataprovider loop.  This example tries for an exact match first, so if you know you'll never have an exact match you can save more time by cutting out that first call to super.selectedItem = value;</p>

<p><a href="http://blogs.adobe.com/aharui/FindSelectedItemComboBox.as">Source for ComboBox subclass</a></p>

<p><a href="http://blogs.adobe.com/aharui/FindSelectedItemComboBoxTest.mxml">Test file source</a><br />
<a href="http://blogs.adobe.com/aharui/Person.as">Helper class source for Test file</a></p>

<p><a href="http://blogs.adobe.com/aharui/FindSelectedItemComboBoxTest.swf">Test file</a></p>

<p>Usual caveats apply.<br />
</p>]]></description>
         <link>http://blogs.adobe.com/aharui/2008/01/selecteditem_and_combobox.html</link>
         <guid>http://blogs.adobe.com/aharui/2008/01/selecteditem_and_combobox.html</guid>
         <category>General</category>
         <pubDate>Wed, 02 Jan 2008 12:47:51 -0800</pubDate>
      </item>
            <item>
         <title>Threads in Actionscript 3</title>
         <description><![CDATA[<p>Every once in a while, someone decides they would like to see threading or background processing in Actionscript.  While the underlying Flash Player and Operating System use threads, the execution model for Actionscript does not.  </p>

<p>For those who don't know, 'threading' is essentially the ability to have the code do something in the background while the UI is doing something else.  Because Actionscript is single-threaded, if you spend lots of time doing heavy computation, the UI cannot be updated while you're doing that computation so your application appears stuck or effects don't run smoothly.</p>

<p>Similarly, there is no yielding or blocking in Actionscript either.  If the next line of code is supposed to run, you cannot prevent the next line of code from running.  That means that when you call Alert.show(), the next line of code following that runs right away.  In many other runtimes, the Alert window has to be closed before the next line of code continues.</p>

<p>Threading may be a feature of Actionscript some day, but until then, you have to live with the fact that there is no such thing right now.</p>

<p>In other single-threaded environments, you can get something like threads via 'pseudo-threading', which involves dividing up the heavy computation into small chunks on your own.  (There is no solution to allow for blocking or yielding other than refactoring the application to be even-driven).  Pseudo-threading is painful, but doable in most situations.  Iterative tasks are easier than recursive ones, the chunk size has to be small enough to not degrade the UI response time and restoration of the execution context must be efficient otherwise you'll spend too much time saving and restoring your state and not get anything done.</p>

<p>Someone asked me how I would generalize such a thing.  I put this together in a couple of hours.  It represents my first thoughts, not some deep thinking on the subject.  A PseudoThread instance takes a callback function and a context object and calls the callback function with the context object as mahy times as it thinks it can get away with it within the frame interval.  The callback function should update the context object before returning and return false when done and the PseudoThread instance dispatches an event and destroys itself.</p>

<p><a href="http://blogs.adobe.com/aharui/pseudothread/PseudoThread.as">PseudoThread.as</a></p>

<p>The following is the a test that loads an image, and adds a red tint to a copy of the image one row at a time.  I purposefully slowed it down with trace statements so you can see that it doesn't do it all at once and doesn't seem to affect the rotating button.</p>

<p><a href="http://blogs.adobe.com/aharui/pseudothread/PseudoThreadTest.swf">PseudoThreadTest.swf</a></p>

<p>These two links are the source file and the test image.<br />
<a href="http://blogs.adobe.com/aharui/pseudothread/PseudoThreadTest.mxml">PseudoThreadTest.mxml</a><br />
<a href="http://blogs.adobe.com/aharui/pseudothread/assets/Nokia_6630.png">the test image</a></p>

<p>The usual caveats apply (there are probably bugs, limitations, etc).  Hope it helps.<br />
</p>]]></description>
         <link>http://blogs.adobe.com/aharui/2008/01/threads_in_actionscript_3.html</link>
         <guid>http://blogs.adobe.com/aharui/2008/01/threads_in_actionscript_3.html</guid>
         <category>General</category>
         <pubDate>Tue, 01 Jan 2008 22:54:19 -0800</pubDate>
      </item>
            <item>
         <title>HTML and Flex</title>
         <description><![CDATA[<p>In case you didn't know, the Flash Player is not very good at displaying HTML content.  Since the Flash Player is the foundation for Flex, Flex apps deployed on the Web aren't very good at displaying HTML either.  In the Adobe AIR Player, essentially a full browser is built in and HTML content is rendered faithfully.  However, the amount of code required to display HTML in AIR is measured in megabytes and is too large to be included in the Flash Player download at this time.<br />
 <br />
Various folks have made reasonable attempts to get something to work in Flash.  There is the <a href="http://deng.com.br/">DENG</a> project .  And popular among many Flex developers is the third-party <a href="http://drumbeatinsight.com/">HTMLComponent </a> which uses the IFrame trick to display HTML "over" chosen areas in your Flex application.  <a href="http://labs.adobe.com/wiki/index.php/Flex_Framework:FABridge">FABridge</a> lets you integrate your Ajax application with Flex widgets.<br />
 <br />
None of these solutions are fully-integrated with Flex in the sense that the HTML is part of the Flex DOM.  Right after 2.0 shipped, I was doing some testing on how fast Flash Player 9 and ActionScript 3 was and hacked together a little test which grabs an XHTML file, parses it using E4X, and creates a UIComponent for every HTML tag and one or more TextFields for every run of text.  It ran suprisingly fast.  I put it down to get on to Flex 3 work and poked at it a bit since then.  I finally found time to fix post this code.  You'll see that there are many bugs and missing features.</p>

<p>To fully finish off HTML rendering and CSS, fix bugs, etc in this code is outside of the scope of Adobe's focus at this time.  It might make a great community project if some of you want to take on the effort.  I'm no expert in HTML so you may or may not want to start with the code attached here.  This test just proves the feasiblity of mapping HTML tags to UIComponents so there is better integration with Flex and better HTML rendering than you can currently get in the Flash Player.</p>

<p><a href="http://blogs.adobe.com/aharui/FlexHTML.zip">Source Code for flex.html.*</a><br />
<a href="http://blogs.adobe.com/aharui/FlexHTMLTest.zip">Source Code for test files for flex.html.*</a><br />
<a href="http://blogs.adobe.com/aharui/bin-debug.zip">SWFs, HTML, etc for test files for flex.html.*</a></p>

<p>The zips can be imported into FlexBuilder 3.   I didn't post the SWFs because you need to run out of your local sandbox to get around security restrictions, so it is best to download the files, import the projects, build them and run them.</p>

<p>Personally, I don't believe most of you need a full browser.  You probably just have 'plain' HTML documents that don't run scripts, don't do fancy DIV stuff like wrapping text around images, etc.  So you might be able to fix a few bugs and get what you want to work in relatively short order.  You probably also don't need to wade through hand-authored HTML and 'bad' HTML.  All of that sutff adds weight to the code.  <br />
 <br />
For example, htmltest3 in the test zip is test for the superscript/subscript tags.  Maybe all you need is a few tags like those plus bold and italic.<br />
 <br />
The hmltest2 test also shows the principle of dynamic UI.  You can send your UI over as XHTML and by wrapping your Flex component appropriately, you can generate the UI from the XHTML description.  Notice the DataGrid in the document.<br />
 <br />
The code has an IHTMLElement interface so you can talk to it in DHTML/AJAX-like ways.  There's even the beginnings of an XMLHTTPRequest class.  There is also a class that tries to clean up bad HTML.<br />
 <br />
Have fun, hope it helps, and DO NOT REPORT BUGS.  I will probably delete all comments reporting bugs as this is totally unsupported by me.<br />
 <br />
 <br />
 <br />
 <br />
</p>]]></description>
         <link>http://blogs.adobe.com/aharui/2008/01/html_and_flex_1.html</link>
         <guid>http://blogs.adobe.com/aharui/2008/01/html_and_flex_1.html</guid>
         <category>General</category>
         <pubDate>Tue, 01 Jan 2008 17:06:58 -0800</pubDate>
      </item>
            <item>
         <title>Debugging Tricks</title>
         <description><![CDATA[<p>FlexBuilder 3 Beta 2 no longer makes both release and debug versions on every build, in order to speed up build times.  This means that the debug version is no longer suffixed with -debug and it appears more than one of you used that to turn on debugging functionality w/o changing your code.</p>

<p>Also, a few folks have asked for a single line of code that could be pasted verbatim into function bodies that would report the name of the function, and a few others have wondered if there is a way to get the name of the calling function.</p>

<p>Assuming you are using a debugger player, the source code at this link demonstrates how to do each of these things.  See setDebugFlag(), getFunctionName() and getCallingFunctionName().</p>

<p><a href="http://blogs.adobe.com/aharui/DebugTricks/test.mxml">Download file</a></p>



<pre>
private function setDebugFlag():void
{
	var e:Error = new Error();
	var s:String = e.getStackTrace();
	// trace(s);
	var i:int = s.indexOf(&quot;setDebugFlag&quot;);
	if (s.charAt(i + 14) == '[')
		debugMode = true;
}

[Bindable]
public var debugMode:Boolean = false;

private function getFunctionName(e:Error):String
{
	var s:String = e.getStackTrace();
	var i:int = s.indexOf(&quot;at &quot;);
	var j:int = s.indexOf(&quot;()&quot;);
	return s.substring(i + 3, j);
}

private function getCallingFunctionName(e:Error):String
{
	var s:String = e.getStackTrace();
	// trace(s);
	var i:int = s.indexOf(&quot;at &quot;);
	i = s.indexOf(&quot;at &quot;, i + 3);
	if (i == -1)
		return &quot;caller unknown&quot;;
	var j:int = s.indexOf(&quot;()&quot;, i + 3);
	return s.substring(i + 3, j);
}
</pre>



<p>where the latter two functions are can be used like this:</p>



<pre>
private function doSomething():void
{
	trace(getFunctionName(new Error()));
	doit();
}

private function doSomethingElse():void
{
	trace(getFunctionName(new Error()));
	doit();
}

private function doit():void
{
	trace(getFunctionName(new Error()));
	trace(&quot;   called by&quot;, getCallingFunctionName(new Error()));
}
</pre>



<p>Usual caveats apply, and the numbers and strings might have to be adjusted for different languages.</p>]]></description>
         <link>http://blogs.adobe.com/aharui/2007/10/debugging_tricks.html</link>
         <guid>http://blogs.adobe.com/aharui/2007/10/debugging_tricks.html</guid>
         <category>Troubleshooting and FAQ</category>
         <pubDate>Fri, 05 Oct 2007 13:26:05 -0800</pubDate>
      </item>
            <item>
         <title>ActionScript Read/Write Performance</title>
         <description><![CDATA[<p><strong>Reading, Writing and Arithmetic</strong></p>

<p>ActionScript 3 (AS3) on FlashPlayer 9 has delivered on its promise of much improved performance.  Sure, we&#8217;ll probably always wish it could be faster, but it is much better than ActionScript 2 (AS2).   In <span class="caps">AS2, </span>everything was essentially dynamic.   You could add properties to classes at runtime, change their types, modify methods, and all kinds of evil tricks.  This required a certain amount of overhead at runtime to allow for this because you couldn&#8217;t know up front what a property was and how to access it.</p>

<p><span class="caps">AS3 </span>introduced &#8216;sealed&#8217; classes (classes that are not dynamic).  Sealed classes cannot have properties added to them or those other nasty <span class="caps">AS2 </span>tricks.  As such, the runtime can make assumptions about how to access that property.  <span class="caps">AS3 </span>also implemented Ecmascript For <span class="caps">XML </span>(E4X) which made it possible to access the pieces of an <span class="caps">XML </span>hierarchy as if they were all objects, using the &#8216;.&#8217; syntax.  This is a vast improvement over the old way of working with <span class="caps">XML </span>in <span class="caps">AS2.</span></p>

<p>One of the prices paid for this faster access is the notion of change detection.  If objects do not have change detection by default, you can write to them faster as well.  However, if you want to detect changes you have to add code to do so.  <span class="caps">AS3 </span>provides a Proxy class that builds in change detection, and Flex provides [Bindable] metadata that the compiler detects and generates different code to handle change detection.</p>

<p>This means that there are a variety of objects (sealed, dynamic, proxy, bindable, <span class="caps">XML, </span>etc) that you can read from and write to in your application.  These different objects have different read and write times.  The basic runtime of <span class="caps">AS3 </span>is very fast so most if the time you won&#8217;t care about this information and will use the type of object most convenient to you, but in case you&#8217;re wondering, I put together a little test to see how fast things really are.</p>

<p>The test methodology is pretty rudimentary.  Call getTimer(), save away the value, run a sequence of code, call getTimer() again and see what the difference is.  Various things can cause errors in such testing, but a couple of runs showed reasonable consistency since I was most interested in relative time instead of absolute time.  As such, your mileage will vary based on your environment, but here&#8217;s what I learned:</p>

<p><strong>Reading</strong></p>

<p>As promised, reading a variable from a sealed class is very fast.  My tests accessed variables 200,000 times in just 2ms or less!  Everything else was notably less fast, but remember, most of the time, this won&#8217;t matter to you, or the cost of optimization may be prohibitive, but here are the numbers anyway.  The results will be reported in the following format: a title, a number, and my thoughts on the results.  For this first batch of tests, the basic loop looks lke:</p>

<blockquote>for (i = 0; i &lt; counter; i++)
{<br />
	s = obj.label;<br />
	s = obj2.label;<br />
}</blockquote>

<p>where obj and obj2 are local variables typed as sealed classes, Objects, <span class="caps">XML </span>or a Proxy subclass, so the compiler knows exactly how to access the data</p>

<p><em>Reading From Dynamic Object: 40</em></p>

<p>This means that reading from a dynamic object (created using { label: &#8220;foo&#8221; }) took roughly 40ms compared to the sealed class variable&#8217;s time of around 2ms.   This implies that reading from a dynamic object is 20 times slower than reading from a sealed class.  So, if you know the set of properties and access them often, define a class instead of using Object.  You&#8217;ll also get compilation errors if you mis-type a property name.</p>

<p>The reason I&#8217;m just using numbers and not times in this report is because the actual amount of time will vary based on your computer&#8217;s speed, so numbers give you a relative feel.  You&#8217;ll see that nothing else runs its test in 2ms, and that there are numbers in the 40-100 range which means that the difference is probably ignorable since it would take 2,000,000 reads to cost your application 400ms such that someone might notice a half-second.  Scenarios with numbers in the 300-800 range might we worth your consideration for optimization, but remember, it still took 200,000 reads or writes to add up to less than a second of time.</p>

<p>Anyway, here&#8217;s the rest of the results.</p>

<p><em>Reading From Proxy: 350</em></p>

<p>That&#8217;s right, reading from a Proxy object is significantly slower!.  But if you need change detection, you have to pay a price.  While that number seems scary, note that it took 200,000 accesses to cost and additional 350ms, so like I said, many times you won&#8217;t notice.</p>

<p><em>Reading From Sealed Classes via Getters:  38</em></p>

<p>Many times, you&#8217;ll actually implement properties as getter/setter pairs instead of plain &#8216;vars&#8217; because they can be overridden, more logic can be added to the getters or setters (especially to do change detection), or because the properties are defined in an interface.  In fact, the vast majority of properties you access in a Flex app are getter/setters so you&#8217;re almost always paying this overhead.  It is essentially just as fast as dynamic objects, but is much faster than Proxy if you also need change detection.  Note also that these numbers are for the simplest getter that just returns a backing variable.</p>

<p><em>Reading <span class="caps">XML</span> Attributes: 550</em></p>

<p>Yes, that&#8217;s right, E4x is slow.  But it sure is convenient, and if you had to use other functions to get at the attribute, it would be even worse.  However, if you access the same attributes many times, it might pay to convert them to sealed classes or dynamic objects first.  And this is simple obj.@label access, not some deeper fetch.</p>

<p><em>Reading <span class="caps">XML</span> Sub-Node: 750</em></p>

<p>Reading sub-nodes is even slower than reading attributes, so if you have a choice, attributes will be faster, but still not like converting to sealed classes or objects.</p>

<p><strong>More Results</strong></p>

<p>The first set of tests assumed you knew the type of the object you are reading.  Often, we don&#8217;t know, or don&#8217;t know right away.  For example, in an event handler, the event.target is typed as Object but you often know it is some other type, and arrays are not typed so when you are indexing into an array to get an object, you have to think about whether to coerce to a known type or not.  So, the next set of tests I ran examined reading and writing when pulling objects from an array.  The basic loop looked like:</p>

<blockquote>for (i = 0; i &lt; counter; i++)
{<br />
	obj = arrObject&#91;0&#93;;<br />
	s = obj.label;<br />
	obj = arrObject&#91;1&#93;;<br />
	s = obj.label;<br />
}</blockquote>

<p>where the arrObject array might contain sealed classes, <span class="caps">XML, </span>etc, and obj is or isn&#8217;t strongly typed.</p>

<p><em>Reading From Sealed Class Variables (Coercion): 24</em></p>

<p>The benchmark for these test is reading when we have a local variable of the correct type and coerce the array entry via:</p>

<blockquote>var lv:SomeClass = SomeClass(arrClass&#91;1&#93;);</blockquote>

<p>That more or less says the price of coercing 200,000 times was some 24ms on my computer, so it is very inexpensive and will give you type-checking at compile time.</p>

<p><em>Reading From Sealed Class Variables (as): 30</em></p>

<p>This implies that coercion using &#8220;as&#8221; is slighly slower than coercion via a function as in the previous test.</p>

<p><em>Reading From Sealed Class Variables as Objects: 90</em></p>

<p>This says that it actually pays to coerce objects to known types before accessing variables, otherwise your reads can be 3 times slower.</p>

<p><em>Reading From Sealed Class Getters: 60</em></p>

<p>This says that coercion overhead starts to drown out the difference between access via vars vs getters, but there is still a cost.  However, most of the time you don&#8217;t really have a choice whether to use vars vs getters.</p>

<p><em>Reading From Bindable Class: 60</em></p>

<p>This says that if you make a class [Bindable] you are converting the vars to getters and paying the required price for doing so.</p>

<p><em>Reading Objects: 45</em></p>

<p>This says that it is worth the cost of defining sealed classes and doing the coercion in the loop, unless the sealed class is using getters in which case it is slightly faster.  I&#8217;d still go with sealed classes for the type-checking benefits.</p>

<p><em>Reading Proxys: 370</em></p>

<p>Proxys are slow.  You should use [Bindable] on sealed classes instead.  Note also that ArrayCollection is a Proxy so [] access is way slower than [] access of the internal array.  It&#8217;s probably even faster to use getItemAt() than [] access.</p>

<p><em>Reading <span class="caps">XML</span> Attributes: 575</em><br />
<em>Reading <span class="caps">XML</span> Sub-Nodes: 770</em></p>

<p><span class="caps">XML </span>is even slower than Proxys.  As mentioned earlier, you&#8217;d have to access the same attributes quite often in order for it to be worth the cost of converting the <span class="caps">XML </span>to objects, but there&#8217;ll be occasions where it is worth it.</p>

<p><strong>Writing</strong></p>

<p>A similar loop was used to test writing to properties.  We take objects from an array, coerce to a local variables if necessary, then write to a property.  The results are:</p>

<p><em>Writing To Sealed Class Variables: 450</em></p>

<p>Reading may be fast, but writing is still slow, almost 20x slower than reading (450 / 24).</p>

<p><em>Writing To Sealed Class Setters:  930</em></p>

<p>Writing to the most simple setter that dispatches a change event is twice as slow as writing to variables.</p>

<p><em>Writing to Bindable Sealed Class: 1030</em></p>

<p>Bindable is slightly slower because it takes the time to do a value changed check before dispatching an event.</p>

<p><em>Writing to Dynamic Object: 500</em></p>

<p>Sealed classes are slightly faster unless they use setters, but that&#8217;s the price you pay for change detection and compile-time checking</p>

<p><em>Writing to Proxy: 830</em></p>

<p>Proxy is only better in this case because it didn&#8217;t send a change event.  If it did it would probably be slower than sealed classes with setters.</p>

<p><em>Writing to <span class="caps">XML</span> Attributes: 580</em><br />
<em>Writing to <span class="caps">XML</span> Sub-Nodes: 950</em></p>

<p>No surprise here.  <span class="caps">XML </span>isn&#8217;t very fast, but is very convenient.</p>

<p><em>Writing to <span class="caps">XML</span> Attributes That Have Binding: 7700</em><br />
<em>Writing to <span class="caps">XML</span> Sub-Nodes That Have Binding: 8900</em></p>

<p>This is the big surprise.  <span class="caps">XML </span>data binding is very expensive in terms of the cost of modifying the <span class="caps">XML </span>data.</p>

<p><strong>Arithmetic</strong></p>

<p>The main takeaway is that <span class="caps">XML </span>is slower than objects, but its convenience might outwiegh the performance considerations.  Note, though, that anytime you shove <span class="caps">XML </span>into an <span class="caps">XMLL</span>istCollection all of the nodes get setup for binding so the cost of modifying those nodes might be measurable if you do a lot of modifications, and conversion to object may reap benefits.</p>

<p>There&#8217;s no easy way to test the speed of converting an <span class="caps">XML </span>tree to objects.  Our WebService code has functionality that does the conversion, but the speed will depend a lot on the kinds of <span class="caps">XML </span>data you are getting.  However, it has occurred to me that the conversion code converts the entire tree, and maybe a custom collection could convert on the fly and save the big hit of converting lots of nodes if the query returns a large chunk of <span class="caps">XML </span>when only a few nodes might be seen in a list.  Hopefully I&#8217;ll get to that someday soon and blog about it.</p>

<p>Other than that, unless you really care about saving a tenth of a second here or there, you probably don&#8217;t have to think about which data types you are using, but if you want to impress your friends at holiday parties, you can memorize these numbers and recite them.   To decide whether to optimize is pure arithmetic.  Look at what it would take to convert to a faster access method vs how many accesses you are doing and  what the expected payoff might be and decide from there.</p>

<p><strong>Credits</strong></p>

<p>Thanks to Scott from Fast Lane and Tracy Spratt for getting me started on this topic</p>

<p><strong>Additional Information about <span class="caps">XMLL</span>istCollection</strong></p>

<p>In Flex 2.x, <span class="caps">XMLL</span>istCollections eat lots of memory.  That&#8217;s how I originally got started on this topic as Tracy pointed me to Scott&#8217;s blog.  I&#8217;m unconvinced that it is really a leak, but the memory utilization is such that it doesn&#8217;t matter. This kind of memory utilization can cause paging in the operating system and exacerbate the performance cost of using <span class="caps">XML. </span> Changes were made in Flex 3 Beta 2 to address this problem and memory utilization is better and bounded, but still not as good as objects, so some of you may also want to convert from <span class="caps">XML </span>to objects for this reason as well.</p>]]></description>
         <link>http://blogs.adobe.com/aharui/2007/10/actionscript_readwrite_perform_1.html</link>
         <guid>http://blogs.adobe.com/aharui/2007/10/actionscript_readwrite_perform_1.html</guid>
         <category>General</category>
         <pubDate>Wed, 03 Oct 2007 21:22:40 -0800</pubDate>
      </item>
            <item>
         <title>Popup Dialogs as Modules</title>
         <description><![CDATA[<p>Recently, it was pointed out that there were bugs in the PopUpDialogAsModule example.  The dialog would not center and was not draggable.  The reason was that the thing being popped up was a Module that parented a TitleWindow and not the TitleWindow tiself.  After thinking about that for a bit, I decided to create a subclass of TitleWindow that can be a Module's top level MXML tag.  The source is available at this link:<br />
<a href="http://blogs.adobe.com/aharui/PopUpDialogAsModule2.zip">Download source</a></p>

<p>Of course, the usual caveats apply.  I could have certainly missed something again.</p>

<p>In theory, any component can be made into a module's top-level tag by adding the [frame] metadata.  Hope this helps.  I've been seeing this issue a lot recently.  Also, sorry for the errors in the older example.<br />
</p>]]></description>
         <link>http://blogs.adobe.com/aharui/2007/08/popup_dialogs_as_modules.html</link>
         <guid>http://blogs.adobe.com/aharui/2007/08/popup_dialogs_as_modules.html</guid>
         <category>Presentations</category>
         <pubDate>Sun, 05 Aug 2007 00:00:48 -0800</pubDate>
      </item>
            <item>
         <title>The Future of List Classes (Tree, TileList, DataGrid, etc)</title>
         <description><![CDATA[<p>Up through Flex 2.x, the primary goal of the list classes was to be as fast as possible.  Many assumptions were taken in order to squeeze better performance out of these classes.  Those assumptions have the negative effect of reducing ways you can extend the components.</p>

<p>We've seen that the Flash Player 9 and the new AS3 VM is pretty fast and are looking to spend a few cycles in Moxie and future versions on generality/subclassing/extending and new features at the expense of performance.  Our rationale is that many of you want to do really fancy stuff with the list classes that is really hard to do right now, and that execution and rendering speeds are sufficient today and will continue to get better and thus should absorb and negate additional computation required by being more general.</p>

<p>Post-Moxie, we are considering a major overhaul to the list classes and framework in general.  For Moxie, we are adding some new features and new APIs.  We've made it easy to add effects to the renderers in the List and TileList classes (not sure DataGrid effects will make the first Moxie release).  Another team is building an AdvancedDataGrid complete with summary rows, column span, grouping and more.  In order to do implement these new features we've added some new APIs to allow renderers to be created based on the data object, divided renderers into sub-containers to separate scrollable renderers from fixed ones (header, locked columns and rows do not always scroll), and exposed more of the internals of the scrolling logic.</p>

<p>The Moxie versions are far from general.  There'll still be private and mx_internal variables to trip over.  In subsequent releases we hope to greatly improve generality and create more common subclassing patterns throughout the framework.  But the main point I want to bring out right now about the Moxie versions is about backward compatibility.</p>

<p>We have a commitment to retain backward compatibility with the previous version of Flex (2.x).  However, we do not commit to bug-for-bug behavior compatibility.  If we fix a bug and you were relying on that buggy behavior, your application's behavior may change.  We promise not to remove APIs that existed in Flex 2.x, but the fuzzy area is in how those APIs should behave.  In the strictest sense, those APIs should remain the same: that some input produces the same output.  However, right now, because the set of changes to the list classes was so significant, we are thinking of allowing the output to change.  It would take significant additional time and effort to get 100% compatibility in the API behavior and further degrade performance and increase code size.  I'm telling you this now so we can gauge the impact this will have on those of you that have subclasses the List classes.  If there are certain APIs that you all use, we can consider trying to make those APIs behave more like 2.x.  The percentage of folks that have done significant subclassing is small and most of what you've done might be in the AdvancedDataGrid and/or the effects features anyway so you might be better of using the new component or features.</p>

<p>Following is a sample of the changes we've made so far.  Please give us feedback as to what the impact on you will be.  Note also, that if we do a major refactoring post-Moxie, that may present a whole new learning curve in order to customize the List classes.</p>

<p>lockedRowCount - bug fix - no longer includes the header.  If you've set lockedRowCount in an app, you will probably need to decrease it by one.</p>

<p>rowCount - bug fix - no longer includes the header.</p>

<p>listItems - API change - no longer includes the header at row 0.  No longer includes locked columns or locked rows.</p>

<p>listContent - API change - no longer parents renderers that represent the header, locked columns or locked rows.</p>

<p>makeRowsAndColumns() - API change - only draws items for listContent, so no longer draws items for all items if there are locked columns or locked rows</p>

<p>visibleColumns - API change - only contains the columns that are not locked</p>

<p>draw***() - now draws backgrounds, highlights and selections in listContent as well as the lockedColumns sub-container if it exists</p>

<p>itemRenderer.parent - API change - no longer guaranteed to be listContent.  Can be another sub-container.</p>

<p> <br />
In addition, there used to be an assumption that only the set of visible item renderers were created.  In Moxie, we may create more off-screen renderers in order to handle effects and column and row span.  listContent used to be positioned at 0,0 in the List class and now can be moved around in order to handle span and certain effects.  </p>

<p>In summary, your subclass is almost guaranteed to compile, but may not run correctly, and if you've set lockedRowCount, you may need to adjust it by one.</p>

<p>If we get lots of responses, I am unlikely to reply to each one, but we'll be listening to what you have to say.</p>

<p>-Alex<br />
</p>]]></description>
         <link>http://blogs.adobe.com/aharui/2007/07/the_future_of_list_classes_tre.html</link>
         <guid>http://blogs.adobe.com/aharui/2007/07/the_future_of_list_classes_tre.html</guid>
         <category></category>
         <pubDate>Wed, 18 Jul 2007 01:08:10 -0800</pubDate>
      </item>
      
   </channel>
</rss>
