Skip to content

Instantly share code, notes, and snippets.

@DanPuzey
Created October 26, 2015 17:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DanPuzey/21d578c8b602ea2345fe to your computer and use it in GitHub Desktop.
Save DanPuzey/21d578c8b602ea2345fe to your computer and use it in GitHub Desktop.
Prototype Unity3d service locator (nicer than singletons!)
using UnityEngine;
namespace FunkyGeek.Core
{
/// <summary>
/// Adds a list of components (typically from this or child GameObjects) to the global registry.
/// </summary>
public class AddToRegistry : MonoBehaviour
{
public Object[] ObjectsToAdd;
private void Awake()
{
foreach (var o in ObjectsToAdd)
{
Registry.Add(o);
}
}
}
}
using System;
using System.Collections.Generic;
using UEObject = UnityEngine.Object;
namespace FunkyGeek.Core
{
/// <summary>
/// Tracks and returns singleton instances of Unity objects.
/// </summary>
public static class Registry
{
private static Dictionary<Type, WeakReference> _registeredObjects = new Dictionary<Type, WeakReference>();
public static void Add<T>(T value) where T : UEObject
{
var key = typeof(T);
WeakReference reference;
if (_registeredObjects.TryGetValue(key, out reference))
{
if (!reference.IsAlive || reference.Target == null)
{
Log.MessageFormat("REGISTRY: replacing destroyed instance for type '{0}' with new object.", key.FullName);
_registeredObjects[key] = new WeakReference(value);
}
else
{
Log.ErrorFormat("REGISTRY: cannot replace existing value of type '{0}'.", key.FullName);
}
}
else
{
Log.MessageFormat("REGISTRY: registering new object for type '{0}'.", key.FullName);
_registeredObjects.Add(key, new WeakReference(value));
}
}
public static T Get<T>() where T : UEObject
{
var key = typeof(T);
WeakReference reference;
if (_registeredObjects.TryGetValue(key, out reference))
{
if (!reference.IsAlive || reference.Target == null)
{
Log.ErrorFormat("REGISTRY: the registered instance of type '{0}' has been destroyed.", key.FullName);
return null;
}
else
{
var stronglyTyped = reference.Target as T;
if (stronglyTyped == null)
{
Log.ErrorFormat("REGISTRY: Object was not of expected type. Expecting '{0}' but got '{1}'.", key.FullName, reference.GetType().FullName);
}
return stronglyTyped;
}
}
else
{
Log.ErrorFormat("REGISTRY: there is no registered instance of type '{0}'", key.FullName);
return null;
}
}
}
}
@DanPuzey
Copy link
Author

The static Registry class allows components to be registered through code, or through the AddToRegistry component. You can then retrieve an instance of a type by calling Registry.Get<MyComponent>().

This is currently untested code - knocked up in a text editor in an idle moment and yet to be tested in a real project!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment