<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Peanut Butter Thoughts</title>
	
	<link>http://pbking.com/blog</link>
	<description>Thoughts of a Flash Geek</description>
	<lastBuildDate>Wed, 04 Nov 2009 09:27:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/ThePeanutButterThoughts" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>Swiz vs RobotLegs</title>
		<link>http://feedproxy.google.com/~r/ThePeanutButterThoughts/~3/ZY8T1bUfJuk/</link>
		<comments>http://pbking.com/blog/?p=203#comments</comments>
		<pubDate>Wed, 04 Nov 2009 09:27:44 +0000</pubDate>
		<dc:creator>Jason Crist</dc:creator>
				<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://pbking.com/blog/?p=203</guid>
		<description><![CDATA[Recently I spent some time converting a medium-sized project first to Swiz and then to RobotLegs.  The following is my take on the two frameworks and how I chose a winner.  Right now there are definitely a lot of things I like about both frameworks, and I wish I could pick and choose the features [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I spent some time converting a medium-sized project first to <a href="http://swizframework.org/">Swiz </a>and then to <a href="http://wiki.github.com/robotlegs/robotlegs-framework">RobotLegs</a>.  The following is my take on the two frameworks and how I chose a winner.  Right now there are definitely a lot of things I like about both frameworks, and I wish I could pick and choose the features I like best.  I would call it the Peanut Butter Framework Mashup Extraordinaire.</p>
<p>I have considered giving <a href="http://mate.asfusion.com/">Mate </a>and <a href="http://www.spicefactory.org/parsley/">Parsley </a>a similar go but Swiz and RobotLegs were the two that definitely interested me the most so I&#8217;ve done them first.  I&#8217;m pretty familiar with <a href="http://opensource.adobe.com/wiki/display/cairngorm/">Cairngorm </a>and don&#8217;t personally like it.  I think I&#8217;ve read and tinkered with <a href="http://puremvc.org/">PureMVC</a> enough to know that it isn&#8217;t my ball of wax either.</p>
<p>Keep in mind that I am refactoring an EXISTING project to use these frameworks.  I am not starting a project from scratch.  If I were then I might feel differently.  Maybe.</p>
<p><strong>What is important to me?</strong></p>
<p>The most important things about a development tool, be it an IDE, a library, a repository or a framework is:</p>
<ol>
<li>How quickly can it help me get the job done?</li>
<li>How quickly can it help me add new features?</li>
<li>How quickly can it help me find and squash bugs?</li>
<li>How little code can I write to get the job done?</li>
</ol>
<p>And that&#8217;s it really.  I want to write as LITTLE easily understandable code as possible and I want to be able to easily fix it and add to it.</p>
<p><em>Don&#8217;t code it &#8217;till you need it.</em></p>
<p>For me writing code is not always a task of reuseability.  If I build something for a project then it&#8217;s for THAT project.  If I see that some piece of code could be helpful elsewhere then I will take the time to make that piece a project and allot it its own time.  By carefully choosing what gets &#8220;bumped up&#8221; into reuseability land I am able to get the job done faster and with less effort.</p>
<p>With that in mind it&#8217;s important that the framework I&#8217;m using allow me to do that; write code quickly.  That isn&#8217;t to say I&#8217;ll settle for spaghetti code just because it closes the job ticket faster.  I know I&#8217;ll also be the one adding features to this puppy and fixing bugs.  So I want it to stand the test of time.  So the framework will also need to gently guide me to do that as well.</p>
<p><strong>Map Commands vs Mediate Methods</strong></p>
<p>One difference between Swiz and RobotLegs seems to be how they handle &#8220;triggered logic&#8221;.</p>
<p>Using Swiz you define instances of Controllers in your Bean Map.  In those controllers you will have a number of methods that get called when an event is fired that Swiz captures (mediates).</p>
<p>You can use events to trigger calls to methods in RobotLegs as well but only in certain siturations (Mediator classes).  It seems to instead suggest that you map Commands to Events, a technique which I was first introduced to in Cairngorm.  The WAY this happens is different than Cairngorm, but the idea is roughly the same: When X happens this Command Class is created and executed.</p>
<p>That&#8217;s actually how the project was working before the conversion (though it was using a home-rolled solution for that).</p>
<p>Now I LOVE commands.  I really like to use <a href="http://code.google.com/p/pbutils/">my own command library</a>.  I don&#8217;t always want to have to link a command up to an event.  With my library I can play with my commands from anywhere in my code.  Generally I don&#8217;t care when a command starts, finishes, etc except from where I actually called the command.  This helps me keep my code-base as small as possible; needless custom events aren&#8217;t created when only one place cares about something happening.  When I DO find that event information is helpful elsewhere then I can just dispatch some informative events from the command itself (using whatever the framework of the day is).  With this in mind any tool that lets me to easily continue working in this manner is a win for me.</p>
<p>Using RobotLegs I&#8217;m able to map an Event to a Command.  Awesome.  I can even inject some data into it.  Cool.  But the Command needs to be an ICommand.  And I couldn&#8217;t find ICommand in the library so AFAIK the commands actually have to extend robotlegs.Command.  Not cool.  I have dozens of commands already written and tied to another library.  I could just change the Commands that need to be triggered by events but that sounds like a royal pain-in-the-ass and additional work == bad thing.</p>
<p>Using Swiz I&#8217;m not able to map the commands to events.  I don&#8217;t like that.  However I CAN create and execute the commands from the Controller.  The Controller is mapped from the same BeanMask that the model objects are mapped in and it just contains a bunch of methods that get called when events fire (defined by MetaData).  That actually gives me a little more control.  I can inject the dependencies into my existing commands if I want to.  But in my project all of my commands actually have constructor parameters.  So I just inject properties into my Controller and using that and the properties on the dispatched events I handle the execution of the commands.  It&#8217;s not incredibly elegant but it gets the job done and there isn&#8217;t much code to write or change.</p>
<p><strong>Getting Events Out There</strong></p>
<p>Bubbled events are cool right?  Sure they are technically &#8220;expensive&#8221; and there are the rare cases of apps fighting each other over bubbled events that they throw at each other.  A &#8220;Bubble Fight&#8221; I call it.  Personally I&#8217;ve never witnessed one.</p>
<p>RobotLegs is very strict about NOT relying on the DisplayObject tree as a means to move event messaging back and forth (bubbling).  Swiz lets you do just that.  Bubble an event up from any attached view and any methods assigned to that event will be called.  Easy-peasy.   That&#8217;s another win for Swiz.</p>
<p><strong>Singletons are Awesome</strong></p>
<p>No their not.</p>
<p>Fortunately both frameworks allow you to more elegantly handle Singletons and actually ALL the data that exists in a project.  Using DI (<strong>D</strong>ependency <strong>I</strong>njection) you can have objects that the framework is aware of injected right into your classes.  Both use some type of MetaData to define that.  [Autowire] is Swiz&#8217;s and [Inject] is RobotLegs, but it comes down to the same thing.</p>
<p>DI allows you to do away with the classic &#8220;Singleton&#8221; pattern.  Class.getInstance() sucks.  Even when you don&#8217;t care about reuseability it still sucks.  As far as the injecting/tagging goes I can&#8217;t say that I&#8217;ve got a preference.  But for registering these items I like Swiz better.</p>
<p>In RobotLegs you have a class that kind of &#8220;kick starts&#8221; things.  One popular place to put the items to be injected is there.  I understand, however, that you can actually do this in a number of places in a number of ways.  That sounds like trouble to me.</p>
<p>In Swiz the accepted way of doing this is in an (M)XML document; the BeanMask.  This document will define all of your &#8220;model&#8221; objects.  These are the objects that can be [Autowire]d.  That seems clean to me and I like it.  You can have multiple Bean Masks if your project gets large, but at least you&#8217;ll know where to look for stuff.</p>
<p><strong>Code from Behind vs Reach Around</strong></p>
<p>I&#8217;ve got a number of views that are small.  Small enough that I just put the necessary view logic in a &lt;Script/&gt; tag.</p>
<p>Sometimes that logic will grow and grow and I&#8217;ll just pull it out into it&#8217;s own class.  Usually I just do a code-behind.  (The MXML class extends an ActionScript class which has all the logic in it.)</p>
<p>Previously I had a &#8220;Global Event Dispatcher&#8221; that my views listened to.  Methods were called when those events were dispatched from that &#8220;Global Event Dispatcher&#8221;.</p>
<p>RobotLegs doesn&#8217;t like that.  I need to have a Mediator class for my logic.  Then I need to bind that mediator class to the view.  But not actually IN the view.  Or even in the mediator (though the mediator should have a REFERENCE to the view).  The binding takes places somewhere else.  If I don&#8217;t play by those rules then I don&#8217;t get the benefit of mediated methods for my view.</p>
<p>Swiz doesn&#8217;t care.  I can just stick [Mediate] on any public view method (&lt;Script/&gt; or code-behind) and it will work just fine.  I&#8217;m not opposed to mediator classes.  I think that is a fine (and cleaner) alternative to a code behind.  But I don&#8217;t want to HAVE to do it that way.  Unfortunately, that method DOES need to be public, which I DON&#8217;T like.  I think I can get over that, but it&#8217;s essentially an event handler.  It&#8217;s not something that anyone outside of that view needs to know about.</p>
<p><strong>Services</strong></p>
<p>Ok, I honestly didn&#8217;t put either framework through the paces when it came to working with my Services.  All of my service handling is already done in a way that is already clean and I saw no need to change that at all.  This wasn&#8217;t an important part of either framework for me.</p>
<p><strong>Best Practice vs Get &#8216;er Done</strong></p>
<p>Shaun Smith had a <a href="http://shaun.boyblack.co.za/blog/2009/04/29/another-architectural-framework-but-why/">great piece about &#8220;why RobotLegs&#8221;</a>.  And I couldn&#8217;t help but get fired up about his reasons.  They are good ones.  But they seem like good reasons on paper, not necessarily in practice.  Like I said, if I had started this project out fresh instead of trying to port it then I might feel differently.  But when I look at all the code I would have to change/add using RobotLegs that shows me that there might be a lot of code that I shouldn&#8217;t have to write.</p>
<p>When I ported everything to Swiz it took me a couple of hours and I had things rolling.  I was able to change just a portion of my application to rely on the framework.  It worked alongside what I already had.  But it took me the better part of some valueable sleepy-time to get RobotLegs working.  And even then I still had mountains of Mediators to create before the app was truly &#8220;working&#8221;.  Don&#8217;t think I&#8217;m a hater.  I DO really like what RobotLegs is all about.  But it&#8217;s just not for me; it doesn&#8217;t fit my workflow or my coding style.</p>
<p>Swiz does.</p>
<p><strong>It&#8217;s late</strong></p>
<p>If I&#8217;ve gotten anything wrong describing the usage of either of those frameworks then please correct me.  I admit that I am a total n00b at both of these.  I tried to keep it general and relatively vague; there are plenty of other resources that explain how these things actually work much better than I could.</p>
<p>Sleepy time.</p>
]]></content:encoded>
			<wfw:commentRss>http://pbking.com/blog/?feed=rss2&amp;p=203</wfw:commentRss>
		<slash:comments>12</slash:comments>
		<feedburner:origLink>http://pbking.com/blog/?p=203</feedburner:origLink></item>
		<item>
		<title>Swiz; But I don’t WANT everything public!</title>
		<link>http://feedproxy.google.com/~r/ThePeanutButterThoughts/~3/bXegxcXarWg/</link>
		<comments>http://pbking.com/blog/?p=201#comments</comments>
		<pubDate>Tue, 03 Nov 2009 20:05:25 +0000</pubDate>
		<dc:creator>Jason Crist</dc:creator>
				<category><![CDATA[uncategorized]]></category>

		<guid isPermaLink="false">http://pbking.com/blog/?p=201</guid>
		<description><![CDATA[So I was wrapping up my project&#8217;s Swiz conversion before I took RobotLegs for a spin and noticed something I didn&#8217;t like.  None of my view&#8217;s mediated events were firing.  I didn&#8217;t actually have many, so I didn&#8217;t notice at first.  Then I realized that all of my methods were private.  They were private because [...]]]></description>
			<content:encoded><![CDATA[<p>So I was wrapping up my project&#8217;s Swiz conversion before I took RobotLegs for a spin and noticed something I didn&#8217;t like.  None of my view&#8217;s mediated events were firing.  I didn&#8217;t actually have many, so I didn&#8217;t notice at first.  Then I realized that all of my methods were private.  They were private because I didn&#8217;t want to expose them.  Kind of like my parts.</p>
<p>I switched all of those methods to public and things started working.  Except, now I had all of these even handlers exposed.  It doesn&#8217;t really BREAK anything, it just . . . feels dirty.  I really don&#8217;t think that anybody working with this project would mistakenly call onActionHandler() but I just don&#8217;t like exposing things that shouldn&#8217;t be exposed.</p>
<p>Of course that&#8217;s not an issue at all for my Controller classes.  Public events make sense.</p>
<p>Also I didn&#8217;t get a compiler (or even runtime) error about that.  Likely that&#8217;s a mistake on my part.  If anybody has a suggestion as to how I would be aware of that private issue please let me know.</p>
<p>As to the Flex-only comment I made earlier <a href="http://www.benclinkinbeard.com/">Ben Clinkinbeard</a> <a href="http://pbking.com/blog/?p=197&amp;cpage=1#comment-18025">let me know</a> that it shouldn&#8217;t be that way for long.  That&#8217;s excellent news for sure.  If I can figure out (or get over) the public mediated handlers then I&#8217;ll probably stick with Swiz for a while.</p>
<p>Before I settle though, I am going to give this <a href="http://wiki.github.com/robotlegs/robotlegs-framework">RobotLegs</a> a try first.  Getting started on it now.  Wish me luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://pbking.com/blog/?feed=rss2&amp;p=201</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://pbking.com/blog/?p=201</feedburner:origLink></item>
		<item>
		<title>My Swiz Tryout</title>
		<link>http://feedproxy.google.com/~r/ThePeanutButterThoughts/~3/ls9lvSVZtwQ/</link>
		<comments>http://pbking.com/blog/?p=197#comments</comments>
		<pubDate>Fri, 30 Oct 2009 22:23:16 +0000</pubDate>
		<dc:creator>Jason Crist</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[swiz]]></category>

		<guid isPermaLink="false">http://pbking.com/blog/?p=197</guid>
		<description><![CDATA[I&#8217;ve just given Swiz a little test-run.  I&#8217;m not going to write about how Swiz works or anything here.  There&#8217;s plenty of that all over the place by people much more skilled than myself.  But so far my experience has been very positive.  I&#8217;ve converted a medium-sized project into using it instead of a hand-rolled [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just given <a href="http://swizframework.org/">Swiz</a> a little test-run.  I&#8217;m not going to write about how Swiz works or anything here.  There&#8217;s plenty of that all over the place by people much more skilled than myself.  But so far my experience has been very positive.  I&#8217;ve converted a medium-sized project into using it instead of a hand-rolled solution.  I&#8217;m still using a lot of the original code but since it was already in an MVC pattern it was easy to change the important bits.  I&#8217;m a big fan of my <a href="http://code.google.com/p/pbutils/">command library</a> and have a lot of code written that depends on it.  I&#8217;m sure there are a dozen just like it out there and probably something just like it rolled into Swiz (I haven&#8217;t found out yet, mine worked without change so I didn&#8217;t.)  I was very pleased to see that they fit so smoothly into this framework.</p>
<p>Joe Rinehart&#8217;s post <a href="http://www.firemoss.com/index.cfm/2009/10/21/Swiz-in-20-minutes-video--byebye-boilerplate">Swiz in 20 minutes</a> was very instrimental in getting me up to speed very quickly.  I don&#8217;t often opt for video presentations over the written work (searching, rewinding, etc is so much harder) but this was so straightforward I was able to watch it once and then just flip open Eclipse and do it.  The minimal documentation on the Swiz page was helpful too of course since my memory only lasts about as long as it takes to switch from one tab to another.</p>
<p>But Swiz is Flex-only.  One of the benefits of Swiz is that it <em>augments</em> the abilities of Flex instead of replaces them.  I&#8217;m already using Flex right?  Might as well . . . use it.  But not everything I do is in Flex so I want to see if I can become familiar with a framework that will work in Flash as well and still stay out of my hair.  It&#8217;s gotta be &#8220;micro&#8221; or I just can&#8217;t bring myself to care.</p>
<p>Thinking of giving <a href="http://wiki.github.com/robotlegs/robotlegs-framework">RobotLegs </a>the same treatment.  It&#8217;s about to hit 1.0 and that always has a nice sound to it.  Do a quick project conversion to see how it works in a real-world situation.  Maybe Mate; I&#8217;ve got peeps that seem to like it a lot.  Any suggestions?</p>
]]></content:encoded>
			<wfw:commentRss>http://pbking.com/blog/?feed=rss2&amp;p=197</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://pbking.com/blog/?p=197</feedburner:origLink></item>
		<item>
		<title>Gold Nugget Fever and Dunbar’s Number</title>
		<link>http://feedproxy.google.com/~r/ThePeanutButterThoughts/~3/G3cQFVVmexE/</link>
		<comments>http://pbking.com/blog/?p=191#comments</comments>
		<pubDate>Fri, 30 Oct 2009 18:51:53 +0000</pubDate>
		<dc:creator>Jason Crist</dc:creator>
				<category><![CDATA[uncategorized]]></category>

		<guid isPermaLink="false">http://pbking.com/blog/?p=191</guid>
		<description><![CDATA[A couple of days ago I said farewell to social networks.  I removed my Facebook and Twitter accounts from Digsby and continued on my merry little way just bursting with productivity since I wasn&#8217;t spending any time staying updated.
I was slinging code left and right.  But then I kinda got stuck and needed [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://pbking.com/blog/wp-content/uploads/2009/10/6a00d8341c4e2e53ef00e54f2da1198834-800wi.jpg"><img class="alignleft size-medium wp-image-194" title="6a00d8341c4e2e53ef00e54f2da1198834-800wi" src="http://pbking.com/blog/wp-content/uploads/2009/10/6a00d8341c4e2e53ef00e54f2da1198834-800wi-300x245.jpg" alt="6a00d8341c4e2e53ef00e54f2da1198834-800wi" width="210" height="172" /></a>A couple of days ago I said farewell to social networks.  I removed my Facebook and Twitter accounts from Digsby and continued on my merry little way just bursting with productivity since I wasn&#8217;t spending any time staying updated.</p>
<p>I was slinging code left and right.  But then I kinda got stuck and needed a break.  It was an easy problem, I just need a short breather to let my brain figure it out.  So I went to <a href="http://www.google.com/reader/">Google Reader</a> like I always do.  But dang, I had already read all of the worth-reading blogs.  So I did the next-best thing.  <a href="http://fark.com">Fark</a>.</p>
<p>Ok, there&#8217;s really nothing GOOD about Fark other than it&#8217;s entertainment value.  There&#8217;s plenty there, but it&#8217;s kinda like sitting down to watch TV and just flipping through the channel.  Rarely do I enjoy it but it passes the time.</p>
<p>Well the next time I actually had something GOOD to read in my blog list I read <a href="http://sethgodin.typepad.com/seths_blog/2009/10/the-penalty-for-violating-dunbars-law.html">this article</a> from Seth Godin about Dunbar&#8217;s law.   I realized that one of the things that wasn&#8217;t working for me about social networking was that I was attempting to break that law and it just wasn&#8217;t working.  It never works.  <em>&#8220;Dunbar postulated that the typical human being can only have 150 friends. . .  After that, we just aren&#8217;t cognitively organized to handle and track new people easily.&#8221;</em> I actually think that my number is more like 20.  Maybe. Once I realized my mistake I decided to try again.</p>
<p>This time I installed a different Social app, <a href="http://www.tweetdeck.com/beta/">TweetDeck</a>.  It&#8217;s another fantastic Air app that I&#8217;m having a great experience with.  With TweetDeck I was able to filter my Facebook friends down into a manageable (and very small) list.  I get only a dozen or so Facebook updates a day from only those people that I actually care about.</p>
<p>Same thing with Twitter.  I was getting some REALLY great information from all of those flash guys I was following and I found that I was really missing that stuff.  So I just filtered my following list down.  I no longer feel obligated to follow EVERYTHING that comes in, but when I have a couple of minutes when my brain needs to work without me then I&#8217;ve got a few things to read.  I&#8217;m still sick of all the re-tweets and I wish that there was some &#8220;rating&#8221; mechanism that I could use to filter incoming tweets.  <a href="http://twitter.com/theFlashbum">@theFlashBum</a> I&#8217;m still on the fence about you.  You send me great stuff but there&#8217;s just so much . . . dirt . . . in with the nuggets.</p>
<p>But this whole process has gotten me thinking a lot about my communication.  I used to spend so much time thinking and preparing for blog entries (both personal and professional).  Perhaps you couldn&#8217;t tell, I&#8217;ve never been a fantastic writer.  But I&#8217;m gonna quit that.  I should be writing for myself anyway.  If others want to read it then fine.  I hope you get something good from it.  Or are at least entertained for a moment.  So look for a lot more (and less grammatically correct) posts to come.  This isn&#8217;t a New Year&#8217;s resolution, it&#8217;s one of those important ones that I&#8217;ll actually stick with.</p>
]]></content:encoded>
			<wfw:commentRss>http://pbking.com/blog/?feed=rss2&amp;p=191</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://pbking.com/blog/?p=191</feedburner:origLink></item>
		<item>
		<title>Panning for Gold – My Social Network Farewell</title>
		<link>http://feedproxy.google.com/~r/ThePeanutButterThoughts/~3/SxhIFZKRabY/</link>
		<comments>http://pbking.com/blog/?p=176#comments</comments>
		<pubDate>Fri, 23 Oct 2009 06:28:00 +0000</pubDate>
		<dc:creator>Jason Crist</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[social networks]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://pbking.com/blog/?p=176</guid>
		<description><![CDATA[I think I am over &#8220;social networks&#8221;.  I&#8217;ve just got to let things settle a little bit and let the world decide how things are going to connect before I start to care again.
I still love the idea of connecting people together, mashing all that relationship information together and doing some great things with it. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://pbking.com/blog/wp-content/uploads/2009/10/twitter_bird_dead.jpg"><img class="alignleft size-medium wp-image-183" title="TWEEee..." src="http://pbking.com/blog/wp-content/uploads/2009/10/twitter_bird_dead-300x161.jpg" alt="TWEEee..." width="126" height="68" /></a>I think I am over &#8220;social networks&#8221;.  I&#8217;ve just got to let things settle a little bit and let the world decide how things are going to connect before I start to care again.</p>
<p>I still love the idea of connecting people together, mashing all that relationship information together and doing some great things with it.  The power of &#8220;social&#8221; has certainly been shown.  The problem is I just haven&#8217;t found anything that is in a popular &#8220;social network&#8221; that has really changed my life for the better.</p>
<p>I just went through a very hardy attempt at using Twitter.  I honestly gave it a real go.  I tried a number of different apps and found one that fit my style (<a href="http://www.digsby.com/features.php" target="_blank">Digsby</a> really is an awesome piece of software even if you just use it to chat).  I tried to stay current with what people were tweeting about but I got burned out.  Staying updated became difficult.  Sifting through the mountain of tweets (and re-tweets, my goodness what&#8217;s with the RT&#8217;s!) became a daily chore.  It felt a lot like panning for gold.  Through my twitter feed I have discovered some fantastic nuggets of information.  Real pieces of gold that I might not have otherwise stumbled upon.  But the nuggets of usefulness were just outweighed by the mountain of things that I just didn&#8217;t care about.  I would end up with hundreds of unread tweets, give up and clear it out, and start all over again.</p>
<p>As a twitter user my overall productivity really suffered.  My level of productivity is really important to me; I&#8217;m a busy guy and while I love my job I do want to get it done and get out.  Same for the personal projects I choose to work on; I want to get as much done in the little time I have to work on them.  If I&#8217;m interrupted every few moments then I&#8217;m never getting in the groove.  And if I&#8217;m NOT paying attention then the messages pile up to an unmanageable level so I might as well ignore them.  Until I can get a &#8220;quality&#8221; filter I can set to 9 or 10 I just don&#8217;t have the bandwidth to consume all the tweets.</p>
<p>The same thing happened for me with Facebook.  I really do think many aspects of it are great and I&#8217;ve certainly spent some quality time all up in tha workin&#8217;s of it to understand that the possibilities of mashing up those connections are really powerful.  But there is just SO MUCH STUFF going on that I just can&#8217;t spend the time necessary to . . pan for gold.</p>
<p>Of course I&#8217;m not giving up on ALL social networks.  Any form of communication is still a social network.  You wanna call me? I&#8217;ll talk to you.  If I&#8217;m at <a href="http://pckeyboards.stores.yahoo.net/3153terminal.html">my keyboard</a> and you have a pointed topic you want to discuss with me then I&#8217;m here.  IM is definitely one of my favorite ways to communicate. I can type faster and often more pointedly then I can talk and the response is so much better than email.  Email will be a go for me too though until we&#8217;ve got a better solution (Wave is on the right track, looking forward to seeing how that grows and what it spawns).</p>
<p>And of course there are blogs.  There is SO much less gold-sifting when reading a blog.  If somebody takes the time to actually construct a meaningful message then I&#8217;ll be happy to read it and <a href="http://www.google.com/reader/public/atom/user%2F13145445999299722136%2Fstate%2Fcom.google%2Fbroadcast">share it</a> when I think it&#8217;s appropriate.  I also recently read a <a href="http://www.insideria.com/2009/10/what-i-dislike-about-social-ne.html">blog post from Tom Barker</a> who seems to share my feelings as well, though I think that I&#8217;ve given the whole thing a little more effort than he has.  But what he said about <a href="http://www.linkedin.com/in/pbking" target="_blank">LinkedIn </a>does seem to jive with what I&#8217;m looking for in a Social Network Relationship.  Not much in the way of commitment but I won&#8217;t have to go to the movies alone.  If you know me then hook up with me there.  Just don&#8217;t expect flowers.</p>
<p>Dang, I just noticed that I have 13 unread tweets.  That bugs the crap out of me, I feel obligated to go down there and see what those people have been up to since I started writing this.  Excuse me while I wreck my train of thought.</p>
<p>. . .</p>
<p>There was nothing important.  No gold and 2 minutes lost.  Add to that the 5 or so it will take me to get back into the swing of things.  Now where was I?  Right.  Quitting twitter.</p>
<p>So if you&#8217;re reading this and you happen to follow me on Twitter then don&#8217;t be surprised if you don&#8217;t see anything else from me.  Or if you&#8217;re my Facebook friend then I&#8217;m sorry if I don&#8217;t notice your status updates or provide meaningful conversation on your wall.  If you miss me then please don&#8217;t hesitate to hit me up on IM.  Or shoot, give me a call.  I&#8217;ll go out for a beer with you.  Or a corn dog.</p>
<p>Man, I&#8217;m hungry now.  Anyone up for some Waffle House?</p>
]]></content:encoded>
			<wfw:commentRss>http://pbking.com/blog/?feed=rss2&amp;p=176</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://pbking.com/blog/?p=176</feedburner:origLink></item>
		<item>
		<title>Tracing Bitmaps in AS3</title>
		<link>http://feedproxy.google.com/~r/ThePeanutButterThoughts/~3/xfJXeoiiu2M/</link>
		<comments>http://pbking.com/blog/?p=151#comments</comments>
		<pubDate>Fri, 18 Sep 2009 07:12:45 +0000</pubDate>
		<dc:creator>Jason Crist</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[polygons]]></category>

		<guid isPermaLink="false">http://pbking.com/blog/?p=151</guid>
		<description><![CDATA[Recently I was tasked with creating a tool so that a user could draw some polygons in a Flash tool.  It was for a map; simple polygons marked interact-able areas.  The tool that users were using was old and kludgy and just didn&#8217;t work very well.  Ok, easy enough.  I built [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I was tasked with creating a tool so that a user could draw some polygons in a Flash tool.  It was for a map; simple polygons marked interact-able areas.  The tool that users were using was old and kludgy and just didn&#8217;t work very well.  Ok, easy enough.  I built a simple polygon editor.</p>
<p>But in the application users will sometimes create HUNDREDS of polygons for a map.  The polygons are all traced over a bitmap that&#8217;s loaded and shown in the background of the editor.  For demonstration purposes lets say a bitmap to be traced looks like this:</p>
<p><a href="http://pbking.com/blog/wp-content/uploads/2009/09/redface.png"><img class="aligncenter size-medium wp-image-152" title="Ok, probably not like this.  But I'm just trying to demonstrate a proof-of-concept here." src="http://pbking.com/blog/wp-content/uploads/2009/09/redface-300x300.png" alt="redface" width="300" height="300" /></a>While a tool letting a user click on each corner defining the points on the polygon works, that could become tedious work creating and adjusting hundreds of polygons with many potential points for each one.  Wouldn&#8217;t it be a lot easier if the user could just click on the polygon in the bitmap and let the application figure out where the points are?  (<a href="http://pbking.com/blog/wp-content/uploads/2009/09/polyExample/index.html">Click here to see that proof-of-concept in action.</a>)</p>
<p>Our users sure thought so.  So here&#8217;s how I went about doing that in ActionScript:</p>
<p><span id="more-151"></span>To begin I listen for a mouse click so I know where to begin. When that click happens I have to grab the BitmapData of the image that I&#8217;m working with.  Then I can really get started!</p>
<div class="dean_ch" style="white-space: nowrap;">
<span class="kw3">private</span> <span class="kw2">function</span> onMouseClick<span class="br0">&#40;</span><span class="kw3">e</span>:MouseEvent<span class="br0">&#41;</span>:<span class="kw3">void</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="kw2">var</span> point:Point = <span class="kw2">new</span> Point<span class="br0">&#40;</span><span class="kw3">e</span>.<span class="me1">localX</span>, <span class="kw3">e</span>.<span class="me1">localY</span><span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw2">var</span> bmd:BitmapData = Bitmap<span class="br0">&#40;</span>_backgroundImage.<span class="me1">content</span><span class="br0">&#41;</span>.<span class="me1">bitmapData</span>;<br />
&nbsp; <span class="kw2">var</span> p:Polygon = traceBitmap<span class="br0">&#40;</span>point, bmd<span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span></div>
<p><br/></p>
<p>It may be important to know exactly what I&#8217;m trying to build here and that&#8217;s an instance of a Polygon class.  This is just a very simple class with a property that is a collection of points.  These points are used to draw the polygons in a renderer (not mentioned here) with graphics.moveTo(), .lineTo() methods.</p>
<div class="dean_ch" style="white-space: nowrap;">
package com.<span class="me1">pbking</span>.<span class="me1">polygon</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="kw3">import</span> flash.<span class="me1">geom</span>.<span class="me1">Point</span>;<br />
&nbsp; <span class="kw3">import</span> mx.<span class="me1">collections</span>.<span class="me1">ArrayCollection</span>;<br />
&nbsp; <span class="kw3">public</span> <span class="kw2">class</span> Polygon<br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">var</span> points:ArrayCollection = <span class="kw2">new</span> ArrayCollection<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">function</span> Polygon<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw3">super</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
<p><br/></p>
<p>There are a lot of customizations in my production class that I&#8217;m not including here (optimizations for angle/color tolerance, etc).  I&#8217;m going to do my best to keep the code simple to illustrate the concept.  To begin I setup a few variables that I&#8217;ll be needing to use.</p>
<div class="dean_ch" style="white-space: nowrap;">
<span class="kw3">public</span> <span class="kw3">static</span> <span class="kw2">function</span> traceBitmap<span class="br0">&#40;</span>origin:Point, bitmapData:BitmapData<span class="br0">&#41;</span>:Polygon<br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="co1">//this is what we&#8217;re creating</span><br />
&nbsp; <span class="kw2">var</span> poly:Polygon = <span class="kw2">new</span> Polygon<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; <span class="co1">//but while we&#8217;re building it we&#8217;ll keep all the points in here.</span><br />
&nbsp; <span class="kw2">var</span> edgePoints:<span class="kw3">Array</span> = <span class="br0">&#91;</span><span class="br0">&#93;</span>;<br />
&nbsp; <br />
&nbsp; <span class="co1">//find the color the user clicked on</span><br />
&nbsp; <span class="co1">//we&#8217;ll use that in our comparisons</span><br />
&nbsp; <span class="kw2">var</span> clickColor:uint = bmd.<span class="me1">getPixel</span><span class="br0">&#40;</span>origin.<span class="me1">x</span>, origin.<span class="me1">y</span><span class="br0">&#41;</span>;<br />
&nbsp; <br />
&nbsp; <span class="co1">//once we trace around and get back to the start we&#8217;ll set this to true</span><br />
&nbsp; <span class="kw2">var</span> loopComplete:<span class="kw3">Boolean</span> = <span class="kw2">false</span>;<br />
&nbsp; <br />
&nbsp; <span class="co1">//to stop us from going into an internal loop</span><br />
&nbsp; <span class="kw2">var</span> maxIterations = <span class="nu0">10000</span>;<br />
&nbsp; <span class="kw2">var</span> iterations:uint = <span class="nu0">0</span>;<br />
&nbsp; <br />
&nbsp; <span class="co1">//iterating variables we&#8217;ll use in our loopings</span><br />
&nbsp; <span class="kw2">var</span> direction:<span class="kw3">int</span>;<br />
&nbsp; <span class="kw2">var</span> p:Point;<br />
&nbsp; <span class="kw2">var</span> i:<span class="kw3">int</span>;<br />
&nbsp; <span class="kw2">var</span> nextColors:<span class="kw3">Array</span> = <span class="br0">&#91;</span><span class="br0">&#93;</span>;<br />
&nbsp;</div>
<p><br/></p>
<p>Next I need to figure out where to start.  Beginning from the point where the user clicked I work my way up pixel by pixel until the color changes.  The last pixel that was the same as where the user clicked is where I&#8217;ll call my starting point.</p>
<div class="dean_ch" style="white-space: nowrap;">
&nbsp; <span class="co1">//move up until I hit the top</span><br />
&nbsp; <span class="co1">//this will be my starting point</span><br />
&nbsp; p = origin;<br />
&nbsp; <span class="kw1">while</span><span class="br0">&#40;</span>clickColor == bmd.<span class="me1">getPixel</span><span class="br0">&#40;</span>p.<span class="me1">x</span>, p.<span class="me1">y</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; p.<span class="me1">y</span>&#8211;;<br />
&nbsp; p.<span class="me1">y</span>++;</p>
<p>&nbsp; <span class="kw2">var</span> <span class="kw3">start</span>:Point = p.<span class="me1">clone</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; <span class="co1">//this starting point will be the first one in my array of edge points</span><br />
&nbsp; edgePoints.<span class="kw3">push</span><span class="br0">&#40;</span><span class="kw3">start</span><span class="br0">&#41;</span>;<br />
&nbsp;</div>
<p><br/></p>
<p>Now I&#8217;m need to begin moving in some direction to follow the edge of the polygon and add all of the points along this edge.  I&#8217;m using numbers to represent directions. My direction value is where I just CAME from.  This is used to prevent me from backtracking along the polygon or just turning and moving INTO it without following the edge.  X is the current point and the other numbers represent some direction.</p>
<div class="dean_ch" style="white-space: nowrap;">
&nbsp; <span class="co1">// 5 6 7</span><br />
&nbsp; <span class="co1">// 4 X 0</span><br />
&nbsp; <span class="co1">// 3 2 1</span><br />
&nbsp; direction = <span class="nu0">6</span>;<br />
&nbsp;</div>
<p>now walk around the edge adding all the points I come across</p>
<div class="dean_ch" style="white-space: nowrap;">
&nbsp; <span class="kw1">while</span><span class="br0">&#40;</span>!loopComplete<span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="co1">//we have to cut this off at some point.</span><br />
&nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>iterations++ &gt; maxIterations<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw3">throw</span> <span class="kw2">new</span> <span class="kw3">Error</span><span class="br0">&#40;</span><span class="st0">&quot;Exceeded maximum move iterations.&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co1">//grab the pixels in all 8 directions from where we are</span><br />
&nbsp; &nbsp; nextColors<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> = <span class="kw2">new</span> PixelTracker<span class="br0">&#40;</span>p.<span class="me1">x</span> + <span class="nu0">1</span>, p.<span class="me1">y</span>, bmd<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; nextColors<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span> = <span class="kw2">new</span> PixelTracker<span class="br0">&#40;</span>p.<span class="me1">x</span> + <span class="nu0">1</span>, p.<span class="me1">y</span> + <span class="nu0">1</span>, bmd<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; nextColors<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span> = <span class="kw2">new</span> PixelTracker<span class="br0">&#40;</span>p.<span class="me1">x</span>, p.<span class="me1">y</span> + <span class="nu0">1</span>, bmd<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; nextColors<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span> = <span class="kw2">new</span> PixelTracker<span class="br0">&#40;</span>p.<span class="me1">x</span> &#8211; <span class="nu0">1</span>, p.<span class="me1">y</span> + <span class="nu0">1</span>, bmd<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; nextColors<span class="br0">&#91;</span><span class="nu0">4</span><span class="br0">&#93;</span> = <span class="kw2">new</span> PixelTracker<span class="br0">&#40;</span>p.<span class="me1">x</span> &#8211; <span class="nu0">1</span>, p.<span class="me1">y</span>, bmd<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; nextColors<span class="br0">&#91;</span><span class="nu0">5</span><span class="br0">&#93;</span> = <span class="kw2">new</span> PixelTracker<span class="br0">&#40;</span>p.<span class="me1">x</span> &#8211; <span class="nu0">1</span>, p.<span class="me1">y</span> &#8211; <span class="nu0">1</span>, bmd<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; nextColors<span class="br0">&#91;</span><span class="nu0">6</span><span class="br0">&#93;</span> = <span class="kw2">new</span> PixelTracker<span class="br0">&#40;</span>p.<span class="me1">x</span>, p.<span class="me1">y</span> &#8211; <span class="nu0">1</span>, bmd<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; nextColors<span class="br0">&#91;</span><span class="nu0">7</span><span class="br0">&#93;</span> = <span class="kw2">new</span> PixelTracker<span class="br0">&#40;</span>p.<span class="me1">x</span> + <span class="nu0">1</span>, p.<span class="me1">y</span> &#8211; <span class="nu0">1</span>, bmd<span class="br0">&#41;</span>;<br />
&nbsp;</div>
<p><br/></p>
<p>That PixelTracker class there is just a little helper class to keep track of the pixel point and its color.</p>
<div class="dean_ch" style="white-space: nowrap;">
<span class="kw3">import</span> flash.<span class="me1">geom</span>.<span class="me1">Point</span>;<br />
<span class="kw3">import</span> flash.<span class="me1">display</span>.<span class="me1">BitmapData</span>;</p>
<p><span class="kw2">class</span> PixelTracker<br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="kw3">public</span> <span class="kw2">var</span> point:Point;<br />
&nbsp; <span class="kw3">public</span> <span class="kw2">var</span> <span class="kw3">color</span>:uint;<br />
&nbsp; <br />
&nbsp; <span class="kw2">function</span> PixelTracker<span class="br0">&#40;</span>x:<span class="kw3">int</span>, y:<span class="kw3">int</span>, bmd:BitmapData<span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw3">this</span>.<span class="me1">point</span> = <span class="kw2">new</span> Point<span class="br0">&#40;</span>x, y<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw3">this</span>.<span class="kw3">color</span> = bmd.<span class="me1">getPixel</span><span class="br0">&#40;</span>point.<span class="me1">x</span>, point.<span class="me1">y</span><span class="br0">&#41;</span>;<br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
<p><br/></p>
<p>Now we don&#8217;t always want to start at 0 in our nextColors array.  Where we start looking for the next pixel depends on what direction we previously traveled in.  For instance if we were travelling in direction 4 (from the left) then we want to start looking at 5 (up and left).  This next code shifts that array and also drops the direction we came in since we won&#8217;t want to go back that way.</p>
<div class="dean_ch" style="white-space: nowrap;">
&nbsp; &nbsp; <span class="co1">//shift the array so that we start on the pixel AFTER the one we came from</span><br />
&nbsp; &nbsp; <span class="co1">//dropping that previous pixel so we don&#8217;t go back that way</span><br />
&nbsp; &nbsp; <span class="kw1">for</span><span class="br0">&#40;</span>i=<span class="nu0">0</span>; i&lt;direction; i++<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; nextColors.<span class="kw3">push</span><span class="br0">&#40;</span>nextColors.<span class="me1">shift</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; nextColors.<span class="me1">shift</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp;</div>
<p><br/></p>
<p>Now we look for the first pixel that matches our click color.  We&#8217;re testing going clockwise since that is how we are traversing the polygon.</p>
<div class="dean_ch" style="white-space: nowrap;">
&nbsp; &nbsp; <span class="kw2">var</span> foundPix:<span class="kw3">Boolean</span> = <span class="kw2">false</span>;</p>
<p>&nbsp; &nbsp; <span class="kw1">for</span><span class="br0">&#40;</span>i=<span class="nu0">0</span>; i&lt;nextColors.<span class="kw3">length</span>; i++<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw2">var</span> pt:PixelTracker = PixelTracker<span class="br0">&#40;</span>nextColors<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>pt.<span class="kw3">color</span> == clickColor<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; foundPix = <span class="kw2">true</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//set the direction we moved in</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; direction = direction + i + <span class="nu0">5</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//ensure that it is a value between 0 and 7</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span><span class="br0">&#40;</span>direction &gt; <span class="nu0">7</span><span class="br0">&#41;</span> direction = direction &#8211; <span class="nu0">8</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span><span class="br0">&#40;</span>direction &lt; <span class="nu0">0</span><span class="br0">&#41;</span> direction = direction + <span class="nu0">8</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//figure out if we made it back to the start and are done</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>pt.<span class="me1">point</span>.<span class="me1">x</span> == <span class="kw3">start</span>.<span class="me1">x</span> &amp;&amp; pt.<span class="me1">point</span>.<span class="me1">y</span> == <span class="kw3">start</span>.<span class="me1">y</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; loopComplete = <span class="kw2">true</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//or if we should just add the point and keep on going</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; edgePoints.<span class="kw3">push</span><span class="br0">&#40;</span>pt.<span class="me1">point</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//now our current point is the one we decided to move to</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; p = pt.<span class="me1">point</span>.<span class="me1">clone</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span>;<br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp;</div>
<p><br/></p>
<p>If at this point you just couldn&#8217;t figure out where to go . . . well crap.  That sucks.  I&#8217;ve got some recursive optimizations in my class that help me get out of those situations but to keep this as simple as I can I&#8217;m just going to suggest throwing an error.</p>
<div class="dean_ch" style="white-space: nowrap;">
&nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>!foundPix<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw3">throw</span> <span class="kw2">new</span> <span class="kw3">Error</span><span class="br0">&#40;</span><span class="st0">&quot;found a dead end&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; <span class="br0">&#125;</span><br />
&nbsp;</div>
<p><br/></p>
<p>And with that you&#8217;re done finding the edges!  You should have a big &#8216;ol honkin&#8217; array of points representing the edge of your polygon.  Which, really is a polygon right?  Just with many many many sides.  Lets filter those points down to the bare minimum we need.</p>
<div class="dean_ch" style="white-space: nowrap;">
&nbsp; <span class="co1">//we&#8217;ll loop through this &#8217;till it can&#8217;t be filtered down any more</span><br />
&nbsp; <span class="co1">//it will probably take quite a few passes</span><br />
&nbsp; <span class="kw2">var</span> eliminatedPoints:<span class="kw3">Boolean</span> = <span class="kw2">true</span>;<br />
&nbsp; <span class="kw2">var</span> angleTolerance:<span class="kw3">Number</span> = .<span class="nu0">5</span>;</p>
<p>&nbsp; <span class="kw1">while</span><span class="br0">&#40;</span>eliminatedPoints<span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; eliminatedPoints = <span class="kw2">false</span>;<br />
&nbsp; &nbsp; <span class="kw1">for</span><span class="br0">&#40;</span>i=<span class="nu0">0</span>; i&lt;edgePoints.<span class="me1">length</span><span class="nu0">-2</span>; i++<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="co1">//loop through the points and grab three at a time</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw2">var</span> a:Point = edgePoints<span class="br0">&#91;</span>i<span class="br0">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; <span class="kw2">var</span> b:Point = edgePoints<span class="br0">&#91;</span>i<span class="nu0">+1</span><span class="br0">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; <span class="kw2">var</span> c:Point = edgePoints<span class="br0">&#91;</span>i<span class="nu0">+2</span><span class="br0">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span class="co1">//compair the distance from a to c to the distaces of a to b + b to c</span><br />
&nbsp; &nbsp; &nbsp; <span class="co1">//if it&#8217;s (roughly) the same then it&#8217;s a straight line and </span><br />
&nbsp; &nbsp; &nbsp; <span class="co1">//the middle point can be removed</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw2">var</span> delta:<span class="kw3">Number</span> = <span class="kw3">Math</span>.<span class="kw3">abs</span><span class="br0">&#40;</span>Point.<span class="me1">distance</span><span class="br0">&#40;</span>a, c<span class="br0">&#41;</span> &#8211; <span class="br0">&#40;</span>Point.<span class="me1">distance</span><span class="br0">&#40;</span>a, b<span class="br0">&#41;</span> + Point.<span class="me1">distance</span><span class="br0">&#40;</span>b, c<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>delta &lt; angleTolerance<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; edgePoints.<span class="kw3">splice</span><span class="br0">&#40;</span>i<span class="nu0">+1</span>, <span class="nu0">1</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; eliminatedPoints = <span class="kw2">true</span>;<br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co1">//cycle point from front to back so it has a chance to be calculated</span><br />
&nbsp; &nbsp; edgePoints.<span class="kw3">push</span><span class="br0">&#40;</span>edgePoints.<span class="me1">shift</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; <span class="br0">&#125;</span></div>
<p><br/></p>
<p>Then all I have to do is move the points into the polygon and return it!</p>
<div class="dean_ch" style="white-space: nowrap;">
&nbsp; poly.<span class="me1">points</span> = <span class="kw2">new</span> ArrayCollection<span class="br0">&#40;</span>edgePoints<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">return</span> poly;<br />
<span class="br0">&#125;</span></div>
<p><br/></p>
<p>So that seemed like an awful lot of typing, but I hope it might have demystified how polygon bitmap tracing might go down.  If anyone reading this is aware of an easier way of doing this (I&#8217;ll be a little ill if I find that the language has this functionally built in and I just couldn&#8217;t find it) or has any questions then please feel free to comment!</p>
]]></content:encoded>
			<wfw:commentRss>http://pbking.com/blog/?feed=rss2&amp;p=151</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://pbking.com/blog/?p=151</feedburner:origLink></item>
		<item>
		<title>A more controlled way to travel a collection: IViewCursor</title>
		<link>http://feedproxy.google.com/~r/ThePeanutButterThoughts/~3/_BU375OtH2g/</link>
		<comments>http://pbking.com/blog/?p=139#comments</comments>
		<pubDate>Thu, 17 Sep 2009 00:27:14 +0000</pubDate>
		<dc:creator>Jason Crist</dc:creator>
				<category><![CDATA[flex]]></category>
		<category><![CDATA[collections]]></category>

		<guid isPermaLink="false">http://pbking.com/blog/?p=139</guid>
		<description><![CDATA[I recently had to convert a very processor intensive command I had been working on into a psudo-threaded command (using my Command Framework).  It had been a while since I did and I had forgotten a few of the tricks that make it easy to work with so I&#8217;m putting them down so I don&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had to convert a very processor intensive command I had been working on into a psudo-threaded command (using my <a href="http://code.google.com/p/pbutils/">Command Framework</a>).  It had been a while since I did and I had forgotten a few of the tricks that make it easy to work with so I&#8217;m putting them down so I don&#8217;t forget.</p>
<p>Generally when I create a <a href="http://pbutils.googlecode.com/svn/trunk/pbcommands/build/doc/com/pbking/app/command/ThreadedCommand.html">threaded command</a> I&#8217;m working with a large pile of data.  The threaded command works by calling handleRun() every frame (or every two or three frames, depending on how high a priority the command is).  You can&#8217;t just rip through all of the data elements; that kind of defeats the purpose of breaking it up into a psudo-thread.  Additionally the command I&#8217;ve built will attempt to optimize the number of elements you process in each run if you give it a little hand.  You could just keep an index of where you&#8217;re at in the array and increment that.  That&#8217;s small and tidy, doesn&#8217;t require an (often bulky) <a href="http://livedocs.adobe.com/flex/3/langref/mx/collections/ICollectionView.html">ICollectionView</a> and I really recommend doing that if you can.  But sometimes you need to do a little more while you&#8217;re running through your data.</p>
<p>To do that you could use a <a href="http://livedocs.adobe.com/flex/3/langref/mx/collections/IViewCursor.html">IViewCursor</a>.  The collection view cursor is a very handy tool that I forget to use more often than I should.  I certainly don&#8217;t utilize its full potential in this example but it does do a good job of keeping track of things for me.</p>
<p><span id="more-139"></span>Let&#8217;s say you start off with an XMLList pulled from some XML.  We need to work instead on an XMLListCollection so make sure to create one of those.  (Likewise you would need to use an ArrayCollection rather than an Array, remember we must work with the ICollectionView.)  Then just create a view cursor from that collection with the <b>createCursor()</b> method.</p>
<div class="dean_ch" style="white-space: nowrap;">
<span class="kw2">var</span> xmlList:XMLList = myXml.<span class="me1">node</span>..<span class="me1">items</span>;<br />
<span class="kw2">var</span> collection:XMLListCollection = <span class="kw2">new</span> XMLListCollection<span class="br0">&#40;</span>xmlList<span class="br0">&#41;</span>;<br />
<span class="kw2">var</span> cursor:IViewCursor = collection.<span class="me1">createCursor</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp;</div>
<p>Now instead of getting an element from your collection like this: <b>element = collection[i];</b> you can instead grab it from your cursor like this: <b>element = cursor.current;</b> and use the methods on the cursor to move through (and modify) the collection. </p>
<p>Here is a very brief example of how I use it in a ThreadedCommand.</p>
<div class="dean_ch" style="white-space: nowrap;">
package com.<span class="me1">pbking</span>.<span class="me1">application</span>.<span class="me1">commands</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="kw3">import</span> com.<span class="me1">ender</span>.<span class="me1">threads</span>.<span class="me1">Thread</span>;<br />
&nbsp; <span class="kw3">import</span> com.<span class="me1">pbking</span>.<span class="me1">app</span>.<span class="me1">command</span>.<span class="me1">ThreadedCommand</span>;<br />
&nbsp; <span class="kw3">import</span> mx.<span class="me1">collections</span>.<span class="me1">IViewCursor</span>;<br />
&nbsp; <span class="kw3">import</span> mx.<span class="me1">collections</span>.<span class="me1">XMLListCollection</span>;</p>
<p>&nbsp; <span class="kw3">public</span> <span class="kw2">class</span> ParseClientData <span class="kw3">extends</span> ThreadedCommand<br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw3">private</span> <span class="kw2">var</span> <span class="kw3">data</span>:<span class="kw3">XML</span>;<br />
&nbsp; &nbsp; <span class="kw3">private</span> <span class="kw2">var</span> seatsToProcess:XMLListCollection;<br />
&nbsp; &nbsp; <span class="kw3">private</span> <span class="kw2">var</span> cursor:IViewCursor;</p>
<p>&nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">function</span> ParseClientData<span class="br0">&#40;</span><span class="kw3">data</span>:<span class="kw3">XML</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw3">super</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span class="kw3">this</span>.<span class="kw3">data</span> = <span class="kw3">data</span>;<br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span class="co1">//I&#8217;m not doing anything else while this is going on </span><br />
&nbsp; &nbsp; &nbsp; <span class="co1">//so I&#8217;m setting it to URGENT PRIORITY so that it</span><br />
&nbsp; &nbsp; &nbsp; <span class="co1">//runs every frame.</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw3">this</span>.<span class="me1">priority</span> = Thread.<span class="me1">URGENT_PRIORITY</span>;</p>
<p>&nbsp; &nbsp; &nbsp; <span class="co1">//this will calculate the optimum number of iterations</span><br />
&nbsp; &nbsp; &nbsp; <span class="co1">//that should be made in a single run (starting with 2 per run)</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw3">this</span>.<span class="me1">autoOptimizeIterations</span> = <span class="kw2">true</span>;<br />
&nbsp; &nbsp; &nbsp; <span class="kw3">this</span>.<span class="me1">iterationsPerRun</span> = <span class="nu0">2</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; override protected <span class="kw2">function</span> handleExecution<span class="br0">&#40;</span><span class="br0">&#41;</span>:<span class="kw3">void</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="co1">//handle execution is called once before any runs</span><br />
&nbsp; &nbsp; &nbsp; <span class="co1">//create my collection from my data and a cursor from that collection</span><br />
&nbsp; &nbsp; &nbsp; seatsToProcess = <span class="kw2">new</span> XMLListCollection<span class="br0">&#40;</span><span class="kw3">data</span>.<span class="me1">clientDataXML</span>..<span class="me1">seat</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; cursor = seatsToProcess.<span class="me1">createCursor</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span class="co1">//the first run will start in the super handler</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw3">super</span>.<span class="me1">handleExecution</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; override protected <span class="kw2">function</span> handleRun<span class="br0">&#40;</span><span class="br0">&#41;</span>:<span class="kw3">void</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw2">var</span> infoX:<span class="kw3">XML</span>;</p>
<p>&nbsp; &nbsp; &nbsp; <span class="co1">//checking to see if I have made as many passes as I should (iterationCount vs iterationsPerRun</span><br />
&nbsp; &nbsp; &nbsp; <span class="co1">//or if I have moved past the end of the collection (cursor.afterLast)&nbsp; &nbsp; &nbsp; </span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">while</span><span class="br0">&#40;</span>iterationCount &lt; iterationsPerRun &amp;&amp; !cursor.<span class="me1">afterLast</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//pull the current node from my cursor</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//I&#8217;ll move the cursor on at the end of this while loop</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; infoX = cursor.<span class="me1">current</span> as <span class="kw3">XML</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//do all of my magic processing on the infoX object.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//processing each of these takes a while; that&#8217;s why it&#8217;s</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//in a psudo-thread.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//the benefit of using a cursor here instead of a recorded index</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//is that now I can add/subtract things from my collection</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//(either here or elsewhere) and the code can still handle that</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//this next value helps the optimizer (in the parent ThreadedCommand class)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//know how many elements were processed and will automatically</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//adjust the iterationsPerRun based on how long the run took</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//and the desired amount of time per run</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; iterationCount++;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// This moves the cursor to the next element.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// cursor.current has now advanced to the next element</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// and if we&#8217;ve gone past the end then cursor.afterLast is true</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; cursor.<span class="me1">moveNext</span><span class="br0">&#40;</span><span class="br0">&#41;</span>; <br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>cursor.<span class="me1">afterLast</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//all done; wrap up the command</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; onComplete<span class="br0">&#40;</span><span class="br0">&#41;</span>; &nbsp;<br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//yeield the command. We&#8217;ll come back and finish up later</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//with another call to run()</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; yield<span class="br0">&#40;</span><span class="br0">&#41;</span>; <br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://pbking.com/blog/?feed=rss2&amp;p=139</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://pbking.com/blog/?p=139</feedburner:origLink></item>
		<item>
		<title>Flex in the Cloud</title>
		<link>http://feedproxy.google.com/~r/ThePeanutButterThoughts/~3/i5NwaoqJbog/</link>
		<comments>http://pbking.com/blog/?p=134#comments</comments>
		<pubDate>Wed, 26 Aug 2009 19:08:07 +0000</pubDate>
		<dc:creator>Jason Crist</dc:creator>
				<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://pbking.com/blog/?p=134</guid>
		<description><![CDATA[Cloud computing is really starting to come into its own.  Technologies like Amazon&#8217;s EC3 and Google&#8217;s App Engine make the barrier of entry very low for developers to create scaleable applications and not concern themselves with the details of hardware and operating systems.
I&#8217;ve started playing around with getting a Flex application running on Google&#8217;s App [...]]]></description>
			<content:encoded><![CDATA[<p>Cloud computing is really starting to come into its own.  Technologies like Amazon&#8217;s EC3 and Google&#8217;s App Engine make the barrier of entry very low for developers to create scaleable applications and not concern themselves with the details of hardware and operating systems.</p>
<p>I&#8217;ve started playing around with getting a Flex application running on Google&#8217;s App engine and it&#8217;s pretty exciting. Murat Yener wrote up a very helpful pair of tutorials on <a href="http://java.dzone.com/articles/flex-meets-google-app-engine" target="_blank">getting simple XML messaging</a> and <a href="http://java.dzone.com/articles/flex-remoting-google-app">BlazeDS to work with Google App Engine</a> that helped me to get going.  I got the XML stuff working without a hitch but there still seems to be some problems getting Blaze to integrate smoothly.  There is a patch but even with that I was unable to get it working remotely.  Things worked fine in my development environment but just not in the cloud.</p>
<p>Sekhar Ravinutala also has a very nice walkthrough of <a href="http://blog.allurefx.com/2009/05/cloud-to-ria-accessing-google-app.html">getting GAE to work with GraniteDS</a>.  I&#8217;m much more familar with Blaze personally so I&#8217;ll have some learning to do to work with GraniteDS.  But this solution worked RIGHT out of the box.  No problems (other than my own silly mistakes).  Thanks a bunch Sekhar!  I&#8217;ll probably be using this setup moving forward (unless BlazeDS comes together soon).</p>
<p>We also have Mark Piller from MidnightCoders at the <a href="http://www.gotoandstop.org/?p=97">Phoenix FlashPlatform User Group</a> tonight.  I&#8217;m looking forward to discussing the benefits of using their tool, WebORB in the GAE cloud.  I understand that there is at least a patch to get it working on GAE.</p>
<p>And today I noticed that <a href="http://cornelcreanga.com/2009/08/blazeds-and-livecycle-data-services-in-the-cloud-max-laboratory/">Cornel Creanga and collegues are hosting a lab at Max</a> about deploying BlazeDS and LCDS in both EC2 and GAE. Not yet sure if I&#8217;m making it to Max this year but if I do I hope to make that part of my agenda!</p>
<p>I also wanted to note that when I started this research I was looking into the <a href="http://gaeswf.appspot.com/">GAE SWF Project</a>.  I gotta say, THAT sure did make things confusing for me.  I really don&#8217;t see what benefit you would have using this library . . .  If somebody understands the benefits then please fill me in.  It looks like the project is dead; the latest update is pretty old.</p>
<p>I&#8217;m looking forward to building on this platform!</p>
]]></content:encoded>
			<wfw:commentRss>http://pbking.com/blog/?feed=rss2&amp;p=134</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://pbking.com/blog/?p=134</feedburner:origLink></item>
		<item>
		<title>Peanut Butter Utilities on Google Code</title>
		<link>http://feedproxy.google.com/~r/ThePeanutButterThoughts/~3/wA8yny3A6ME/</link>
		<comments>http://pbking.com/blog/?p=125#comments</comments>
		<pubDate>Tue, 18 Aug 2009 18:20:24 +0000</pubDate>
		<dc:creator>Jason Crist</dc:creator>
				<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://pbking.com/blog/?p=125</guid>
		<description><![CDATA[A little while ago I made a post about the logging framework that I made/use.  I put the code on my own SVN server in case anybody wanted it.  But it was kind of a pain in the butt to manage there.  I wanted to get the command framework out as well so I&#8217;ve posted [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://code.google.com/p/pbutils/"><img class="alignleft size-full wp-image-127" src="http://pbking.com/blog/wp-content/uploads/2009/08/pbugrab.PNG" alt="pbugrab" width="115" height="123" /></a>A little while ago I made a post about the logging framework that I made/use.  I put the code on my own SVN server in case anybody wanted it.  But it was kind of a pain in the butt to manage there.  I wanted to get the command framework out as well so I&#8217;ve posted both projects (as one) on google code as the <a href="http://code.google.com/p/pbutils/">Peanut Butter Utilities</a>.</p>
<p>The logging framework is similar to Flex&#8217;s but can be used in Flash. <a href="http://pbutils.googlecode.com/svn/trunk/pblogger/build/doc/index.html"> Documentation</a> and <a href="http://code.google.com/p/pbutils/wiki/pblogger_examples">instructions</a> can be found on the project&#8217;s site.</p>
<p>The command framework is pretty simple but it allows for undoable commands, syncrynous/asyncranous commands, composite commands and even psudo-threaded commands.  It&#8217;s all pretty simple but it&#8217;s an effort to make my project code (my bread and butter) as sparse and easy to understand as possible.  Calling this a &#8220;framework&#8221; is stretching it a little far really.  It&#8217;s just a collection of command utilities that I find makes my code easier to write, understand and upkeep.</p>
<p><a href="http://pbutils.googlecode.com/svn/trunk/pbcommands/build/doc/index.html">Documentation</a> is available now  and some examples will probably make their way onto this blog at some point in the future.</p>
<p>I hope some people find these tools helpful.  If you find a problem with any of them or are looking for a little something extra that you think might belong in one of those libraries then please don&#8217;t hesitate to let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://pbking.com/blog/?feed=rss2&amp;p=125</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://pbking.com/blog/?p=125</feedburner:origLink></item>
		<item>
		<title>Serving HTML from SVN</title>
		<link>http://feedproxy.google.com/~r/ThePeanutButterThoughts/~3/-D0CKba_UEQ/</link>
		<comments>http://pbking.com/blog/?p=109#comments</comments>
		<pubDate>Fri, 14 Aug 2009 15:43:19 +0000</pubDate>
		<dc:creator>Jason Crist</dc:creator>
				<category><![CDATA[uncategorized]]></category>

		<guid isPermaLink="false">http://pbking.com/blog/?p=109</guid>
		<description><![CDATA[This is one of those posts that&#8217;s a little embarrassing to write.  Just a little bit.  Once I figured it out I kind of think it&#8217;s one of those things that a lot of people probably know about.  But I didn&#8217;t and I never found any instructions so I&#8217;m putting them here [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-117" title="htmlclip" src="http://pbking.com/blog/wp-content/uploads/2009/08/htmlclip1.PNG" alt="htmlclip" width="86" height="104" />This is one of those posts that&#8217;s a little embarrassing to write.  Just a little bit.  Once I figured it out I kind of think it&#8217;s one of those things that a lot of people probably know about.  But I didn&#8217;t and I never found any instructions so I&#8217;m putting them here in case somebody else can benefit.</p>
<p>I recently setup a <a href="http://code.google.com/p/pbutils/">project on Google Code</a> (more on that later) that uses SVN to host the project files.  I wanted to be able to easily host and update my project&#8217;s documentation so keeping that in SVN and serving that straight from there seemed optimal.  Previously I had always made a spot on this server for my generated AS3 documentation.  For that I had to generate it and then upload it here.  Not exactly HARD but sometimes I would change the code and updating the documentation just seemed like a step I didn&#8217;t want to bother with.  Plus, I see documentation the same as a binary.  It&#8217;s a direct result of the project code.</p>
<p><span id="more-109"></span>So I added the documentation straight into my build script and now my /build folder has the binary (.swc) and a /doc folder with the generated documentation.  Run build; commit.  Done.  Easy.  Except it looks like poo because SVN serves up the files as text files.  Good if you want to browse HTML files in an SVN server to see what&#8217;s in &#8216;em.  But bad if you want to actually USE those HTML files.</p>
<p style="text-align: center;"><a href="http://pbking.com/blog/wp-content/uploads/2009/08/rawhtml1.png"><img class="aligncenter size-full wp-image-120" title="rawhtml" src="http://pbking.com/blog/wp-content/uploads/2009/08/rawhtml1.png" alt="rawhtml" width="560" height="452" /></a></p>
<p>To fix this I set the<a href="http://svnbook.red-bean.com/en/1.2/svn.advanced.props.html"> svn mime-type property</a> on all of the files in the /doc folder (except for the images).  I found <a href="http://tortoisesvn.tigris.org/">Tortise </a>a much better tool for this then <a href="http://subclipse.tigris.org/">subclipse </a>in Eclipse.  I just right-clicked on the top doc folder and added a property; selecting svn:mime-type and typing &#8220;text/html&#8221;.  I checked &#8220;Apply property recursively&#8221; to just apply it to ALL files and then I reverted the changes to the graphics files before I committed.</p>
<p><a rel="attachment wp-att-111" href="http://pbking.com/blog/?attachment_id=111"><img class="aligncenter size-full wp-image-111" title="svn properties" src="http://pbking.com/blog/wp-content/uploads/2009/08/svnprops.PNG" alt="svn properties" width="346" height="309" /></a></p>
<p>Also make sure that your .css files are set to &#8220;text/css&#8221; otherwise your pages won&#8217;t use the CSS files in chrome or FireFox.  I committed those changes and boom.  Servin&#8217; my projects <a href="http://pbutils.googlecode.com/svn/trunk/pblogger/build/doc/pblogger/index.html">generated html docs from SVN</a>.</p>
<p style="text-align: center;"><a href="http://pbking.com/blog/wp-content/uploads/2009/08/formattedhtml1.PNG"><img class="aligncenter size-full wp-image-121" title="formattedhtml" src="http://pbking.com/blog/wp-content/uploads/2009/08/formattedhtml1.PNG" alt="formattedhtml" width="560" height="452" /></a></p>
<p>Hope this helps somebody out there!  I really appreciate documentation; especially the generated kind.  It helps me to quickly grasp the code without actually looking at it.  Maybe this will help us see more of it!</p>
]]></content:encoded>
			<wfw:commentRss>http://pbking.com/blog/?feed=rss2&amp;p=109</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://pbking.com/blog/?p=109</feedburner:origLink></item>
	</channel>
</rss>
