Sunday, March 02, 2014

 

Getting started with StrangeIoC

StrangeIoC is a design pattern enabler for Unity3D projects. It focuses on decoupling logic from presentation through the use of Inversion of Control. This idea is summed up well in this old (2008) but well explained hour long video: http://www.dnrtv.com/default.aspx?showNum=126

StrangeIoC compared to MVVM in XAML

I come from a XAML background, where MVVM is the popular pattern. Some initial mapping of StrangeIoC to something I'm familiar with helped me get a grasp of its goals. This is how I found MVVM maps to StrangeIoC:
Unity3D game objects are the MVVM View, the XAML & Codebehind
StrangeIoC ContextView, Root GameObject & MvcsContext are the binding of the MVVM View to the ViewModel, aka XAML's DataContext
StrangeIoC View and Mediator is the MVVM ViewModel, what's bound to XAML DataContext
StrangeIoC Model/Service is the MVVM Model

How StrangeIoC gets started

The first hook into StrangeIoC is a top level GameObject from the Unity3D Scene Hierarchy. The \examples\Assets\scenes\myfirstproject\TestView.unity example that comes with strange shows this on the "ViewGO" gameobject with its MyFirstProjectRoot.cs component script. The purpose of this Root.cs script is to define and initialize a StrangeIoC context. This is explained with detail in the StrangeIoC How-To. I was looking for something with a little less detail to get started.

Building a Unity3D app with rudimentary usage of StrangeIoC

I made a top level Cube gameObject and attached a CubeRoot.cs script to it:
using strange.extensions.context.impl;
public class CubeRoot : ContextView
{
 void Awake()
 {
  context = new CubeContext(this); 
 }
}
The CubeContext is the mapping container for all StrangeIoC objects. It's not used correctly in the code below, as no mapping is done. This usage instead allows you to test that you have StrangeIoC included in your project correctly.
using UnityEngine;
using strange.extensions.context.impl;
using strange.extensions.context.api;
public class CubeContext : MVCSContext
{
 public CubeContext(MonoBehaviour view) : base(view)
 {
  view.renderer.material.color = Color.yellow; //verify view loads it's context
 }
}
You now have a completed basic framework for StrangeIoC. You can run the project. The cube should change to yellow by using its context.

Following a pattern by using injection

The constructor of the context class is not the right place for making modifications to the view. The purpose of the Context is to define mappings between the MVCS layers and to define the scope where GameObjects can send or receive events from other GameObject.
The initialization of a GameObject's modifiable properties should be pulled from a model and put into a view. There are views for many GameObjects inside a single context. This should also be represented in the Unity3D Hierarchy by making GameObjects with a view be children of a GameObject with a context. We need a context GameObject in the Unity3D Hierarchy. Our cube either needs a parent empty GameObject with a CubeContext.cs component or to become an empty GameObject and have a child Cube object. We'll also need a new CubeView.cs script. This is what our GameObject Hierarchy should look like:
The CubeContext will contain all the bindings for this Context. To create bindings in a context we need to overload the mapBindings() function of MVCSContext. This binding says that within this context, any property of type Color that has the [Inject] attribute will be initialized with the value Color.red.
using UnityEngine;
using strange.extensions.context.impl;
using strange.extensions.context.api;

public class CubeContext : MVCSContext
{
 public CubeContext(MonoBehaviour view) : base(view) { }

 protected override void mapBindings()
 {
  injectionBinder.Bind().To(Color.red); // map binding to a model
 }
}
For the sake of simplicity, I hijacked the Color datatype, using Color as our Model. The Color type would normally be replaced with a model interface and injected with a model that uses that interface. The CubeView makes use of the bindings defined in CubeContext.cs to inject the CubeColor from the model.
using UnityEngine;
using strange.extensions.mediation.impl;

public class CubeView : View
{
 [Inject]
 public Color CubeColor {get; set;}

 protected override void Start()
 {
  base.Start();
  this.renderer.material.color = CubeColor;
 }
}
There is much more to StrangeIoC than just these fundamentals. Understanding the flow above will make the StrangeIoC How-To easier to digest. There is also an introductory video on StrangeIoC in this article.

Labels: ,


This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]