<?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>lowpitch.com &#187; Actionscript 2.0</title>
	<atom:link href="http://lowpitch.com/blog/category/actionscript-2/feed/" rel="self" type="application/rss+xml" />
	<link>http://lowpitch.com/blog</link>
	<description>Flex and flex ramblings.</description>
	<lastBuildDate>Sun, 24 Aug 2008 22:57:11 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>ModuleManager and IModuleInfo &#8211; loading Flex Modules dynamically</title>
		<link>http://lowpitch.com/blog/modulemanager-and-imoduleinfo-loading-flex-modules-dynamically/</link>
		<comments>http://lowpitch.com/blog/modulemanager-and-imoduleinfo-loading-flex-modules-dynamically/#comments</comments>
		<pubDate>Sat, 16 Aug 2008 23:51:12 +0000</pubDate>
		<dc:creator>lowpitch</dc:creator>
				<category><![CDATA[Actionscript 2.0]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Modules]]></category>

		<guid isPermaLink="false">http://lowpitch.com/blog/?p=19</guid>
		<description><![CDATA[When you&#8217;re working with Flex Modules, most of the time the ModuleLoader component will be enough to get you up and running. It will quickly and easily let you load your Modules and add them to the display list, it&#8217;ll even dispatch an event to let you know when the Module is ready. Lovely stuff. [...]]]></description>
			<content:encoded><![CDATA[<p>When you&#8217;re working with Flex Modules, most of the time the <em><a target="_blank" href="http://livedocs.adobe.com/flex/201/langref/mx/modules/ModuleLoader.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/livedocs.adobe.com');">ModuleLoader</a></em> component will be enough to get you up and running. It will quickly and easily let you load your Modules and add them to the display list, it&#8217;ll even dispatch an event to let you know when the Module is ready. Lovely stuff. It&#8217;s very similar to the <em>SWFLoader</em> component with some added Module-related goodness thrown in.</p>
<p>However, there may be times when the <em>ModuleLoader</em> component may not be appropriate for your needs, and you&#8217;ll have to get your hands dirty and get involved with the lower-level <em><a href="http://livedocs.adobe.com/flex/201/langref/mx/modules/ModuleManager.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/livedocs.adobe.com');" target="_blank">ModuleManager</a></em> class. Some examples of when <em>ModuleLoader</em> might not be suitable include:</p>
<ul>
<li>Your Module is entirely non-visual, and therefore shouldn&#8217;t be added to the display list</li>
<li>Performance is really important to your application, and the extra overhead of the <em>ModuleLoader</em> container is something you need to remove to try and speed things up. (<em>ModuleLoader</em> essentially wraps your Module&#8217;s content in an extra container, incurring a slight performance hit).</li>
<li>You need greater control over how and when your modules are loaded and unloaded.</li>
</ul>
<h3>How does <em>ModuleManager</em> work?</h3>
<p><em>ModuleManager</em> maintains a map of modules, indexed by each module&#8217;s URL. Information about the module is stored as an object implementing <em><a href="http://livedocs.adobe.com/flex/201/langref/mx/modules/IModuleInfo.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/livedocs.adobe.com');" target="_blank">IModuleInfo</a></em>, and is retrieved by calling the <em>ModuleManager.getModule </em>method, passing in the module&#8217;s URL as the method&#8217;s only parameter. Once you&#8217;ve retrieved the<em> IModuleInfo </em>object, you can call its <em>load </em>method to starting loading in the module. While the module is loading, you can monitor the load progress using a variety of different events (of type <em>ModuleEvent</em>). Finally, when the module is loaded and available, you can create an instance of that module using <em>someModuleInfo.factory.create ()</em>.</p>
<p><span id="more-19"></span></p>
<h3><em>IModuleInfo</em> in more detail</h3>
<p>As mentioned above, <em>ModuleManager</em> maintains a mapping of URLs to modules. When you call <em>ModuleManager</em>&#8217;s static <em>getModule</em> method, it returns an object of type <em>IModuleInfo</em>. If you dig around within the <em>ModuleManager</em> class, you&#8217;ll see that this interface is implemented internally. It&#8217;s useful to know a little bit more about how you can interact with the <em>ModuleInfo</em>, what methods it exposes, and what events it dispatches.</p>
<p>There are four read-only public Boolean properties which offer information about the current state of the module. They can briefly be described:</p>
<ul>
<li><strong>IModuleInfo.error</strong> &#8211; This&#8217;ll be <em>true</em> if there was an error during loaded. You&#8217;re also notified of such an error by the <em>ModuleEvent.ERROR</em> event.</li>
<li><strong>IModuleInfo.loaded</strong> &#8211; This will be <em>true</em> if you&#8217;ve previously called the <em>IModuleInfo.load</em> method. Note: It does not necessarily signify that the module has been loaded, just that the module load has begun.</li>
<li><strong>IModuleInfo.setup</strong> &#8211; When enough of the module has loaded to be able to call the <em>factory.info ()</em> method, this flag will be <em>true</em>. When this point in the load has been reached, a<em> ModuleEvent.SETUP</em> event will be dispatched.</li>
<li><strong>IModuleInfo.ready</strong> &#8211; When enough of the module has been loaded for you to be able to instantiate an instance of the module using the <em>factory.create ()</em> method, this flag will be <em>true</em>. At this stage, a <em>ModuleEvent.READY</em> event will be dispatched. This property will typically become <em>true</em> at some point after the<em> IModuleInfo.setup</em> becomes true.</li>
</ul>
<p>There are some additional properties which can also be useful:</p>
<ul>
<li><strong>IModuleInfo.url </strong>fairly obviously returns the URL associated with the <em>IModuleInfo </em>object. This could be useful if you&#8217;re using one event handler to listen out for the events from multiple modules &#8211; the <em>event.currentTarget.url</em> property could be used to identify which module had sent out the event.</li>
<li><strong>IModuleInfo.data</strong> is an object which you can use to associate data with a particular module. The data will be shared across all instances of a particular module, so this property comes in handy if you want to share state, or user information between multiple instances of the same dynamically loaded module.</li>
<li><strong>IModuleInfo.factory</strong> is pretty important. Once the the module is &#8216;ready&#8217; (after the <em>ModuleEvent.READY</em> event has been dispatched, or when <em>IModuleInfo.ready</em> returns <em>true</em>), you can create an instance of your module by calling the <em>IFlexModuleFactory.create</em> method. Additionally, once the module has been &#8217;setup&#8217; (after <em>ModuleEvent.SETUP</em> has fired, or when <em>IModuleInfo.setup</em> returns <em>true</em>), you can query the <em>IFlexModuleFactory.info</em> method to find out a little more about the module that has been loaded.</li>
</ul>
<p>Next we should look at some of the methods exposed by an <em>IModuleInfo</em>:</p>
<ul>
<li><strong>IModuleInfo.load</strong> &#8211; This is the method you&#8217;ll call to start loading a module. You can optionally pass in information about the current ApplicationDomain and SecurityDomain if necessary. When the module is loading, events will be dispatched along the way as detailed below. Quite a nice feature here is that if the module has already been loaded, and you attempt to reload it, it&#8217;ll still dispatch the &#8220;setup&#8221; and &#8220;ready&#8221; events, meaning that you can use one set of event listener methods without needing to worry about whether the module is loading for the first time, or if it already exists in local memory. Snazzy&#8230;</li>
<li><strong>IModuleInfo.release</strong> &#8211; This method will release the current reference to the module. Internally, when this method is called, a reference counter will be decremented. If no references to the module exist after this method has been called, it will automatically be unloaded.</li>
<li><strong>IModuleInfo.unload</strong> &#8211; This triggers the unload of the module. It&#8217;s worth noting that if any references to the module exist, it will not be garbage collected. Also, calling this method won&#8217;t remove your module from the display list, you&#8217;ll have to do that too.</li>
</ul>
<p>Lastly, let&#8217;s look at the events dispatched&#8230; All the events listed here are instances of <em>ModuleEvent</em>, and for some of the events you&#8217;ll be able to access information about the load progress through the event&#8217;s <em>bytesLoaded</em> and <em>bytesTotal </em>properties.</p>
<ul>
<li><strong>ModuleEvent.ERROR</strong> &#8211; Rather obviously, this is dispatched when an error occurs during loading. This will also be indicated by the <em>IModuleInfo.error</em> property returning <em>true</em>.</li>
<li><strong>ModuleEvent.PROGRESS</strong> &#8211; This event is dispatched periodically during the load, giving you the chance to display a visual indication of load progress if you want. This is one of the events where the <em>bytesLoaded</em> and <em>bytesTotal</em> properties will be set.</li>
<li><strong>ModuleEvent.SETUP</strong> &#8211; This event is dispatched when enough of the module has downloaded for you to call the <em>IModuleInfo.factory.info</em> method. At this point, <em>IModuleInfo.setup</em> will also return <em>true</em>. This event does not allow you to access load progress through the <em>bytesLoaded</em> and <em>bytesTotal</em> properties.</li>
<li><strong>ModuleEvent.READY</strong> &#8211; This event is dispatched when enough of the module has downloaded for you to create an instance of the module through the<em> IModuleInfo.factory.create</em> method. From then on, <em>IModuleInfo.ready</em> will also return <em>true</em>. Apparently, this event is one where the <em>bytesLoaded</em> and <em>bytesTotal</em> properties should be set, although I&#8217;ve noticed that this isn&#8217;t always the case. I reckon it&#8217;s safer just to use the <em>ModuleEvent.PROGRESS</em> information for displaying progress information.</li>
<li><strong>ModuleEvent.UNLOAD</strong> &#8211; This event is dispatched when the module has been unloaded. No progress information is available through the event object with this event.</li>
</ul>
<h3>A simple example</h3>
<p>First, a basic module, <em>SimpleModule</em>, which does nothing more than display a label within a panel.</p>
<div class="codecolorer-container actionscript"><div class="codecolorer" style="font-family: monospace;">SimpleModule.<span class="me1">mxml</span><br />
&lt;?<span class="kw3">xml</span> <span class="kw3">version</span>=<span class="st0">&quot;1.0&quot;</span> encoding=<span class="st0">&quot;utf-8&quot;</span>?&gt;<br />
&lt;mx:Module xmlns:mx=<span class="st0">&quot;http://www.adobe.com/2006/mxml&quot;</span> layout=<span class="st0">&quot;absolute&quot;</span>&gt;<br />
&nbsp; &nbsp; &lt;mx:TitleWindow x=<span class="st0">&quot;10&quot;</span> y=<span class="st0">&quot;10&quot;</span> <span class="kw3">width</span>=<span class="st0">&quot;120&quot;</span> <span class="kw3">height</span>=<span class="st0">&quot;100&quot;</span> layout=<span class="st0">&quot;absolute&quot;</span>&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;mx:<span class="kw3">Text</span> <span class="kw3">text</span>=<span class="st0">&quot;SimpleModule!&quot;</span> /&gt; <br />
&nbsp; &nbsp; &lt;/mx:TitleWindow&gt;<br />
&lt;/mx:Module&gt;</div></div>
<p>The the main application, which will load in this module and attach instances to a Tile control.</p>
<div class="codecolorer-container actionscript" style="height:280px;"><div class="codecolorer" style="font-family: monospace;">Shell.<span class="me1">mxml</span><br />
&lt;?<span class="kw3">xml</span> <span class="kw3">version</span>=<span class="st0">&quot;1.0&quot;</span> encoding=<span class="st0">&quot;utf-8&quot;</span>?&gt;<br />
&lt;mx:Application xmlns:mx=<span class="st0">&quot;http://www.adobe.com/2006/mxml&quot;</span> <br />
&nbsp; &nbsp; applicationComplete=<span class="st0">&quot;initApp()&quot;</span>&gt; <br />
&nbsp; &nbsp; &lt;mx:Script&gt; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;!<span class="br0">&#91;</span>CDATA<span class="br0">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> mx.<span class="me1">modules</span>.<span class="me1">Module</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> mx.<span class="me1">events</span>.<span class="me1">ModuleEvent</span>; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> mx.<span class="me1">modules</span>.<span class="me1">ModuleManager</span>; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> mx.<span class="me1">modules</span>.<span class="me1">IModuleInfo</span>; <br />
&nbsp;<br />
&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;protected <span class="kw2">var</span> _moduleInfo:IModuleInfo;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw3">private</span> <span class="kw2">function</span> initApp<span class="br0">&#40;</span><span class="br0">&#41;</span>:<span class="kw3">void</span> <span class="br0">&#123;</span> <br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addToLog <span class="br0">&#40;</span><span class="st0">&quot;Application initialised&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// create the module - note, we're not loading it yet</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_moduleInfo = ModuleManager.<span class="me1">getModule</span><span class="br0">&#40;</span><span class="st0">&quot;SimpleModule.swf&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// add some listeners</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _moduleInfo.<span class="me1">addEventListener</span><span class="br0">&#40;</span>ModuleEvent.<span class="me1">READY</span>, onModuleReady<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _moduleInfo.<span class="me1">addEventListener</span><span class="br0">&#40;</span>ModuleEvent.<span class="me1">SETUP</span>, onModuleSetup<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _moduleInfo.<span class="me1">addEventListener</span><span class="br0">&#40;</span>ModuleEvent.<span class="me1">UNLOAD</span>, onModuleUnload<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _moduleInfo.<span class="me1">addEventListener</span><span class="br0">&#40;</span>ModuleEvent.<span class="me1">PROGRESS</span>, onModuleProgress<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; protected <span class="kw2">function</span> getModuleInfo <span class="br0">&#40;</span><span class="br0">&#41;</span> : IModuleInfo <span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// return the module info</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> _moduleInfo;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; * Adds output to the log<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; **/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; protected <span class="kw2">function</span> addToLog <span class="br0">&#40;</span>msg:<span class="kw3">String</span><span class="br0">&#41;</span> : <span class="kw3">void</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">log</span>.<span class="kw3">text</span> += msg + <span class="st0">&quot;<span class="es0">\n</span>&quot;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// scroll to the bottom on the next frame</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; callLater<span class="br0">&#40;</span>scrollToBottom<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; protected <span class="kw2">function</span> scrollToBottom <span class="br0">&#40;</span><span class="br0">&#41;</span> : <span class="kw3">void</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// scroll to the bottom</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">log</span>.<span class="me1">verticalScrollPosition</span> = <span class="kw3">log</span>.<span class="me1">maxVerticalScrollPosition</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Called when the &quot;load&quot; button is pressed<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* <br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Starts loading the module - when the module has been <br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* loaded, an instance of the module will be created<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* and added to the tile control<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* <br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;**/</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw3">private</span> <span class="kw2">function</span> loadModule <span class="br0">&#40;</span><span class="br0">&#41;</span> : <span class="kw3">void</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; addToLog <span class="br0">&#40;</span><span class="st0">&quot;Loading module&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">// load the module</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;getModuleInfo<span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="kw3">load</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; * Called when the &quot;unload&quot; button is pressed<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; * <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; * Removes all the instances of the module from the<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; * tile control, then unloads the module<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; * <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; */</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw3">private</span> <span class="kw2">function</span> unloadModule <span class="br0">&#40;</span><span class="br0">&#41;</span> : <span class="kw3">void</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; addToLog <span class="br0">&#40;</span><span class="st0">&quot;Unloading module&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; <span class="co1">// clear out all the the instances </span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; <span class="co1">// of the module from the tile</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; tile.<span class="me1">removeAllChildren</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; <span class="co1">// unload the module</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; getModuleInfo<span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">release</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; <span class="co1">//getModuleInfo().un</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="coMULTI">/**<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Handler for the ModuleEvent.PROGRESS event<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;**/</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;protected <span class="kw2">function</span> onModuleProgress <span class="br0">&#40;</span><span class="kw3">e</span>:ModuleEvent<span class="br0">&#41;</span> : <span class="kw3">void</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; addToLog <span class="br0">&#40;</span><span class="st0">&quot;ModuleEvent.PROGRESS received: &quot;</span> + <span class="kw3">e</span>.<span class="kw3">bytesLoaded</span> + <span class="st0">&quot; of &quot;</span> + <span class="kw3">e</span>.<span class="kw3">bytesTotal</span> + <span class="st0">&quot; loaded.&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="coMULTI">/**<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Handler for the ModuleEvent.SETUP event<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;**/</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw3">private</span> <span class="kw2">function</span> onModuleSetup <span class="br0">&#40;</span><span class="kw3">e</span>:ModuleEvent<span class="br0">&#41;</span> : <span class="kw3">void</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; addToLog <span class="br0">&#40;</span><span class="st0">&quot;ModuleEvent.SETUP received&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; <span class="co1">// cast the currentTarget</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; <span class="kw2">var</span> moduleInfo:IModuleInfo = <span class="kw3">e</span>.<span class="me1">currentTarget</span> as IModuleInfo;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; addToLog <span class="br0">&#40;</span><span class="st0">&quot;Calling IModuleInfo.factory.info ()&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; <span class="co1">// grab the info and display information about it</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; <span class="kw2">var</span> info:<span class="kw3">Object</span> = moduleInfo.<span class="me1">factory</span>.<span class="me1">info</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> each:<span class="kw3">String</span> <span class="kw1">in</span> info<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; addToLog <span class="br0">&#40;</span><span class="st0">&quot;&nbsp; &nbsp; &nbsp;&quot;</span> + each + <span class="st0">&quot; = &quot;</span> + info<span class="br0">&#91;</span>each<span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; <br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="coMULTI">/**<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Handler for the ModuleEvent.READY event<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;**/</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw3">private</span> <span class="kw2">function</span> onModuleReady <span class="br0">&#40;</span><span class="kw3">e</span>:ModuleEvent<span class="br0">&#41;</span>:<span class="kw3">void</span> <span class="br0">&#123;</span> <br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; addToLog <span class="br0">&#40;</span><span class="st0">&quot;ModuleEvent.READY received&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; <span class="co1">// cast the currentTarget</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; <span class="kw2">var</span> moduleInfo:IModuleInfo = <span class="kw3">e</span>.<span class="me1">currentTarget</span> as IModuleInfo;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; <span class="co1">// Add an instance of the module's class to the </span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">// display list. </span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;addToLog <span class="br0">&#40;</span><span class="st0">&quot;Calling IModuleInfo.factory.create ()&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;tile.<span class="me1">addChild</span><span class="br0">&#40;</span> moduleInfo.<span class="me1">factory</span>.<span class="me1">create</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> as SomeModule<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;addToLog <span class="br0">&#40;</span><span class="st0">&quot;SomeModule instance created and added to Display List&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="coMULTI">/**<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Handler for the ModuleEvent.UNLOAD event<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;**/</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw3">public</span> <span class="kw2">function</span> onModuleUnload <span class="br0">&#40;</span><span class="kw3">e</span>:ModuleEvent<span class="br0">&#41;</span> : <span class="kw3">void</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; addToLog <span class="br0">&#40;</span><span class="st0">&quot;ModuleEvent.UNLOAD received&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span> <br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#93;</span><span class="br0">&#93;</span>&gt; <br />
&nbsp; &nbsp; &lt;/mx:Script&gt; <br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; &lt;mx:HBox <span class="kw3">width</span>=<span class="st0">&quot;100%&quot;</span> <span class="kw3">height</span>=<span class="st0">&quot;100%&quot;</span>&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;mx:Tile id=<span class="st0">&quot;tile&quot;</span> <span class="kw3">width</span>=<span class="st0">&quot;100%&quot;</span> <span class="kw3">height</span>=<span class="st0">&quot;100%&quot;</span> /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;mx:TextArea id=<span class="st0">&quot;log&quot;</span> <span class="kw3">width</span>=<span class="st0">&quot;100%&quot;</span> <span class="kw3">height</span>=<span class="st0">&quot;100%&quot;</span>/&gt;<br />
&nbsp; &nbsp; &lt;/mx:HBox&gt;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; &lt;mx:ApplicationControlBar&gt;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp;&lt;mx:<span class="kw3">Button</span> label=<span class="st0">&quot;Load&quot;</span> click=<span class="st0">&quot;loadModule ()&quot;</span> /&gt;<br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp;&lt;mx:<span class="kw3">Button</span> label=<span class="st0">&quot;Unload&quot;</span> click=<span class="st0">&quot;unloadModule ()&quot;</span>/&gt;<br />
&nbsp; &nbsp; &lt;/mx:ApplicationControlBar&gt;<br />
&nbsp; &nbsp; <br />
&lt;/mx:Application&gt;</div></div>
<p>What&#8217;s going on here? Well&#8230; when the app is created, <em>initApp</em> is called and the <em>IModuleInfo</em> object is created, and various event listeners are setup. When the user clicks the <strong>load</strong> button, the module is loaded. It doesn&#8217;t matter whether this is the first time the module is loaded, or if the module is already loaded and ready, the <em>ModuleEvent.READY</em> event will be dispatched to let us know that the module is ready, and that we can now create an instance of it. Within the handler for the <em>ModuleEvent.READY</em> event, we call <em>IModuleInfo.factory.create ()</em> and add the instance of the module to our Tile control.</p>
<p>When the user clicks the <strong>unload</strong> button, all instances of the Module that we&#8217;ve added to the Tile control are removed, and we call <em>IModuleInfo.unload</em> to unload the module. A log message from within the handler for <em>ModuleEvent.UNLOAD</em> demonstrates that this is happening.</p>
<p>Additionally, within the event handler for <em>ModuleEvent.SETUP</em> we show an example of the <em>IModuleInfo.factory.info</em> method &#8211; this&#8217;ll give you an example of the kind of information you can retrieve about the module, and from looking at the log messages you&#8217;ll be able to see the order in which these events are dispatched.</p>
<p>Lastly, here&#8217;s the finished example:</p>
<p>[kml_flashembed movie="/blog/bin/modulemanager/Shell.swf" height="400" width="600" /]</p>
<p>&nbsp;</p>
<p><em>(Update: I&#8217;ve <a href='/blog/2008/08/17/iflexmodulefactory-create-and-examine-loaded-flex-modules/'>explained the IFlexModuleFactory class in a little more detail here</a>.)</em></p>
]]></content:encoded>
			<wfw:commentRss>http://lowpitch.com/blog/modulemanager-and-imoduleinfo-loading-flex-modules-dynamically/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Flash plays certain MP3s back at double speed &#8211; why?</title>
		<link>http://lowpitch.com/blog/flash-plays-mp3s-back-at-double-speed-why/</link>
		<comments>http://lowpitch.com/blog/flash-plays-mp3s-back-at-double-speed-why/#comments</comments>
		<pubDate>Sun, 27 Jul 2008 10:06:59 +0000</pubDate>
		<dc:creator>lowpitch</dc:creator>
				<category><![CDATA[Actionscript 2.0]]></category>
		<category><![CDATA[AS 2.0]]></category>
		<category><![CDATA[Audio]]></category>
		<category><![CDATA[Bugs]]></category>
		<category><![CDATA[Flash]]></category>

		<guid isPermaLink="false">http://lowpitch.com/blog/?p=11</guid>
		<description><![CDATA[A colleague and I recently found some odd things happening with dynamically loaded audio in an elearning application we have been working on. The external MP3s seemed to be playing back at double speed, and as a result the audio was a hideously high-pitched mess. The weird thing was, this wasn&#8217;t happening on every machine. [...]]]></description>
			<content:encoded><![CDATA[<p>A colleague and I recently found some odd things happening with dynamically loaded audio in an elearning application we have been working on. The external MP3s seemed to be playing back at double speed, and as a result the audio was a hideously high-pitched mess. The weird thing was, this wasn&#8217;t happening on every machine. Some computers, including mine, would play the audio back fine but a couple of other people were reporting the same problem so we had to look into it. Bah.</p>
<p>After much fiddling, we reached the following conclusions:</p>
<ul>
<li>Flash seems unable to handle MP3s encoded with a <a href="http://en.wikipedia.org/wiki/Variable_bit_rate" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">variable bit rate</a> (VBR)</li>
<li>Flash seems unable to reliably handle MP3s which have a <a href="http://en.wikipedia.org/wiki/Sampling_rate" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">sample rate</a> which is <strong>not</strong> 44,100 <em>Hz</em>, 22,050 <em>Hz</em> or 11,025 <em>Hz</em>.</li>
<li>Additionally, it seems possible that there are certain bit rates which are also not handled well by Flash. We&#8217;ve tested files successfully at 40kbps, 80kps, 120kbps (and many other multiples of 40).</li>
</ul>
<p><em>(Note: This was happening in an application built with Actionscript 2.0 for Flash Player 8. I haven&#8217;t had a chance as yet to see if the same problem occurs in SWFs running in AVM2)</em></p>
<p>While the problem of the audio playing at double speed did seem fairly hard to recreate, we did find another way of highlighting the problem. The <a href="http://www.jeroenwijering.com/?item=JW_FLV_Player" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.jeroenwijering.com');">JW Media Player</a> is a popular, open-source MP3/FLV Player and can see be seen in-use all over the internet. From our tests, &#8216;incorrectly&#8217; encoded MP3 files can also create a problem when played as part of a playlist in the JW Media Player. If the user is listening to one of these MP3s, and moves the seek bar somewhere between half-way and the end of the file, the Media Player incorrectly decides that the MP3 has finished, and automatically moves to the next item in the playlist. Without looking into the code in more detail, this kind of assumes that the information Flash is broadcasting about the MP3 (for example sample length, or current position.) is incorrect, which is causes the MP3 to finish prematurely. Re-encoding the audio to match the criteria listed above will always fix this problem. </p>
<p><em>(Note: Current versions of the free Audio editing software <a href="http://audacity.sourceforge.net/" onclick="javascript:pageTracker._trackPageview('/outbound/article/audacity.sourceforge.net');" target="_blank">Audacity</a>, used in tandem with the <a href="http://lame.sourceforge.net/index.php" onclick="javascript:pageTracker._trackPageview('/outbound/article/lame.sourceforge.net');" target="_blank">LAME MP3 encoder</a>, do not allow you to choose the bitrate of the exported MP3. However, the Beta version of Audacity 1.3 does offer that functionality via the Options button in the Export Dialog. The Beta version of this software can currently be downloaded from <a href="http://audacity.sourceforge.net/download/" onclick="javascript:pageTracker._trackPageview('/outbound/article/audacity.sourceforge.net');" target="_blank">http://audacity.sourceforge.net/download/</a>.)</em></p>
]]></content:encoded>
			<wfw:commentRss>http://lowpitch.com/blog/flash-plays-mp3s-back-at-double-speed-why/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
