<?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>alecmce.com &#187; events</title>
	<atom:link href="http://alecmce.com/tag/events/feed" rel="self" type="application/rss+xml" />
	<link>http://alecmce.com</link>
	<description></description>
	<lastBuildDate>Thu, 10 Nov 2011 21:56:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Replacing ENTER_FRAME</title>
		<link>http://alecmce.com/as3/replacing-enter_frame</link>
		<comments>http://alecmce.com/as3/replacing-enter_frame#comments</comments>
		<pubDate>Thu, 26 Nov 2009 23:37:30 +0000</pubDate>
		<dc:creator>alecmce</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[opinion]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[as3signals]]></category>
		<category><![CDATA[compiler]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[mxmlc]]></category>

		<guid isPermaLink="false">http://alecmce.com/?p=552</guid>
		<description><![CDATA[Today an interesting discussion took place on Twitter, in which I was involved. It caught my attention for a variety of reasons, and I wanted to document the conversation, the problem and the solution here. It started when it was identified that Flash&#8217;s event dispatcher is sub-optimal in performance terms, and revolved around trying to [...]]]></description>
			<content:encoded><![CDATA[<p>Today an interesting discussion took place on Twitter, in which I was involved. It caught my attention for a variety of reasons, and I wanted to document the conversation, the problem and the solution here. It started when it was identified that Flash&#8217;s event dispatcher is sub-optimal in performance terms, and revolved around trying to find a solution.</p>
<h2>Why replace the ENTER_FRAME?</h2>
<p>Every event that is dispatched creates an object. An ENTER_FRAME creates as many objects per second as there are frames. If you have mutliple objects dispatching ENTER_FRAME events, that&#8217;s many objects creating event objects many times per second. Computationally, chains of &#8220;many&#8221; are one of those things you want to avoid. So, can we do better?</p>
<h2>Doing Better</h2>
<p>Robert Penner proposed creating an as3signal and using a MovieClip with two frames to dispatch that signal on each frame. He posted his idea to <a href="http://gist.github.com/243630">this GitHub gist</a>.</p>
<p>One drawback to this approach is that it requires a MovieClip symbol with two empty frames, to which the two event dispatcher methods could be attached. I remembered reading in <a href="http://www.bit-101.com/blog/?p=946">this excellent article by Bit 101</a> how using a [Frame] metadata tag would force your application to have two frames. This seemed to be what Penner needed for his functionality to work correctly, so I came up with <a href="http://gist.github.com/243692">my own GitHub gist</a> which extends the concept. The code is also added &#8216;<a href="#fold">below the fold</a>&#8216;, at the bottom of this article.</p>
<p><em>[Update, after <a href="http://alecmce.com/as3/replacing-enter_frame#comment-24152811">Jackson's comment</a>, below]</em> The idea behind the approach is that a frame-loop is an internal Flash player structure. It sits underneath the AS3 functionality, and so it doesn&#8217;t produce ENTER_FRAME events. By hooking into them we can produce our own iterative &#8216;event&#8217; (Penner proposes using an as3signal), which doesn&#8217;t construct an object each time it is dispatched. It is a lovely idea, and quite distinct from invoking one ENTER_FRAME dispatcher on the root or stage of the application.</p>
<p><em>[Update, after <a href="http://alecmce.com/as3/replacing-enter_frame#comment-24168332">Joa Ebert tweeted test results</a>]</em> Whether this method is superior to the &#8216;one-event ticker&#8217; is open to question. Joa Ebert applied the frameloop concept to AudioBox and found no memory nor performance improvements.</p>
<h2>Background</h2>
<p>It all started today with a statement on Twitter from Robert Penner:</p>
<blockquote><p>Listening to a single #AS3 enterFrame will create over 1000 event instances per minute. <em><a href="http://bit.ly/5A36ZS">@robpenner</a></em></p></blockquote>
<p>In fact, at a decent frame rate, you&#8217;re looking at 1800 event instances per minute. Across the blogosphere and on Twitter, there has been a lot of talk about the cost of object construction in AS3. People are pushing the limitations of the player, and are looking for performance optimisation wherever they can find it. Strategies such as object pooling are becoming mainstream in order to avoid the creation and destruction of objects. In the meanwhile, the internal Flash event model is creating and destroying huge numbers of objects to furnish us with an event model.</p>
<p>At the same time however, there has been a murmur of discomfiture about the state of the event model. (Not that I have much of a voice, but I <a href="http://alecmce.com/opinion/as4-thought-experiment">chimed in to this debate</a> as well!). The most notable result of this murmur was Penner&#8217;s decision to create <a href="http://github.com/robertpenner/as3-signals">as3signals</a>. It is an on-going project to which I have contributed in a small way, and which I whole-heartedly support.</p>
<p>After Penner&#8217;s tweet, the <a href="http://twitter.com/alecmce/flashdevs">#as3 twitterati</a> (please tweet if there are glaring omissions from this list) became very excited indeed.</p>
<p>My initial thoughts led to the idea that maybe the setInterval/setTimeout functions, which are hangovers from AS2 might offer a solution &#8211; perhaps they shortcut the event system? Not only ain&#8217;t it so, they&#8217;re even worse <a href="http://bit.ly/4E1Unk">as this Action Script Viewer deconstruction of the setInterval methods</a> demonstrate.</p>
<p>So what else? Mike Chambers (aka <a href="http://twitter.com/mesh">@Mesh</a>) in conversation with <a href="http://twitter.com/theflashbum">@TheFlashBum</a> pointed towards <a href="http://bit.ly/7NK8hQ">a solution using a &#8216;ticker&#8217;</a>; a single ENTER_FRAME dispatcher, and <a href="twitter.com/bengarney">@bengarney</a> confirmed that <a href="http://bit.ly/8iKdQC">he also uses this technique</a>.</p>
<p>It seems that @scottjanousek and @robpenner had the idea of using the player frameloop (which the solution offered here exploits) at pretty much the same time. (@scottjanousek&#8217;s tweets are protected, but it was reported by <a href="http://bit.ly/4ZdU1Q">this tweet</a>.)</p>
<p>Whether and how this vein of thought will develop is really interesting. It is fascinating how a tweet from one of the best-known ActionScript developers can provoke such a lot of attention from the general community. It is interesting too to see the envelope of what is possible being pushed.</p>
<p><span id="more-552"></span></p>
<h2><a name="fold">FrameLoop Example Source Code</a></h2>
<p>To use this code, you will need the <a href="http://github.com/robertpenner/as3-signals">as3signals</a> library. You will also need to compile through the MXML compiler. I have tested it with the Flex 4 SDK &#8211; if you try and discover that it does not work for other target platforms, please share the information by leaving a comment!.</p>
<h3>Main.as</h3>
<pre class="brush: as3; title: ; notranslate">
package
{
	import org.osflash.signals.Signal;

	import flash.display.Shape;
	import flash.display.Sprite;

	/**
	 * A Main application class that uses the [Frame] MetaData Tag to use the
	 * EventFrameDispatcher class to configure itself. This class contains a
	 * frame signal which is constructed and passed into it by the
	 * EventFrameDispatcher class before init() is called. Application
	 * functionality should be placed in the init() method
	 *
	 * @author Alec McEachran
	 */
	[Frame(factoryClass=&quot;EnterFrameDispatcher&quot;)]
	public class Main extends Sprite
	{
		/** an as3signal that is dispatched on every ENTER_FRAME */
		public var frame:Signal;

		/**
		 * do interesting things in here...
		 */
		public function init():void
		{
			// functionality here...
		}
	}
}
</pre>
<h3>EnterFrameDispatcher.as</h3>
<pre class="brush: as3; title: ; notranslate">
package
{
	import org.osflash.signals.Signal;

	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.utils.getDefinitionByName;

	/**
	 * The EnterFrameDispatcher is injected into the Main class through
	 * the [Frame] MetaData tag.
	 *
	 * The class creates a frame signal. By being injected, two frames are
	 * generated, onto which the frameMethod are attached so that the
	 * frame signal is dispatched on every frame cycle. It then injects this
	 * object into the Main class and calls the Main class's init() method.
	 *
	 * @author Alec McEachran
	 *
	 * based on an idea by Robert Penner @see http://gist.github.com/243630
	 */
	public class EnterFrameDispatcher extends MovieClip
	{
		public var frame:Signal;

		public function EnterFrameDispatcher()
		{
			frame = new Signal();
			addFrameScript(0, frameMethod, 1, frameMethod);

			addEventListener(Event.ENTER_FRAME, onEnterFrame);
			nextFrame();
		}

		private function onEnterFrame(event:Event):void
		{
			removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			init();
			play();
		}

		private function frameMethod():void
		{
			frame.dispatch();
		}

		private function init():void
		{
			var mainClass:Class = Class(getDefinitionByName(&quot;Main&quot;));
			if (mainClass)
			{
				var app:* = new mainClass();
				app.frame = frame;
				addChild(app);
				app.init();
			}
		}
	}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://alecmce.com/as3/replacing-enter_frame/feed</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
		<item>
		<title>Weak Event Listeners and Inline Methods</title>
		<link>http://alecmce.com/as3/weak-event-listeners-and-inline-methods</link>
		<comments>http://alecmce.com/as3/weak-event-listeners-and-inline-methods#comments</comments>
		<pubDate>Fri, 07 Aug 2009 17:04:51 +0000</pubDate>
		<dc:creator>alecmce</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[gotcha]]></category>
		<category><![CDATA[event listeners]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[weak reference]]></category>

		<guid isPermaLink="false">http://alecmce.com/?p=198</guid>
		<description><![CDATA[I encountered this strange issue today. The useful bulk loader library produces error events when it comes across problems and captures them with the following event listener. The accompanying comment says that this is to prevent unhandled errors that would otherwise produce a stack trace to (debug player) users indicating an error: I passed malformed [...]]]></description>
			<content:encoded><![CDATA[<p>I encountered this strange issue today. The useful <a href="http://code.google.com/p/bulk-loader/">bulk loader library</a> produces error events when it comes across problems and captures them with the following event listener. The accompanying comment says that this is to prevent unhandled errors that would otherwise produce a stack trace to (debug player) users indicating an error:</p>
<pre class="brush: as3; title: ; notranslate">addEventListener(BulkLoader.ERROR, function (e:Event):void{}, false, 1, true);</pre>
<p>I passed malformed XML into the loader, and found that about 25% of the time, I was getting just such a stack trace. I was not changing <em>anything</em>, but simply running and re-running a whole list of tests, with this test among them. The only thing that I could think of is that the Garbage Collector was occassionally considering the event listener available for collection and was removing it. Testing that hypothesis, I replaced the code with:</p>
<pre class="brush: as3; title: ; notranslate">
addEventListener(BulkLoader.ERROR, squashError, false, 1, true);
...
private function squashError(event:Event):void {}
</pre>
<p>and the error disappeared. I have <a href="http://code.google.com/p/bulk-loader/issues/detail?id=99#makechanges">posted a patch to the Bulk Library codebase</a>, so hopefully it will be resolved soon.</p>
<h3>There&#8217;s Nothing New Under The Sun</h3>
<p>I&#8217;ve known about <a href="http://gskinner.com/blog/archives/2006/07/as3_weakly_refe.html">Grant Skinner&#8217;s analysis of event listeners</a> for years, and have accepted that event listeners should always be defined weakly for as long. However, that article contains the very point that I have spent an afternoon rediscovering! It turns out I&#8217;ve been doing work that Grant Skinner did three years ago on behalf of another third party library vendor&#8230; which is disheartening because if I knew that article in more detail I could have saved my afternoon. It&#8217;s encouraging as well though; there&#8217;s a cliché about earning your learning somewhere&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://alecmce.com/as3/weak-event-listeners-and-inline-methods/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

