Toolbox

From Unify Community Wiki
Jump to: navigation, search

Contents

Introduction

The "Toolbox" is a concept introduced by J.B. Rainsberger in the article Use your singletons wisely. The basic idea being that the application, not the components, should be the singleton. This basically means creating one singleton (the toolbox) that aggregates and manages all other classes that would normally be singletons themselves. This improves upon the concept by reducing coupling and making it much easier to test.

Implementation

Toolbox.cs

using System;
using System.Collections.Generic;
using UnityEngine;
 
public class Toolbox : Singleton<Toolbox>
{
    // Used to track any global components added at runtime.
    private Dictionary<string, Component> m_Components = new Dictionary<string, Component>();
 
 
    // Prevent constructor use.
    protected Toolbox() { }
 
 
    private void Awake()
    {
        // Put initialization code here.
    }
 
 
    // Define all required global components here. These are hard-codded components
    // that will always be added. Unlike the optional components added at runtime.
 
 
    // The methods below allow us to add global components at runtime.
    // TODO: Convert from string IDs to component types.
    public Component AddGlobalComponent(string componentID, Type component)
    {
        if (m_Components.ContainsKey(componentID))
        {
            Debug.LogWarning("[Toolbox] Global component ID \""
                +componentID + "\" already exist! Returning that." );
            return GetGlobalComponent(componentID);
        }
 
        var newComponent = gameObject.AddComponent(component);
        m_Components.Add(componentID, newComponent);
        return newComponent;
    }
 
 
    public void RemoveGlobalComponent(string componentID)
    {
        Component component;
 
        if (m_Components.TryGetValue(componentID, out component))
        {
            Destroy(component);
            m_Components.Remove(componentID);
        }
        else
        {
            Debug.LogWarning("[Toolbox] Trying to remove nonexistent component ID \""
                + componentID + "\"! Typo?");
        }
    }
 
 
    public Component GetGlobalComponent(string componentID)
    {
        Component component;
 
        if (m_Components.TryGetValue(componentID, out component))
        {
            return component;
        }
 
        Debug.LogWarning("[Toolbox] Global component ID \""
    + componentID + "\" doesn't exist! Typo?");
        return null;
    }
}

Requirements

Usage

Any required components should be defined in the toolbox class itself. So for example, let's say we have a very important PlayerData MonoBehaviour. We should create an instance of this in the toolbox and add a public function to allow us to retrieve it.

private PlayerData m_PlayerData = new PlayerData();
 
public PlayerData GetPlayerData()
{
    return m_PlayerData;
}

Now to retrieve this global component we simply use Toolbox.Instance followed by the function we defined in the toolbox.

var playerData = Toolbox.Instance.GetPlayerData();
Debug.Log(playerData.CurrentLevel);

You can also add, get or remove global components at runtime. However, these methods use strings for IDs which are error-prone, so use with cation!

// Add and get a global component.
var playerData = Toolbox.Instance.AddGlobalComponent("PlayerData", PlayerData);
Debug.Log(playerData.CurrentLevel);
 
// Getting a global component.
var playerData = Toolbox.Instance.GetGlobalComponent("PlayerData");
Debug.Log(playerData.CurrentLevel);
 
// Delete existing global component.
Toolbox.Instance.RemoveGlobalComponent("PlayerData");

Note: It's best not to add or delete components directly on the toolbox yourself, since this will likely lead to problems.

Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox