{"id":303,"date":"2011-11-15T15:52:55","date_gmt":"2011-11-15T19:52:55","guid":{"rendered":"http:\/\/www.eqsim.com\/blog\/?p=303"},"modified":"2011-11-21T11:45:50","modified_gmt":"2011-11-21T15:45:50","slug":"adventures-in-component-writing-for-flash-as3","status":"publish","type":"post","link":"https:\/\/www.eqsim.com\/blog\/adventures-in-component-writing-for-flash-as3\/","title":{"rendered":"Adventures in Component Writing for Flash AS3"},"content":{"rendered":"<p>To say it is a long time coming is an understatement, but I found myself last week with a little time that I could devote to updating my <a href=\"http:\/\/www.flashsim.com\/FMXISComponents\/\">Flash Equipment Interface component set<\/a>. I didn&#8217;t quite get to them all, but I hit the ones I thought were the most important. \u00a0Over the next few days, I&#8217;m going to clean things up and release them somewhere. \u00a0<span style=\"text-decoration: line-through;\">I am not completely decided yet where\/how I will distribute them<\/span>. \u00a0When I do that, if you have some need for one or more of the remaining components, let me know and I&#8217;ll do my best to create them.<\/p>\n<p><strong>Update: I decided to release the components as open source under the New BSD License. \u00a0Check out my <a href=\"https:\/\/code.google.com\/p\/eqsim-state-machine-and-interface-components\/\" target=\"_blank\">Google Code project<\/a> to get them.<\/strong><br \/>\n<!--more--><\/p>\n<p>First off, I had made AS3 components over the years, here and there, and <a href=\"http:\/\/www.adobe.com\/devnet\/flash\/articles\/creating_as3_components.html\">Jeff Kamerer&#8217;s multi-part series<\/a> is really good (though I seem to discover new things each time I read it!). \u00a0Here are few more I found useful to help fill in some details, or get other perspectives:<\/p>\n<ul>\n<li><a href=\"http:\/\/redbjarne.wordpress.com\/actionscript-3-0-custom-components-from-hell\/\">ActionScript 3 Custom Components from Hell<\/a> (Red Bjarne)<\/li>\n<li><a href=\"http:\/\/www.flashgrind.com\/blog\/2010\/06\/25\/building-an-as3-component-with-a-swfpanel-and-a-livepreview\/\">Building an AS3 FLA based component with SWFPanel and LivePreview<\/a> (FlashGrind)<\/li>\n<li><a href=\"http:\/\/active.tutsplus.com\/tutorials\/actionscript\/creating-flash-components-for-distribution\/\">Creating Flash Components for Distribution<\/a> (Andre Cavallari)<\/li>\n<li><a href=\"http:\/\/www.flexiblefactory.co.uk\/flexible\/?p=16\">Creating FLA-based Components with ActionScript 3 in Flash CS3<\/a> (Flexible Factory)<\/li>\n<li><a href=\"http:\/\/jeffkamerer.com\/blog\/2009\/04\/03\/custom-component-ui-with-actionscript-30\/\">Custom Component UI with ActionScript 3.0<\/a> (Jeff Kamerer)<\/li>\n<\/ul>\n<p>In general, it was a somewhat benign (yet tedious) experience, but there were a few gotcha&#8217;s that I wanted to document.<\/p>\n<h3>Events<\/h3>\n<p>The first question I asked myself was whether I should follow the pattern of the standard static constant-based events that are in the AS3 event model, for example, MouseEvent.MOUSE_DOWN. \u00a0I realized that at the top of my priorities was integrating the interface components with my State Engine, and the constant-based approach is not directly compatible with that. \u00a0For example, if all buttons issue MouseEvent.CLICK, and a state wants to listen to a specific click on a button, it means the state can really only subscribe to one button &#8212; without the handler having a mess to distinguish which button sent the event. \u00a0I prefer the ability to allow the instance to customize the event message. \u00a0Therefore, in my implementation, two buttons can send different events, such as &#8220;onPower&#8221; and &#8220;onNextPage&#8221;. \u00a0In reality, this gives developers the option to use the default event name, or rename it for their purpose. \u00a0I realize one of the complaints of the AS3 event model is that event handler typing is not enforced at compile time, and my approach flies in the face of that direction, but I didn&#8217;t see a compatible alternative.<\/p>\n<h3>Skinning<\/h3>\n<p>Most of my work is done within Flash Professional, FlashDevelop, or FDT. \u00a0I have not used CSS much at all, and so I decided for the first go around to make skinning something easy to accomplish with Flash Pro. \u00a0I added a property that gives the class name for the skin, using the default skin class name as the default property value. \u00a0That way, anyone who wants to create a skin just needs to make a Sprite or MovieClip (depending on the component) and give it a class name, then stick in the class name into the appropriate property. \u00a0I need to work on documenting how the skin should be created (rotation base, size, etc.) but I hope it is straightforward. \u00a0I played around a bit with setStyle() and the like, but in the end I went with what was easiest.<\/p>\n<h3>ASDoc<\/h3>\n<p>The most natural way of writing documentation is using ASDoc, but I struggled quite a lot getting it to work with my *.as files. \u00a0It was one of those things that I thought would take 30 minutes that turned into more than half a day affair. One big discovery was hearing that I needed to use JRE 5, instead of the more recent JRE 6 or JRE 7 versions. \u00a0I am shocked that this could have been the culprit, as Adobe seems to depend heavily on ASDoc and I wonder what the dependency is to version 5. \u00a0I am surprised I don&#8217;t see it somewhere in Flash CS5, but then again, maybe not so surprised, as Adobe is pushing development through Flash Builder. \u00a0<a href=\"http:\/\/www.wastedpotential.com\/?p=252\">This article from Wasted Potential<\/a> helped a lot, though I still had some tweaks (hard earned through several hours). \u00a0BTW, here is my batch file that worked:<\/p>\n<pre style=\"padding-left: 30px;\">cls\r\nset path=C:\\Program Files (x86)\\Adobe\\Adobe Flash Builder 4.5\\sdks\\4.5.1\\bin\r\nset JAVA_HOME=\"C:\\Program Files (x86)\\Java\\jre1.5.0_22\"\r\nasdoc.exe -source-path \"C:\\Users\\Jonathan\\Documents\\My Dropbox\\FMXIS3\" -doc-sources \"C:\\Users\\Jonathan\\Documents\\My Dropbox\\FMXIS3\\com\" -window-title \"EqSim Hierarchical State Engine and Equipment Interface Components\" -main-title \"Flash State Engine and Components\" -footer \"Copyright 2011&lt;br\/&gt;www.eqsim.com\" -output \"C:\\Users\\Jonathan\\Documents\\My Dropbox\\FMXIS3\\docs\" -library-path \"C:\\Users\\Jonathan\\Documents\\My Dropbox\\FMXIS3\\fl-shim.swc\"\r\npause<\/pre>\n<p>You&#8217;ll see I set the path variable at top because I didn&#8217;t want to interfere with the real JAVA_HOME (and get inundated with Java update messages, just for ASDoc). \u00a0Before having the library-path argument, I remember I had a lot of trouble with weird errors like UIComponent not being defined. \u00a0That eventually led me to a site that discussed creating a shim with the UIComponent code, which you can see here. \u00a0That site basically said to create a MovieClip that includes any Flash component (from Adobe), then export that clip as a SWC, then add the library-path argument above. \u00a0With the benefit of foresight, I bet I could just drop a component on the stage, then go find the ComponentShim component in the _private folder that gets added when one brings in one of those components (I used a Button), and use that, but I&#8217;m too lazy to go back and try that.<\/p>\n<h3>LivePreview<\/h3>\n<p>I struggled with the decision about whether I would produce FLA-based components or SWC-based components. \u00a0I have not come down conclusively on either side, yet. \u00a0The easiest process seems to be letting Flash produce the file as part of an exported SWC, then using that SWF file in the Components panel under Live Preview. \u00a0That wasn&#8217;t so helpful for two of my components, Timer and Stopwatch, because they have no visible presence at run-time, so the Live Preview would empty. \u00a0I tried to follow Jeff Kamerer&#8217;s suggestions in his <a href=\"http:\/\/www.adobe.com\/devnet\/flash\/articles\/creating_as3_components_pt3.html#articlecontentAdobe_numberedheader_6\">Part 3 on LivePreview<\/a>, but I found he glossed over the most important part, unfortunately:<\/p>\n<blockquote><p>If I had wanted the UILoader Live Preview to handle component parameters, I would have simply implemented those parameters.<\/p><\/blockquote>\n<p>He doesn&#8217;t say how to implement the parameters, and his example doesn&#8217;t show how to retrieve a UILoader-specific parameter &#8212; the live preview movie itself is not of the type of the component, so I don&#8217;t know how to access the parameters I want to display. \u00a0For example, in my Timer component, \u00a0I want to show the timing interval. \u00a0I don&#8217;t know how to access the timing interval of the real instance from the Live Preview movie. \u00a0Very frustrating. \u00a0Maybe someday I&#8217;ll figure it out, but for now I just created a box that shows up if isLivePreview is true (only during Live Preview). \u00a0So I will deploy my Timer and Stopwatch as SWC components, and then using the default preview mechanism will show the box I wanted. \u00a0Kind of gnawing at me how to access the parameters from a Live Preview movie, though.<\/p>\n<p>UPDATE: I had some insight into the LivePreview, after giving it some more thought, but still did not get it to work. \u00a0Here is my comment I added to Jeff Kamerer&#8217;s article on making a LivePreview:<\/p>\n<blockquote><p>This series has been great, but I have one problem for the life of me I can&#8217;t overcome (and this part, #3, does not give the details).\u00a0\u00a0I also have searched over the Internet at other tutorials, but to no avail.<\/p>\n<p>I want to create a LivePreview movie for my component that has no visual representation on the stage.\u00a0\u00a0The UILoader example is good, but it leaves out a few critical details.\u00a0\u00a0For example, it says if you need to get component parameters, define them.\u00a0\u00a0However, it does not say how to reach the parameters in the instance.\u00a0\u00a0I looked in fl.livepreview.LivePreviewParent to find the answer: myInstance.\u00a0\u00a0That property is the component instance.\u00a0\u00a0Great, I&#8217;m thinking, almost there!<\/p>\n<p>So inside the class I define for my LivePreview, for my component&#8217;s property &#8220;instance&#8221;, I retrieve &#8220;LivePreviewParent(parent).myInstance.interval&#8221; (because parent inherits from the LivePreviewParent class).\u00a0\u00a0If &#8220;interval&#8221; is defined as a public variable (with Inspectable), great, I get the value as I want.\u00a0\u00a0However, my &#8220;interval&#8221; happens to be a getter\/setter (with an Inspectable tag, of course), and nothing happens.\u00a0\u00a0I&#8217;m stuck.\u00a0\u00a0I don&#8217;t know why it works for a public variable but not for a getter\/setter.<\/p>\n<p>Furthermore, even with an Inspectable variable, when I update the value in the property inspector, it does not change in the LivePreview.\u00a0\u00a0I see in the LivePreviewParent class there is a method called &#8220;onUpdate&#8221;.\u00a0\u00a0If I define that in my LivePreview movie, I&#8217;m thinking I will get notified when the properties change.\u00a0\u00a0Nope.\u00a0\u00a0I even tried defining it in the parent, and then having a function call into the LivePreview clip, but still nothing.<\/p>\n<p>I have spent many hours on this, and just can&#8217;t afford to continue, so I have to go back to my fallback, which is adding the live preview into the real component and using the basic process.\u00a0\u00a0This inflates the size of my component, but it is the only thing I can see reliably working.<\/p><\/blockquote>\n<h3>The Future<\/h3>\n<p>It was a somewhat fun exercises, but it&#8217;s time to get back to my other work that has piled up. \u00a0It did occur to me that I may in the future want to port these to HTML5\/JavaScript, which I don&#8217;t think would be too bad, or port them to Flex components (even easier). \u00a0Maybe someone out there would like to do this! \u00a0Stay tuned and I will post where I ultimately put the component set.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>To say it is a long time coming is an understatement, but I found myself last week with a little time that I could devote to updating my Flash Equipment Interface component set. I didn&#8217;t quite get to them all, but I hit the ones I thought were the most important. \u00a0Over the next few\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.eqsim.com\/blog\/adventures-in-component-writing-for-flash-as3\/\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[17],"tags":[],"_links":{"self":[{"href":"https:\/\/www.eqsim.com\/blog\/wp-json\/wp\/v2\/posts\/303"}],"collection":[{"href":"https:\/\/www.eqsim.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.eqsim.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.eqsim.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.eqsim.com\/blog\/wp-json\/wp\/v2\/comments?post=303"}],"version-history":[{"count":6,"href":"https:\/\/www.eqsim.com\/blog\/wp-json\/wp\/v2\/posts\/303\/revisions"}],"predecessor-version":[{"id":312,"href":"https:\/\/www.eqsim.com\/blog\/wp-json\/wp\/v2\/posts\/303\/revisions\/312"}],"wp:attachment":[{"href":"https:\/\/www.eqsim.com\/blog\/wp-json\/wp\/v2\/media?parent=303"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.eqsim.com\/blog\/wp-json\/wp\/v2\/categories?post=303"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.eqsim.com\/blog\/wp-json\/wp\/v2\/tags?post=303"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}