<br />
<b>Warning</b>:  include() [<a href='function.include'>function.include</a>]: Unable to access /var/www/html/rogue-development/blog2/wp-content/advanced-cache.php in <b>/var/www/html/rogue-development/blog2/wp-settings.php</b> on line <b>62</b><br />
<br />
<b>Warning</b>:  include(/var/www/html/rogue-development/blog2/wp-content/advanced-cache.php) [<a href='function.include'>function.include</a>]: failed to open stream: No such file or directory in <b>/var/www/html/rogue-development/blog2/wp-settings.php</b> on line <b>62</b><br />
<br />
<b>Warning</b>:  include() [<a href='function.include'>function.include</a>]: Failed opening '/var/www/html/rogue-development/blog2/wp-content/advanced-cache.php' for inclusion (include_path='.:/usr/share/pear:/usr/share/php') in <b>/var/www/html/rogue-development/blog2/wp-settings.php</b> on line <b>62</b><br />
<br />
<b>Notice</b>:  add_option was called with an argument that is <strong>deprecated</strong> since version 2.3 with no alternative available. in <b>/var/www/html/rogue-development/blog2/wp-includes/functions.php</b> on line <b>3468</b><br />
<br />
<b>Notice</b>:  register_sidebar_widget is <strong>deprecated</strong> since version 2.8! Use wp_register_sidebar_widget() instead. in <b>/var/www/html/rogue-development/blog2/wp-includes/functions.php</b> on line <b>3382</b><br />
<br />
<b>Notice</b>:  register_widget_control is <strong>deprecated</strong> since version 2.8! Use wp_register_widget_control() instead. in <b>/var/www/html/rogue-development/blog2/wp-includes/functions.php</b> on line <b>3382</b><br />
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Marc's Musings &#187; Actionscript</title>
	<atom:link href="http://www.rogue-development.com/blog2/category/actionscript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.rogue-development.com/blog2</link>
	<description>Comments and thoughts on technology from Marc Hughes</description>
	<lastBuildDate>Tue, 29 Mar 2011 00:04:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>ObjectHandles V2, sneak peek</title>
		<link>http://www.rogue-development.com/blog2/2009/05/objecthandles-v2-sneak-peek/</link>
		<comments>http://www.rogue-development.com/blog2/2009/05/objecthandles-v2-sneak-peek/#comments</comments>
		<pubDate>Fri, 22 May 2009 20:15:04 +0000</pubDate>
		<dc:creator>Marc</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[ObjectHandles]]></category>

		<guid isPermaLink="false">http://www.rogue-development.com/blog2/?p=418</guid>
		<description><![CDATA[Today I&#8217;ve been working on the next major release of ObjectHandles. Below is an example showing off some of the new features. I&#8217;m most excited about the enhanced rotation support.   This new version is focused on making a version that will easily work with MVC frameworks like Moccasin. Some of the changes include: You no [...]]]></description>
			<content:encoded><![CDATA[<p>Today I&#8217;ve been working on the next major release of <a href="http://rogue-development.com/objectHandles.html">ObjectHandles</a>.  Below is an example showing off some of the new features.  I&#8217;m most excited about the enhanced rotation support.    This new version is focused on making a version that will easily work with MVC frameworks like <a href="http://code.google.com/p/moccasin/">Moccasin</a>.   Some of the changes include:</p>
<ul>
<li>You no longer have to re-parent your components.</li>
<li>What and where handles appear is now completely configurable</li>
<li>ObjectHandles modifies your data object instead of moving a component around (there&#8217;s 3 example visual components / data models in the source)</li>
<li>Optionally, object handles won&#8217;t swallow all of your mouse events.</li>
<li>Will now work with non-flex components (still requires Flex SDK to compile, I have to look into that)</li>
<li>Rotation support is completely smooth</li>
<li>Configurable constraints/rules system</li>
<li>Smaller, cleaner code base!</li>
</ul>
<p>Scroll down for demo.</p>
<p><a href="http://rogue-development.com/uploads/moccasin/simpleworld.swf">Click to see</a> the early proof of concept of it working within Mocassin.</p>
<p>ObjectHandles is a library to easily add graphical move/resize user gestures to a Flex based application.</p>
<p>[kml_flashembed fversion="8.0.0" movie="/uploads/ohv2/ObjectHandles2Example.swf" targetclass="flashmovie" publishmethod="static" width="700" height="700" fvars="undefined"]</p>
<p><a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>
<p>[/kml_flashembed]</p>
<p><a href="http://rogue-development.com/uploads/moccasin/simpleworld.swf"><br />
</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.rogue-development.com/blog2/2009/05/objecthandles-v2-sneak-peek/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Reminder: Floats are not precise</title>
		<link>http://www.rogue-development.com/blog2/2009/05/reminder-floats-are-not-precise/</link>
		<comments>http://www.rogue-development.com/blog2/2009/05/reminder-floats-are-not-precise/#comments</comments>
		<pubDate>Wed, 13 May 2009 13:03:09 +0000</pubDate>
		<dc:creator>Marc</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.rogue-development.com/blog2/?p=405</guid>
		<description><![CDATA[I was chatting with a couple friends the other day about an odd bug that was due to floating point precision.  Neither of them got it at first, and it reminded me that not everyone realizes how imprecise floating point math can be.  I know this, you know this, even the friends I was talking [...]]]></description>
			<content:encoded><![CDATA[<p>I was chatting with a couple friends the other day about an odd bug that was due to floating point precision.  Neither of them got it at first, and it reminded me that not everyone realizes how imprecise floating point math can be.  I know this, you know this, even the friends I was talking to knew it after they thought about it.  But it&#8217;s so easy to ignore it since floating point math usually does what we want.  Here&#8217;s three amazingly simple examples:</p>
<p>Actionscript:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">var</span> val:<span class="kw3">Number</span> = <span class="nu0">0.0</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">for</span><span class="br0">&#40;</span> <span class="kw2">var</span> i:<span class="kw3">int</span> = <span class="nu0">0</span> ; i &lt; <span class="nu0">10</span> ; i++ <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; val += <span class="nu0">0.1</span>;</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">trace</span><span class="br0">&#40;</span>val<span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>Java:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">public</span> <span class="kw2">class</span> FloatTest <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">static</span> <span class="kw4">void</span> main<span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3AString+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">String</span></a><span class="br0">&#91;</span><span class="br0">&#93;</span> args<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">float</span> val = <span class="nu0">0</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span><span class="br0">&#40;</span> <span class="kw4">int</span> i = <span class="nu0">0</span> ; i &lt; <span class="nu0">10</span> ; i++<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; val += <span class="nu0">0.1</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3ASystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">System</span></a>.<span class="me1">out</span>.<span class="me1">println</span><span class="br0">&#40;</span> val <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Ruby (I had to go a bit higher on the loop since it rounds differently):</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">val = <span class="nu0">0</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#40;</span><span class="nu0">1</span>..<span class="nu0">100</span><span class="br0">&#41;</span>.<span class="me1">each</span> <span class="kw1">do</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; val += <span class="nu0">0.1</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw3">print</span> val</div>
</li>
</ol>
</div>
<p>What would you expect the output of those to be?  Probably 1, 1, and 10 right?</p>
<p>Wrong.</p>
<p>The actionscript example comes out to 0.9999999999999999, java has 1.0000001, and ruby gets 9.99999999999998</p>
<p>Here&#8217;s another actionscript example:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw3">trace</span><span class="br0">&#40;</span> <span class="br0">&#40;</span><span class="nu0">0.1</span> + <span class="nu0">0.1</span> <span class="br0">&#41;</span> == <span class="br0">&#40;</span><span class="nu0">2</span>/<span class="nu0">10</span><span class="br0">&#41;</span> <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">trace</span><span class="br0">&#40;</span> <span class="br0">&#40;</span><span class="nu0">0.1</span> + <span class="nu0">0.1</span> + <span class="nu0">0.1</span><span class="br0">&#41;</span> == <span class="br0">&#40;</span><span class="nu0">3</span>/<span class="nu0">10</span><span class="br0">&#41;</span> <span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>That traces out:<br />
  true<br />
  false</p>
<p>Baffling huh?  A float should easily have the precision to represent a tenth, right?  It should easily be able to add up ten tenths to get one, right?</p>
<p>Here&#8217;s the problem.  Floats really operate in binary (duh).  In binary, you can&#8217;t represent a lot of simple decimal values, such as 0.10 without a repeating pattern.  0.10 decimal works out to 0.000110011 in binary, with the last 4 digits repeating forever.  So the 0.1 you see when you trace out 0.1 is really just a rounded off binary value.  If you do math with those values, the error can accumulate until it&#8217;s big enough to be seen despite the rounding.</p>
<p>So you should never use floats for anything like:</p>
<ul>
<li> Money</li>
<li>&#8220;Real mathematics&#8221; (for instance, I work on educational math software where the numbers have to always actually add up)</li>
<li>Anything requiring a certain precision, like sending a probe to mars or calculating medication dosage</li>
</ul>
<p>You should use floats for things where precision doesn&#8217;t really matter.  Things, that if you&#8217;re off by a little nobody will ever notice.  Games, animations, audio compression, etc.   Otherwise, the easiest solution is to stick to integer based math.  You can pick a unit of measure magnitudes higher than you need.  Example: for money use cents (or thenths of cents?) instead of dollars as your UoM.  Then when you display the value you divide by 100 to show dollars.  Or you could use a richer class that handles precise numbers like Java&#8217;s BigDecimal, or ruby&#8217;s Rational type.</p>
<p>But like I said, we already knew this, right?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rogue-development.com/blog2/2009/05/reminder-floats-are-not-precise/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Bubbling events in data models</title>
		<link>http://www.rogue-development.com/blog2/2009/04/bubbling-events-in-data-models/</link>
		<comments>http://www.rogue-development.com/blog2/2009/04/bubbling-events-in-data-models/#comments</comments>
		<pubDate>Tue, 14 Apr 2009 20:17:06 +0000</pubDate>
		<dc:creator>Marc</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://www.rogue-development.com/blog2/?p=373</guid>
		<description><![CDATA[I&#8217;ve been using moccasin for a bit now on a smallish project.  One of the cool things it does is give you a sort of event bubbling in your datamodel.  While moccasin is a very specific framework for a very specific sort of application, the more I think about it, the more I like the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using <a href="http://code.google.com/p/moccasin/">moccasin</a> for a bit now on a smallish project.  One of the cool things it does is give you a sort of event bubbling in your datamodel.  While moccasin is a very specific framework for a very specific sort of application, the more I think about it, the more I like the bubbling-events in the data model part as a general solution to a wider variety of problems.</p>
<p>Let&#8217;s look at a very simplified example that illustrates the general idea (actual mocasin implementation varies quite a bit from this).  Imagine this code&#8230;</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">public</span> <span class="kw2">class</span> PizzaModel</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#91;</span>Bindable<span class="br0">&#93;</span> <span class="kw3">public</span> <span class="kw2">var</span> sauce:PizzaSauce;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="br0">&#91;</span>Bindalbe<span class="br0">&#93;</span> <span class="kw3">public</span> <span class="kw2">var</span> <span class="kw3">size</span>:<span class="kw3">Number</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&#8230;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#91;</span>Bindable<span class="br0">&#93;</span> <span class="kw3">public</span> <span class="kw2">class</span> PizzaSauce</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw3">public</span> <span class="kw2">var</span> <span class="kw3">name</span>:<span class="kw3">String</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw3">public</span> <span class="kw2">var</span> displayColor:uint;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&#8230;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">public</span> <span class="kw2">class</span> PizzaView <span class="kw3">extends</span> UIComponent</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="kw3">public</span> <span class="kw2">function</span> setPizza<span class="br0">&#40;</span> pizza:PizzaModel <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;pizza.<span class="me1">addEventListener</span><span class="br0">&#40;</span>ModelChangeEvent.<span class="me1">MODEL_CHANGE</span>, onModelChange<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; protected <span class="kw2">function</span> onModelChange<span class="br0">&#40;</span>event:ModelChangeEvent<span class="br0">&#41;</span>:<span class="kw3">void</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">switch</span><span class="br0">&#40;</span> event.<span class="me1">property</span> <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">case</span> <span class="st0">&quot;size&quot;</span>: <span class="co1">// the pizza size changed, handle that.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">case</span> <span class="st0">&quot;sauce/displayColor&quot;</span>: <span class="co1">// the sauce color changed, handle that.</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw2">default</span>: <span class="co1">// some property that we can&#8217;t incrementally </span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// update changed, handle that&#8230;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>We have some kind of model object, let&#8217;s call it the <strong>PizzaModel</strong>.</p>
<p>That model has a property, that itself is some kind of complex object.  Lets call that property <strong>sauce</strong>, and the type will be called <strong>PizzaSauce</strong></p>
<p>Now, we have some kind of view object.  Let&#8217;s call it the <strong>PizzaView</strong>.</p>
<p>A normal way to implement something like this would be to have the pizza view listen to events on both the pizza object and it&#8217;s sauce object.  Or it could manually set up some change-watchers that watched the hierarchy to the required properties.  </p>
<p>That&#8217;s all fine and dandy until we get to more complex object hierarchies.  What if we had an arraycollection of toppings and we needed to know when individual properties of those toppings changed?  Now, we&#8217;d have to listen to yet another type of event.</p>
<p>And what happens of those toppings themselves had lists of ingredients we wanted to listen to, suddenly the event chain is getting pretty gnarly to manage.</p>
<p>If we had some kind of magical bubbling model event, we&#8217;d only have to listen at a single location, as shown above.  Especially if there was an expressive way of identifying what changed.</p>
<p>How might something like this be implemented?</p>
<p>Mocassin does it by having a meta-data model that wraps the actual data model and provides this extra functionality.</p>
<p>Another way would be to force the data model objects to all extend from a common superclass (I believe earlier versions of Moccasin did just that)</p>
<p>Someday, I&#8217;d like to explore either creating a general purpose framework for this or extracting it from Moccasin.  I&#8217;m blogging about it hoping someone might do it before I get a chance <img src='http://www.rogue-development.com/blog2/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.rogue-development.com/blog2/2009/04/bubbling-events-in-data-models/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flex ADDED_TO_STAGE event and scrollbars</title>
		<link>http://www.rogue-development.com/blog2/2009/01/flex-added_to_stage-event-and-scrollbars/</link>
		<comments>http://www.rogue-development.com/blog2/2009/01/flex-added_to_stage-event-and-scrollbars/#comments</comments>
		<pubDate>Thu, 15 Jan 2009 15:19:34 +0000</pubDate>
		<dc:creator>Marc</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://www.rogue-development.com/blog2/?p=281</guid>
		<description><![CDATA[Be careful with ADDED_TO_STAGE event handlers, I ran into a interesting bug today.  Upon resizing the browser window, the current &#8220;activity&#8221; the user was working on would restart.  It should only have restarted when it was added to the stage and was confusing me why it would occur upon resizing a browser window. A little [...]]]></description>
			<content:encoded><![CDATA[<p>Be careful with ADDED_TO_STAGE event handlers, I ran into a interesting bug today.  Upon resizing the browser window, the current &#8220;activity&#8221; the user was working on would restart.  It should only have restarted when it was added to the stage and was confusing me why it would occur upon resizing a browser window.</p>
<p>A little digging, and I figured out why.</p>
<p>If you have a component inside a flex container like a Canvas.  And the container is resized and all of a sudden it requires a scrollbar to fit everything you will get an extra ADDED_TO_STAGE event.  Internally the container removes the component, creates a content pane to scroll around, and moves all of it&#8217;s children from the base container object onto this content pane.  That removal/addition causes the ADDED_TO_STAGE events to fire and caused my bug.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rogue-development.com/blog2/2009/01/flex-added_to_stage-event-and-scrollbars/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>One good reason for IoC</title>
		<link>http://www.rogue-development.com/blog2/2009/01/one-good-reason-for-ioc/</link>
		<comments>http://www.rogue-development.com/blog2/2009/01/one-good-reason-for-ioc/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 14:31:27 +0000</pubDate>
		<dc:creator>Marc</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[IoC]]></category>

		<guid isPermaLink="false">http://www.rogue-development.com/blog2/?p=279</guid>
		<description><![CDATA[So often I get asked why it&#8217;s a good idea to use an IoC container and it&#8217;s always difficult for me to explain.  It&#8217;s actually a fairly hard question to answer to somebody who has never used one.  I came across one great example this week. We&#8217;re working on an educational application made up of [...]]]></description>
			<content:encoded><![CDATA[<p>So often I get asked why it&#8217;s a good idea to use an IoC container and it&#8217;s always difficult for me to explain.  It&#8217;s actually a fairly hard question to answer to somebody who has never used one.  I came across one great example this week.</p>
<p>We&#8217;re working on an educational application made up of a series of lessons.  The general flow of our app is:</p>
<ol>
<li>Start Up</li>
<li>Login</li>
<li>Request what the next lesson is from the server.</li>
<li>Do the lesson</li>
<li>Send results</li>
<li>Goto #3</li>
</ol>
<p>To do #3 we have a service object that knows how to make that request to the server and handle the response.</p>
<p>But&#8230;</p>
<p>We don&#8217;t want to have to deal with having a server running all of the time during development of the client.  So we created a brand new class that implements the same interface as that service.  However, instead of asking the server what the next lesson should be, it displays a UI that lets the developer/qa person select a lesson.  With IoC we simply changed the configuration that instantiated that object to use this new class and bamn, it works throughout the application.</p>
<p>Now, I&#8217;m working on a demo of the software for management.  We want it to go through a predefined, fixed, list of lessons for the demo.  I created a new service object that maintains a list of lessons to go through sequentially, updated the config, and bamn&#8230; our demo is ready.</p>
<p>So now, the exact same application code can be run three different ways depending on what configuration we give it.</p>
<p>Now, it&#8217;s certainly easy to do a similar thing using other non-IoC approaches.  Maybe you&#8217;d need a recompile for those (but is that all that bad?).  The benefit with IoC is that it tends to make developing like this automatic.  It pushes developers to code to interfaces and create modules that can be easily replaced with others.  It&#8217;s a developer &#8220;state of mind&#8221; benefit.</p>
<p>In case you&#8217;re curious, we use <a href="http://www.spicefactory.org/parsley/">Parsley</a> as our IoC container.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rogue-development.com/blog2/2009/01/one-good-reason-for-ioc/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>OpenID From AIR</title>
		<link>http://www.rogue-development.com/blog2/2008/08/openid-from-air/</link>
		<comments>http://www.rogue-development.com/blog2/2008/08/openid-from-air/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 02:03:35 +0000</pubDate>
		<dc:creator>Marc</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[AIR]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[red5]]></category>

		<guid isPermaLink="false">http://www.rogue-development.com/blog2/2008/08/openid-from-air/</guid>
		<description><![CDATA[I&#8217;ve been working on some web services recently.&#160; There&#8217;s both plain old browser accessed HTML pages plus an AMF interface to them.&#160; One feature of the HTML version is OpenID authentication.&#160; Now OpenID is all fine and dandy for a web application, but we get some problems when we want to use an AIR desktop [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on some web services recently.&#160; There&#8217;s both plain old browser accessed HTML pages plus an AMF interface to them.&#160; One feature of the HTML version is OpenID authentication.&#160; Now OpenID is all fine and dandy for a web application, but we get some problems when we want to use an AIR desktop client to connect and authenticate through OpenID.&#160; </p>
<p>If you&#8217;re not familiar with how OpenID works, here&#8217;s a quick summary.</p>
<ol>
<li>User goes to an application (Usually a web-app)</li>
<li>User types in their OpenID URL to that app</li>
<li>They get forwarded to their OpenID page where they can either grant or deny access.</li>
<li>That page then forwards them back to the original web app with an authentication token set.</li>
</ol>
<p>Obviously, it&#8217;s kind of hard to redirect back to a desktop application.&#160; I was thinking up some wacky work-a-rounds for this but then it hit me. </p>
<p>In the AIR app I can just use the HTML component and point it towards the login form of the web services.&#160; The user can then log in using either username/password or OpenID just like they do on the website.&#160; Now, here&#8217;s the cool part&#8230;&#160; The AIR HTML component shares a network stack with the AIR/Flex NetConnection object.&#160; That means any session/cookies/whatever opened in the HTML component carry through to the remoting calls I want to make from Actionscript. So I can authenticate using a web form, but then consume BlazeDS/LiveCycleDS/AMFPHP/Red5 services using AMF over Netconnection. </p>
<p>I did up a quick proof of concept and it works on both Windows and OSX.&#160; I was able to successfully call a remoting service that requires an authenticated session.&#160; So this was actually a much easier problem to figure out than I had feared. </p>
<p><img src="http://www.rogue-development.com/uploads/adlScreenSnapz014.png" width="600" height="448" /></p>
<p>Now, I&#8217;ll just need to make the web page that loads after a successful login somehow indicate to the AIR app that the user is successfully logged in.&#160; I&#8217;ll probably either use a tiny Flash component that signals over LocalConnection, or I&#8217;ll just make the AIR app watch for when the HTML component gets to a specific URL. I&#8217;m pretty sure I can get this to be a completely seamless experience for the user.</p>
<p>Oh, and as a bonus&#8230; the user can sign up for a new account instead of log into an existing one from &quot;within the app&quot; instead of going to an external website to do that.  </p>
<p><br/>
		      </p>
]]></content:encoded>
			<wfw:commentRss>http://www.rogue-development.com/blog2/2008/08/openid-from-air/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Model Adapters &#8211; A binding pattern using an Adapter</title>
		<link>http://www.rogue-development.com/blog2/2008/07/model-adapters-a-binding-pattern/</link>
		<comments>http://www.rogue-development.com/blog2/2008/07/model-adapters-a-binding-pattern/#comments</comments>
		<pubDate>Fri, 18 Jul 2008 05:26:21 +0000</pubDate>
		<dc:creator>Marc</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[actionscript 3]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://www.rogue-development.com/blog2/2008/07/model-adapters-a-binding-pattern/</guid>
		<description><![CDATA[Binding in Flex is great. It&#8217;s an ultra convienent way to get information from your data model to show up in your views. But it does have some limitations, and to work around those limitations I&#8217;ve been using the &#8220;Model Adapter&#8221; aka the &#8220;Wrapper&#8221; or just plain &#8220;Adapter&#8221; pattern (some info, and more). The basic [...]]]></description>
			<content:encoded><![CDATA[<p>Binding in Flex is great.  It&#8217;s an ultra convienent way to get information from your data model to show up in your views.  But it does have some limitations, and to work around those limitations I&#8217;ve been using the &#8220;Model Adapter&#8221; aka the &#8220;Wrapper&#8221; or just plain &#8220;Adapter&#8221; pattern (<a href="http://en.wikipedia.org/wiki/Wrapper_pattern">some info</a>, <a href="http://developerlife.com/tutorials/?p=19">and more</a>).</p>
<p>The basic idea is you shouldn&#8217;t have to modify your data model to use it in a specific view.  If you need to <strong>filter</strong>, <strong>sort</strong>, or <strong>summarize</strong> the data for a view you can do that through an Adapter so your model doesn&#8217;t need to understand that logic and you&#8217;re view isn&#8217;t reliant on a specific implementation of your model.</p>
<p><strong>Example</strong>: If you had a list of books in an array, and you want to filter by some property of books (say publisher) you shouldn&#8217;t apply the filter directly to the model.  Instead, create an adapter that can watch that array, and have that adapter apply the filter (or sort, or whatever).</p>
<p><strong>More Examples</strong>:  Consider <a href="http://www.tomsnyder.com/timelinerxe/">Timeliner XE,</a> a product I&#8217;ve been working on at my day-job.  The main data model is a list of events.  There are several views for that data.  We have a text based / grid view, and some graphical views.  Here&#8217;s a couple screenshots:</p>
<p><img src="http://www.rogue-development.com/blog2/wp-content/uploads/2008/07/adlscreensnapz012.png" alt="" width="628" height="388" /></p>
<p><img src="http://www.rogue-development.com/blog2/wp-content/uploads/2008/07/adlscreensnapz013.png" alt="" width="628" height="388" /></p>
<p>Each of those screenshots has 2 views active at a time, the grid, and then a seperate graphical view.  That makes 3 views that all want to bind to our data model.  But, notice the grid has 5 events in it, while the graphical views only have 3.  This is because only 3 of those events are valid to plot (they have a date).  It&#8217;d be nice if we only had to bind to a list of events that actually has the data we want.</p>
<p>Now take a look at these three screenshots from <a href="http://www.agileagenda.com/">AgileAgenda</a>, my project scheduling application.</p>
<p><img src="http://www.rogue-development.com/blog2/wp-content/uploads/2008/07/agileagendascreensnapz007.png" alt="" width="570" height="427" /><img src="http://www.rogue-development.com/blog2/wp-content/uploads/2008/07/agileagendascreensnapz008.png" alt="" width="570" height="427" /><img src="http://www.rogue-development.com/blog2/wp-content/uploads/2008/07/agileagendascreensnapz009.png" alt="" width="593" height="429" /></p>
<p>In all of these the data we have is a list of tasks.  The first two show one view with two different filters applied to the data.  The third shows a large grid with all of our tasks, and a much shorter pulldown that only has the tasks that are also milestones.  (A milestone is a specific type of task)</p>
<p>To create an adapter:</p>
<ul>
<li>Create a new adapter class</li>
<li>Create a constructor for that class that takes in the &#8220;source&#8221; data model, and any options that might be specific to the adapter.</li>
<li>Add event listeners to the &#8220;source&#8221; model.</li>
<li>Write event handlers in the adapter to update the adapter&#8217;s internal state when the source changes.</li>
<li>Write accessors in the adapter, so other components can get data from it.</li>
</ul>
<p><strong>A simple example&#8230;</strong></p>
<p><a href="http://rogue-development.com/uploads/model_adapter/ModelAdapterExample.html">Click here</a> to run a simple example.  <a href="http://rogue-development.com/uploads/model_adapter/srcview/index.html">View-source</a> is enabled in that. Here&#8217;s a screenshot of the example:</p>
<p><img src="http://www.rogue-development.com/blog2/wp-content/uploads/2008/07/firefoxscreensnapz001.png" alt="" width="387" height="471" /></p>
<p>When you run the example, it creates a simple data model, populates that data model with 4 sample items, and then creates 4 panels.  Each of those panels represents a view. The example also creates 4 different model adapters all from the same data model, but with different options set.  Then each panel gets a different adapter.</p>
<p>As you add items to the data model, you can see that the 4 views update depending on whether or not they are filtered and sorted.</p>
<p><strong>Our Data Model:</strong></p>
<pre>package
{
    public  DataItemExample
    {
        public var name:String;
        public var amount:Number;
        public var active:Boolean;
    }
}</pre>
<p>&#8212;-</p>
<pre>package
{
    import mx.collections.ArrayCollection;

    public  DataModelExample
    {
        [Bindable] public var myDataItems:ArrayCollection = new ArrayCollection();

    }
}</pre>
<p>As you can see, it&#8217;s a pretty simple data model.  There are items with a name, amount and active properties, and then there is DataModelExample class with an array of those.  Notice that no view-specific data is in there.</p>
<p>Now, lets create our adapter and name it &#8220;AdapterExample&#8221;</p>
<p>First, create a constructor and some variables to hold some information about the adapter.  We&#8217;ll have 2 options. onlyActiveItems and sorted.  For sorted, we&#8217;ll also create a Sort object to actually do the sort for us.  And we&#8217;ll also create an array to hold our filtered/sorted list of items.  Note that we add an event listener for the COLLECTION_CHANGE event.  This is how we&#8217;ll propogate changes from the data model to our adapter.  We&#8217;ll see the handler for that later.</p>
<pre> public  AdapterExample extends EventDispatcher
    {
        protected var model:DataModelExample;
        protected var filteredDataItems:ArrayCollection = new ArrayCollection();
        protected var _onlyActiveItems:Boolean;
        protected var _sorted:Boolean = false;
        protected var sort:Sort;        

        public function AdapterExample(dataModel:DataModelExample, onlyActiveItems:Boolean, sorted:Boolean)
        {
            _sorted = sorted;
            _onlyActiveItems = onlyActiveItems;

            model = dataModel;
            model.myDataItems.addEventListener(CollectionEvent.COLLECTION_CHANGE, onItemsChanged );    

            if(sorted)
            {
                sort = new Sort();
                sort.fields = [new SortField("name",true)];
            }

            rebuildFilteredArray();
        }</pre>
<p>Notice that we called rebuildFilteredArray above.  Lets write that next.    All this method does is loop through our data model and grab all the items from it (respecting our filtering option) and adds them to our internal array.  It also applies the sort if neccessary.  At the end we dispatch two events which will be used for binding later.</p>
<pre>  protected function rebuildFilteredArray() : void
        {
            var tmp:Array = [];
            for each ( var item:DataItemExample in model.myDataItems )
            {
                if( (! _onlyActiveItems ) || (item.active) )
                {
                    tmp.push(item);
                }
            }                        

            filteredDataItems = new ArrayCollection(tmp);

            if( sort )
            {
                filteredDataItems.sort = sort;
                filteredDataItems.refresh();
            }

            dispatchEvent(new Event("dataItemsUpdated") );
            dispatchEvent(new Event("totalChanged") );
        }</pre>
<p>So now if we made an adapter it would start up, read in the source data model, and populate our internal array of items.  But it wouldn&#8217;t respond to changes in the source data model.  So lets create the event handler that we set up in the constructor. We&#8217;ll also create  a couple helper methods</p>
<pre>    protected function onItemsChanged(event:CollectionEvent):void
        {
            switch(event.kind)
            {
                case CollectionEventKind.ADD: addItems(event.items); break;
                case CollectionEventKind.REMOVE: removeItems(event.items); break;

                case CollectionEventKind.MOVE:
                case CollectionEventKind.REFRESH:
                case CollectionEventKind.REPLACE:
                case CollectionEventKind.RESET:    rebuildFilteredArray();
                                                break;

                case CollectionEventKind.UPDATE:  

            }

        }

        protected function addItems(items:Array):void
        {
            for each ( var item:DataItemExample in items )
            {
                if( (! _onlyActiveItems ) || (item.active) )
                {
                    filteredDataItems.addItem(item);
                }
            }
            dispatchEvent(new Event("totalChanged") );
        }

        protected function removeItems(items:Array):void
        {
            for each ( var item:DataItemExample in items )
            {
                var index:int = filteredDataItems.getItemIndex(item);
                if( index != -1 )
                {
                    filteredDataItems.removeItemAt(index);
                }
            }
            dispatchEvent(new Event("totalChanged") );
        }</pre>
<p>For adding/removing items we&#8217;re going to our internal array and manually adding or removing items from it.  We&#8217;re making sure to account for filtered items, but the sort object is taking care of the sorting for us.</p>
<p>For the other types of events,  we&#8217;re kind of cheating.  We only really care about adding / removing operations so we&#8217;ll just rebuild our entire internal array on other types of events.  If your application uses those types of events often, you should implement them in the adapter in a more efficient manner.</p>
<p><strong>Exposing data from the Adapter</strong></p>
<p>We now have the internal state of the adapter updating as the model changes.  So the only thing left to do in there is expose some properties so we can get at that info from our view.  Let&#8217;s write two bindable getters.  One of them will summarize the data (get total()) the other will give us our filtered list (get dataItems())</p>
<p>Note that we set the event=&#8221;" property in the [Bindable] tags so our views can correctly know when these properties change.</p>
<pre>  [Bindable(event="dataItemsUpdated")]
        public function get dataItems() : ArrayCollection
        {
            return filteredDataItems;
        }

        [Bindable(event="totalChanged")]
        public function get total() : Number
        {
            var total:Number = 0;
            for each ( var item:DataItemExample in filteredDataItems )
            {
                total += item.amount;
            }    

            return total;
        }</pre>
<p><strong>Using the Adapter</strong></p>
<p>Once you&#8217;ve done all of that, you can actually use your adapter.  So create your data model, create your adapter, and use it!</p>
<pre> [Bindable] protected var dataModel:DataModelExample = new DataModelExample();
 [Bindable] protected var example1:AdapterExample = new AdapterExample( dataModel, true ,true);</pre>
<p>&#8230;</p>
<pre>    <span class="MXMLComponent_Tag">&lt;mx:Panel</span><span class="MXMLDefault_Text"> x="</span><span class="MXMLString">10</span><span class="MXMLDefault_Text">" y="</span><span class="MXMLString">218</span><span class="MXMLDefault_Text">" width="</span><span class="MXMLString">250</span><span class="MXMLDefault_Text">" height="</span><span class="MXMLString">200</span><span class="MXMLDefault_Text">" layout="</span><span class="MXMLString">absolute</span><span class="MXMLDefault_Text">" title="</span><span class="MXMLString">Filtered, Sorted</span><span class="MXMLDefault_Text">"</span><span class="MXMLComponent_Tag">&gt;</span>
        <span class="MXMLComponent_Tag">&lt;mx:Label</span><span class="MXMLDefault_Text"> x="</span><span class="MXMLString">10</span><span class="MXMLDefault_Text">" y="</span><span class="MXMLString">132</span><span class="MXMLDefault_Text">" text="</span><span class="MXMLString">Total:</span><span class="MXMLDefault_Text">"</span><span class="MXMLComponent_Tag">/&gt;</span>
        <span class="MXMLComponent_Tag">&lt;mx:Label</span><span class="MXMLDefault_Text"> x="</span><span class="MXMLString">56</span><span class="MXMLDefault_Text">" y="</span><span class="MXMLString">132</span><span class="MXMLDefault_Text">" text="</span><span class="MXMLString">{</span>example1.total<span class="MXMLString">}</span><span class="MXMLDefault_Text">"</span><span class="MXMLComponent_Tag">/&gt;</span>
        <span class="MXMLComponent_Tag">&lt;mx:List</span><span class="MXMLDefault_Text"> x="</span><span class="MXMLString">10</span><span class="MXMLDefault_Text">" y="</span><span class="MXMLString">4</span><span class="MXMLDefault_Text">" width="</span><span class="MXMLString">210</span><span class="MXMLDefault_Text">" height="</span><span class="MXMLString">120</span><span class="MXMLDefault_Text">" dataProvider="</span><span class="MXMLString">{</span>example1.dataItems<span class="MXMLString">}</span><span class="MXMLDefault_Text">" labelField="</span><span class="MXMLString">name</span><span class="MXMLDefault_Text">"</span><span class="MXMLComponent_Tag">&gt;</span><span class="MXMLComponent_Tag">&lt;/mx:List&gt;</span>
    <span class="MXMLComponent_Tag">&lt;/mx:Panel&gt;</span></pre>
<p>If you look at the source of the example, we actually create 4 adapters with varying options.</p>
<p><strong>Beyond this basic example</strong></p>
<p>If you want your adapter to respect changes to individual items, your items should implement the IPropertyChangeNotifier interface.  So in our example if we edited an item so it&#8217;s active flag changed, the views would not update.  To make that work we would implement that IPropertyChangeNotifier interface, and then write some code for the CollectionEventKind.UPDATE event.</p>
<p>Often times only one or two views are visible at a time and it&#8217;d be nice if all the views in the background weren&#8217;t madly updating themselves every change.  To accomplish that I often write an enable() disable() method on the adapter.  They usually look something like this:</p>
<p>protected function enable() : void</p>
<p>{</p>
<p>model.myDataItems.addEventListener(CollectionEvent.COLLECTION_CHANGE, onItemsChanged );</p>
<p>rebuildFilteredArray();</p>
<p>}</p>
<p>protected function disable() : void</p>
<p>{</p>
<p>model.myDataItems.removeEventListener(CollectionEvent.COLLECTION_CHANGE, onItemsChanged );</p>
<p>}</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rogue-development.com/blog2/2008/07/model-adapters-a-binding-pattern/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>The Essential Guide to Open Source Flash Development</title>
		<link>http://www.rogue-development.com/blog2/2008/07/the-essential-guide-to-open-source-flash-development/</link>
		<comments>http://www.rogue-development.com/blog2/2008/07/the-essential-guide-to-open-source-flash-development/#comments</comments>
		<pubDate>Mon, 14 Jul 2008 13:34:22 +0000</pubDate>
		<dc:creator>Marc</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[actionscript 3]]></category>
		<category><![CDATA[ant]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[OpenSource]]></category>
		<category><![CDATA[red5]]></category>
		<category><![CDATA[Schedule]]></category>
		<category><![CDATA[XRay]]></category>

		<guid isPermaLink="false">http://www.rogue-development.com/blog2/2008/07/the-essential-guide-to-open-source-flash-development/</guid>
		<description><![CDATA[The book I&#8217;ve been working on, The Essential Guide to Open Source Flash Development, is now out in stores.  It&#8217;s hard to believe that I started working on it about 11 months ago!  It&#8217;s really great to see all of that hard work finally in print. So What is it about? The book does a [...]]]></description>
			<content:encoded><![CDATA[<p>The book I&#8217;ve been working on, <em>The Essential Guide to Open Source Flash Development</em>, is now out in stores.  It&#8217;s hard to believe that I started working on it about 11 months ago!  It&#8217;s really great to see all of that hard work finally in print.</p>
<p><img src="http://rogue-development.com/uploads/book.jpg" alt="" width="600" height="528" /></p>
<p>So What is it about?</p>
<p>The book does a few things.  First, about a third of the book introduces you to some open source tools for doing flash development.  Things like FlashDevelop, MTASC, SwfMill, ANT, and ASDT.  It&#8217;ll show you how to create an AS2 and an AS3 based flash application using completely free and open software.  This goes all the way from installing the tools, creating a sample app, writing up some unit tests for it, and then  to publishing it to the web.  Along the way it&#8217;ll give you a brief introduction to each tool, explain what it does, and then give a quick example of how to use it.  (That&#8217;s the 5 chapters I wrote)</p>
<p>The remaining 2/3 of the book dedicates a chapter to various open source projects going into a little more detail about them.  There&#8217;s a chapter on Papervision 3D, SWX, FUSE/Go, HAXE, AMFPHP, two for Red5 and a couple more.</p>
<p>This was a lot of fun to work on, and my only regret is not getting to know the other authors better.</p>
<p>If you&#8217;re looking for a place to buy it, check out <a href="http://www.bookpool.com/sm/1430209933">Bookpool</a>.   I worked for them for a year and they&#8217;re really stellar guys.  They offer good prices, but more importantly;  as long as the book is in stock, they do their damndest to get it on a truck the day you order it. (Of course, you&#8217;re at the mercy of the publisher if it&#8217;s out of stock)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rogue-development.com/blog2/2008/07/the-essential-guide-to-open-source-flash-development/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>New Object Handles release</title>
		<link>http://www.rogue-development.com/blog2/2008/05/new-object-handles-release/</link>
		<comments>http://www.rogue-development.com/blog2/2008/05/new-object-handles-release/#comments</comments>
		<pubDate>Wed, 14 May 2008 12:00:55 +0000</pubDate>
		<dc:creator>Marc</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[flex 3]]></category>
		<category><![CDATA[ObjectHandles]]></category>

		<guid isPermaLink="false">http://www.rogue-development.com/blog2/2008/05/new-object-handles-release/</guid>
		<description><![CDATA[I just whipped up a new ObjectHandles release.  Couple notable things&#8230; They now automatically remove themselves from the SelectionManager when removed from the stage (they add themselves back when added as well).  This fixes a fairly serious memory leak. I&#8217;m deprecating the useage of the Handle class.  It draws the handles through the drawing API.  [...]]]></description>
			<content:encoded><![CDATA[<p>I just whipped up a new <a href="http://www.rogue-development.com/objectHandles.html">ObjectHandles</a> release.  Couple notable things&#8230;</p>
<p>They now automatically remove themselves from the SelectionManager when removed from the stage (they add themselves back when added as well).  This fixes a fairly serious memory leak.</p>
<p>I&#8217;m deprecating the useage of the Handle class.  It draws the handles through the drawing API.  Now, instead use the ImageHandle class which draws the handles from an embedded image.  There was some wonky logic in there that turned clipping on or off depending on this setting and that was just plain dumb.  Lets just do it one way.  I included sample .png files to simulate the old look.</p>
<p>I fixed some weird flickering when resizing to the left or up.  It only happened on certain cases, and I&#8217;m not sure why.  I think it had to do with delayed execution of the Flex layout manager.  Now, I delay the setting of x,y,width, and height and force a validateNow() right after setting those.  Let me know if this causes any problems in your application.</p>
<p>I still don&#8217;t have conditional compile for Flex2/Flex3 in there, so this will only compile under Flex 3.  Does anyone know how to get that conditional compiling to detect Flex version without having to pass an extra compiler param?</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="632" height="515" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="quality" value="high" /><param name="src" value="http://www.rogue-development.com/objecthandles/MoveAndResize.swf" /><embed type="application/x-shockwave-flash" width="632" height="515" src="http://www.rogue-development.com/objecthandles/MoveAndResize.swf" quality="high"></embed></object></p>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.rogue-development.com/blog2/2008/05/new-object-handles-release/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Case Study: Three large Flex/AIR applications</title>
		<link>http://www.rogue-development.com/blog2/2008/05/case-study-three-flex-applications/</link>
		<comments>http://www.rogue-development.com/blog2/2008/05/case-study-three-flex-applications/#comments</comments>
		<pubDate>Mon, 12 May 2008 14:08:45 +0000</pubDate>
		<dc:creator>Marc</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[AIR]]></category>
		<category><![CDATA[AgileAgenda]]></category>
		<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://www.rogue-development.com/blog2/2008/09/06/case-study-three-flex-applications/</guid>
		<description><![CDATA[I&#8217;m currently wrapping up three different fairly large AIR applications developed in different ways. In this blog post I hope to describe the methods used in them, what worked well, and what didn&#8217;t work so well.    Hopefully this will be useful to others starting up projects in the near future. I&#8217;m going to call [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently wrapping up three different fairly large AIR applications developed in different ways. In this blog post I hope to describe the methods used in them, what worked well, and what didn&#8217;t work so well.    Hopefully this will be useful to others starting up projects in the near future.</p>
<p>I&#8217;m going to call these &#8220;large&#8221; applications since they go a lot deeper than a simple toy or small experience site that most Flex apps seem to be.  Your definition of &#8220;large&#8221; may differ.  These are full blown desktop applications, not a web-app ported to the desktop or a simple desktop app to augment a web-app.  All three were planned on being desktop apps from the start.  It&#8217;s not a common target audience for AIR, but I believe in the platform for this use.</p>
<h2>A description of the projects</h2>
<p>First, a quick rundown of the apps.</p>
<p><strong>AgileAgenda</strong></p>
<p><img src="http://www.rogue-development.com/blog2/wp-content/uploads/2008/05/agileagendascreensnapz002.png" alt="" width="611" height="444" /></p>
<p>This was my entry for the Adobe AIR Derby so the beginnings were a rapid no-holds barred get-something-out-the-door effort.  There was no good planning that went into this, and no framework used.  This is one of my solo projects.</p>
<p>It&#8217;s since gone through several major UI revisions, with some parts of the application completly changing how they work or look several times over.</p>
<p>It&#8217;s a project scheduling application focusing on allowing users to create a schedule by entering tasks, priorities, and durations while letting the software calculate start/end dates.  Besides that it&#8217;s got some nifty sharing functionality, a PDF export, and a few different ways to look at your data.  I&#8217;ve been <a href="http://www.agileagenda.com/">selling it commercially</a> for while and not doing too bad, take a look and let me know what you think.  I&#8217;m always interested in feedback.</p>
<p> </p>
<p> </p>
<hr /> </p>
<p><strong>AgileTracker</strong></p>
<p><img src="http://www.rogue-development.com/blog2/wp-content/uploads/2008/05/agiletrackerscreensnapz002.png" alt="" width="526" height="405" /></p>
<p>AgileAgenda was doing pretty good, and a time-tracking application to work with it seemed like the next logical step.  I had been looking around and found Parsley and was fairly impressed so I decided to give it a shot. This is also one of my solo projects.</p>
<p>The AgileTracker allows you to subscribe to a schedule in AgileAgenda to get your list of tasks.  Then you can use the built in timer, or manually enter time to keep track of how long you spend on various tasks.  Someday, it&#8217;ll have full read/write capabilities to AgileAgenda for a full round trip exchanging of data.</p>
<p> </p>
<p> </p>
<hr /> </p>
<p><strong>TimeLiner XE </strong></p>
<p><img src="http://www.rogue-development.com/blog2/wp-content/uploads/2008/05/adlscreensnapz001.png" alt="" width="635" height="418" /></p>
<p>This is probably where I learned the most.  I acted as the project lead on a 3-5 engineer team that grew or shrunk throughout the process depending on other needs.  It was developed in a commercial setting (at Tom Snyder Productions, my <a href="http://www.tomsnyder.com/">day-job</a>, which I&#8217;ve been very fortunate to find)  We&#8217;ve got a formal art, engineering, and QA team over there.</p>
<p>TimeLiner XE is the 6th major revision of one of the best selling desktop applications my employer publishes.  Previous versions were written in C++ with a proprietary cross platform layer.  It was a big gamble betting on Flex/AIR instead of sticking with C++, but we&#8217;ve been pretty happy so far.  The built in WebKit HTML renderer made one of our features (a web based research mode) a &#8220;killer feature&#8221; and doing that in a cross platform way in C++ would have been a huge investment compared to what we accomplished in AIR fairly simply.</p>
<p>You can see a pre-recorded webcast seminar at the TimeLinerXE web page. <a href="http://www.tomsnyder.com/timelinerxe/">http://www.tomsnyder.com/timelinerxe/</a><br />
If you jump to about the 3 minute mark, that&#8217;s where they start actually showing off the software. </p>
<p> </p>
<p> </p>
<hr /> </p>
<p><strong>Quick summary</strong>&#8230;</p>
<table border="1" cellspacing="0" cellpadding="6" width="491" bgcolor="#FFFFFF" bordercolor="#000000">
<tbody>
<tr valign="top">
<td width="83" valign="top"><strong>App Name </strong></td>
<td width="199" valign="top">Info</td>
<td width="165" valign="top"><strong>Framework</strong></td>
</tr>
<tr valign="top">
<td valign="top"><a href="http://www.agileagenda.com/">Agile Agenda </a></td>
<td valign="top">~ 25,000 Lines of Code             </p>
<p>1 Developer</p>
<p>First released on AIR Beta 1</td>
<td valign="top">None             </p>
<p>(Developed Quickly &amp; AdHoc for the <a href="http://labs.adobe.com/showcase/special/airderby/">Adobe AIR Derby</a>)</td>
</tr>
<tr valign="top">
<td valign="top"><a href="http://www.agileagenda.com/download/">Agile Tracker </a></td>
<td valign="top">~ 8,000 Lines of Code             </p>
<p>1 Developer</p>
<p>First released on AIR 1.0</td>
<td valign="top"><a href="http://spicefactory.org/">Parsley</a> MVC + IoC</td>
</tr>
<tr valign="top">
<td height="83" valign="top"><a href="http://www.tomsnyder.com/Products/product.asp?SKU=TIMV50">TimeLiner XE </a>             </p>
<p> </td>
<td valign="top">~ 100,000 Lines of Code             </p>
<p>3-5 Developers</p>
<p>1 Designer</p>
<p>Several QA engineers</p>
<p>Not yet released</td>
<td valign="top"><a href="http://labs.adobe.com/wiki/index.php/Cairngorm">Cairngorm</a></td>
</tr>
</tbody>
</table>
<p>LoC numbers above are just to give an idea of the scope of the project and does not include code from libraries (either internally developed or open source).  There&#8217;s a similar coding style in all three, so it&#8217;s purely meant to give an idea of the relative size of the projects.  The AgileTracker is larger than listed, because it reused a bunch of code from AgileAgenda which isn&#8217;t reflected in those numbers.</p>
<p> </p>
<p> </p>
<hr /> </p>
<p> </p>
<h2>Things we did right</h2>
<p><strong>QA / Bug Tracking</strong></p>
<p>Tom Snyder has a first class QA team. Having them involved early in the project helped direct it to be a project that was easier to test, and of higher quality than might otherwise have been possible.  Having a dedicated and passionate QA team is the single best thing that can happen to any software project.  We&#8217;re using Bugzilla for tracking which works pretty well, but will be moving to HP&#8217;s Quality Center in the near future (which I hope works even better!)</p>
<p>On the AgileAgenda side of things, this wasn&#8217;t so great.  I&#8217;m looking to rectify that in the near future, but finding the right person (at the right price) is difficult.  Since it&#8217;s a simple 1-person project I&#8217;ve been using <a href="http://hogbaysoftware.com/products/taskpaper">TaskPaper</a> to keep track of  my list of bugs, my list of future features, and my general todo list.  I&#8217;m currently looking for a good end-user bug reporting system, but haven&#8217;t found anything that really fits my needs yet.</p>
<p><strong>Open Source!</strong></p>
<p>All three applications use some very good open source projects.  Without these, the development would have taken a lot longer, and been a lot more labor intensive.  Two of the more important libraries were&#8230;</p>
<p><strong>Object Handles</strong> (Open Source)</p>
<p><a href="http://www.rogue-development.com/objectHandles.html">ObjectHandles</a> is a library I wrote a while back that makes it easy to create interfaces that let the user drag and resize components around the screen.  It&#8217;s amazing how having a library like that can make you add that type of functionality into places where you may not have wanted to spend the time implementing without it.  Take a look at AgileAgenda&#8217;s <a href="http://www.agileagenda.com/help/lightTable.html">Light Table</a>.  The Light Table is one of the features I get the most positive feedback about.  It took an afternoon to implement with this libray.  Without it, it would likely have taken a week and would have never gone into the 1.0 version.  Almost the entire TimeLiner interface was build with this library.</p>
<p><strong>AlivePDF</strong> (Open Source)</p>
<p>The printing in AgileAgenda is completly done with <a href="http://alivepdf.bytearray.org">AlivePDF</a>.  This lets the usercreate a PDF to print, send to a colleague, post on a website, etc.   It&#8217;s amazing easy to use and creates high quality PDF&#8217;s.  (Yeah, AgileAgenda doesn&#8217;t deal with margins well right now, that&#8217;s my fault and not AlivePDF&#8217;s).  </p>
<p><strong>Parsley<span style="font-weight: normal;"> (Open Source)</span></strong></p>
<p><a href="http://spicefactory.org/parsley/">Parsley</a> is great, unfortunately it was only used in the AgileTracker.  Using an IoC container for applications like these makes perfect sense, and the MVC infrastructure it provides makes it super easy to stick to the MVC model without being tempted to just have the UI muck around with your data.  The only frustrating thing I&#8217;ve found with it, is that it&#8217;s harder to debug a parsley based application when problems occur.</p>
<p>When you&#8217;re using Java/Spring on the server side, it&#8217;s also helpful to use a client side framework where you can think in the same way. </p>
<p><strong>Perforce</strong></p>
<p>We use <a href="http://www.perforce.com/">Perforce</a> for the version control system for all the mentioned projects.  It rocks, hardcore.  Even for my single-developer projects I find myself more organized with less of chance for losing something important because of it.  Subversion, CVS, whatever other version control system you use is fine too, but just make sure to use one!</p>
<p><strong>ANT</strong></p>
<p>All three projects can be fully built through a single <a href="http://ant.apache.org/">ANT</a> command.  The release builds of all the projects are made in this way.  It doesn&#8217;t matter if a developer updates his build environment, or if your FlexBuilder license gets funky, you can always make a known-good build through a simple single command line. </p>
<p>For AgileAgenda we actually end up making several builds (<a href="http://www.rogue-development.com/blog2/2008/03/01/self-signed-vs-ca-signed-air-apps/">ready why</a>), plus update the download page all automatically from the build script.  No more creating a release version from FlexBuilder, copying it to the web directory, using FTP to transfer it and editing a file to update the version on the website!</p>
<p>If you&#8217;re making release builds of your software from within Flex Builder, you really are missing out and wasting a lot of time.</p>
<p><strong>CruiseControl</strong> (Continuos integration)</p>
<p>For TimeLiner we&#8217;re automatically running builds through CruiseControl after every single code checkin.  When you have between 3 and 5 developers, it&#8217;s very easy to submit code that builds for you but nobody else.  By using CruiseControl, whoever submits a change to perforce like that gets an email telling them within 10 minutes.  No more yelling &#8220;Who forgot to add SomeWeirdClass.as to version control?&#8221;</p>
<p>For a while we had it running our unit tests as well, but unfortunately we don&#8217;t anymore (see below).</p>
<p><strong>We didn&#8217;t try to hire Flex developers</strong></p>
<p>Well, we did try, and then gave up.  Flex Developers are hard to find.  Really hard.  Many people out there claiming to be a Flex Developer are really just coders and not software engineers.   Going into TimeLiner there was Me and one contractor that knew flex well.  Everyone else was either completely new to ActionScript or only had Flash experience.  But every single one of our developers was a good engineer.  Having smart people who can get things done (certainly not my <a href="http://www.joelonsoftware.com/articles/fog0000000073.html">original idea</a>) was the best way to go, especially given the duration of the project.  Teaching an engineer flex is easy compared with teaching a flex coder to be a flex engineer.</p>
<p>I think a big part of the problem here (besides Flex being so new) is Adobe doesn&#8217;t really focus on the developer market all that much.  A lot of (non-flash/flex) developers out there still see Flash simply as a way to make annoying advertisements where you punch a monkey or watch a video of a kid setting himself on fire.  Adobe is really great to their developers, but I really wish they would go after those developers letting them know what most of us know, that Actionscript is a full featured application development language, and Flex provides a great set of components.  When do we get to see Kevin Lynch on stage shouting &#8220;<em><a href="http://www.youtube.com/watch?v=KMU0tzLwhbE">DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS</a></em>&#8220;?  Of course, I hope they never lose their designer focus, it&#8217;s what sets the platform apart.</p>
<p><strong>Design / Artwork</strong></p>
<p>Having a great design team on TimeLiner really made the project.  It looks amazing.  Unfortunately, I didn&#8217;t have the budget for that in AgileAgenda.  I ended up getting my design from three main sources.</p>
<p>1)  An eager student in France was willing to do some of this for me.  Unfortunately as time went one his priorities changed and it was hard keeping that relationship going.  (You rock Olivier)</p>
<p>2) I bought a pack of icons from <a href="http://www.iconshock.com/">IconShock</a>.  I don&#8217;t know how I lived without these.  Now, whenever I&#8217;m creating something new I can look through that library of images and pop on an icon that really spruces things up and maintains a consistent feel throughout the app.  Just imagine this, without any icons, booooring.</p>
<p><img src="http://www.rogue-development.com/blog2/wp-content/uploads/2008/05/agileagendascreensnapz001.png" alt="" width="519" height="301" /></p>
<p>3) And lastly, I needed a logo.  For $150 I ran a contest on a logo design website and got my final design.  You can&#8217;t beat that price, and it&#8217;s better than anything I could have done myself.</p>
<p><img src="http://www.rogue-development.com/blog2/wp-content/uploads/2008/05/site-name-white.png" alt="" width="269" height="84" /></p>
<p>It may not win any awards, but it looks pleasing enough and the process of creating it didn&#8217;t distract me too much from the development of the software.</p>
<p> </p>
<h2>Things we did wrong</h2>
<p><strong>Plan for modules</strong></p>
<p>The biggest thing I learned is to plan for modules in large applications from the start.  At one point during the TimeLiner development we were approaching compile times of 2-3 minutes.  Making a 1-line change and then waiting for several minutes kills productivity.  We abstracted all of our styles, graphics, and sounds into modules and got that back down to a semi-reasonable compile time, but I think if we had properly planned for modules and broke the application up in a logical manner it would have been even better.</p>
<p><strong>Printing </strong>(AlivePDF for screen grabs)</p>
<p>If you&#8217;ve been reading along, you might have noticed AlivePDF above and be suprised to see it listed here as well.  Well, it&#8217;s not a problem with the library, but a problem with how we chose to use it in TimeLiner.  We made the mistake of thinking we could take an on screen visual timeline, grab a screen scrape, and dump it into a PDF for all of the benefits mentioned above.  Turns out that the antialiasing of text looks horrible after you print one of these out.  It&#8217;s a problem with the difference in resolution from screen to print.  We wrote a lot of printing code targetted at AlivePDF and it turned out not to be high enough quality when we put those PDF&#8217;s on paper.  Luckily, at least 80% of that code was re-used to create a printing system using the normal Flash/Flex printing API.  So in TimeLiner, you can now use a file-&gt;export command to make a PDF using AlivePDF to get a PDF that looks great until you print it (and then it just looks &#8220;ok&#8221;) or you can use the File-&gt;Print command to get a great looking printout.  This lets people share it either in paper or digitally with decent results in both.</p>
<p>Using AlivePDF&#8217;s methods to add text does not have this type of problem.</p>
<p><strong>Unit Tests</strong></p>
<p>For a while we were running our unit tests as a part of the TimeLiner build, but AIR 1.0 broke our unit tests and we never found the time to go back and fix them.  I wish we had, because it would have prevented some bugs from going through the QA/Fix/Verify process and saved us some time.</p>
<p><strong>Data Binding directly to the model</strong></p>
<p>TimeLiner and AgileAgenda&#8217;s interface both used to bind directly to the data model.  That&#8217;s fine for smaller applications, but for things of this complexity they break down.  Try using AgileAgenda sometime, the interface feels sluggish.  That&#8217;s because I haven&#8217;t done anything about it over there yet.  But we did do something about it in TimeLiner. Instead of binding the user interface to the data model, we created intermediary &#8220;model adapters&#8221;.  These adapters act as delegates to the model and only pass on the events that cause binding updates when they&#8217;re active.  This makes it easy to &#8220;turn off&#8221; a big part of the UI in on central place.  It also makes it easy to present the model data in different formats so we can do things like summarize a table of data for a &#8220;totals&#8221; label right inside these.  Using these adapters, it&#8217;s easy to turn on or off access to the model to various parts of the UI without complicated logic in the UI iteself.  The work we did covered about half the binding that was in place and makes a noticeable difference.  Given more time, I&#8217;d convert the entire app over to data model adapters.</p>
<p><strong>Cairngorm</strong></p>
<p>Cairngorm is a great framework.  It&#8217;s a good implementation of the command pattern and does define a decent set of methodologies of doing things.  It suited TimeLiner well and hasn&#8217;t given us many problems.  It has certainly solved far more problems than it has caused.  The only reason I place it in the &#8220;things done wrong&#8221; category is I believe Parsley to be superior, I wish we had used it for all three projects.  Parsley solved all the problems that Cairngorm solved for us, but it also managed to solve a few more.</p>
<p>Also, Cairngorm needs an easier name to say and spell <img src='http://www.rogue-development.com/blog2/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Not using AIR distribution</strong></p>
<p>For business reasons, we&#8217;re not using the AIR distribution model for TimeLiner.  It&#8217;s a shame that we have to ship a physical CD to our customers since keeping a .air file on a website somewhere is so much more cost effective. Making an installer, pressing CD&#8217;s, printing a user&#8217;s guide, and shipping all of that is just a pain and keeps the software away from the end user for an extra few weeks after the end of development.  Plus, it&#8217;s a whole lot harder to get program udpates out there.  (AgileAgenda does not suffer from this problem)</p>
<h2>Problems with the tools</h2>
<p>Disclaimer&#8230; I like Flex Builder.  It works well and gets the job done.  With Thermo focusing on the designer crowd and Flex Builder reportedly re-focusing on the developer, I think most of these problems will be worked out in future versions.</p>
<p>Eclipse/Flex Builder doesn&#8217;t do the &#8220;Run in background&#8221; thing very well and will constantly re-pop that compile progress dialog up.   Before going the module route, this absolutely killed TimeLiner.  Afterwards, it was still a constant annoyance.  Even with modules we might be interrupted, at seemingly random times, by the &#8220;Building workspace&#8221; dialog for 5-25 seconds.  If the little &#8220;stop&#8221; button would always work instantly, this wouldn&#8217;t be a problem.  But it doesn&#8217;t.  Turning off automatic compiling can help, but then you don&#8217;t get all the functionality of FlexBuilder.  When <a href="http://fdt.powerflasher.com/">FDT</a> gets decent MXML supprt, I&#8217;m going to seriously look into it.  In the past I&#8217;ve used it on AS2 projects and problems like this simply didn&#8217;t happen over there.</p>
<p>Coming from an Eclipse/JDT and an Eclipse/FDT world, FlexBuilder is missing a lot of functionality.  Snippets, decent code generation, and refactoring like &#8220;extract method&#8221; or &#8220;create delegate&#8221; would be very helpful.  From what I hear, with Thermo coming out, the FlexBuilder team will be focusing on developer-centric ideas like this which will be great.  If Adobe just made it easier for people to extend FlexBuilder, I&#8217;m sure those things would get written by the developer community.</p>
<p>The Flex compiler will sometimes, seemingly randomly, start throwing unknown variable errors in code completely unrelated to what we&#8217;re working on.  Doing a clean build doesn&#8217;t fix it.  Going in, editing the file where the &#8220;error&#8221; is found by deleting and re typing a character, and letting it rebuild seems to be the only solution.  I think this has to do with the Flex compile cache, but I haven&#8217;t had time to investigate it further.  It happens at least once a day to me.  </p>
<p>Much of the development was done with Beta versions of AIR and Flex Builder.  I underestimated the impact that would have on development.  Beta versions are buggy, and they do suck time out of your schedule.  Little things like installing new versions every few weeks, or crashing more often add up.  But I do think the benefit of using those vs. using the older stuff was worth it this time around.  Unfortunately, I don&#8217;t know if that would always be the case, and I don&#8217;t know how to judge that impact before a project starts.  I guess I&#8217;ll just tend to opt for released versions unless the project requires something in a beta version.</p>
<h2>The future</h2>
<p>I&#8217;ll be moving AgileAgenda over to Parsley bit by bit. Thinking about that framework, it should be pretty easy to move smaller pieces over that I might be working on without disrupting the bigger picture.  AgileAgenda will most likely be in light continuous development for years to come.</p>
<p>The AgileTracker will continue on as-is.  I&#8217;m very happy with how it works and flushing out the rest of the features and functionality is &#8220;all&#8221; that&#8217;s left <img src='http://www.rogue-development.com/blog2/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>TimeLiner will stay a Cairngorm application.  Due to the way commercial educational software companies work it will probably go through cycles of being untouched for months, and then heavy development for a new release.   Those months of quiet and then bursts of activity will give us further insight on how easy it is to maintain a Cairngorm app.  Someday, I hope we do a web version of the software.</p>
<h2>Conclusion</h2>
<p>Overall, I believe Flex/AIR is the way to go for cross platform applications like these. I&#8217;ve done both Java and C++/QT cross platform apps, and neither of those was as easy to get working consistently accross platforms as AIR and Flex. </p>
<p>So, if I were to start a new project today I&#8217;d probably go with the Parsley MVC + IoC approach.  I found it to be easy to work in and it solved more of my problems than the Cairngorm approach. </p>
<p>If I could find experienced Flex engineers, I&#8217;d make my team out of them, but it wouldn&#8217;t be a must-have since I&#8217;m convinced any smart software engineer can pick this stuff up. </p>
<p>I&#8217;ll be using the data model adapter &#8220;pattern&#8221; instead of direct binding for now on for anything except the most trivial of applications.  I&#8217;ll write a full blog post really explaining this sometime.</p>
<p>Modules will be planned  from the start.  I think a lot more in all three applications could have been split into modules without any additional labor if we had just kept it in our minds from the beginning.</p>
<p><em>Disclaimer</em> &#8211; <em>I&#8217;m  an employee of Tom Snyder Productions.  Anything said in this blog post should be considered solely my own opinion, and may not be representative of my employer.</em></p>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.rogue-development.com/blog2/2008/05/case-study-three-flex-applications/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>ArrayCollection weirdness</title>
		<link>http://www.rogue-development.com/blog2/2008/02/arraycollection-weirdness/</link>
		<comments>http://www.rogue-development.com/blog2/2008/02/arraycollection-weirdness/#comments</comments>
		<pubDate>Thu, 28 Feb 2008 16:47:00 +0000</pubDate>
		<dc:creator>Marc</dc:creator>
				<category><![CDATA[Actionscript]]></category>

		<guid isPermaLink="false">http://rogue-development.com/blog2/?p=137</guid>
		<description><![CDATA[I ran into a head-scratcher today&#8230; How can this code: var index:Number = rows.getItemIndex(partition.placeholderRow );trace( index + " " + (rows.getItemAt(0) === partition.placeholderRow ) ); give this output? -1 true rows is an ArrayCollection with one element. partition.placeholderRow exists and is a valid object. I haven&#8217;t mucked around with rows.source at all. Answer follows in [...]]]></description>
			<content:encoded><![CDATA[<p>I ran into a head-scratcher today&#8230;</p>
<p>How can this code:
<pre>var index:Number = rows.getItemIndex(partition.placeholderRow );trace( index + " " + (rows.getItemAt(0) === partition.placeholderRow ) );</pre>
<p>give this output?</p>
<p>-1 true</p>
<p>rows is an ArrayCollection with one element.  partition.placeholderRow exists and is a valid object.  I haven&#8217;t mucked around with rows.source at all.</p>
<p>Answer follows in comment (so you don&#8217;t peek ahead and cheat!)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rogue-development.com/blog2/2008/02/arraycollection-weirdness/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>New ObjectHandles Build</title>
		<link>http://www.rogue-development.com/blog2/2007/11/new-objecthandles-build/</link>
		<comments>http://www.rogue-development.com/blog2/2007/11/new-objecthandles-build/#comments</comments>
		<pubDate>Thu, 22 Nov 2007 14:55:00 +0000</pubDate>
		<dc:creator>Marc</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[ObjectHandles]]></category>

		<guid isPermaLink="false">http://rogue-development.com/blog2/?p=91</guid>
		<description><![CDATA[I posted a new ObjectHandles build yesterday.  It fixes a couple bugs and integrates some patches people have sent me including: 1) Graphical handle support 2) Fixed aspect ratio support 3) Ability to detect transparency &#38; clicks  There will likely be another build in the next week to integrate another patch and fix a few [...]]]></description>
			<content:encoded><![CDATA[<p>I posted a new <a href="http://rogue-development.com/objectHandles.xml">ObjectHandles</a> build yesterday.  It fixes a couple bugs and integrates some patches people have sent me including:
<div></div>
<div>1) Graphical handle support</div>
<div>2) Fixed aspect ratio support</div>
<div>3) Ability to detect transparency &amp; clicks </div>
<div></div>
<div>There will likely be another build in the next week to integrate another patch and fix a few a performance issue.</div>
]]></content:encoded>
			<wfw:commentRss>http://www.rogue-development.com/blog2/2007/11/new-objecthandles-build/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XML Facade instead of value objects?</title>
		<link>http://www.rogue-development.com/blog2/2007/11/xml-facade-instead-of-value-objects/</link>
		<comments>http://www.rogue-development.com/blog2/2007/11/xml-facade-instead-of-value-objects/#comments</comments>
		<pubDate>Mon, 19 Nov 2007 14:33:00 +0000</pubDate>
		<dc:creator>Marc</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[actionscript 3]]></category>
		<category><![CDATA[red5]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://rogue-development.com/blog2/?p=89</guid>
		<description><![CDATA[I have a project I&#8217;m working on where it&#8217;d be great if older versions of the software preserved information in the XML file format that it didn&#8217;t understand. For example, imagine if Version 1 (V1) of the software had this for a file format: &#60;data&#62;&#60;value&#62;1&#60;/value&#62;&#60;/data&#62; Now imagine if V2 of the file added an attribute [...]]]></description>
			<content:encoded><![CDATA[<p>I have a project I&#8217;m working on where it&#8217;d be great if older versions of the software preserved information in the XML file format that it didn&#8217;t understand.  For example, imagine if Version 1 (V1) of the software had this for a file format:</p>
<p>&lt;data&gt;<br />&lt;value&gt;1&lt;/value&gt;<br />&lt;/data&gt;</p>
<p>Now imagine if V2 of the file added an attribute</p>
<p>&lt;data&gt;<br />&lt;value type=&#8221;number&#8221;&gt;1&lt;/value&gt;<br />&lt;/data&gt;</p>
<p>It&#8217;d be great if you opened that second file with the V1 software and then saved it again, it would preserve the stuff it didn&#8217;t understand.  Unfortunately that&#8217;s not how I usually write my value objects.  Usually I do something like:</p>
<pre>public class ValueObject{public var value:Number;public static function fromXML( xml:XML ) : ValueObject{var v:ValueObject = new ValueObject();v.value = xml.value;}

public function toXML(  ) : XML{var xml:XML = &lt;data&gt;;xml.value = value;return xml;}}</pre>
<p>As you can see, anything in the file that it doesn&#8217;t understand is lost.  But what if we followed a facade pattern for our data objects and did something more like this:</p>
<pre>public class ValueObject{protected var source:XML;

public static function fromXML( xml:XML ) : ValueObject{v.source = xml;}

public function toXML() : XML{return source;}

public function get value() : Number {return source.value;}public function set value(val:Number) : void {source.value = val;}}</pre>
<p>They both have the exact same API, but the second one will preserve XML attributes (or even nodes) that it doesn&#8217;t understand.</p>
<p>What about AMF based projects, especially when passing rich objects with a Red5 server?  I know there&#8217;s a pretty seamless mechanism in place if properties aren&#8217;t known, but how do you get those unknown properties back to the server?</p>
<p>What other solutions or best-practices do other people follow for solving this issue?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rogue-development.com/blog2/2007/11/xml-facade-instead-of-value-objects/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Slow Flex Builder compile and refresh solution &#8211; Modules</title>
		<link>http://www.rogue-development.com/blog2/2007/11/slow-flex-builder-compile-and-refresh-solution-modules/</link>
		<comments>http://www.rogue-development.com/blog2/2007/11/slow-flex-builder-compile-and-refresh-solution-modules/#comments</comments>
		<pubDate>Sun, 04 Nov 2007 14:01:00 +0000</pubDate>
		<dc:creator>Marc</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[flex 3]]></category>

		<guid isPermaLink="false">http://rogue-development.com/blog2/?p=80</guid>
		<description><![CDATA[For the past month I&#8217;ve been plagued with up to three minute compile times on Flex Builder 3 Beta 2. I&#8217;ve also been plagued with long several minute waits of &#8220;Refresing bin/&#8221;. Last week I solved the issue for one of my projects and prevented it from happening to another. Apparently embedding graphics causes a [...]]]></description>
			<content:encoded><![CDATA[<p>For the past month I&#8217;ve been plagued with up to three minute compile times on Flex Builder 3 Beta 2. I&#8217;ve also been plagued with long several minute waits of &#8220;Refresing bin/&#8221;.</p>
<p>Last week I solved the issue for one of my projects and prevented it from happening to another.</p>
<p>Apparently embedding graphics causes a performance hit in compiling, refreshing directories, and even just before launching. So if you have a hundred or so of these:</p>
<p>&lt;mx:Button icon=&#8221;@Embed(&#8230;)&#8221; /&gt;</p>
<p>You&#8217;ll be in a world of pain. The easiest solution is to move those embed calls into your style sheet and then compile your style sheet as a module.</p>
<p>Here&#8217;s how to make a style sheet module:</p>
<p>1) Create a new MXML module (file->new->flex->MXML module)<br />2) Add your stylesheet reference to that.</p>
<p>&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243;?&gt;<br />&lt;mx:Module xmlns:mx=&#8221;http://www.adobe.com/2006/mxml&#8221;<br />      layout=&#8221;absolute&#8221; width=&#8221;0&#8243; height=&#8221;0&#8243;<br />      creationComplete=&#8221;trace(&#8216;iconsloaded&#8217;)&#8221;&gt;<br />&lt;mx:Style source=&#8221;style.css&#8221; /&gt;<br />&lt;/mx:Module&gt;</p>
<p>3) Next, remove the reference to your style sheet from your main application.<br />4) Now, in your main MXML or AS file add some code to load your module.
<pre>protected var styleLoader:ModuleLoader;protected function init() : void{    styleLoader = new ModuleLoader();    styleLoader.addEventListener(ModuleEvent.READY, onModuleLoad );    styleLoader.addEventListener(ModuleEvent.ERROR, onModuleError );    styleLoader.url = "IconsModule.swf";       styleLoader.loadModule();}protected function onModuleLoad( e:ModuleEvent ) : void{    maximize();    var mainApp:MainApplication = new MainApplication();    mainApp.percentHeight = 100;    mainApp.percentWidth = 100;    addChild(mainApp);   }

protected function onModuleError(e : ModuleEvent ) : void{    Alert.show("Could not load module IconsModule.swf","Error",Alert.OK );}</pre>
<p>You can see there that I intialize my main application component after the module has loaded. I didn&#8217;t have to do this in a Flex app, but in my AIR app that component wouldn&#8217;t get all of the new styles if created before the module was loaded.</p>
<p><span style="font-weight: bold;font-size:130%;" >Option 2</span></p>
<p>Sometimes, it wasn&#8217;t practical for me to put the embedded graphic in a stylesheet.  In those cases I:</p>
<p>1) Made an interface listing all the embedded graphics
<pre>public interface MyGraphicsModule{// Bindable tags are there purely to suppress warnings,// these properties never change after startup.[Bindable(event="moduleChanged")] function get addIcon() : Class;...}</pre>
<p>2) Make a class that implements that interface and extends ModuleBase, also embed the graphics in there.
<pre>public class MyGraphics extends ModuleBase implements TimeLinerGraphicsModule{[Embed(source="﻿/art/toolbars/add.png")]protected var _addIcon:Class;public function get addIcon() : Class { return _addIcon; }

...}</pre>
<p><span style="font-weight: bold; color: rgb(153, 0, 0);">NEVER import or otherwise use this class into your application.  The goal is to keep it completely separate.</span></p>
<p>3) Create a module manager class
<pre>public class MyModules{[Bindable] public static var graphics:MyGraphicsModule;}</pre>
<p>4) Set MyGraphics to be a module that gets built in your Project->Properties->Flex Modules settings.</p>
<p>5) Load your module somewhere at startup
<pre>public function loadModules() : void{graphicsModuleLoader = new ModuleLoader();graphicsModuleLoader.addEventListener(ModuleEvent.READY, onModuleLoaded );graphicsModuleLoader.addEventListener(ModuleEvent.ERROR, onModuleLoadFailure );graphicsModuleLoader.url = "MyGraphics.swf";graphicsModuleLoader.loadModule();}

protected function onModuleLoaded( event:ModuleEvent ) : void{if( event.target == graphicsModuleLoader ){var o:Object = event.module.factory.create();MyModules.graphics = event.module.factory.create() as MyGraphicsModule;}}</pre>
<p>6) Find the spot in your code that used that icon and replace it</p>
<p>So this:
<pre>[Embed(source="/art/icons/addIcon.png")]public var addIcon:Class;</pre>
<p>Would become this:
<pre>public var addIcon:Class = MyModules.graphics.addIcon;</pre>
<p>This all seems like a pretty tedius job to do, but I ended up writing a perl script to scour the source tree, find all the references, and replace them for me. Unfortunately I did that script as part of my day-job and can&#8217;t share it with everyone right now. I&#8217;ll ask for permission on Monday.</p>
<p>The end result was we went from a 3.5 minute wait from saving a code change to executing the application to a 20 second wait. Not too shabby considering the size of the codebase we have.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rogue-development.com/blog2/2007/11/slow-flex-builder-compile-and-refresh-solution-modules/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>SwfControls (Graphical Buttons and Popup Menus)</title>
		<link>http://www.rogue-development.com/blog2/2007/07/swfcontrols-graphical-buttons-and-popup-menus/</link>
		<comments>http://www.rogue-development.com/blog2/2007/07/swfcontrols-graphical-buttons-and-popup-menus/#comments</comments>
		<pubDate>Thu, 05 Jul 2007 14:29:00 +0000</pubDate>
		<dc:creator>Marc</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[SwfControls]]></category>

		<guid isPermaLink="false">http://rogue-development.com/blog2/?p=28</guid>
		<description><![CDATA[On Saturday I blogged about a new component I was working on and I got a few responses saying it looked really useful. So I threw up a project page and it&#8217;s available for download. I&#8217;m calling it &#8220;swfControls&#8221; for now, but I&#8217;m hating the name the more I think of it. Any suggestions? At [...]]]></description>
			<content:encoded><![CDATA[<p>On Saturday I blogged about a new component I was working on and I got a few responses saying it looked really useful.  So I threw up a project page and it&#8217;s available for download.</p>
<p>I&#8217;m calling it &#8220;swfControls&#8221; for now, but I&#8217;m hating the name the more I think of it.  Any suggestions?  At this point, I&#8217;m really considering bundling ALL of my controls together, maybe I should just do that to avoid naming them all.</p>
<p><a href="http://rogue-development.com/swfControls.xml">http://rogue-development.com/swfControls.xml</a></p>
<p>Right now there&#8217;s just a binary SWC for download, I&#8217;ll get full source posted soon.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rogue-development.com/blog2/2007/07/swfcontrols-graphical-buttons-and-popup-menus/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

