Mud Designer Sprint 1

I have layed out the user stories for the first sprint in my effort to re-establish development of the Mud Engine. I have a clear path now that I will follow and with any luck, complete the sprint on time. My sprint starts tonight and will run for two weeks.

Currently, the engine modifications already include the re-wrote telnet server, so now I am moving forward with the World. The world needs to go ahead and get wrapped up, so I am implementing day/night transitions, weather support, server wide time of day states and some events that other objects can register to receive.

Mud Design - The Agile Way

One of the issues the Mud Designer has suffered with over the years is lack of direction. I have a grand vision, but don't have any kind of proper design documentation wrote up or flow charts created to indicate the apps flow. Without a lot of the lower level stuff defined, I find myself hitting barriers because of gaps in the engine I missed. I end up fixing or adding things to bridge the gap, which in turn break other items in the engine and before I know it, I've someone managed to modify a massive chunk of the engine in one check-in.

If it's one thing I've learned from my day job, is that improper planning can ruin a product. We spend a lot of time planning and making sure things are crystal clear before progressing and it makes a huge difference. In our previous Sprint, I improperly planned it and we failed to finish it. This really made me think about the Mud Engine too. I haven't ever properly planned out what the finished product is, nor what features it should fully support. That's going to change.

I created a VisualStudio online project tonight for the Mud Designer. It gives me access to a full TFS project, with Agile planning tools, user story and work item support and source control support all in one. The plus side is I have a one stop shop for the project and it's work items. I'll even be able to attach Tasks, User Stories and Bug items to my check-ins. The fact that it supports Git is a plus, however I just stuck with the standard TFS source control since that's what I use on a daily basis at work.

The downside to this is that VisualStudio online does not support open source projects. So the source code will no longer be hosted on Codeplex. I will provide the source code as a download on codeplex, so I can stay within the Codeplex policies, but the actual source code repository will be moved to a closed server.

Most of the users who downloaded the product, did not download the source so I don't think this will be a big deal. The source will still be available, just at a higher scope. Each individual check-in will not be made readily available to the public.

So moving forward, I've started writing user stories and got on board the agile bandwagon for Mud. I have a lot of ideas that I have always wanted to do, but never got them wrote down. Without seeing the cool concepts and ideas every day, motivation tends to suffer. This should go a long way towards addressing that. I'm also anxious to start tackling it in verticle slices and shipping a product again. I enjoyed the feedback and communication I received from users when I was actively pushing new versions out. I'm hoping to get some of that interaction back.

Reflection in Native C#

Today, Microsoft announced that their native .NET compiler in the cloud would support reflection via XML styled directive files. Essentially, the app will hit the XML for meta-data associated with a Type it needs to reflect in order to access its Members. This is interesting but could create a headache for develoeprs in the App Store.

There is potential that this might cause problems in the apps, by having static assemblies try to do something that a dynamic assembly was designed to do. If the application crashes due to an issue with the reflection work-around Microsoft is using it will be hard for a developer to troubleshoot it. The developer will try to reproduce the steps required to crash, only to have the app work in the development environment. Since the native conversion takes place in the cloud, I would be extremely apprehensive about enabling this feature on any of my apps.

It would be one thing if I could perform this conversion locally so I can test it, but there is a lot of requirements for native compiling due to varying hardware that would make this feature expensive for local builds.

My current project doesn't make use of Reflection and so if I need to, I could make it native. My next planned project (already started on) makes heavy use of reflection so I'll probably avoid native C#.

Why I prefer C# Development over Objective-C

I spent the bulk of 2012 and and all of 2013 developing on iOS in Objective-C and found it pretty decent. As I got more and more experienced with it, I began needing to do more and more complex stuff. Things like using semaphores and digging in to some of the lower level C functions in Foundation.

I have since moved back to using C#, and find my self enjoying development a lot more. The C# language and .NET framework have come a long way since 2005 when I first started using it. There are some things in Objective-C that just drove me crazy. Things like string literals for your Predicates. 

For example, to filter an array by a persons age in objective-c with a predicate, you do the following:

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"Age > %d", 21];
    NSArray *results  = [self.people filteredArrayUsingPredicate:predicate];
    

Filtering an array in C# is a lot easier. 

    var results = this.People
        .Where(p => p.Age > 21);
    

So much cleaner! There are things like this all throughout the .NET framework that are just really simple compared to Objective-C, with the exact same result. 

Another example is running something on a background thread. In objective-C, if I have three methods and I want to run one out of the three in the background, I have to do this:

    [self myFoo];
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
     [self heavyStuff];
     dispatch_async(dispatch_get_main_queue(), ^{
       [self myBar];
     });
    });
    

While in C#, I can do this:

    this.Foo();
    Task.Run(this.HeavyStuff);
    this.MyBar;
    

And I have ran the heavy method on another thread. Doing call backs in objective-c are pretty close to the same between the two languages. In objective-c:

    - (void)syncSelectedTags:(NSArray *)tags withFailure:(void (^)(NSError *))failure {
        if (!tags) {
            NSDictionary *syncErrorInfo = @{ @"Failure" : @"Could not begin tag synchronization",
                                         @"Reason" : @"A synchronization process is already running. Can not run more than one." };
            NSError *syncError = [NSError errorWithDomain:@"com.AllocateThis.LifeBlog.LBTagRepository.syncWithCompletion" code:0 userInfo:syncErrorInfo];
    
            failure(syncError);
        }
    }
    

In C# the code looks like:

    SyncSelectedTags(List<Tag> tags, Func<NullReferenceException> failure)
    {
        if (tags == null)
        {
            string message = string.Format(
                "{0}\n{1}",
                "Could not begin tag synchronization.",
                "A synchronization process is already running. Can not run more than one.");
            var syncError = new NullReferenceException(message);
            failure(syncError);
        }
    }
    

I really have gotten in to C# a lot more lately and really enjoy coding in it again. The framework and language is just so much cleaner and less verbose which makes readability much better and lets me focus more on just getting my product done rather than writing a lot of support code to perform a single action.

I did take a few things away from my time in Objective-C and that was making sure I adhere to standards better. In C# I wrote the code how I wanted to write it, and when I returned I've forced myself to adhere to the langauge standards. My source code has improved dramatically over the last 6 months. It's really nice being back in it.

Broadcast 1.1 Released

When I originally put Broadcast on Github, it provided synchronous and asynchronous broadcasting of messages that objects could register to receive.

I ran into a problem with the original release however. Any message that was broadcasted from another thread and received by a UI object, would throw an exception. UI elements can not be accessed from any thread other than the main thread.

For example, let's assume the user pressed a sync button. The sync process is very time consuming, so we need to run it asynchronously.

public class SyncManager
{
    public void Sync()
    {
        // Run sync async and return control to the UI.
        Task.Run(() => PerformSync());
    }

    private void PerformSync()
    {
        // Do sync stuff....



        // Notify UI that sync is completed.
        NotificationManager.PostNotification(this, "SyncFinished");
    }
}

Inside of our UI constructor we register to receive the notification.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        NotificationManager.RegisterObserver(this, "SyncFinished", this.HandleSyncComplete);
    }

    public void HandleSyncComplete(object sender, Dictionary<string, data-preserve-html-node="true" object> userData)
    {
        MessageBox.Show("Sync finished!");
    }
}

In the above code, when the MessageBox.Show is invoked, an exception would be thrown. This is caused by the fact that a UI element is being accessed from another thread. How do we fix this?

We can wrap each registered method in a

    public void HandleSyncComplete(object sender, Dictionary<string, data-preserve-html-node="true" object> userData)
    {
        Application.Current.Dispatcher.Invoke(() =>
            {
                MessageBox.Show("Sync completed!");
            });
    }

This is a real pain though. So in order to fix this, I looked into handling broadcasts on a specific thread. I discovered the SynchronizationContext class. So now we can tell the NotificationManager to run all synchronous broadcasts on the main thread.

NotificationManager.Context = System.Threading.SynchronizationContext.Current;

The SynchronizationContext.Current will grab the current threads SynchronizationContext. If you access this property from within a UI elements constructor, it will always provide the thread associated with the main UI thread. So we can modify our above MainWindow constructor to be like the following.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        NotificationManager.Context = System.Threading.SynchronizationContext.Current;

        NotificationManager.RegisterObserver(this, "SyncFinished", this.HandleSyncComplete);
    }

    public void HandleSyncComplete(object sender, Dictionary<string, data-preserve-html-node="true" object> userData)
    {
        MessageBox.Show("Sync finished!");
    }
}

Now when the "SyncFinished" notification is broadcasted, registered HandleSyncComplete method will be ran on the main thread. When the Messagebox.Show method is invoked, it will be invoked on the main thread and no longer throw an exception.

If the NotificationManager.Context property is null, the message will always be broadcasted on the same thread that the message was broadcasted from.

This only works in the message was broadcasted synchronously from within an Async method. If a message was broadcasted asynchronously from within an an Async method, the context is ignored and the message is broadcasted on it's own thread.

To provide support on the UI for these scenarios, you can register the observer and specify that it can not run async.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        NotificationManager.Context = System.Threading.SynchronizationContext.Current;

        NotificationManager.RegisterObserver(this, "SyncFinished", this.HandleSyncComplete, canRunAsync: false);
    }

    public void HandleSyncComplete(object sender, Dictionary<string, data-preserve-html-node="true" object> userData)
    {
        MessageBox.Show("Sync finished!");
    }
}

By setting the canRunAsync argument to false, the observer will have its method invoked in a synchronous fashion even if the message was posted asynchronously. If context is null, then it will still run async.