<?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>The bAS3 Class &#187; cache</title>
	<atom:link href="http://www.brandondement.com/blog/tag/cache/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.brandondement.com/blog</link>
	<description>Adventures in software development</description>
	<lastBuildDate>Thu, 29 Sep 2011 23:31:38 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Creating an Image Cache with ActionScript 3</title>
		<link>http://www.brandondement.com/blog/2009/08/18/creating-an-image-cache-with-actionscript-3/</link>
		<comments>http://www.brandondement.com/blog/2009/08/18/creating-an-image-cache-with-actionscript-3/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 03:04:49 +0000</pubDate>
		<dc:creator>Brandon</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.brandondement.com/blog/?p=3</guid>
		<description><![CDATA[A Flash application that loads images at runtime and uses them over and over won&#8217;t attempt to reuse any previously downloaded assets.  Instead, the Flash Player will download a new image from the server over and over, wasting time and bandwidth.  The additive effect of this can create a real noticeable difference in [...]]]></description>
			<content:encoded><![CDATA[<p>A Flash application that loads images at runtime and uses them over and over won&#8217;t attempt to reuse any previously downloaded assets.  Instead, the Flash Player will download a new image from the server over and over, wasting time and bandwidth.  The additive effect of this can create a real noticeable difference in performance on a large scale.  </p>
<p>For example, we ran into this problem on the leaderboard of the <a href="http://www.pgatour.com/shottracker/">PGA Tour Shot Tracker</a>.  The leaderboard displays the player&#8217;s name and the flag of the country they&#8217;re from.  There can be hundreds of players in the tournament, but they all come from about 2 dozen countries or so.  This setup is a perfect use case for caching images internally.</p>
<p>I started looking around for a solution, and came across <a href="http://stackoverflow.com/questions/303054/how-to-control-flex-3-image-control-caching/1123379">this question on StackOverflow.com</a> as well as an excellent pseudo-code example: <a href="http://userflex.wordpress.com/2008/07/28/image-caching/">this blog post</a>.</p>
<p>With about an hour&#8217;s worth of free time I created a fully functioning ActionScript image cache of my own.  There are only 2 parts:</p>
<ol>
<li><code>CachedImage.as</code> &#8211; A subclass of the Image control. A <code>CachedImage</code> adds itself to the cache when its <code>COMPLETE</code> event is fired.</li>
<li><code>ImageCache.as</code> &#8211; Stores the <code>BitMapData</code> of the <code>CachedImages</code> in a dictionary and provides a small set of static methods for querying, adding, and retrieving from the cache.
</ol>
<p><strong>CachedImage.as</strong></p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;">package com.<span style="color: #006600;">bdement</span>.<span style="color: #006600;">imagecache</span>
<span style="color: #66cc66;">&#123;</span>
<span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">events</span>.<span style="color: #006600;">Event</span>;
&nbsp;
<span style="color: #0066CC;">import</span> mx.<span style="color: #006600;">controls</span>.<span style="color: #006600;">Image</span>;
&nbsp;
<span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">class</span> CachedImage <span style="color: #0066CC;">extends</span> Image
<span style="color: #66cc66;">&#123;</span>
	<span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> onComplete<span style="color: #66cc66;">&#40;</span>event:Event<span style="color: #66cc66;">&#41;</span> : <span style="color: #0066CC;">void</span>
	<span style="color: #66cc66;">&#123;</span>		
		ImageCache.<span style="color: #0066CC;">add</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">this</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span> 
&nbsp;
	<span style="color: #0066CC;">public</span> override <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #0066CC;">set</span> source<span style="color: #66cc66;">&#40;</span>source:<span style="color: #0066CC;">Object</span><span style="color: #66cc66;">&#41;</span> : <span style="color: #0066CC;">void</span>
	<span style="color: #66cc66;">&#123;</span>
		<span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">!</span>ImageCache.<span style="color: #006600;">contains</span><span style="color: #66cc66;">&#40;</span>source<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
			addEventListener<span style="color: #66cc66;">&#40;</span>Event.<span style="color: #006600;">COMPLETE</span>, onComplete<span style="color: #66cc66;">&#41;</span>; 
		<span style="color: #66cc66;">&#125;</span>			
		<span style="color: #0066CC;">super</span>.<span style="color: #006600;">source</span> = ImageCache.<span style="color: #0066CC;">get</span><span style="color: #66cc66;">&#40;</span>source<span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>		
<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p><strong>ImageCache.as</strong></p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;">package com.<span style="color: #006600;">bdement</span>.<span style="color: #006600;">imagecache</span>
<span style="color: #66cc66;">&#123;</span>
<span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">Bitmap</span>;
<span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">BitmapData</span>;
<span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">utils</span>.<span style="color: #006600;">Dictionary</span>;
&nbsp;
<span style="color: #808080; font-style: italic;">/**
 * 
 * @author bdement
 * 
 * This class reduces the amount of HTTP requests your application has to make
 * by storing the BitMapData of CachedImage objects in memory for reuse
 * by images created after the first one completes.
 */</span>
<span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ImageCache
<span style="color: #66cc66;">&#123;</span>
	<span style="color: #808080; font-style: italic;">/**
	 * The internal representation of the cache
	 */</span>		
	<span style="color: #0066CC;">private</span> <span style="color: #0066CC;">static</span> <span style="color: #000000; font-weight: bold;">var</span> cache:Dictionary = <span style="color: #000000; font-weight: bold;">new</span> Dictionary<span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">false</span><span style="color: #66cc66;">&#41;</span>;				
	<span style="color: #808080; font-style: italic;">/**
	 * All the methods of ImageCache are static, so the constructor shouldn't be called.
	 * 
	 */</span>				
	<span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> ImageCache<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
	<span style="color: #66cc66;">&#123;</span>
		<span style="color: #0066CC;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #0066CC;">Error</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;You don't need to instantiate the ImageCache!&quot;</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>	
	<span style="color: #808080; font-style: italic;">/**
	 * 
	 * @param imageSource The source of an image
	 * @return Whether the cache already contains the image indicated by imageSource 
	 * 
	 */</span>				
	<span style="color: #0066CC;">public</span> <span style="color: #0066CC;">static</span> <span style="color: #000000; font-weight: bold;">function</span> contains<span style="color: #66cc66;">&#40;</span>imageSource:<span style="color: #0066CC;">Object</span><span style="color: #66cc66;">&#41;</span> : <span style="color: #0066CC;">Boolean</span>
	<span style="color: #66cc66;">&#123;</span>
		<span style="color: #b1b100;">return</span> cache<span style="color: #66cc66;">&#91;</span>imageSource<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">!</span>= <span style="color: #000000; font-weight: bold;">null</span>;
	<span style="color: #66cc66;">&#125;</span>		
	<span style="color: #808080; font-style: italic;">/**
	 * Retrieves the image 
	 * 
	 * @param imageSource The source of an image
	 * @return Either: The image if it exists in the cache, OR the default
	 * source that was passed in via imageSource.
	 * 
	 */</span>		
	<span style="color: #0066CC;">public</span> <span style="color: #0066CC;">static</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #0066CC;">get</span><span style="color: #66cc66;">&#40;</span>imageSource:<span style="color: #0066CC;">Object</span><span style="color: #66cc66;">&#41;</span> : <span style="color: #0066CC;">Object</span>
	<span style="color: #66cc66;">&#123;</span>
		<span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>contains<span style="color: #66cc66;">&#40;</span>imageSource<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
			<span style="color: #0066CC;">trace</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;using '&quot;</span> + imageSource + <span style="color: #ff0000;">&quot;' from cache!&quot;</span><span style="color: #66cc66;">&#41;</span>;
			<span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">new</span> Bitmap<span style="color: #66cc66;">&#40;</span>cache<span style="color: #66cc66;">&#91;</span>imageSource<span style="color: #66cc66;">&#93;</span> as BitmapData<span style="color: #66cc66;">&#41;</span>;	
		<span style="color: #66cc66;">&#125;</span>
		<span style="color: #b1b100;">return</span> imageSource; <span style="color: #808080; font-style: italic;">// String or Object</span>
	<span style="color: #66cc66;">&#125;</span>
	<span style="color: #808080; font-style: italic;">/**
	 * Adds an image to the cache
	 * @param image The image to be cached 
	 * 
	 */</span>		
	<span style="color: #0066CC;">public</span> <span style="color: #0066CC;">static</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #0066CC;">add</span><span style="color: #66cc66;">&#40;</span>image:CachedImage<span style="color: #66cc66;">&#41;</span> : <span style="color: #0066CC;">void</span>
	<span style="color: #66cc66;">&#123;</span>			
	    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">!</span>contains<span style="color: #66cc66;">&#40;</span>image.<span style="color: #006600;">source</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
	    <span style="color: #66cc66;">&#123;</span>
	    	<span style="color: #0066CC;">trace</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;adding '&quot;</span> + image.<span style="color: #006600;">source</span> + <span style="color: #ff0000;">&quot;' to cache!&quot;</span><span style="color: #66cc66;">&#41;</span>;
	        <span style="color: #000000; font-weight: bold;">var</span> bitmapData:BitmapData = 
	        	        <span style="color: #000000; font-weight: bold;">new</span> BitmapData<span style="color: #66cc66;">&#40;</span>	image.<span style="color: #006600;">content</span>.<span style="color: #0066CC;">width</span>, 
	        	                                        image.<span style="color: #006600;">content</span>.<span style="color: #0066CC;">height</span>,
                                                                <span style="color: #000000; font-weight: bold;">true</span>,
	        		                                0x00000000<span style="color: #66cc66;">&#41;</span>;
&nbsp;
	        bitmapData.<span style="color: #006600;">draw</span> <span style="color: #66cc66;">&#40;</span>image.<span style="color: #006600;">content</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
	        cache<span style="color: #66cc66;">&#91;</span>image.<span style="color: #006600;">source</span><span style="color: #66cc66;">&#93;</span> = bitmapData;
	    <span style="color: #66cc66;">&#125;</span>
	<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>Finally, you leverage the <code>ImageCache</code> and <code>CachedImage</code> in your application.  You can set the source of your <code>CachedImage</code>s in all the ways you normally would, and the <code>ImageCache</code> will be used automatically.  Note that our <code>ImageCache</code> doesn&#8217;t cache embedded images.  This is because embedded images don&#8217;t fire the  <code>COMPLETE</code> event, which is OK because they&#8217;re already cached in memory and they can be reused without using our <code>ImageCache</code>.  </p>
<p><strong>Application.mxml</strong></p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:Application</span> </span>
<span style="color: #009900;">	<span style="color: #000066;">xmlns:mx</span>=<span style="color: #ff0000;">&quot;http://www.adobe.com/2006/mxml&quot;</span> </span>
<span style="color: #009900;">	<span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;*&quot;</span></span>
<span style="color: #009900;">	<span style="color: #000066;">width</span>=<span style="color: #ff0000;">&quot;500&quot;</span> <span style="color: #000066;">height</span>=<span style="color: #ff0000;">&quot;200&quot;</span></span>
<span style="color: #009900;">	<span style="color: #000066;">layout</span>=<span style="color: #ff0000;">&quot;horizontal&quot;</span>	</span>
<span style="color: #009900;"> <span style="color: #000000; font-weight: bold;">&gt;</span></span>  
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;CachedImage</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;image1&quot;</span> <span style="color: #000066;">source</span>=<span style="color: #ff0000;">&quot;http://www.brandondement.com/blog/wp-content/uploads/2009/08/rooster.gif&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>			
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:VBox<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:Label</span> <span style="color: #000066;">text</span>=<span style="color: #ff0000;">&quot;Set image2.source to...&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:Button</span> <span style="color: #000066;">click</span>=<span style="color: #ff0000;">&quot;{image2.source = image1.source}&quot;</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;image1.source&quot;</span> <span style="color: #000066;">toolTip</span>=<span style="color: #ff0000;">&quot;image1.source&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:Button</span> <span style="color: #000066;">click</span>=<span style="color: #ff0000;">&quot;{image2.source = 'http://www.brandondement.com/blog/wp-content/uploads/2009/08/rooster.gif'}&quot;</span>	<span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;HTTP URL&quot;</span> <span style="color: #000066;">toolTip</span>=<span style="color: #ff0000;">&quot;http://www.brandondement.com/blog/wp-content/uploads/2009/08/rooster.gif&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:Button</span> <span style="color: #000066;">click</span>=<span style="color: #ff0000;">&quot;{image2.source = null}&quot;</span>	<span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;null&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:VBox<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;CachedImage</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;image2&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:Application<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>And finally, here&#8217;s the working example.  To doublecheck that it&#8217;s <strong>actually</strong> using the cache, reload this page with a web debugging proxy on, like <a href="http://www.charlesproxy.com/">Charles</a>.  You&#8217;ll notice a request for &#8220;rooster.gif,&#8221; which is the flash movie downloading the image on the left.  (There will probably be two, since there are two example files)  But notice that when you click the buttons below, <strong>no</strong> more requests are made.  Success!</p>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_ImageCache_2122681026"
			class="flashmovie"
			width="500"
			height="200">
	<param name="movie" value="http://www.brandondement.com/blog/wp-content/uploads/2009/08/ImageCache.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="http://www.brandondement.com/blog/wp-content/uploads/2009/08/ImageCache.swf"
			name="fm_ImageCache_2122681026"
			width="500"
			height="200">
	<!--<![endif]-->
		
<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>

	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<p>And here, just for comparison&#8217;s sake, is the example using normal <code>mx:Image</code>s <strong>without</strong> caching built in.  With <a href="http://www.charlesproxy.com/">Charles</a> on you&#8217;ll notice that <strong>every</strong> time the image source is changed from null, a new request is made!</p>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_ImageCache1_1166308556"
			class="flashmovie"
			width="500"
			height="200">
	<param name="movie" value="http://www.brandondement.com/blog/wp-content/uploads/2009/08/ImageCache1.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="http://www.brandondement.com/blog/wp-content/uploads/2009/08/ImageCache1.swf"
			name="fm_ImageCache1_1166308556"
			width="500"
			height="200">
	<!--<![endif]-->
		
<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>

	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
]]></content:encoded>
			<wfw:commentRss>http://www.brandondement.com/blog/2009/08/18/creating-an-image-cache-with-actionscript-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

