Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEngine;
- using Object = UnityEngine.Object;
- public static class Verfices
- {
- // I just think doing a: Verfices.Register(this); is nicer than Verfices<Type>.Register(this);
- // That's why I wrapped everything up like that - personal preference, don't like it? get rid of it
- public static void Register<T>(T service) where T : class, IService
- {
- VerficesInternal<T>.Register(service);
- }
- public static void Unregister<T>(T service) where T : class, IService
- {
- VerficesInternal<T>.Unregister(service);
- }
- public static void RemoveServiceType<T>() where T : class, IService
- {
- VerficesInternal<T>.UnregisterAll();
- }
- public static T RequestAt<T>(int index) where T : class, IService
- {
- return VerficesInternal<T>.RequestAt(index);
- }
- public static T Request<T>() where T : class, IService
- {
- return VerficesInternal<T>.RequestAt(0);
- }
- public static List<T> RequestAll<T>() where T : class, IService
- {
- return VerficesInternal<T>.RequestAll();
- }
- public static List<T> RequestMany<T>(int n) where T : class, IService
- {
- return VerficesInternal<T>.RequestMany(n);
- }
- public static bool HasRegistered<T>(T service) where T : class, IService
- {
- return VerficesInternal<T>.HasRegistered(service);
- }
- public static int GetServicesCount<T>() where T : class, IService
- {
- return VerficesInternal<T>.ServicesCount;
- }
- public static T CreateService<T>() where T : class, IService
- {
- Type type = typeof(T);
- if (typeof(MonoBehaviour).IsAssignableFrom(type)) {
- var go = new GameObject(type.ToString());
- return go.AddComponent(type) as T;
- }
- return Activator.CreateInstance(type) as T;
- }
- // In case you didn't know, doing a:
- // VerficesInternal<SomeService>.Register(...); and VerficesInternal<SomeOTHERService>.Register(...);
- // the compiler will _not_ create two separate classes - they will use the same place in memory!
- // For more info, see Jamie King's: https://www.youtube.com/watch?v=9eZnUk0Gu7M
- private static class VerficesInternal<T> where T : class, IService
- {
- private static List<T> services = new List<T>();
- public static int ServicesCount { get { return services.Count; } }
- public static void Register(T service)
- {
- if (services.Contains(service))
- throw new RegistrationException("[Vervices]: Service instance: `" + service + "` has already registered!");
- else services.Add(service);
- var mb = service as MonoBehaviour;
- if (mb != null)
- Object.DontDestroyOnLoad(mb);
- }
- // Becareful though - when you register a MonoBehaviour service, it gets marked with DontDestroyOnLoad
- // Unregistering a service, will remove it from the services list so make sure you still have a reference
- // to the service somewhere or else it's a leak
- public static void Unregister(T service)
- {
- services.Remove(service);
- }
- public static T RequestAt(int index)
- {
- AssertNotEmpty();
- // I know, index could be out of bounds I should probably throw an exception if so.
- // But I think it's not neccessary cause accessing an array/list in an out-of-bounds index
- // will throw the exception anyway...
- return services[index];
- }
- public static void UnregisterAll()
- {
- services.Clear();
- }
- public static List<T> RequestAll()
- {
- return services;
- }
- public static List<T> RequestMany(int n)
- {
- AssertNotEmpty();
- if (n > services.Count)
- throw new InvalidOperationException(string.Format(
- "There's only {0} services of type {1}, yet requesting {2}",
- services.Count, typeof(T).Name, n));
- return services.Take(n).ToList();
- }
- public static bool HasRegistered(T service)
- {
- return services.Contains(service);
- }
- private static void AssertNotEmpty()
- {
- if (services.Count == 0)
- throw new InvalidOperationException("No registered services of type `" + typeof(T).Name + "`");
- }
- private class RegistrationException : Exception
- {
- public RegistrationException(string msg) : base(msg) { }
- }
- }
- }
- public interface IService
- {
- void Ping();
- }
- using UnityEngine;
- public class InventoryMan : MonoBehaviour, IService
- {
- void Awake()
- {
- Verfices.Register(this);
- }
- public void Ping()
- {
- Debug.Log(this + ": providing service!");
- }
- void OnDestroy()
- {
- Verfices.Unregister(this);
- }
- }
- using UnityEngine;
- public class AtlasMan : MonoBehaviour, IService
- {
- void Awake()
- {
- Verfices.Register(this);
- }
- public void Ping()
- {
- Debug.Log(this + ": providing service!");
- }
- void OnDestroy()
- {
- Verfices.Unregister(this);
- }
- }
- using System.Collections.Generic;
- using UnityEngine;
- public class User : MonoBehaviour
- {
- void OnGUI()
- {
- if (GUILayout.Button("inventory count"))
- Debug.Log(Verfices.GetServicesCount<InventoryMan>());
- if (GUILayout.Button("atlas count"))
- Debug.Log(Verfices.GetServicesCount<AtlasMan>());
- if (GUILayout.Button("request inventory"))
- Verfices.Request<InventoryMan>().Ping();
- if (GUILayout.Button("request atlas"))
- Verfices.Request<AtlasMan>().Ping();
- if (GUILayout.Button("unregister an inventory service"))
- Verfices.Unregister(Verfices.Request<InventoryMan>());
- if (GUILayout.Button("unregister an atlas service"))
- Verfices.Unregister(Verfices.Request<AtlasMan>());
- if (GUILayout.Button("request all inventories"))
- foreach (var inventory in Verfices.RequestAll<InventoryMan>())
- inventory.Ping();
- if (GUILayout.Button("request all atlas"))
- foreach (var atlas in Verfices.RequestAll<AtlasMan>())
- atlas.Ping();
- if (GUILayout.Button("request 2 atlases"))
- foreach (var atlas in Verfices.RequestMany<AtlasMan>(2))
- atlas.Ping();
- if (GUILayout.Button("request 2 inventories"))
- foreach (var inventory in Verfices.RequestMany<InventoryMan>(2))
- inventory.Ping();
- if (GUILayout.Button("create a new inventory service"))
- Verfices.CreateService<InventoryMan>();
- if (GUILayout.Button("create a new atlas service"))
- Verfices.CreateService<AtlasMan>();
- }
- void Start()
- {
- //Comment this out if you wanna test the OnGUI stuff
- //Test();
- }
- void Test()
- {
- var inventory = Verfices.Request<InventoryMan>();
- var atlas = Verfices.Request<AtlasMan>();
- Debug.Log("Ping test");
- atlas.Ping();
- inventory.Ping();
- Debug.Log("Requesting an atlas man, at index 100");
- Verfices.RequestAt<AtlasMan>(100).Ping();
- Debug.Log("altas manager RequestMany test: requesting 5 out of " + Verfices.GetServicesCount<AtlasMan>());
- List<AtlasMan> many = Verfices.RequestMany<AtlasMan>(5);
- foreach (var atlasMan in many) {
- atlasMan.Ping();
- }
- Debug.Log(string.Format("altas manager RequestMany test: requesting -1 out of {0} (should not get output)", Verfices.GetServicesCount<AtlasMan>()));
- many = Verfices.RequestMany<AtlasMan>(-1);
- foreach (var atlasMan in many) {
- atlasMan.Ping();
- }
- Debug.Log("inventory manager RequestAll test, total: " + Verfices.GetServicesCount<InventoryMan>());
- var all = Verfices.RequestAll<InventoryMan>();
- foreach (var inventoryMan in all) {
- inventoryMan.Ping();
- }
- Debug.Log("unregistering an instance of the atlas manager, then printing all, current total: " + Verfices.GetServicesCount<AtlasMan>());
- Verfices.Unregister(Verfices.Request<AtlasMan>());
- foreach (var atlasMan in Verfices.RequestAll<AtlasMan>())
- atlasMan.Ping();
- Debug.Log("removing the inventory manager service type, and then printing all, shouldn't get anything");
- Verfices.RemoveServiceType<InventoryMan>();
- foreach (var inventoryMan in Verfices.RequestAll<InventoryMan>())
- inventoryMan.Ping();
- Debug.Log("removing the atlas manager service type, and then trying to request many, shouldn't get any output");
- Verfices.RemoveServiceType<AtlasMan>();
- foreach (var atlasMan in Verfices.RequestMany<AtlasMan>(10))
- atlasMan.Ping();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement