<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>New Fun Blog - Scott Bilas</title>
	<atom:link href="http://scottbilas.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://scottbilas.com</link>
	<description>Take what you want, and leave the rest (just like your salad bar).</description>
	<lastBuildDate>Tue, 09 Mar 2010 02:25:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Assertive Finalizers</title>
		<link>http://scottbilas.com/blog/assertive-finalizers/</link>
		<comments>http://scottbilas.com/blog/assertive-finalizers/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 02:04:14 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://scottbilas.com/?p=485</guid>
		<description><![CDATA[
In my previous post, I talked about why I have stopped using finalizers for unmanaged resource collection. I want this to be done through the disposable pattern instead, forcing the programmer to manage resources manually.
Ironically, finalizers are a great way to verify this.
Sander van Rossen quickly figured out where I was going with this and [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://scottbilas.com/wp-content/uploads/2010/03/MG_3288.jpg"><img style="margin: 0px 0px 10px 10px; display: inline; border-width: 0px;" title="Oruro" src="http://scottbilas.com/wp-content/uploads/2010/03/MG_3288_thumb.jpg" border="0" alt="Oruro" width="120" height="168" align="right" /></a></p>
<p>In my <a href="http://scottbilas.com/blog/finalizers-an-incomplete-pattern">previous post</a>, I talked about why I have stopped using finalizers for unmanaged resource collection. I want this to be done through the disposable pattern instead, forcing the programmer to manage resources manually.</p>
<p><em>Ironically, finalizers are a great way to verify this.</em></p>
<p><a href="http://sandervanrossen.blogspot.com/">Sander van Rossen</a> quickly figured out where I was going with this and proposed in a <a href="http://scottbilas.com/blog/finalizers-an-incomplete-pattern#comment-413">comment</a> that we can just assert in a finalizer. We just need a couple more things:</p>
<ol>
<li>We need to track the source of the object to figure out where the leak is.</li>
<li>We need to ensure that finalizers run on shutdown, or our assert will never get hit.</li>
</ol>
<p>This is familiar territory to C++ programmers. Most of us use memory management libraries that provide <a href="http://msdn.microsoft.com/en-us/library/e5ewb1h3%28VS.80%29.aspx">leak detection and reporting</a>. Let’s do something similar in C#.</p>
<h2>DisposableBase</h2>
<p>If you look around online, you’ll find some full-featured IDisposable <a href="http://www.danrigsby.com/blog/index.php/2008/03/15/disposable-base-class/">base classes</a> intended to deal with the full finalization model. We can eliminate most of that as either too complicated or unnecessary. We just need a few things:</p>
<ul>
<li><em>A stack trace grabbed at construction time<br />
</em>This will be used for the error report. Because this is expensive to gather, we need to control it with an #if that is off by default, only turned on if needed to help an investigation. Most of the time a leaked disposable will be easy to find by inspection, but in the 5% case we will need a lot more context.</li>
<li><em>A finalizer that reports the problem<br />
</em>It could throw an exception, fire an assert, or route to an error reporter. Depends on the application. In my example I just have it output to the debug window for a demo.</li>
<li><em>Disposal helper methods</em><br />
These wrap up disposal a bit, so inheritors only need to implement OnDispose. The most important feature, though, is that Dispose will call <strong>GC.SuppressFinalize</strong> when our object is disposed. This eliminates the performance cost of having a finalizer in the normal case when clients are disposing this class properly. This is why the finalizer has no “if” in it – if it ever gets called, then we have a bug.</li>
</ul>
<p>This is what I am currently using as my base class for handling unmanaged resources:</p>
<pre class="brush: csharp;">
// comment out unless diagnosing a leak
#define DEBUG_DISPOSE

public abstract class DisposableBase : IDisposable
{
    // store stack at point of construction for possible later use
#	if DEBUG_DISPOSE
    StackTrace _trace = new StackTrace(true);
#	endif

    // finalizer will not be called if object was properly disposed
    ~DisposableBase()
    {
        string message = &quot;!! Forgot to dispose a &quot; + GetType().FullName;
#		if DEBUG_DISPOSE
        message += &quot;\n\nStack at construction:\n\n&quot; + _trace + &quot;!!&quot;;
#		endif
        Debug.WriteLine(message);
    }

    public bool IsDisposed { get; private set; }

    public void Dispose()
    {
        ThrowIfDisposed();
        IsDisposed = true;

        try { OnDispose(); }
        finally { GC.SuppressFinalize(this); }
    }

    protected abstract void OnDispose();

    protected void ThrowIfDisposed()
    {
        if (IsDisposed)
            throw new ObjectDisposedException(GetType().FullName);
    }
}
</pre>
<h2>Demonstration</h2>
<p>Here is a simple test app that shows what happens if we forget to dispose an instance.</p>
<pre class="brush: csharp;">
public class DatabaseConnection : DisposableBase
{
    protected override void OnDispose()
        { Debug.WriteLine(&quot;Disposing&quot;); }
}

public class Program
{
    static void Main(string[] args)
    {
        using (var remembered0 = new DatabaseConnection())
        using (var remembered1 = new DatabaseConnection())
        {
        }

        var forgotten = new DatabaseConnection();

        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
}
</pre>
<p>The first two instances dispose fine, but the third is leaked and so we get a log to the output window:</p>
<pre class="brush: plain;">
Disposing
Disposing
!! Forgot to dispose a DatabaseConnection

Stack at construction:

   at DisposableBase..ctor() in C:\Users\Scott\Cloud\Proj\tests\BlogSamples\ConsoleApplication1\Finalizers.cs:line 18
   at DatabaseConnection..ctor()
   at Program.Main(String[] args) in C:\Users\Scott\Cloud\Proj\tests\BlogSamples\ConsoleApplication1\Finalizers.cs:line 89
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
!!
</pre>
<p>We can easily zero in on the exact spot where the leaked resource was allocated and wrap it in a ‘using’ to resolve.</p>
<p>Note the use of <strong>GC.Collect</strong> and <strong>GC.WaitForPendingFinalizers</strong> right before the test application exits. This is necessary in order to force all finalizing objects to be collected and reported before process shutdown, otherwise they are simply dropped by the system when the process’s memory is released.</p>
<p>These two can even be called during normal app run as well for leak testing without needing to wait for shutdown. This would be useful in a live service with a periodic leak for which we want an in-session nonfatal log of leaks.</p>
<h2>What About External Classes?</h2>
<p>This takes care of our own classes, where we have full control. But what about system or third party classes that are using finalizers? With those it’s back to square one.</p>
<p>Well, I suppose would write a helper class..</p>
<pre class="brush: csharp;">
public class SafeDisposer&lt;T&gt; : DisposableBase where T : IDisposable
{
    public SafeDisposer(T disposable) { Obj = disposable; }

    public T Obj { get; private set; }

    protected override void OnDispose()
    {
        Obj.Dispose();
        Obj = default(T);
    }
}

public static class SafeDisposer
{
    public static SafeDisposer&lt;T&gt; Wrap&lt;T&gt;(T disposable) where T : IDisposable
        { return new SafeDisposer&lt;T&gt;(disposable); }
}
</pre>
<p>And equivalent updates in the demo code:</p>
<pre class="brush: csharp;">
public class Program
{
    static void Main(string[] args)
    {
        using (var remembered2 = SafeDisposer.Wrap(new StringReader(&quot;foo&quot;)))
        using (var remembered3 = SafeDisposer.Wrap(new StringReader(&quot;poo&quot;)))
        {
            remembered2.Obj.Peek();
        }

        var forgotten2 = SafeDisposer.Wrap(new StringReader(&quot;boo&quot;));

        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
}
</pre>
<p>And output:</p>
<pre class="brush: plain;">
!! Forgot to dispose a SafeDisposer`1[[System.IO.StringReader, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]

Stack at construction:

   at DisposableBase..ctor() in C:\Users\Scott\Cloud\Proj\tests\BlogSamples\ConsoleApplication1\Finalizers.cs:line 18
   at SafeDisposer`1..ctor(T disposable) in C:\Users\Scott\Cloud\Proj\tests\BlogSamples\ConsoleApplication1\Finalizers.cs:line 53
   at SafeDisposer.Wrap[T](T disposable) in C:\Users\Scott\Cloud\Proj\tests\BlogSamples\ConsoleApplication1\Finalizers.cs:line 67
   at Program.Main(String[] args) in C:\Users\Scott\Cloud\Proj\tests\BlogSamples\ConsoleApplication1\Finalizers.cs:line 98
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
!!
</pre>
<p>So to use, we just wrap a disposable at the point of creation in SafeDisposer.Wrap() and access it through “.Obj”. Not bad, but not great either. I’m ok with the wrapper function, but the required access via the Obj member is a pain, and also means that converting an unsafe disposable into a safe one requires updating a lot of code.</p>
<p>Another option is (maybe) to use a <a href="http://www.castleproject.org/dynamicproxy/index.html">dynamic proxy system</a> to inject the functionality we need, letting client code remain unchanged except at the point of creation. Or perhaps a run-time system that patches system assemblies to do the injection.</p>
<p>I’ll leave this as an exercise for the reader because I think we’re probably getting seriously diminishing returns at this point. Most disposable objects in a large system will be classes that we have full control over. The few objects <em>not</em> under our control will likely be low level primitives that will be wrapped up by our own foundation classes anyway.</p>
<a href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fassertive-finalizers%2F&amp;linkname=Assertive%20Finalizers" title="Delicious" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a> <a href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fassertive-finalizers%2F&amp;linkname=Assertive%20Finalizers" title="Digg" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a> <a href="http://www.addtoany.com/add_to/facebook?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fassertive-finalizers%2F&amp;linkname=Assertive%20Finalizers" title="Facebook" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/facebook.png" width="16" height="16" alt="Facebook"/></a> <a href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fassertive-finalizers%2F&amp;linkname=Assertive%20Finalizers" title="Reddit" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a> <a href="http://www.addtoany.com/add_to/twitter?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fassertive-finalizers%2F&amp;linkname=Assertive%20Finalizers" title="Twitter" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/twitter.png" width="16" height="16" alt="Twitter"/></a> <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fassertive-finalizers%2F&amp;linkname=Assertive%20Finalizers">Share/Save</a>]]></content:encoded>
			<wfw:commentRss>http://scottbilas.com/blog/assertive-finalizers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Finalizers: An Incomplete Pattern</title>
		<link>http://scottbilas.com/blog/finalizers-an-incomplete-pattern/</link>
		<comments>http://scottbilas.com/blog/finalizers-an-incomplete-pattern/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 04:45:38 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://scottbilas.com/?p=473</guid>
		<description><![CDATA[ When you were first learning about how .NET finalization works, did it just feel wrong to you? It sure did for me. The mechanisms and rules involved with finalizers always felt painfully over-complicated, hard to get right, and hacky. Here we have this clean managed-memory paradigm that feels great to use. And it’s got [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://scottbilas.com/wp-content/uploads/2010/03/DSC04726.jpg"><img style="margin: 0px 0px 10px 10px; display: inline; border-width: 0px;" title="Whistler" src="http://scottbilas.com/wp-content/uploads/2010/03/DSC04726_thumb.jpg" border="0" alt="Whistler" width="150" height="230" align="right" /></a> When you were first learning about how .NET finalization works, did it just feel <em>wrong</em> to you? It sure did for me. The mechanisms and rules involved with finalizers always felt painfully <a href="http://msdn.microsoft.com/en-us/library/fs2xkftw%28VS.80%29.aspx">over-complicated</a>, <a href="http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=88e62cdf-5919-4ac7-bc33-20c06ae539ae">hard to get right</a>, and hacky. Here we have this clean managed-memory paradigm that feels great to use. And it’s got a big gnarly barnacle named Finalize growing out of its side that we’re supposed to use to deal with unmanaged resources.</p>
<p>I learned .NET when the beta of 1.0 was out, and at the time Microsoft was putting a lot of effort into educating programmers the difference between native and managed programming to make the switch. “In C++ you’d do <em>this</em>, but in .NET you do <em>this</em>” kind of thing. So practically <em>every </em>article on the CLR talked about finalizers. They often made analogies to C++ destructors. C# even added some ill-advised sugar that converts ~Class() to Finalize() to make us grognards feel more at home.</p>
<p>Finalizers were obviously very important, and so we learned about them. We evolved <a href="http://www.danrigsby.com/blog/index.php/2008/03/15/disposable-base-class/">base classes</a> to help us do the boilerplate work and wished that the .NET languages supported <a href="http://www.re-motion.org/blogs/team/archive/2008/02/20/introducing-mixins-finally.aspx">mixins</a>. But it never felt right to me.</p>
<h2>The Problem With Finalizers</h2>
<p>Recently, after a couple conversations at work, I figured out what’s been bothering me about finalizers. The problem is that <em>we’re using a commodity manager to manage non-commodity resources</em>.</p>
<p>In .NET, raw memory can be treated as a commodity, like a gas tank. We can use it fluidly and at any granularity, and treat it all roughly the same. This is a simplification of course, and there are performance considerations, but they closely map onto the underlying OS and are familiar to everyone.</p>
<p>Yet non-memory resources are not commodities and cannot be treated with a one-size-fits-all pattern. They have semantics and effects far beyond incrementally draining and refilling that gas tank. Each situation, each class, is different, and has different implications that we have to remember. Because of this, we can’t treat these resources in a nondeterministic way without potential hazards.</p>
<p>For example, take a file handle managed by a finalizer. Off the top of my head, there are three adverse effects of an unused handle not finalizing in time:</p>
<ol>
<li>If there are pending writes to the file, then they are lost if the app exits without forcing finalizers to be called.</li>
<li>If the file was opened with restrictive sharing, then other applications cannot manipulate it until the GC gets around to finalizing the file object.</li>
<li>The OS isn’t designed to treat file handles as a commodity, and using them that way can negatively affect performance. We could even run out of file handles because the GC has no idea when there’s pressure in this space (all finalizers are equal).</li>
</ol>
<p>Worse yet, in diagnosing any of the above issues, we also must roll our own tools. System tools such as <a href="http://www.lockhunter.com/">LockHunter</a> and <a href="http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx">Process Explorer</a> have no way of distinguishing which handles are actually in use and will just give us a noisy, useless mess.</p>
<p>And that&#8217;s just a simple file handle example. The situation is obviously worse as more limited and complicated resources are involved like DirectX surfaces or database connections.</p>
<h2>Dispose: Only A Partial Solution</h2>
<p>You might wonder why I’m making a fuss. There’s an obvious answer to the non-determinism, right? Microsoft recognized this problem early in in .NET 1.0 and gave us the <a href="http://msdn.microsoft.com/en-us/library/b1yfkh5e%28VS.71%29.aspx">disposable pattern</a>. It is a standard way of managing resources the old-fashioned way: ‘new’ allocates the resource, and Dispose() frees it. We even have some special syntax that helps automate this:</p>
<pre class="brush: csharp;">
using (var textureMgr = new TextureManager())
using (var texture = textureMgr.AllocTexture())
{
    texture.Fill(Color.White);
}
</pre>
<p>The above is roughly equivalent to:</p>
<pre class="brush: csharp;">
var textureMgr = new TextureManager();
try
{
	texture = textureMgr.AllocTexture();
	try
	{
		texture.Fill(Color.White);
	}
	finally
	{
		texture.Dispose();
	}
}
finally
{
	textureMgr.Dispose();
}
</pre>
<p>This gives us a rough, though somewhat tedious approximation of the <a href="http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization">RAII</a> pattern used universally in C++.</p>
<p>In Microsoft’s .NET classes that wrap unmanaged resources, both patterns are typically used. There is a Dispose system that closes the handle, and a safety Finalize that cleans up if not already done already via Dispose.</p>
<p>So what&#8217;s the big deal? Well, the problem is in (a) knowing when it is necessary to call Dispose, (b) remembering to call it, and (c) updating dependent code when an existing type adds a new IDisposable implementation. It’s easy to miss something and let bugs creep in. For every single ‘new’ call, we must check the type to see if it or one of its parent classes implements IDisposable. If it does, then we must manage the instance directly. This means wrapping allocation in the ‘using’ construct for local temporaries, or <a href="http://stackoverflow.com/questions/661815/how-do-you-prevent-idisposable-from-spreading-to-all-your-classes">implementing IDisposable</a> and forwarding Dispose if contained as a member in another class.</p>
<p>Forgetting to dispose an unmanaged resource can lead to some of the most frustrating and difficult to track down bugs. And the nondeterminism in the underlying system pretty much squares that problem. It’s guaranteed to behave differently in the field than on a development machine.</p>
<p>Every new .NET programmer figures this out quickly when they write their first command line app that opens a file, does something to it, and writes out a new file. They find that, apparently randomly, sometimes the end of the new file is cut off. Forgot to call Dispose to flush and close it eh?</p>
<h2>Most Strategies Not 100% Guaranteed</h2>
<p>It’s not hopeless. We’ve come up with strategies to deal with this. First is knowledge base. Over time, we get a sense for what types of objects tend to implement IDisposable. File handles, database connections and so on, those are easy. Though what about systems written by someone else on your team? Does the source control connection have to get disposed when you’re done with it because it wraps a COM object? For those cases, it’s better to be safe and check for IDisposable until the foreign classes become familiar.</p>
<p>There are also tools that help out. <a href="http://msdn.microsoft.com/en-us/library/bb429476%28VS.80%29.aspx">FxCop</a> can find problems <a href="http://stackoverflow.com/questions/2214605/is-there-a-fxcop-rule-for-local-used-idisposables">that are discoverable</a> via static analysis. <a href="http://www.devexpress.com/Products/Visual_Studio_Add-in/Coding_Assistance/">CodeRush</a> will draw graphical markup for types it detects as IDisposable.</p>
<p>But these strategies still aren’t enough for me. I want <em>absolute certainty</em> that Dispose is called on all unmanaged resources, and not left to the nondeterministic finalizer system to cause latent timing problems.</p>
<p>So I want to propose an additional strategy. It’s pretty simple, actually: consider the finalizer to be a last, and <strong>illegal</strong> resort. Microsoft&#8217;s guidelines say that you should not assume Dispose has been called. I propose the reverse: if the finalizer is called, then there is a bug in the code.</p>
<p>More on this in the next post.</p>
<a href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Ffinalizers-an-incomplete-pattern%2F&amp;linkname=Finalizers%3A%20An%20Incomplete%20Pattern" title="Delicious" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a> <a href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Ffinalizers-an-incomplete-pattern%2F&amp;linkname=Finalizers%3A%20An%20Incomplete%20Pattern" title="Digg" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a> <a href="http://www.addtoany.com/add_to/facebook?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Ffinalizers-an-incomplete-pattern%2F&amp;linkname=Finalizers%3A%20An%20Incomplete%20Pattern" title="Facebook" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/facebook.png" width="16" height="16" alt="Facebook"/></a> <a href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Ffinalizers-an-incomplete-pattern%2F&amp;linkname=Finalizers%3A%20An%20Incomplete%20Pattern" title="Reddit" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a> <a href="http://www.addtoany.com/add_to/twitter?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Ffinalizers-an-incomplete-pattern%2F&amp;linkname=Finalizers%3A%20An%20Incomplete%20Pattern" title="Twitter" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/twitter.png" width="16" height="16" alt="Twitter"/></a> <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Ffinalizers-an-incomplete-pattern%2F&amp;linkname=Finalizers%3A%20An%20Incomplete%20Pattern">Share/Save</a>]]></content:encoded>
			<wfw:commentRss>http://scottbilas.com/blog/finalizers-an-incomplete-pattern/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Bracketing Operations With IDisposable</title>
		<link>http://scottbilas.com/blog/bracketing-operations-with-idisposable/</link>
		<comments>http://scottbilas.com/blog/bracketing-operations-with-idisposable/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 05:45:27 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[trick]]></category>

		<guid isPermaLink="false">http://scottbilas.com/?p=459</guid>
		<description><![CDATA[ I learned a fun little .NET trick today at work, figured I’d pass it along. This is probably a well-known pattern, but I don’t know its name.
The Problem
Say you have a pair of functions that bracket other operations you want to do. For example, you must first call BeginRender() before you call RenderModel(), and [...]]]></description>
			<content:encoded><![CDATA[<p><img style="margin: 0px 0px 10px 10px; display: inline; border: 0px;" title="Carnaval Oruro" src="http://scottbilas.com/wp-content/uploads/2010/02/MG_3046.jpg" border="0" alt="Carnaval Oruro" width="160" height="121" align="right" /> I learned a fun little .NET trick today at work, figured I’d pass it along. This is probably a well-known pattern, but I don’t know its name.</p>
<h2>The Problem</h2>
<p>Say you have a pair of functions that bracket other operations you want to do. For example, you must first call BeginRender() before you call RenderModel(), and after you’re all done, you need to call EndRender(). Another example would be a EnterLock() on a critical section, that must be accompanied by a LeaveLock(). I’ll call these bracketing functions simply “BeginX” and “EndX” for the purposes of this article.</p>
<p>The problem is that the caller must not only remember to call EndX, but must do so even in case of an exception, to avoid blocking the system.</p>
<h2>The Solution: IDisposable</h2>
<p>What we’re doing here, really, is acquiring and releasing a resource. The .NET Framework already has a pattern for that, and it’s called <a href="http://msdn.microsoft.com/en-us/library/system.idisposable.aspx">IDisposable</a>. Ok, that’s not much of a trick in itself. What I learned today was a little twist on the concept.</p>
<p>The trick is simple:</p>
<ol>
<li>Create a private inner class that implements IDisposable.</li>
<li>Return a new’d instance of this class in BeginX.</li>
<li>In the instance’s Dispose(), have it call the private EndX.</li>
<li>Callers can simply wrap the &#8216;handle&#8217; in a using declaration for cleanup.</li>
</ol>
<p>It&#8217;s obvious in retrospect, and it’s clean. The &#8216;using&#8217; guarantees calling EndX even in case of an exception. And in leveraging IDisposable we can build on top of the C# programmer’s instinct to wrap usages of IDisposable objects in ‘using’ constructs. As a fallback, we can rely on tools like <a href="http://www.devexpress.com/Coderush">CodeRush</a> to catch it as we type (or <a href="http://msdn.microsoft.com/en-us/library/bb429476%28VS.80%29.aspx">FxCop</a> as a fallback).</p>
<h2>Implementation</h2>
<p>First, we need a fun little helper base class.</p>
<pre class="brush: csharp;">
public abstract class DisposerBase&lt;T&gt; : IDisposable
{
    bool _disposed;
    T _owner;

    public DisposerBase(T owner)
        { _owner = owner; }

    public void Dispose()
    {
        Debug.Assert(!_disposed);
        _disposed = true;
        OnDispose(_owner);
    }

    protected abstract void OnDispose(T owner);
}
</pre>
<p>Here&#8217;s a sample class that demonstrates the IDisposable-bracket pattern. Note the inner class that has access to private methods, which we use to call EndX. This method is private so that the only way to close the bracket is to call Dispose() on the handle. Simple, straightforward, consistent.</p>
<pre class="brush: csharp;">
public class TransactionManager
{
    bool _inTransaction;

    public IDisposable BeginTransaction()
    {
        Debug.Assert(!_inTransaction);
        Console.WriteLine(&quot;Begin Transaction&quot;);

        _inTransaction = true;

        // ... do other transaction setup here ...

        // caller must dispose this when done
        return new TransactionDisposer(this);
    }

    private void EndTransaction(TransactionDisposer state)
    {
        Debug.Assert(_inTransaction);
        Console.WriteLine(&quot;End Transaction&quot;);

        // ... do transaction cleanup here ...
        // (state could provide more context if needed)

        _inTransaction = false;
    }

    #region TransactionDisposer

    class TransactionDisposer : DisposerBase&lt;TransactionManager&gt;
    {
        // obviously some state could go here
        // (say, for more transactions in flight at once)

        public TransactionDisposer(TransactionManager owner)
            : base(owner) { }

        protected override void OnDispose(TransactionManager owner)
            { owner.EndTransaction(this); }
    }

    #endregion

    public void DoSomeAction(string actionName)
    {
        Debug.Assert(_inTransaction);

        // ... do the action ...
        Console.WriteLine(&quot;  Action performed: &quot; + actionName);
    }
}
</pre>
<p><em>Note that this is a very simple example that only permits one transaction in flight at once.</em> If we wanted to do more, we could have a Dictionary that maps outstanding transactions to pending state, or we could just put the state directly into the TransactionDisposer. I&#8217;ve noted this in the comments.</p>
<p>Now, it’s a bit of typing to implement this disposer, but that’s what <a href="http://msdn.microsoft.com/en-us/library/ms165392%28VS.80%29.aspx">snippets</a> are for, right? Bracketed code like this isn&#8217;t overwhelmingly common either, so it shouldn&#8217;t be a big deal. Still, I have to say I miss my old friend <a href="http://en.wikipedia.org/wiki/C_preprocessor#Macro_definition_and_expansion">#define</a> from the C world sometimes. Not often. I&#8217;m looking forward to a future version of the C# compiler that lets us plug into the <a href="http://en.wikipedia.org/wiki/Abstract_syntax_tree">AST</a> directly and codegen as we go.</p>
<p>Anyway, here is an example usage of this pattern:</p>
<pre class="brush: csharp;">
var transactionManager = new TransactionManager();
using (var handle = transactionManager.BeginTransaction())
{
    transactionManager.DoSomeAction(&quot;action 1&quot;);
}
</pre>
<h2>Implicit Chaining</h2>
<p>There is one interesting benefit that comes from this: <strong>implicit chaining</strong>.</p>
<p>Say you have a higher level class that provides additional functionality within its own BeginX. Perhaps it calls BeginRender() and then immediately sets some default states. Rather than having to create a new inner class to manage the bracketing, you can simply return the result of BeginRender, and the caller will not know the difference.</p>
<p>Let&#8217;s extend the above example in this way.</p>
<pre class="brush: csharp;">
public class RequestManager
{
    TransactionManager _transactionManager;

    public RequestManager(TransactionManager transactionManager)
        { _transactionManager = transactionManager; }

    public IDisposable BeginRequest(string initialActionName)
    {
        var handle = _transactionManager.BeginTransaction();
        _transactionManager.DoSomeAction(initialActionName);
        return handle;
    }
}
</pre>
<p>See how it chains the TransactionManager&#8217;s bracketed calls through itself? We could have gone through the trouble of making an inner RequestDisposer class and a private EndRequest and all that, using the IDisposable from TransactionManager as the state, but why bother? Just chain it along. When the caller disposes the handle, it routes straight through to the TransactionManager, which is all we needed.</p>
<p>Some sample usage:</p>
<pre class="brush: csharp;">
var requestManager = new RequestManager(transactionManager);
using (var handle = requestManager.BeginRequest(&quot;action 2&quot;))
{
    transactionManager.DoSomeAction(&quot;action 3&quot;);
}
</pre>
<p>Of course, if RequestManager has to do anything special in its EndX, then we&#8217;ll have to go and add that inner class after all. It&#8217;s a nice shortcut otherwise.</p>
<p>The output from both examples looks like this:</p>
<pre class="brush: plain;">
Begin Transaction
Action performed: action 1
End Transaction
Begin Transaction
Action performed: action 2
Action performed: action 3
End Transaction
</pre>
<p>Easy huh?</p>
<h2>Performance Implications</h2>
<p>It&#8217;s worth asking what the costs of this method are. <em>How does this compare to simply calling BeginX and EndX?</em></p>
<p>Let&#8217;s consider this sample usage again:</p>
<pre class="brush: csharp;">
using (var handle = transactionManager.BeginTransaction())
{
    transactionManager.DoSomeAction(&quot;action 1&quot;);
}
</pre>
<p>This is <a href="http://en.wikipedia.org/wiki/Syntactic_sugar">syntactic sugar</a> (I loathe this term but it is unfortunately apt) that the compiler translates into something like this:</p>
<pre class="brush: csharp;">
IDisposable handle = transactionManager.BeginTransaction();
try
{
    transactionManager.DoSomeAction(&quot;action 1&quot;);
}
finally
{
    if (handle != null)
        handle.Dispose();
}
</pre>
<p>Note that the runtime does not do anything special with IDisposable types. They are created and collected exactly the same as any other type. And as a result, this is almost identical to what we&#8217;d have to do for a manual BeginX/EndX:</p>
<pre class="brush: csharp;">
transactionManager.BeginTransaction();
try
{
    transactionManager.DoSomeAction(&quot;action 1&quot;);
}
finally
{
    transactionmanager.EndTransaction();
}
</pre>
<p>Now, this is assuming no state needs to be maintained in the handle. If it were, then we&#8217;d have to store it in a local and pass it into EndTransaction, and the BeginX/EndX pattern would almost exactly match the disposer pattern.</p>
<p>So: the cost of the disposer pattern over BeginX/EndX is that an extra object gets new&#8217;d up, with a bit of glue logic that runs. Insignificant, not worth worrying about.</p>
<p>Even if it did have a real cost, I&#8217;d <em>still</em> not worry about it. This is intended to be used in bracket patterns where resources are being allocated and freed. The cost of the underlying resource management is going to mask whatever minor cost the disposer adds.</p>
<p>The cleaner, more maintainable, and statically-analyzable code that results is an easy win.</p>
<a href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fbracketing-operations-with-idisposable%2F&amp;linkname=Bracketing%20Operations%20With%20IDisposable" title="Delicious" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a> <a href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fbracketing-operations-with-idisposable%2F&amp;linkname=Bracketing%20Operations%20With%20IDisposable" title="Digg" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a> <a href="http://www.addtoany.com/add_to/facebook?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fbracketing-operations-with-idisposable%2F&amp;linkname=Bracketing%20Operations%20With%20IDisposable" title="Facebook" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/facebook.png" width="16" height="16" alt="Facebook"/></a> <a href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fbracketing-operations-with-idisposable%2F&amp;linkname=Bracketing%20Operations%20With%20IDisposable" title="Reddit" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a> <a href="http://www.addtoany.com/add_to/twitter?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fbracketing-operations-with-idisposable%2F&amp;linkname=Bracketing%20Operations%20With%20IDisposable" title="Twitter" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/twitter.png" width="16" height="16" alt="Twitter"/></a> <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fbracketing-operations-with-idisposable%2F&amp;linkname=Bracketing%20Operations%20With%20IDisposable">Share/Save</a>]]></content:encoded>
			<wfw:commentRss>http://scottbilas.com/blog/bracketing-operations-with-idisposable/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Dungeon Siege Page Posted</title>
		<link>http://scottbilas.com/blog/dungeon-siege-page-posted/</link>
		<comments>http://scottbilas.com/blog/dungeon-siege-page-posted/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 04:49:11 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[dungeon siege]]></category>

		<guid isPermaLink="false">http://scottbilas.com/blog/dungeon-siege-page-posted/</guid>
		<description><![CDATA[By popular request, I just posted a new page that has everything I could find that I’ve done related to Dungeon Siege. It’s got the good, the bad, and the ugly. A large, memorable chapter of my early game development life.
Until now, this stuff has been scattered all over four different defunct websites in a [...]]]></description>
			<content:encoded><![CDATA[<p>By popular request, I just <a href="http://scottbilas.com/games/dungeon-siege">posted a new page</a> that has everything I could find that I’ve done related to Dungeon Siege. It’s got the good, the bad, and the ugly. A large, memorable chapter of my early game development life.</p>
<p>Until now, this stuff has been scattered all over four different defunct websites in a mess of broken links. This new page fixes all of that for good.</p>
<blockquote><p><a href="http://scottbilas.com/games/dungeon-siege"><img style="border-right-width: 0px; margin: 0px 0px 0px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Dungeon Siege" border="0" alt="Dungeon Siege" align="right" src="http://scottbilas.com/wp-content/uploads/2010/01/image7.png" width="120" height="217" /></a>I worked at Gas Powered Games between November 1999 and October 2003, back when it was a fresh startup. In that time, I lectured and wrote about some of the technology we used to build Dungeon Siege and later projects. I also released specifications for some of the internals of the engine to help the mod community.</p>
<p>This page collects all of my published Dungeon Siege work.</p>
<p><em>…continued <a href="http://scottbilas.com/games/dungeon-siege">here</a></em></p>
</blockquote>
<a href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fdungeon-siege-page-posted%2F&amp;linkname=Dungeon%20Siege%20Page%20Posted" title="Delicious" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a> <a href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fdungeon-siege-page-posted%2F&amp;linkname=Dungeon%20Siege%20Page%20Posted" title="Digg" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a> <a href="http://www.addtoany.com/add_to/facebook?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fdungeon-siege-page-posted%2F&amp;linkname=Dungeon%20Siege%20Page%20Posted" title="Facebook" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/facebook.png" width="16" height="16" alt="Facebook"/></a> <a href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fdungeon-siege-page-posted%2F&amp;linkname=Dungeon%20Siege%20Page%20Posted" title="Reddit" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a> <a href="http://www.addtoany.com/add_to/twitter?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fdungeon-siege-page-posted%2F&amp;linkname=Dungeon%20Siege%20Page%20Posted" title="Twitter" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/twitter.png" width="16" height="16" alt="Twitter"/></a> <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fdungeon-siege-page-posted%2F&amp;linkname=Dungeon%20Siege%20Page%20Posted">Share/Save</a>]]></content:encoded>
			<wfw:commentRss>http://scottbilas.com/blog/dungeon-siege-page-posted/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Finally Onto WPF</title>
		<link>http://scottbilas.com/blog/finally-onto-wpf/</link>
		<comments>http://scottbilas.com/blog/finally-onto-wpf/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 15:00:00 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[wpf]]></category>

		<guid isPermaLink="false">http://scottbilas.com/2010/01/14/finally-onto-wpf/</guid>
		<description><![CDATA[ I’ve been learning WPF for some GUI tools I’m building, and it’s a whole new world. I feel like I’m back with .NET 1.0 in the late 90’s trying to inhale a bunch of new technology and patterns all at once.
It’s pretty exciting, even if I am joining this game very late.
As I work [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://scottbilas.com/wp-content/uploads/2010/01/P1000584.jpg"><img style="border-right-width: 0px; margin: 0px 0px 10px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="In Lima" border="0" alt="In Lima" align="right" src="http://scottbilas.com/wp-content/uploads/2010/01/P1000584_thumb.jpg" width="160" height="106" /></a> I’ve been learning <a href="http://en.wikipedia.org/wiki/Windows_Presentation_Foundation">WPF</a> for some GUI tools I’m building, and it’s a <em>whole new world</em>. I feel like I’m back with .NET 1.0 in the late 90’s trying to inhale a bunch of new technology and patterns all at once.</p>
<p>It’s pretty exciting, even if I am joining this game very late.</p>
<p>As I work in the WPF world (and maybe <a href="http://en.wikipedia.org/wiki/Windows_Communication_Foundation">WCF</a> and other techs as I start messing around with them) I’ll be posting odds and ends here about research I do and dead-end paths I go down.</p>
<h2>Not WinForms++</h2>
<p>The first thing I learned is that <strong>WPF isn’t WinForms++</strong> or even “WinForms in XML”. It lives in an entirely different universe. Though, for folks like me that have been stuck in that old world too long, WPF is initially going to <em>feel</em> like a simple upgrade of an old framework. There are a lot of similar-sounding classes and concepts in the new framework. These are merely false cognates.</p>
<p>I’ve been learning that it’s better for me to enter into new WPF concepts like a 101 student: by reading books and MSDN docs. I haven’t done that in a while. Normally I just bang on code and refine, using <a href="http://www.google.com">Google</a> and <a href="http://www.stackoverflow.com">StackOverflow</a> to guide my way (and <a href="https://addons.mozilla.org/en-US/firefox/addon/12305">surfclarity</a> to filter out spam sites like experts-exchange.com). I’m still doing that as I pick up WPF, but adding on top of it some serious reading.</p>
<p><a href="http://my.safaribooksonline.com/9781590599556"><img style="border-bottom: 0px; border-left: 0px; margin: 0px 10px 0px 0px; display: inline; border-top: 0px; border-right: 0px" title="Pro WPF in C# 2008" border="0" alt="Pro WPF in C# 2008" align="left" src="http://scottbilas.com/wp-content/uploads/2010/01/image.png" width="50" height="88" /></a> <a href="http://my.safaribooksonline.com/9781590599556">Pro WPF in C# 2008</a> (available at <a href="http://www.safaribooksonline.com">Safari</a> where I’m reading it) is my current favorite book for learning WPF concepts. Most books I come across are lame reference manuals disguised as tutorials, or sensationalized drooling over new tech with no real experience to back it up. The author does great things like quickly explaining a cool-sounding WPF concept, then telling you not to use it and why. Not all of WPF turned out to be a good idea, after all.</p>
<p>So, here are some of the key benefits I’ve noticed in the short time I’ve worked in WPF:</p>
<h3>Layout and Composition</h3>
<p>The problem of control layout (wrap, dock, table, stretch, fill, and so on) is <em>solved</em>. It’s nice of WPF to catch up with where HTML has been for a while, though in a much cleaner and more internally consistent way. Later versions of WinForms started to get somewhere with <a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.tablelayoutpanel.aspx">TableLayoutPanel</a> and friends, but it’s still the same old underlying framework, where you run into limitations very quickly.</p>
<p>WPF lets you easily nest any control within nearly any other, and has a sensible system for guiding layout containers (attached properties rather than Control-derived least-common-denominator properties). It’s simple, for example, to put a pair of icons and a few checkboxes into each element of a <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.listview.aspx">ListView</a>, and make it look good. <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.listview.aspx">Virtualization</a> is automatic as well, given certain constraints. Trying to make any of that work in old WinForms requires a lot of custom code.</p>
<p><img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 10px 10px; display: inline; border-top: 0px; border-right: 0px" title="Easy to code, hard to follow" border="0" alt="Easy to code, hard to follow" align="right" src="http://scottbilas.com/wp-content/uploads/2010/01/image1.png" width="150" height="165" /> In fact, it was enough work in WinForms that I tended to avoid doing <em>anything </em>complicated. This led to UI’s that were easier to program but harder to use due to the need to break out elements or hide things behind the ubiquitous “more” or “advanced” buttons. Consider your average Tools|Options dialog and the custom toolwork required to make that work in a Form. This is why “field of checkboxes” settings dialogs proliferate in so many apps (see pic at right).</p>
<p>With WPF I’ve found it easy to not only wire up the initial draft of the UI, but also to go back and do a big reorg without any real trouble, and usually without significantly changing any code. I Just did it three times today, in fact!</p>
<p><em>A Special Note on XAML</em></p>
<p>Layout and composition are now typically done in XML, using Microsoft’s <a href="http://en.wikipedia.org/wiki/Extensible_Application_Markup_Language">XAML</a>. At first I was tentative on XAML compared to <a href="http://en.wikipedia.org/wiki/MXML">MXML</a> due to the total lack of support for writing code inline in the attributes. Well, it turns out that <a href="http://en.wikipedia.org/wiki/Model_View_ViewModel">viewmodels</a> eliminate the need for much of that inline code (with the glaring exception of value converters – more on this in a future post). It’s also probably a good idea to keep code out of the XAML if you’re splitting the work with a designer. Having code in those attributes would not only get in the way, but would be brittle and hard to maintain.</p>
<p>The bottom line is that WinForms’ crazy InitializeComponent is gone. Bye bye merge problems and periodic, inexplicable total reorganization of that function by Visual Studio. Instead, we lay things out hierarchically in nice, simple, consistent, and nearly unreadable XML. Well, that’s what the visual designer is for.</p>
<h3>Data Binding</h3>
<p>I’ll admit I didn’t mess around with data binding much in the WinForms world. It just felt like too much work for what was a simple thing to do by hand. And WPF is vastly more complicated and capable than Forms, so it was intimidating at first.</p>
<p>But in WPF you really need to <em>fully embrace</em> data binding. I suppose it’s possible to do old UI-driven Visual Basic style state management in WPF, by putting everything in the codebehind, but you’re not going to get much support for this. All samples and tutorials you’ll find online use data binding. It really is how the entire system was designed to be used. Data binding is about a lot more than simply tying a textbox to a text string member. It’s about separation of concerns.</p>
<p>Thankfully, it’s not difficult to pick up. There’s some crazy complicated <a href="http://benjismith.net/index.php/2005/09/30/hate-frameworks/">20-levels-deep-stack logic</a> that makes it all work under the hood, but the end result is that you just cover your eyes and type {Binding SomeName} on whatever field you want bound to your viewmodel and it magically works. “Except”, as they say, “when it doesn’t”. So far it’s been rare for me when something fails to bind, or binds to the wrong place, and I’m developing a bag of tricks to debug these issues. I’ll try to post some of these in the future.</p>
<p>Now, about that viewmodel thing. It’s <em>also</em> practically required to embrace the <a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx">MVVM pattern</a> in building up nontrivial WPF-based UI’s. This is the “separation” I mentioned previously. Now, this takes a lot of practice to figure out and to start applying correctly. It took me about two months to really grok WPF+MVVM. So be sure to budget time to learn and practice this. Read the <a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx">article</a> I just linked for a good introduction.</p>
<h3>Styling</h3>
<p>The problem of styling controls and windows is hugely improved. It simply isn’t possible to modify controls in WinForms without writing a totally custom solution. WPF takes a big step forward in enabling simple as well as complex styling of the standard controls. You can completely alter the look and visual behavior of any WPF control without a lot of work.</p>
<p><a href="http://www.microsoft.com/expression/products/Blend_Overview.aspx"><img style="border-bottom: 0px; border-left: 0px; margin: 0px 10px 0px 0px; display: inline; border-top: 0px; border-right: 0px" title="Expression Blend 3" border="0" alt="Expression Blend 3" align="left" src="http://scottbilas.com/wp-content/uploads/2010/01/image2.png" width="64" height="85" /></a> And then there’s <a href="http://www.microsoft.com/expression/products/Blend_Overview.aspx">Expression Blend</a>, my new love interest. Blend is a tool for the design and styling of WPF UI’s, and permits dividing responsibilities between engineers writing code and designers building the look &amp; feel. We have this exact split at work, in fact. Engineers will poke out a rough UI, and later on one of the game UI designers will take some time to upgrade elements to look cool and be consistent with the rest of the tool.</p>
<p>Blend has a goofy, nerdy interface, but it’s really growing on me as I use it every day. It’s far from intuitive, but is powerful in terms of designing controls and styles, previewing it all live, live live! in its awesome designer. It can even build your full Visual Studio solution from within itself. I do almost all of my design work within Blend, partially because VS2008’s designer is so awful as to be almost useless (haven’t used 2010’s enough yet to comment) but mostly because it’s more familiar to the Flash programmer within me. What can I say, I like arty tools.</p>
<h3>Rendering</h3>
<p>One of the reasons styling can be done so easily is that WPF doesn’t rely on the underlying OS window manager to draw checkboxes and so on. This removes all limitations on what you can change. If you use a tool like <a href="http://blois.us/Snoop/">Snoop</a> or <a href="http://www.codeproject.com/KB/macros/MoleForVisualStudioEdit.aspx">Mole</a> to take apart a UI control, you can see that every little graphical piece and state of it resolves down to primitive WPF objects that you can inspect.</p>
<p><img style="border-right-width: 0px; margin: 0px 0px 0px 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ResizeGrip taken apart in Blend" border="0" alt="ResizeGrip taken apart in Blend" align="right" src="http://scottbilas.com/wp-content/uploads/2010/01/image6.png" width="125" height="128" /><img style="border-right-width: 0px; margin: 0px 0px 0px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ResizeGrip control" border="0" alt="ResizeGrip control" align="right" src="http://scottbilas.com/wp-content/uploads/2010/01/image3.png" width="61" height="59" />For fun, I edited the template of the <a href="http://joshsmithonwpf.wordpress.com/cracknet/">ResizeGrip</a> control in Blend to see what makes it tick. This is the little triangular dotted thingy that sits in the lower right corner of most sizable windows. Blend showed me that it’s rendered using a simple brush that has a repeated pattern of gradient squares clipped to a little stair-step box. All vector so it scales nicely.</p>
<p>How does this new rendering model affect Remote Desktop, by the way? Custom-rendered windows typically perform poorly through RDP. Try running Chrome or iTunes through RDP, or nearly any app through VNC, on a low bandwidth VPN connection to see what I mean. In earlier versions of .NET, if a DWM existed on both sides, the WPF graphics primitives would get remoted directly. However, it seems that in .NET 3.5SP1 and newer, <a href="http://blogs.msdn.com/jgoldb/archive/2008/05/15/what-s-new-for-performance-in-wpf-in-net-3-5-sp1.aspx">WPF is remoted completely as bitmaps</a>.</p>
<p>Microsoft is saying that this should actually improve performance in many cases. Well, we can only expect a future of more complex, denser GUI construction (I mean complex in the UI tree sense, not in the end user’s perception of complexity). So the 100%-bitmap-remoting solution may be needed in the long term anyway. But I’m not sure I agree with the timing of this decision. Bitmap remoting so far performs an order of magnitude slower for me than graphic primitive remoting, at least in the everyday apps I use through RDP.</p>
<h2>Bye Bye WinForms</h2>
<p>It’s clear to me that anyone working in WinForms should ditch it as soon as possible in favor of WPF. Rewriting old tools is always a cost-benefit analysis, but for new tools, this is clearly the way to go. Especially if you’re in control of your user environment, such as within the enterprise, where you can force install the framework on every machine.</p>
<p>If you’re still hanging out in the WinForms world, or considering buying an expensive Forms-based UI package to pick up the pace on building UI’s, you really ought to take a hard look at WPF.</p>
<p>Don’t expect to be productive immediately, or even within a month. It will take a while to get used to it, learn the framework, and develop patterns to use in building UI. It’s time well spent. This is clearly the future.</p>
<a href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Ffinally-onto-wpf%2F&amp;linkname=Finally%20Onto%20WPF" title="Delicious" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a> <a href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Ffinally-onto-wpf%2F&amp;linkname=Finally%20Onto%20WPF" title="Digg" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a> <a href="http://www.addtoany.com/add_to/facebook?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Ffinally-onto-wpf%2F&amp;linkname=Finally%20Onto%20WPF" title="Facebook" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/facebook.png" width="16" height="16" alt="Facebook"/></a> <a href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Ffinally-onto-wpf%2F&amp;linkname=Finally%20Onto%20WPF" title="Reddit" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a> <a href="http://www.addtoany.com/add_to/twitter?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Ffinally-onto-wpf%2F&amp;linkname=Finally%20Onto%20WPF" title="Twitter" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/twitter.png" width="16" height="16" alt="Twitter"/></a> <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Ffinally-onto-wpf%2F&amp;linkname=Finally%20Onto%20WPF">Share/Save</a>]]></content:encoded>
			<wfw:commentRss>http://scottbilas.com/blog/finally-onto-wpf/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>You Have Slain A Magic Mushroom!</title>
		<link>http://scottbilas.com/blog/you-have-slain-a-magic-mushroom/</link>
		<comments>http://scottbilas.com/blog/you-have-slain-a-magic-mushroom/#comments</comments>
		<pubDate>Sun, 27 Dec 2009 20:00:00 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[game review]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[ipod]]></category>

		<guid isPermaLink="false">http://scottbilas.com/?p=374</guid>
		<description><![CDATA[I’m excited. The classic Sword of Fargoal has been remade for the iPhonepod platform!
Sword of Fargoal is an ancient Rogue-style game for the C-64, written by Jeff McCord in BASIC (I remember curiously walking through the source code) and published by the long-defunct Epyx, one of my favorite publishers from back in the day. When [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://scottbilas.com/wp-content/uploads/2009/12/foto.jpg"><strong><a href="http://www.fargoal.com"><img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 10px 10px; display: inline; border-top: 0px; border-right: 0px" title="Sword of Fargoal" border="0" alt="Sword of Fargoal" align="right" src="http://scottbilas.com/wp-content/uploads/2009/12/foto1.jpg" width="205" height="69" /></a></strong></a><strong>I’m excited</strong>. The classic <a href="http://en.wikipedia.org/wiki/Sword_of_Fargoal">Sword of Fargoal</a> has been remade for the iPhonepod platform!</p>
<p>Sword of Fargoal is an ancient Rogue-style game for the C-64, written by Jeff McCord in BASIC (I remember curiously walking through the source code) and published by the long-defunct Epyx, one of my favorite publishers from back in the day. When I was a kid I played the hell out of this game and I’m excited to see some game developers who are even bigger fans than me have gone and remade this awesome game.</p>
<p><img style="border-bottom: 0px; border-left: 0px; margin: 0px 10px 10px 0px; display: inline; border-top: 0px; border-right: 0px" title="Thud!" border="0" alt="Thud!" align="left" src="http://scottbilas.com/wp-content/uploads/2009/12/image7.png" width="221" height="257" /> </p>
<p>I’ve been playing <a href="http://www.fargoal.com/">Fargoal LLC</a>’s remake on my iPhone (available <a href="http://click.linksynergy.com/fs-bin/stat?id=I0JoByZ7gc8&amp;offerid=146261&amp;type=3&amp;subid=0&amp;tmpid=1826&amp;RD_PARM1=http%253A%252F%252Fitunes.apple.com%252Fus%252Fapp%252Fsword-fargoal%252Fid343242870%253Fmt%253D8%2526uo%253D6%2526partnerId%253D30">here</a> at the App Store for only five bucks!) and it’s clearly a labor of love. Most remakes of classics are disappointing. Someone writes an emulator and they just run the old game on new hardware. It’s 100% authentic and all, but <em>that’s not necessarily a good thing</em>.</p>
<p>You’re all excited to play the game you loved as a kid, and then, five minutes in you realize that..oh..this game is kind of frustrating, annoying even.. It’s not because the game is <em>bad</em>, it’s because the world of gaming has changed since then.</p>
<p>As an industry we’ve moved <strong>far past</strong> the primitive control techniques and UI’s of the past. We expect to have tutorials and hint screens, auto-save and context-sensitive UI gizmos that help us out.</p>
<p>Old games just didn’t have room for any of that in their 8K or whatever of ROM. While this gave some insane replayability, and created a small sub-industry of invisible ink cheat books, learn-by-dying is just a thing of the past. It’s no fun.</p>
<p>I’m happy to report that the developers of the new Sword of Fargoal did more than just slap some upgraded graphics on this game. They’ve added help, auto-save, and a great control scheme (moving diagonally on the C-64 joysticks was always a dicey affair). But my favorite is a great new feature called the “Smart button” that gives you context-sensitive actions, such as using a teleport spell right when the ceiling is about to collapse on you.</p>
<p>Fargoal LLC has big respect from me. I’m already in love with this game again and now I can bring it everywhere with me. All I need is some OpenFeint (or similar) integration to compete with my brother.</p>
<p>Anyway, go buy Sword of Fargoal immediately. Swoosh! Clang! Thud!!</p>
<a href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fyou-have-slain-a-magic-mushroom%2F&amp;linkname=You%20Have%20Slain%20A%20Magic%20Mushroom%21" title="Delicious" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a> <a href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fyou-have-slain-a-magic-mushroom%2F&amp;linkname=You%20Have%20Slain%20A%20Magic%20Mushroom%21" title="Digg" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a> <a href="http://www.addtoany.com/add_to/facebook?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fyou-have-slain-a-magic-mushroom%2F&amp;linkname=You%20Have%20Slain%20A%20Magic%20Mushroom%21" title="Facebook" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/facebook.png" width="16" height="16" alt="Facebook"/></a> <a href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fyou-have-slain-a-magic-mushroom%2F&amp;linkname=You%20Have%20Slain%20A%20Magic%20Mushroom%21" title="Reddit" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a> <a href="http://www.addtoany.com/add_to/twitter?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fyou-have-slain-a-magic-mushroom%2F&amp;linkname=You%20Have%20Slain%20A%20Magic%20Mushroom%21" title="Twitter" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/twitter.png" width="16" height="16" alt="Twitter"/></a> <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fyou-have-slain-a-magic-mushroom%2F&amp;linkname=You%20Have%20Slain%20A%20Magic%20Mushroom%21">Share/Save</a>]]></content:encoded>
			<wfw:commentRss>http://scottbilas.com/blog/you-have-slain-a-magic-mushroom/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ultimate AS3 Fake Enums</title>
		<link>http://scottbilas.com/blog/ultimate-as3-fake-enums/</link>
		<comments>http://scottbilas.com/blog/ultimate-as3-fake-enums/#comments</comments>
		<pubDate>Thu, 24 Dec 2009 22:00:00 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[enum]]></category>
		<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://scottbilas.com/?p=351</guid>
		<description><![CDATA[I just can’t leave this thing alone. This is hopefully the last revision I’m going to make to my fake AS3 enum class (here’s the original posting, then two updates). This is inspired by commenter Mikko Korpela, who asked about an iteration ability. Well, that sounds like a fun idea! Let’s fill in some holes [...]]]></description>
			<content:encoded><![CDATA[<p>I just can’t leave this thing alone. This is hopefully the last revision I’m going to make to my fake AS3 enum class (here’s the <a href="http://scottbilas.com/blog/faking-enums-in-as3/">original posting</a>, then <a href="http://scottbilas.com/blog/update-faking-enums-in-as3/">two</a> <a href="http://scottbilas.com/2008/12/16/update-2-faking-enums-in-as3/">updates</a>). This is inspired by commenter Mikko Korpela, who <a href="http://scottbilas.com/2008/12/16/update-2-faking-enums-in-as3/#comment-304">asked about</a> an iteration ability. Well, that sounds like a fun idea! Let’s fill in some holes and bring it up to par with the enum support in C#.</p>
<p><em>Sorry it took me so long to get around to this Miko, but I’ve had my Flex work on hold for a while. But recently I did some Flash work at </em><a href="http://www.popcap.com"><em>PopCap</em></a><em> and it got me back in the mood again.</em></p>
<h2>New Enum Features</h2>
<p>Here’s my Ultimate AS3 Fake Enum class, which has the following new features:</p>
<ul>
<li>Further type safety. Only the enum can construct its own constants now, via enum constructor protection. This should prevent people using the constants incorrectly (e.g. someone is incorrectly <strong>new</strong>’ing them up instead of using <i>MyEnum.MyConstant</i>). </li>
<li>Every constant now gets a zero-based index that corresponds to the order it is created in the class. Access via the <strong>Index</strong> accessor on the constant. Useful in serialization code, for example. </li>
<li>Added a new <strong>GetConstants</strong> method that returns an array of all the constants, where each constant’s slot in the array corresponds to its <strong>Index</strong>. </li>
<li>Added a new <strong>ParseConstant</strong> method that does the reverse of <strong>toString()</strong>. Given a constant’s <strong>Name</strong>, return the constant. Case sensitivity optional and off by default for convenience. </li>
</ul>
<p>&#8230;all without any extra burden placed on the derivative class! <i>I’m always interested in solutions that keep client code as clean as possible.</i></p>
<p>I also adjusted the code to my current AS3 coding standards, which is nearly the same as Microsoft’s C# standards. <em>Note that I’d normally use <strong>Vector.&lt;Enum&gt;</strong> instead of the generic <strong>Array</strong> class, but I haven’t upgraded my Flex to the newest SDK yet.</em></p>
<h2>The Code</h2>
<p>Without further ado, here’s the new <strong>Enum.as</strong> file. Stick it in a package if you wish, and drop it wherever you like. No system setup is required to make it work.</p>
<pre class="brush: as3;">
package
{
	import flash.utils.*;

	public /*abstract*/ class Enum
	{
		public function get Name()  :String { return _name; }
		public function get Index() :int    { return _index; }

		public /*override*/ function toString() :String { return Name; }

		public static function GetConstants(i_type :Class) :Array
		{
			var constants :EnumConstants = _enumDb[getQualifiedClassName(i_type)];
			if (constants == null)
				return null;

			// return a copy to prevent caller modifications
			return constants.ByIndex.slice();
		}

		public static function ParseConstant(
				i_type			:Class,
				i_constantName  :String,
				i_caseSensitive :Boolean = false) :Enum
		{
			var constants :EnumConstants = _enumDb[getQualifiedClassName(i_type)];
			if (constants == null)
				return null;

			var constant :Enum = constants.ByName[i_constantName.toLowerCase()];
			if (i_caseSensitive &amp;&amp; (constant != null) &amp;&amp; (i_constantName != constant.Name))
				return null;

			return constant;
		}

		/*-----------------------------------------------------------------*/

		/*protected*/ function Enum()
		{
			var typeName :String = getQualifiedClassName(this);

			// discourage people new'ing up constants on their own instead
			// of using the class constants
			if (_enumDb[typeName] != null)
			{
				throw new Error(
					&quot;Enum constants can only be constructed as static consts &quot; +
					&quot;in their own enum class &quot; + &quot;(bad type='&quot; + typeName + &quot;')&quot;);
			}

			// if opening up a new type, alloc an array for its constants
			var constants :Array = _pendingDb[typeName];
			if (constants == null)
				_pendingDb[typeName] = constants = [];

			// record
			_index = constants.length;
			constants.push(this);
		}

		protected static function initEnum(i_type :Class) :void
		{
			var typeName :String = getQualifiedClassName(i_type);

			// can't call initEnum twice on same type (likely copy-paste bug)
			if (_enumDb[typeName] != null)
			{
				throw new Error(
					&quot;Can't initialize enum twice (type='&quot; + typeName + &quot;')&quot;);
			}

			// no constant is technically ok, but it's probably a copy-paste bug
			var constants :Array = _pendingDb[typeName];
			if (constants == null)
			{
				throw new Error(
					&quot;Can't have an enum without any constants (type='&quot; +
					typeName + &quot;')&quot;);
			}

			// process constants
			var type :XML = flash.utils.describeType(i_type);
			for each (var constant :XML in type.constant)
			{
				// this will fail to coerce if the type isn't inherited from Enum
				var enumConstant :Enum = i_type[constant.@name];

				// if the types don't match then probably have a copy-paste error.
				// this is really common so it's good to catch it here.
				var enumConstantType :* = Object(enumConstant).constructor;
				if (enumConstantType != i_type)
				{
					throw new Error(
						&quot;Constant type '&quot; + enumConstantType + &quot;' &quot; +
						&quot;does not match its enum class '&quot; + i_type + &quot;'&quot;);
				}

				enumConstant._name = constant.@name;
			}

			// now seal it
			_pendingDb[typeName] = null;
			_enumDb[typeName] = new EnumConstants(constants);
		}

		private var _name :String = null;
		private var _index :int = -1;

		private static var _pendingDb :Object = {};	// typename -&gt; [constants]
		private static var _enumDb	  :Object = {};	// typename -&gt; EnumConstants
	}
}

// private support class
class EnumConstants
{
	public function EnumConstants(i_byIndex :Array)
	{
		ByIndex = i_byIndex;

		for (var i :int = 0; i &lt; ByIndex.length; ++i)
		{
			var enumConstant :Enum = ByIndex[i];
			ByName[enumConstant.Name.toLowerCase()] = enumConstant;
		}
	}

	public var ByIndex :Array;
	public var ByName :Object = {};
}
</pre>
<h2>The Samples</h2>
<p>Here are a couple sample enums and some code to demonstrate the features.</p>
<h3>Simple Enum: State</h3>
<p>This is the simplest usage of the <strong>Enum</strong> class. All you have to do to make a fake enum is:</p>
<ol>
<li>Create a class that extends the <strong>Enum</strong> class. Tag it as <strong>final</strong> too so nobody inherits it (that would be weird).</li>
<li>Put some static init code in there that just calls <strong>initEnum(MyTypeName)</strong>. This will get run on demand, on the first usage of the enum by other code. It sets up the necessary lookup tables and attaches a Name and Index to each enum constant.</li>
<li>Create a <strong>public static const</strong> for each enum constant you want, following the pattern in the sample.</li>
</ol>
<p>Here&#8217;s the sample enum. Note that it includes a bug on purpose! (It&#8217;s clearly marked.)</p>
<pre class="brush: as3;">
package
{
	public final class State extends Enum
	{
		{initEnum(State);} // static ctor

		public static const Initializing :State = new State();
		public static const Connecting   :State = new State();
		public static const Loading      :State = new State();
		public static const Ready        :State = new State();

		// illegal; this will fail at runtime
		public static const Test		 :OtherEnum = new OtherEnum();
	}
}
</pre>
<p>And some test code to walk through the features…</p>
<pre class="brush: as3;">
for each (var state :State in Enum.GetConstants(State))
{
	trace(state.Index + &quot;: &quot; + state.Name);
}

trace(&quot;connecting (no case): &quot; + Enum.ParseConstant(State, &quot;connecting&quot;));
trace(&quot;connecting (with case): &quot; + Enum.ParseConstant(State, &quot;connecting&quot;, true));

// illegal; gets a runtime exception
var someEnum :State = new State();
</pre>
<p>Which produces the following output:</p>
<pre class="brush: plain;">
0: Initializing
1: Connecting
2: Loading
3: Ready
connecting (no case): Connecting
connecting (with case): null
Error: Enum constants can only be constructed as static consts in their own enum class (bad type='State')
 ...
</pre>
<h3>Advanced Enum: NetError</h3>
<p>Let’s look at a more advanced sample, which I’m calling an “attributed” enum. Let’s say we have a NetError enum with constants for different types of failures on a network request. We want to be able to show a more user-friendly error, and perhaps classify it as a fatal error or not. We could have a table that associates extended attributes for enum constants with those constants, but why not just attach them to the constants directly?</p>
<p>In .NET I’d do this with attributes. Now, AS3 doesn’t support attributes like we need, so we’ll have to fake it. Given that we already have a fake enum constant, which is really an object underneath, we can attach whatever we like to it!</p>
<p>Take a look at the sample enum.</p>
<pre class="brush: as3;">
package
{
	public final class NetError extends Enum
	{
		{ initEnum(NetError); } // static ctor

	// Constants.

		public static const None			:NetError = new NetError(false, &quot;no error&quot;);
		public static const CantConnect		:NetError = new NetError(false, &quot;can't connect to the server, must be down?&quot;);
		public static const VersionMismatch	:NetError = new NetError(true,  &quot;protocol versions different&quot;);
		public static const Unknown			:NetError = new NetError(true,  &quot;unexpected error type&quot;);

	// Constant attributes.

		public function get IsFatal()	  :Boolean	{ return _isFatal; }
		public function get Description() :String	{ return _description; }		

	// Constant query.

		public static function GetConstants() :Array
			{ return Enum.GetConstants(NetError); }
		public static function ParseConstant(i_constantName :String, i_caseSensitive :Boolean = false) :NetError
			{ return NetError(Enum.ParseConstant(NetError, i_constantName, i_caseSensitive)); }

	// Private.

		/*private*/ function NetError(i_isFatal :Boolean, i_description :String)
			{ _isFatal = i_isFatal; _description = i_description; }
		private var _isFatal	 :Boolean;
		private var _description :String;
	}
}
</pre>
<p>Given a constant, perhaps returned from a function as an error code, or thrown as part of an exception, we can ask it for its friendlier name by accessing its <strong>Description</strong> member.</p>
<p>Also in this class note the helper functions <strong>GetConstants</strong> and <strong>ParseConstant</strong> that wrap the <strong>Enum</strong> class versions, automatically passing in the local type. This isn’t necessary, but is a nice convenience. It is a bit more code to copy-paste around when adding new enums, though. If only AS3 supported templates, we could have a <strong>TEnum</strong> base that does all this for us. Ah well.</p>
<p>Here is some test code to play with the features</p>
<pre class="brush: as3;">
for each (var netError :NetError in NetError.GetConstants())
{
	trace(
		netError.Index + &quot;: &quot; + netError.Name +
		&quot; (&quot; + netError.Description + &quot;) &quot; +
		(netError.IsFatal ? &quot;[FATAL]&quot; : &quot;&quot;));
}
</pre>
<p>Which produces the following output:</p>
<pre class="brush: plain;">
0: None (no error)
1: CantConnect (can't connect to the server, must be down?)
2: VersionMismatch (protocol versions different) [FATAL]
3: Unknown (unexpected error type) [FATAL]
</pre>
<h2>Future?</h2>
<p>I hope this is the last word on fake enums in Actionscript. Not because I don’t think anyone else can improve on it, but because I’m hoping that the next version of the language will have native support for enums. Then we can put all this fakery behind us and get on with our lives.</p>
<p>The enum posts are among the top hitters on my blog, and they are popular topics elsewhere on the web. I’m hoping that Adobe will strongly consider native enum support in their next Flash player.</p>
<a href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fultimate-as3-fake-enums%2F&amp;linkname=Ultimate%20AS3%20Fake%20Enums" title="Delicious" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a> <a href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fultimate-as3-fake-enums%2F&amp;linkname=Ultimate%20AS3%20Fake%20Enums" title="Digg" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a> <a href="http://www.addtoany.com/add_to/facebook?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fultimate-as3-fake-enums%2F&amp;linkname=Ultimate%20AS3%20Fake%20Enums" title="Facebook" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/facebook.png" width="16" height="16" alt="Facebook"/></a> <a href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fultimate-as3-fake-enums%2F&amp;linkname=Ultimate%20AS3%20Fake%20Enums" title="Reddit" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a> <a href="http://www.addtoany.com/add_to/twitter?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fultimate-as3-fake-enums%2F&amp;linkname=Ultimate%20AS3%20Fake%20Enums" title="Twitter" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/twitter.png" width="16" height="16" alt="Twitter"/></a> <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fultimate-as3-fake-enums%2F&amp;linkname=Ultimate%20AS3%20Fake%20Enums">Share/Save</a>]]></content:encoded>
			<wfw:commentRss>http://scottbilas.com/blog/ultimate-as3-fake-enums/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Upcoming Perforce Feature: Shelving</title>
		<link>http://scottbilas.com/blog/upcoming-perforce-feature-shelving/</link>
		<comments>http://scottbilas.com/blog/upcoming-perforce-feature-shelving/#comments</comments>
		<pubDate>Tue, 22 Dec 2009 21:37:11 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[p4]]></category>

		<guid isPermaLink="false">http://scottbilas.com/2009/12/22/upcoming-perforce-feature-shelving/</guid>
		<description><![CDATA[Perforce announced on their blog that they have a new feature in beta testing called “shelve”. Great!
In short, “shelving” is taking a pending changelist and publishing it to the server without checking it into the depot.
As I mentioned in a previous post, this is one of the top features from git that was making me [...]]]></description>
			<content:encoded><![CDATA[<p>Perforce <a href="http://blog.perforce.com/blog/?p=1872">announced</a> on their <a href="http://blog.perforce.com">blog</a> that they have a new feature in beta testing called “shelve”. Great!</p>
<p>In short, “shelving” is taking a pending changelist and publishing it to the server without checking it into the depot.</p>
<p>As I mentioned in a <a href="http://scottbilas.com/2009/04/24/perforce-vs-git/">previous post</a>, this is one of the top features from git that was making me seriously consider checking it out. I started implementing this myself in my p4.exe wrapper, but I never gave it enough priority to get much work done. I’m excited to know that Perforce are adding it themselves. This is the first new feature I’ve seen from them in years that is worth upgrading for!</p>
<p>The things that interest me most about this ability are:</p>
<ul>
<li>Easy trading of in-progress work in a formal, server-supported way that is done out-of-band of the depot, so it cannot break the rest of the team. Good for <a href="http://scottbilas.com/2009/08/26/peer-code-reviews-how-did-we-do/">code reviews</a>, small tests, moving the same pending changes among multiple machines/clients, etc.</li>
<li>Easy, incremental backup of works in progress. This is <em>hot</em>.</li>
<li>Easy ability to temporarily put aside a local change in order to work on something else that collides (typically as an emergency). This eliminates the main reason I needed to use several P4 clients on the same machine.</li>
</ul>
<p>I hope Crucible will have support for this great new feature after it’s released. That would eliminate most of the need for the <a href="http://scottbilas.com/2009/08/05/about-our-crucible-perforce-bridge/">tool</a> I wrote.</p>
<p>I’m looking forward to seeing this new feature in 2010.</p>
<a href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fupcoming-perforce-feature-shelving%2F&amp;linkname=Upcoming%20Perforce%20Feature%3A%20Shelving" title="Delicious" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a> <a href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fupcoming-perforce-feature-shelving%2F&amp;linkname=Upcoming%20Perforce%20Feature%3A%20Shelving" title="Digg" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a> <a href="http://www.addtoany.com/add_to/facebook?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fupcoming-perforce-feature-shelving%2F&amp;linkname=Upcoming%20Perforce%20Feature%3A%20Shelving" title="Facebook" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/facebook.png" width="16" height="16" alt="Facebook"/></a> <a href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fupcoming-perforce-feature-shelving%2F&amp;linkname=Upcoming%20Perforce%20Feature%3A%20Shelving" title="Reddit" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a> <a href="http://www.addtoany.com/add_to/twitter?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fupcoming-perforce-feature-shelving%2F&amp;linkname=Upcoming%20Perforce%20Feature%3A%20Shelving" title="Twitter" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/twitter.png" width="16" height="16" alt="Twitter"/></a> <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fupcoming-perforce-feature-shelving%2F&amp;linkname=Upcoming%20Perforce%20Feature%3A%20Shelving">Share/Save</a>]]></content:encoded>
			<wfw:commentRss>http://scottbilas.com/blog/upcoming-perforce-feature-shelving/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Bungified</title>
		<link>http://scottbilas.com/blog/bungified/</link>
		<comments>http://scottbilas.com/blog/bungified/#comments</comments>
		<pubDate>Thu, 10 Dec 2009 02:00:00 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[bungie]]></category>
		<category><![CDATA[loose cannon studios]]></category>

		<guid isPermaLink="false">http://scottbilas.com/2009/12/09/bungified/</guid>
		<description><![CDATA[ As I mentioned in my last post, I’ve been busy. Did a talk for Audiokinetic, some remodeling at home, supporting my lady in her new MBA program…
…and I got a new job.
Moving On
I’ve moved on from Loose Cannon and am now working at Bungie. The reasons are personal and private, and were due to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://scottbilas.com/wp-content/uploads/2009/12/Tracks.jpg"><img style="border-right-width: 0px; margin: 0px 0px 10px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Tracks in the desert" border="0" alt="Tracks in the desert" align="right" src="http://scottbilas.com/wp-content/uploads/2009/12/Tracks_thumb.jpg" width="150" height="113" /></a> As I mentioned in my last <a href="http://scottbilas.com/?p=340">post</a>, I’ve been busy. Did a talk for <a href="http://www.audiokinetic.com">Audiokinetic</a>, some remodeling at home, supporting my <a href="http://sparklingallison.com">lady</a> in her new MBA program…</p>
<p><em>…and I got a new job.</em></p>
<h2>Moving On</h2>
<p>I’ve moved on from <a href="http://www.loosecannonstudios.com">Loose Cannon</a> and am now working at <a href="http://www.bungie.com">Bungie</a>. The reasons are personal and private, and were due to circumstances beyond anyone’s control. It was the most difficult, painful choice I’ve ever had to make about anything.</p>
<p>So I’ve been laying low while all the emotion passes..it’s felt a lot like breaking up with a girl, I think. Similar feelings, similar lost personal investment, similar broken ties. Similar number of depressing hangovers.</p>
<p>The Loose Cannon crew is a great bunch of intensely creative and smart people, and I wish them all the best. They always treated me very well and I miss them.</p>
<h2>Enter The Bungie</h2>
<p>So now I’m at Bungie. First off, let me make it clear that I don’t speak for the company in any way. But further than that: just because I talk about something on my blog here doesn’t mean it has anything to do with what I’m working on at Bungie, so please don’t make any assumptions to that effect. I’ve been writing and lecturing for a long time now, and have a lot of personal projects and research that I do. This will continue as before.</p>
<p>Now, a lot of the writing that I’ve done has in fact been based directly on my ongoing work on a particular game. Previous companies I’ve worked for have been supportive of, or at least indifferent to, my talking about technical details of our setup or research I’m doing. That doesn’t necessarily have to stop now that I’ve joined Bungie, where they have recently started sharing <a href="http://www.bungie.net/Inside/publications.aspx">quite a lot of information</a>. But it does mean I have to be more careful and get things cleared before saying “this is in our upcoming Halo match-3 game”.</p>
<p>For the moment though, it’s a moot point. I just started and don’t know anything yet.</p>
<p>On the other side of the coin, there are some loose ends I never tied off from <a href="http://scottbilas.com/2009/06/13/almost-gold">previous</a> <a href="http://scottbilas.com/2009/09/22/on-build-integrity/">posts</a>. Now that I’m no longer part of Loose Cannon, I can’t talk about work I did there, or reference code, which I no longer have access to. I think I can speak in generalities, though, about some high level concepts that wouldn’t be specific to the work I did there. We’ll see!</p>
<a href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fbungified%2F&amp;linkname=Bungified" title="Delicious" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a> <a href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fbungified%2F&amp;linkname=Bungified" title="Digg" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a> <a href="http://www.addtoany.com/add_to/facebook?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fbungified%2F&amp;linkname=Bungified" title="Facebook" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/facebook.png" width="16" height="16" alt="Facebook"/></a> <a href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fbungified%2F&amp;linkname=Bungified" title="Reddit" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a> <a href="http://www.addtoany.com/add_to/twitter?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fbungified%2F&amp;linkname=Bungified" title="Twitter" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/twitter.png" width="16" height="16" alt="Twitter"/></a> <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Fbungified%2F&amp;linkname=Bungified">Share/Save</a>]]></content:encoded>
			<wfw:commentRss>http://scottbilas.com/blog/bungified/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tornado Outbreak + Wwise = Love</title>
		<link>http://scottbilas.com/blog/tornado-outbreak-wwise-love/</link>
		<comments>http://scottbilas.com/blog/tornado-outbreak-wwise-love/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 20:50:44 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[conference]]></category>
		<category><![CDATA[loose cannon studios]]></category>
		<category><![CDATA[wwise]]></category>

		<guid isPermaLink="false">http://scottbilas.com/?p=340</guid>
		<description><![CDATA[Well obviously it’s been really quiet here lately. A lot has been going on in my personal life, but the end is in sight. One of the things I’ve been doing is working on a talk for Audiokinetic for their 2009 Wwise Tour. I presented it over at Microsoft last week as part of a [...]]]></description>
			<content:encoded><![CDATA[<p><a title="Tornado Outbreak" href="http://www.konami.com/games/tornado/"><img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 10px 10px; display: inline; border-top: 0px; border-right: 0px" title="Tornado Outbreak" border="0" alt="Tornado Outbreak" align="right" src="http://scottbilas.com/wp-content/uploads/2009/11/image.png" width="153" height="160" /></a>Well obviously it’s been really quiet here lately. A lot has been going on in my personal life, but the end is in sight. One of the things I’ve been doing is working on a talk for Audiokinetic for their 2009 Wwise Tour. I presented it over at Microsoft last week as part of a tag-team with Robert Ridihalgh of <a href="http://omniaudio.com/">OMNI Interactive</a> (he was the principle audio engineer on Tornado Outbreak).</p>
<p>Oh, did I forget to post on here that <a href="http://www.konami.com/games/tornado/">our game</a> shipped? Wow, I totally did! Well, we shipped in September on <a href="http://www.amazon.com/Tornado-Outbreak-Xbox-360/dp/B002BSA1WQ/ref=sr_1_1?ie=UTF8&amp;s=videogames&amp;qid=1258313834&amp;sr=8-1">360</a>, <a href="http://www.amazon.com/Tornado-Outbreak-Playstation-3/dp/B002BRZ6Z4/ref=sr_1_2?ie=UTF8&amp;s=videogames&amp;qid=1258313834&amp;sr=8-2">PS3</a>, and <a href="http://www.amazon.com/Tornado-Outbreak-Nintendo-Wii/dp/B002BS4JI8/ref=sr_1_3?ie=UTF8&amp;s=videogames&amp;qid=1258313834&amp;sr=8-3">Wii</a>. Become a <a href="http://www.facebook.com/#/pages/Tornado-Outbreak/295642410413?ref=search&amp;sid=735055878.316616379..1">fan</a> on Facebook!</p>
<p>The reviews have generally been in the B range, though Metacritic’s <a href="http://www.metacritic.com/search/process?sort=relevance&amp;termtype=all&amp;ts=tornado+outbreak&amp;ty=0&amp;button=search">average</a> is a little depressing at ~70. Nearly every review uses the words “Katamari” and “clone” which makes me think they didn’t really give the game a chance. The similarities with Katamari begin and end at the concept of “grow bigger”. Might as well call Call of Duty a Doom clone because they both involve shooting things to get to the end of the level.</p>
<p>But whatever… I’m proud of our effort, and I think it’s a super fun game. Hell of a job for a small team with a tech base built from scratch, to ship on time and on budget on three platforms.</p>
<h2></h2>
</p>
</p>
<h2><a href="http://scottbilas.com/wp-content/uploads/2009/11/image1.png"><img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 10px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" align="right" src="http://scottbilas.com/wp-content/uploads/2009/11/image_thumb.png" width="91" height="120" /></a> Wwise Tour</h2>
<p>One of the reasons we were able to ship on time was <a href="http://www.audiokinetic.com">Audiokinetic’s</a> <a href="http://www.audiokinetic.com/4105/wwise-introduction.asp">Wwise</a>. I’ve been evangelizing this excellent sound engine to everybody I meet. I just can’t say enough good things about our friends up in Montreal. I’d use Wwise on every future game if I could.</p>
<p>On Tornado Outbreak, I did most of the engineering and the initial audio rig design and prototyping. Robert and his team did the actual audio work, and took over management of the Wwise project. They probably did 95% of the audio related work on the project, which is awesome! As everybody knows, engineers are really slow and are pulled in 20 directions at once, so the more I could step out of the way, the better.</p>
<p>Audiokinetic asked me to put together a talk for the <a href="http://www.audiokinetic.com/4105/events.asp">tour</a> they’re doing right now to promote the product, particularly the new features they’ve been adding. I invited Robert to join me and we presented the two halves of our audio solution for Tornado Outbreak. We split the presentation roughly along the lines of our responsibilities.</p>
<p>The event was recorded, so at some point we may see video clips showing up online. That will be necessary to get Robert’s part of the talk, because he was exclusively walking through the Wwise project, using elements of it to tell his story. So no slides, you’ll have to get the video if it comes out. Anyone using or considering Wwise should try to get a hold of that – his talk was really interesting and includes some great tricks on saving memory without sacrificing variety.</p>
<p>Now, all I know how to do is present slides, so here they are! Tornado Outbreak + Wwise = Love [<a href="http://scottbilas.com/files/2009/wwise_tour/wwise_tornado_love.pptx">PPT 2.5M</a>] [<a href="http://scottbilas.com/files/2009/wwise_tour/wwise_tornado_love.pdf">PDF 1.4M</a>].</p>
<h3></h3>
<h3>Our Project</h3>
<p>I also got approval from the bosses to release the Tornado Outbreak project file for Wwise. This is really generous of them to agree! Here it is. [<a href="http://scottbilas.com/files/2009/wwise_tour/tornado_outbreak_audio.zip">ZIP 1M</a>]</p>
<p>Note that this doesn’t include any content (wav files) but is only the project itself. That should be plenty though.</p>
<p>The point of releasing the project is to help out other studios who are integrating Wwise, in hopes that the favor will be returned. Everybody benefits from information sharing like this. With Wwise, in order to get a good rig set up you really need to have experience and good examples to draw from. As I say in my presentation, <em>Wwise is different</em>. Every other SDK out there is a “play samples + DSP” library. Getting the Wwise rig right is hard, and it’s not going to be right the first time. Just as if you were to build a Maya rig and had no experience with it before. You’ll screw it up for sure.</p>
<p>Audiokinetic provides some synthetic examples to help get started, but it’s not from a real, shipping game, and besides, every game is different. Tornado Outbreak has an enormous amount of unique objects that produce audio (over 400) and all those crashes and shakes and panics can become very difficult to manage. It would have saved a lot of time if, when I started building the initial rig, I had some examples to draw from. To that end, we’re releasing our particular solution for this situation. I hope that it inspires even better solutions and ideas on how to tackle these kinds of problems in the future.</p>
<p>Enjoy.</p>
<a href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Ftornado-outbreak-wwise-love%2F&amp;linkname=Tornado%20Outbreak%20%2B%20Wwise%20%3D%20Love" title="Delicious" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a> <a href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Ftornado-outbreak-wwise-love%2F&amp;linkname=Tornado%20Outbreak%20%2B%20Wwise%20%3D%20Love" title="Digg" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a> <a href="http://www.addtoany.com/add_to/facebook?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Ftornado-outbreak-wwise-love%2F&amp;linkname=Tornado%20Outbreak%20%2B%20Wwise%20%3D%20Love" title="Facebook" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/facebook.png" width="16" height="16" alt="Facebook"/></a> <a href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Ftornado-outbreak-wwise-love%2F&amp;linkname=Tornado%20Outbreak%20%2B%20Wwise%20%3D%20Love" title="Reddit" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a> <a href="http://www.addtoany.com/add_to/twitter?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Ftornado-outbreak-wwise-love%2F&amp;linkname=Tornado%20Outbreak%20%2B%20Wwise%20%3D%20Love" title="Twitter" rel="nofollow" target="_blank"><img src="http://scottbilas.com/wp-content/plugins/add-to-any/icons/twitter.png" width="16" height="16" alt="Twitter"/></a> <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fscottbilas.com%2Fblog%2Ftornado-outbreak-wwise-love%2F&amp;linkname=Tornado%20Outbreak%20%2B%20Wwise%20%3D%20Love">Share/Save</a>]]></content:encoded>
			<wfw:commentRss>http://scottbilas.com/blog/tornado-outbreak-wwise-love/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
