Friday, 19 July 2013

Handling Errors

What do you think will happen when you throw an exception anywhere in a MonoBehaviour's callback (e.g. Awake(), Start(), Update(), etc.) and never catch it? Well, nothing much. Your callback will return, so the code following after the exception's origin won't get executed, a message will be printed to the log, and that's it. Your application will keep running, all your MonoBehaviours will keep running, and all of your callbacks, including the one that caused the error, will be called again as normal.

If you are like me and prefer to address serious errors in a timely fashion instead of ignoring them, you'll be soon wondering how to change this strange behaviour and stop the execution of your program on a non-recoverable error. After some research, I've found no standard solution, only three workarounds:
  1. You can wrap every MonoBehaviour callback in a try-catch block and abort on catch.
  2. You can forgo the standard throwing mechanism altogether and call your own routine, something like ThrowException(new Exception()), which will terminate your application. 
  3. You can attach a listener to the log and react if an exception is logged. It will work even if the Player log is turned off in Player settings.
The problem with the solution #1 is that it slows down the performance and is cumbersome to implement and maintain – there are dozens of MonoBehaviour callbacks and more may appear in the future. #2, on the other hand, would be cumbersome to use, since it's essentially an error checking system. It would look like this:

class ErrorHandler extends MonoBehaviour
{
  static function ThrowException(_exception: Exception)
  { 

    if (exception == null) {
      exception = _exception;
    }
  }

  static function HasExceptionHappened(): boolean
  {
    return (exception != null);
  }

  static private var exception: Exception;


  function Update()
  {
    if (exception != null) {
      Debug.LogException(exception);
      exception = null;
      Application.Quit();
    }
  }
}

DoSomething();
if (ErrorHandler.HasExceptionHappened()) return;
DoSomethingElse();
if (ErrorHandler.HasExceptionHappened()) return;


Also, you couldn't force 3rd party scripts to use it anyway. The only sound solution seems to be the #3 (see [1] for more details).



What if you wanted to abort? Application.Quit() is great for exiting under normal conditions, but how do you indicate to the outside world that your application didn't finish peacefully? System.Environment.Exit() doesn't work, neither do System.Environment.ExitCode, System.Diagnostics.Debug or System.Diagnostics.Trace methods. The best bet would be to store the return value into a file or a system registry, where it could be acted upon by an error reporter or whatever running in parallel.

Considering the System.Diagnostics.Debug and System.Diagnostics.Trace don't work, asserts are also not available. And the System.Diagnostics.Contracts.Contract.Assert() is too new to be supported. It's easy to implement your own basic asserts though:

[Conditional("DEBUG")]
static public void Assert(bool _condition, string _message = "")
{
  if (! _condition) {
    Debug.LogError("Assertion failed: " + _message);
    Application.Quit();
  }
}


Notice the “DEBUG” constant. It is not set by default, and in Unity you cannot use #define to make pre-processor defines. They are simply ignored. However, you can specify them in “Edit → Project Settings → Player” under “Scripting Define Symbols” for each platform. It is a little clumsy to write and delete them by hand, but the process could be possibly automated by a script (see PlayerSettings.SetScriptingDefineSymbolsForGroup).

Friday, 5 July 2013

Fun Fact: Unboxing in UnityScript

Let's write a code snippet in UnityScript that stores integers and strings in an associative array:

var container = new Hashtable();

container.Add("property1", 5);

container.Add("property2", "text");

var num: int = container["property1"];
print("num=" + num);


Retrieving the int value from the container emits a warning: “BCW0028: WARNING: Implicit downcast from 'Object' to 'int'.” But, since we want to maintain a clean code, how do we downcast explicitly?

This widely spread construct – var num: int = (int) container["property1"] – doesn't work. The operator as doesn't help neither; it only works for reference types. What do we do?

We turn to parsing text. Yes, seriously, the advice you'll get from every corner of the Unity community[1] and the only one that seems to work flawlessly so far is to use parseInt(). That means the value is printed to a string, then parsed back basically to the same value, but assigned a different type. All of this is going on in this short line of code:

var num: int = parseInt(container["property1"].ToString());

It's great we don't have to send it to a Unity server and wait until they parse it for us. Thank you, guys.

At the end of the day, it's a tough decision: Do we live with a log polluted with warnings, or do we parse text back and forth? Do you know of a better option?



By the way, C# has no issues with unboxing. This snippet works as expected:

var container = new Hashtable();

container.Add("property1", 5);
container.Add("property2", "text");

int num = (int) container["property1"];
Debug.Log("num=" + num);


Tuesday, 2 July 2013

To Singleton or Not To Singleton?

Singleton is a design pattern that ensures there's only one instance of a class at a time. For example, there should be one GameController; it would make no sense to have more of them. The SaveManager and GUI screens would be singletons. In Unity, the general purpose and manager objects will often stand alone and be accessed by many other objects. Does it benefit us to actually make them follow the pattern, or is it enough to simply remember not to create more of them?

Using singletons brings two distinct advantages. One of them is ease of access. Normally, we would have to call the GameController like this:

GameObject.Find("GameController").GetComponent.<GameController>().DoSomething();

If it were a singleton, the task would be much easier:

GameController.GetInstance().DoSomething();

Hence it's more convenient to use and the object is more performance effective to retrieve.

The other benefit is a safety guard. Imagine you have a pause menu script attached to a camera. Later, you want to move it to another object, so you attach it again to that other object, but forget to remove it from the camera. Now you have it twice in the scene, giving you a not that obvious bug – two screens overlapping each other. Singleton allows only one instance, so it would have detected such a mistake immediately, negated its effects and emitted a warning.



A basic (explicitly initialised) singleton implemented in UnityScript would look like this:

class SingletonPattern
{
  static function GetInstance(): SingletonPattern
  {
    if (! instance) {
      throw new System.Exception("No instance created!");
    }
    else {
      return instance;
    }
  }

  static private var instance: SingletonPattern; 



  function SingletonPattern()
  {
    if (instance) {
      throw new System.Exception("Only one instance allowed!");
    }
    else {
      instance = this;
    }
  }

  function DoSomething() {}
}

new SingletonPattern();
SingletonPattern.GetInstance().DoSomething();
 


As you can see, there's a certain amount of boilerplate code involved. Unless you're a typing monkey, you would soon start to wonder how to separate the pattern and use it universally. In UnityScript, you'd have to employ a hash table to store the instances of children:

public class Singleton 
{
  static public function GetInstance(_type: System.Type): Object
  {
    var instance = instances[_type];
    if (! instance) {
      throw new System.Exception("No instance created!");
    }
    else {
      return instance;
    }
  }

  static protected function SetInstance(_instance: Singleton)
  {
    if (instances.ContainsKey(_instance.GetType())) {
      throw new System.Exception("Only one instance of the same type allowed!");
    }
    else {
      instances.Add(_instance.GetType(), _instance);
    }
  }

  static private var instances: Hashtable = new Hashtable();


  protected function Singleton()
  {
    // the instance could be set directly when the object is created,
    // but it would limit child's options

    // SetInstance(this);
  }
}

class SingletonChild extends Singleton
{
  function SingletonChild()
  {
    SetInstance(this);
  }

  function DoSomething() {} 

}

new SingletonChild();
(SingletonChild.GetInstance(SingletonChild) as SingletonChild).DoSomething();


Huh, look at the end-usage – really ugly code. Unfortunately, it's a real pain to have to recast constantly. But there's a better solution... Generics! Switching to C# allows us to write the following version of an explicitly initialised singleton:

abstract public class Singleton<T> where T: Singleton<T>
{
  static public T Instance
  {
    get {
      if (instance == null) {
        throw new System.Exception("No instance created!");
      }
      return instance;
    }

    protected set {
      if (instance != null) {
        throw new System.Exception("Only one instance allowed!");
      }
      instance = value;
    }
  }

  static private T instance;


  protected Singleton()
  {
    // the instance could be set directly when the object is created,
    // but it would limit child's options

    // Instance = (T) this;
  }
}

class SingletonChild : Singleton<SingletonChild>
{
  public SingletonChild()
  {
    Instance = this;
  }

  public void DoSomething() {}
}

new SingletonChild();
SingletonChild.Instance.DoSomething();


If we don't need a special initialisation of the child, it could be even simpler. Providing the child has a public parameterless constructor, we could instantiate it lazily, when it's accessed for the first time:

public class LazySingleton<T> where T: LazySingleton<T>, new()
{
  static public T Instance
  {
    get {
      if (instance == null) {
        instance = new T();
      }
      return instance;
    }

    private set {}
  }

  static private T instance;


  protected LazySingleton()
  {
    if (instance != null) {
      throw new System.Exception("Only one instance allowed!");
    }
  }
}

class LazyChild : LazySingleton<LazyChild>
{
  public LazyChild() {}

  public void DoSomething() {}
}

LazyChild.Instance.DoSomething();




It is all nice and well, but in Unity the MonoBehaviour is our boss. We no longer instantiate objects, so we need to adapt. There's basically no way to prevent creation of several singleton objects. The best we can do is to disable other instances of the same script. The words put into code:

abstract public class MonoSingleton<T> : MonoBehaviour where T: MonoSingleton<T>
{
  static public T Instance
  {
    get {
      if (instance == null) {
        throw new System.Exception("No instance created!");
      }
      else {
        return instance;
      }
    }

    private set {
      if (instance != null) {
        throw new System.Exception("An instance already exists!");
      }
      else {
        instance = value;
      }
    }
  }

  static private T instance;


  protected virtual void Awake ()
  {
    try {
      Instance = (T) this;
    }
    catch (System.Exception) {
      Debug.LogError("Attempted to create another instance of '" + typeof(T).FullName + "'!");
      Destroy(this);
    }
  }
}

class MonoChild : MonoSingleton<MonoChild>
{
  public void DoSomething() {}

  protected override void Awake ()
  {
    base.Awake();
  }
}

MonoChild.Instance.DoSomething();




Alas, you would run into a wall if you wanted to extend the MonoChild for some reason. First, you'd have to cast whenever you retrieved the instance, because it's already set to the MonoChild type. Second, you could use only the MonoChild or one of its children, because the singleton instance is inherited by all the descendants and it's enforced to be unique given the same base type (i.e. the MonoChild). This can be worked around by separating the members you want to extend and the implementation of the singleton, utilizing nested classes. We will call the singleton MonoBehaviour a Wrapper and the extendible logic a Payload. Their relationship may be confusing at first, but it's enough to realise that you can derive from a Payload at will, whilst a Wrapper will only envelope the scripts you'll intend to use in the scene and will not be extended further. The following dry example demonstrates the approach:

abstract public class MonoSingletonWrapper<T> : MonoBehaviour where T: MonoSingletonPayload, new()
{
  public abstract class MonoSingletonPayload
  {} 



  static public T Instance
  {
    get {
      if (instance == null) {
        throw new System.Exception("No instance created!");
      }
      else {
        return instance;
      }
    }

    private set {
      instance = value;
    }
  }

  static private T instance;


  protected virtual void Awake ()
  {
    if (instance != null) {
      Debug.LogError("Attempted to create another instance of '" + GetType().FullName + "'!");
      Destroy(this);
    }
    else {
      Instance = new T();
    }
  }
}

abstract class MonoBase<T> : MonoSingletonWrapper<T>.MonoSingletonPayload where T: MonoBase<T>, new()
{
  public MonoBase() {}

  public abstract void DoSomething();
}

sealed class MonoBaseChild1 : MonoSingletonWrapper<MonoBaseChild1.MonoChild1Payload>
{
  public class MonoChild1Payload : MonoBase<MonoChild1Payload>
  {

    public MonoChild1Payload() {}

    public override void DoSomething() {}
  }
}


sealed class MonoBaseChild2 : MonoSingletonWrapper<MonoBaseChild2.MonoChild2Payload>
{
  public class MonoChild2Payload : MonoBase<MonoChild2Payload>
  {

    public MonoChild2Payload() {}

    public override void DoSomething() {}
  }
}


MonoBaseChild1.Instance.DoSomething();
MonoBaseChild2.Instance.DoSomething();


Here, MonoBaseChild1 and MonoBaseChild2 are actually two separate objects, which logically derive from the MonoBase, are both singletons, and can coexist at the same time.



Of course, sometimes you can end up in a situation when the generic programming is simply not an option. A compiler for a mobile platform may not support certain generic constructs, or you may be limited to the UnityScript. In such cases, beside “baking” the singleton pattern introduced at the beginning, you can also turn to a static class initialised by a MonoBehaviour, or rather a MonoBehaviour that behaves like a static class:

public class StaticMono extends MonoBehaviour
{
  function Awake()
  {
    var instances = FindObjectsOfType(GetType());
    if (instances && instances.Length > 1) {
      // removing the component here would remove all instances of the script,
      // which could lead to a potential instability

      throw new System.Exception("Created several instances of '" + GetType().FullName + "'!");
    }
  }
}

class StaticMonoChild extends StaticMono
{
  static function DoSomething()
  {
    something += 5;
    print(exposedVarCopy);
  }

  static private var something: int;
  static private var exposedVarCopy: int;


  var exposedVar: int;

  function Awake()
  {
    super.Awake();
    

    something = 10;
    exposedVarCopy = exposedVar;
  }
}

// if it's called before StaticMonoChild.Awake(), the behaviour is undefined
StaticMonoChild.DoSomething();


It does not provide an instance (though it may be looked up if need be), but in most cases it's not needed anyway. The only major drawback is invalid accessing of static members before they're initialised or after they're deinitialised. You can either check in each method whether the initialisation has run, which is annoying, or tweak the script's execution order and hope you were careful enough not to call anything too early, which is unsafe. I think the most viable option is to put all data fields in a private nested class and then create a private static instance of it in Awake(). This way a premature access will trigger a NullReferenceException, which is better than nothing. Variables exposed to the editor can then be copied from the outer shell to the internal state when it's created. Like this:

class StaticMonoSafer extends StaticMono
{
  private class InnerState
  {
    function InnerState(_outer: StaticMonoSafer)
    {
      something = 10;
      exposedVarCopy = _outer.exposedVar;
    }

    var something: int;
    var exposedVarCopy: int;
  }

  static function DoSomething()
  {
    state.something += 5;
    print(state.exposedVarCopy);
  }

  static private var state: InnerState;


  var exposedVar: int;

  function Awake()
  {
    super.Awake();

    state = new InnerState(this);
  }
}

// if it's called before StaticMonoSafer.Awake(), NullReferenceException is thrown
StaticMonoSafer.DoSomething();


All in all, this should be a provisional solution when no better options are available.



Disclosure: I intentionally omitted releasing static references to make the examples more compact. A final implementation should take care to free all the references as soon as they are not needed, because they block the memory occupied by singleton objects even after the objects are seemingly released. (Well, at least in some cases.)